Примеры программ со структурами c. Структура программ на языке си

В программах на языке си - существует некая последовательность:

Для начала мы добавляем нужные нам библиотеки #include Если файл находится в текущем каталоге проекта, он указывается в кавычках. Для файла, находящегося в другом каталоге необходимо в кавычках указать полный путь.

#include
#include «math.h»

После чего Мы можем добавить нужные нам константы #define A 3

После этого начинается функция, командой Main ()

После того как всё выполнено можно ввести getchar ()

2. Для чего в языке Си служит точка с запятой?

Для обозначения конца оператора в языке Си используется точка с запятой

3. Все ли компиляторы Си требуют использования в программе инструкции return?

Для возврата целочисленного значения перед завершением функции дописывается строка

Также в большенстве случаев return означает выход из фуннкции

Операторы тела функции выполняются до первого оператора return. Если в теле функции нет такого оператора (т.е. функция не возвращает никакого результата), то выполняются все операторы до закрывающейся операторной скобки.

Функция вывода элементов массива на печать не возвращает никакого результата, т.е. в теле функции оператор return отсутствует.

4. С какой целью в текст программы вводятся комментарии?

Коментарии вводятся для пояснения того или иного действия

например Printf (‘’Hello World’’) ; // выведем на экран надпись Hello World

Так же коментарии можно ввести символами /* - в начале */ - в конце коментария

5. Для чего при вызове функции используются параметры?

Ссылка - это по сути второе имя того же самого объекта. Когда в функцию передаётся объект по ссылке, то передаётся фактически этот объект. Когда же мы передаём объект по значению, то в функцию передаётся его копия.

void func_1(int a) // передача по значению

6. Все ли функции требуют передачи параметров при вызове?

На мой взгляд совершенно не все, ведь мы можем с лёгкостью записать функцию типа main() без передчи параметров по значению

1. Что такое тип данных char?

Тип данных char - это целочисленный тип данных, который используется для представления символов. То есть, каждому символу соответствует определённое число из диапазона . Тип данных char также ещё называют символьным типом данных, так как графическое представление символов в С++ возможно благодаря char. Для представления символов в C++ типу данных char отводится один байт, в одном байте - 8 бит, тогда возведем двойку в степень 8 и получим значение 256 - количество символов, которое можно закодировать. Таким образом, используя тип данных char можно отобразить любой из 256 символов. Все закодированные символы представлены в таблице ASCII.

2. Чем символ "3" отличается от числа 3?

символ 3 отличается от целого числа 3 тем, что символ не может быть использован в арифметических операциях

3. В чем заключается различие между константой и переменной?

Различие между переменной и константой довольно очевидно: во время выполнения программы значение переменной может быть изменено (например, с помощью присваивания), а значение константы - нет

4. Как определить константу?

Константы в С++ аналогичны константам в Си. Для представления константы в Си использовалась только директива препроцессора #define:

const тип ИмяПеременной = НачальноеЗначение;

Область видимости константы такая же, как у обычной переменной. С помощью ключевого слова const можно объявить указатель на константу

5. Поддерживает ли Си строковый тип данных?

Язык Си не поддерживает отдельный строковый тип данных, но он позволяет определить строки двумя различными способами. В первом используется массив символов, а во втором - указатель на первый символ массива.

6. Сохраняет ли переменная свое значение в ходе выполнения всей программы?

во время выполнения программы значение переменной может быть изменено (например, с помощью присваивания), а значение константы - нет

7. Как изменить значение константы?

1. В чем заключаются различия между escape-последовательностями \n и \r?

Грубо говоря, предполагалось, что \r обнулит номер символа. оставляя неизменным номер строки (т.е. сдвинет каретку пишущей машинки к началу строки, не трогая бумагу), а \n - наоборот, сделает переход к следующей строке, оставляя текущую позицию печати неизменной (прокрутит бумагу, не трогая каретку).

2. Как вывести на экран символ «кавычка»?

printf("My text is: \"my text\"\n");

3. Из каких двух частей состоит список параметров функции printf()?

При печати какого либо числа или выражения сначала пишется Printf ()

В скобках, в начале в кавычках пишем нужные нам данные, а именно

%с – одиночный символ
%d – десятичное целое число со знаком
%f – число с плавающей точкой (десятичное представление)
%s – строка символов (для строковых переменных)
%u – десятичное целое без знака
%% - печать знака процента

Например:

printf ("x=%5i\ty=%f\tz=%7.3f\n",x, y, z);

4. Какие преимущества имеет функция printf() по сравнению с puts()?

5. Что такое указатель формата?

Читает значение с плавающей точкой (только C99)

Аналогично коду %a (только C99)

Читает один символ

Читает десятичное целое

Читает целое в любом формате (десятичное, восьмеричное или шестнадцатеричное)

Аналогично коду %e

Читает число с плавающей точкой

Аналогично коду %f (только С99)

Читает число с плавающей точкой

Аналогично коду %g

Читает восьмеричное число

Читает строку

Читает шестнадцатеричное число

Аналогично коду %x

Читает указатель

Принимает целое значение, равное количеству прочитанных до сих пор символов

Читает десятичное целое без знака

Просматривает набор символов

Читает знак процента

6. Как вывести на экран значение числовой переменной?

Вывести её значение можно с помощью функции Printf()

printf("%7.3f\t%7.3f\n",x,y);

%<количество_позиций_под_значение>.<количество_позиций_под_дробную_часть>f

%<количество_позиций_под_значение>i

Программа, написанная на C# состоит из следующих блоков:

  • объявление пространства имен (своего рода контейнера);
  • объявление класса (основная сущность программы);
  • методы класса (подпрограммы), как минимум метод Main ;
  • операторы и выражения;
  • комментарии.

Пример простейшей программы

Давайте рассмотрим простейшую программу, написанную на C#. Это будет консольное приложение, выводящее строку «Hello World» (своего рода классика, для первой программы в практике программиста). Код такой программы приведен ниже, давайте рассмотрим его:

//Подключение пространства имен System using System; //Объявление пространства имен namespace ProgramStructure { //Объявление класса class Program { //Главный метод программы static void Main(string args) { //Вывод строки Console.WriteLine("Hello World!"); //Вспомогательный оператор Console.ReadKey(); } } }

Первая строка данной программы, это комментарий. Комментарии никак не влияют на работу программы, они нужны для человека, который будет сопровождать код программы (дорабатывать её, исправлять ошибки и т.п.).

Вторая строка программы (using System; ) является оператором, который подключает стандартное пространство имен System . По сути, мы получаем доступ к набору классов имеющихся в «контейнере» System . Как видно, данная строка состоит из двух слов, первое (ключевое слово using ) означает, что мы хотим подключить пространство имен, а второе System — название нужного пространства имен.

В конце второй строки стоит символ «;», который обозначает завершение оператора. Каждый оператор программы должен заканчиваться таким символом.

Четвертая строка программы снова является комментарием, ровно как и строки 7, 10, 13, 15. Комментарии в C# начинаются с символов «//» (две косые черты, два слэша), и действуют только до конца строки.

В C# есть и многострочные комментарии, иногда удобнее использовать их, мы еще столкнемся с ними.

В пятой строке (namespace ProgramStructure ) объявляется своё пространство имен, оно называется «ProgramStructure». Пространство имен является своего рода контейнером, и оно ограничивается фигурными скобками (открывающей — строка 6 и закрывающей — строка 19), следующими за его названием. Таким образом, все что находится между строками 6 и 19 принадлежит пространству имен ProgramStructure .

В строке 8 объявляется класс с именем «Program», это основной и единственный класс нашей программы. Как можно заметить, для объявления класса служит ключевое слово class за которым следует имя класса. В программе, может быть и не один, а несколько классов. Как правило, класс состоит из набора методов, которые определяют так называемое поведение класса (если хотите, функциональность). Границы класса, так же как и пространства имен обозначаются фигурными скобками (строки 9 и 18). В нашем случае, класс имеет только один метод, это метод Main .

В строке 11 как раз и объявляется метод Main . Этот метод является главным в нашей программе, так называемая точка входа в программу. Это означает, что при запуске программы, первым будет выполняться именно метод Main . Каждый метод тоже имеет границы, которые так же обозначаются фигурными скобками (строки 12 и 17).

Метод Main нашей программы содержит только два оператора. Эти операторы значатся в строках 14 и 16. Первый выводит сообщение «Hello World!». А второй, является вспомогательным, он заставляет программу ждать нажатие клавиши на клавиатуре, и не дает её до этого момента завершить свое выполнение (без этого оператора, программа бы вывела строку и быстро закрылась, так что мы даже не успели прочитать что она вывела).

А теперь попробуйте собрать и запустить это программу в Visual Studio. Для этого нужно:

  • запустить Visual Studio;
  • создать новый проект консольного приложения;
  • скопировать строки 13-16 из приведенного выше примера;
  • вставить эти строки в метод Main созданного в Visual Studio проекта;
  • нажать клавишу F5.

О том как создавать проект консольного приложения в Visual Studion я подробно рассказывал в , советую прочитать его.

Пожалуйста, приостановите работу AdBlock на этом сайте.

Я надеюсь вы уже установили себе на компьютер какую-нибудь IDE и научились в ней компилировать программы. Если нет, то

Все программы, написанные на языке Си, имеют общую структуру. О которой мы и поговорим в этом уроке. В этом нам поможет наша первая программа, написанная на предыдущем шаге.

Будем заполнять простую карту. На данный момент мы знаем, что существуют программы, но как они устроены внутри нам неизвестно. Поэтому наша карта будет иметь следующий вид.

Рис.1 Карта "Структура программ на языке Си." Начальный уровень.

На протяжении всего курса мы к этой карте будем возвращаться, уточнять её, дополнять новыми элементами и блоками.

Сейчас внимание. Не пугайтесь! Ниже написан исходный код трёх простеньких программ. Ваша задача внимательно на них посмотреть и попытаться найти в их коде какую-то закономерность (нечто общее, что есть в каждой программе).

Листинг 1. Программа 1. Печатает «Hello, World!»

#include

Листинг 2. Программа 2

Int main(void) { int a, b, c; a = 5; b = 10; c = a+b; return 0; }

Листинг 3. Программа 3

#include int main(void) { FILE *fp; fp = fopen("input.txt", "w"); fprintf(fp, "This is Sparta!"); fclose(fp); return 0; }

Не торопитесь смотреть продолжение урока и правильный ответ на эту задачу. Для начала попробуйте ответить самостоятельно. После этого нажмите кнопку "Смотреть продолжение!"

Итак, ответ: Во всех программах выше присутствует следующая конструкция:

Листинг 4. Главная функция любой программы на языке Си - функция main.

Int main(void) { return 0; }

Что же это за конструкция. Это объявление функции main. Такая функция обязательно есть в каждой программе, которая написана на языке Си.Большая программа или маленькая, компьютерная игра или программа "Hello, World!", написана вами или Биллом Гейтсом -- если программа написана на языке Си -- в ней есть функция main. Это так сказать главная функция нашей программы. Когда мы запускаем программу, то можно думать, что запускаем функцию main этой программы.

Остановимся на секундочку. Мы, кажется, уже кое-что выяснили о структуре программ на языке Си. Любая программа на языке Си должна содержать функцию main. Отобразим этот факт на нашей карте знаний "Структура программ на языке Си."

Рис.2 Карта "Структура программ на языке Си." Функция main.

Теперь карта не напрягает нас своей зияющей пустотой. Продолжим наши исследования.

Давайте я расскажу немного о функции main и о функциях вообще.

Перед именем функции написано int, это сокращение от слова integer, которое переводится с английского, как "целое". Подобная запись означает, что когда функция main завершит свою работу, она должна вернуть вызывающей программе (в нашем случае это операционная система) какое-нибудь целое число. Обычно, для функции main это число ноль, которое оповещает операционную систему: "Мол, всё хорошо. Происшествий не случилось."

Случалось ли вам видеть сообщения об ошибках на экране своего компьютера? Обычно там пишут что-то вроде "Программа аварийно завершена... бла-бла-бла... Код -314." Вот это примерно тоже самое. Разница в том, что когда случаются проблемы операционная система нас об этом оповещает, а когда всё хорошо она нас лишний раз не беспокоит.

После имени функции в скобках записано слово void. Вообще в скобках обычно записывают аргументы функции, но в нашем случае, когда в скобках пишут void, это означает, что аргументов у функции нет. Другими словами, чтобы функция main начала работу ей не нужны никакие дополнительные данные извне. Мы ещё поговорим обо всём этом подробно, а пока просто запомним, что слово void вместо аргументов функции обозначает, что для данной функции никаких аргументов не требуется.

Внутри фигурных скобок идёт описание функции main, т.е. непосредственно то, что эта функция должна делать.

Перед закрывающей фигурной скобкой мы видим команду return. Именно эта команда и отвечает за то, чтобы вернуть значение из функции. Т.е. смотрите, если программа дошла до этого места, то значит всё было хорошо и никаких ошибок не возникло, а значит можно вернуть значение нуль.

Вы можете спросить, а почему именно нуль? А чёрт его знает! Просто так обычно делают. Можно, в принципе, возвращать какое-нибудь другое целое число, например 100, или -236. Лишь бы оно было целым числом. Помните про int? Поэтому и целое.

Вот мы и разобрались с функцией main. Ещё один момент. То что записано в фигурных скобках обычно называют "тело функции" (или описание функции), а первую часть, та что перед фигурными скобками называется заголовок функции.

Вернёмся теперь к нашей первой программе "Hello, World" и посмотрим, что там к чему.

Листинг 5. Программа «Hello, World»

#include int main(void) { printf("Hello, World!\n"); return 0; }

Кое-что нам теперь уже понятно в этой программе. Не ясными остаются только две строки, пойдём по порядку.

Листинг 6. Директива include

#include

Данная строчка это сообщение компилятору. Такие сообщения, начинающиеся с символа #, называются директивами компилятора. Буквально: «подключи файл stdio.h». Во время компиляции вместо этой строчки вставится содержимое файла stdio.h. Теперь немного поговорим об этом файле. stdio.h (от англ. STanDart Input Output) это заголовочный файл, в нем описаны различные стандартные функции, связанные с вводом и выводом.

Возникает резонный вопрос "А зачем нам писать эту строчку? Зачем нам вообще понадобилось вставлять сюда этот файл?" Это нужно для того, что бы в своей программе, мы могли использовать стандартную функцию вывода на экран printf().

Дело вот в чем. Прежде чем использовать что-нибудь в своей программе, нам надо сначала это описать. Представьте ситуацию, вас попросили принести канделябр, а вы знать не знаете что это такое. Непонятно, что делать.

Так же и компилятор. Когда он встречает какую-нибудь функцию, он ищет её описание (т.е. что она должна делать и что обозначает) в начале программы (с самого начала и до момента её использования в программе). Так вот, функция printf() описана в файле stdio.h. Поэтому мы и подключаем его. А вот когда мы его подключим, компилятор сможет найти функцию printf(), иначе он выдаст ошибку.

Кстати, настало время дополнить нашу карту знаний. Перед функцией main добавим ещё один блок, блок подключения заголовочных файлов.

Рис.3 Карта "Структура программ на языке Си." Блок подключения заголовочных файлов.

Продолжим разбираться с нашей программой.

Листинг 7. функция printf()

Printf("Hello, World!\n");

В этой строке мы вызываем стандартную функцию вывода на экран printf(). В данном простейшем случае мы передаем ей один параметр, строку, записанную в кавычках, которую надо вывести на экран, в нашем случае это Hello, World! \n. Но постойте, а что это за \n? На экране, во время запуска программы, никаких \n не было. Зачем тогда мы тут это написали? Данная последовательность это специальный символ, который является командой перейти на следующую строку. Это как в MS Word нажать клавишу Enter. Таких специальных символов несколько, все они записываются с помощью символа "\" - обратный слеш. Такие специальны символы называются управляющими символами. Потом я еще покажу вам их. В остальном на экране появится именно то, что вы написали в двойных кавычках.

Кстати, обратите внимание, каждая команда языка Си заканчивается символом «;» (точкой с запятой). Это похоже на точку в конце предложения, в русском языке. В обычном языке мы разделяем точкой предложения, а в языке программирования Си, точкой с запятой отделяем команды друг от друга. Поэтому ставить точку с запятой обязательно. Иначе компилятор будет ругаться и выдаст ошибку.

Чтобы вызвать какую-нибудь функцию, необходимо написать её имя и указать передаваемые ей параметры в круглых скобках. У функции может быть один или несколько параметров. А может не быть параметров вовсе, в таком случае в скобках писать ничего не нужно. Например, выше мы вызвали функцию printf() и передали ей один параметр строку, которую необходимо вывести на экран.

Кстати, полезный совет. Так как в каждой программе обязательно присутствует функция main, и буквально в каждой программе нам потребуется что-то выводить на экран, то рекомендую вам сразу создать файл со следующей заготовкой, чтобы каждый раз не писать одно и то же.

Листинг 8. Стандартная заготовка для программ на языке Си.

#include int main(void) { return 0; }

Ну вот вроде бы и всё. Этом первый урок можно считать законченным. Хотя нет, ещё один момент есть.

Самое главное в этом уроке это, конечно, общая структура программы. Но кроме того, мы научились выводить на экран произвольный текст. Кажется, что совсем ничего вроде и не узнали, но даже этого хватит для того, чтобы, например, сделать небольшой подарок своей маме на 8 марта.


Исходный код программы-открытки есть в архиве с исходными кодами этого урока. Экспериментируйте! У вас всё получится.

Из чего состоит программа

Для начала стоит понять, что программу нельзя читать и писать как книгу: от корки до корки, сверху вниз, строку за строкой. Любая программа состоит из отдельных блоков. Начало блока кода в C/C++ обозначается левой фигурной скобкой { , его конец - правой фигурной скобкой } .

Блоки бывают разных видов и какой из них когда будет исполняться зависит от внешних условий. В примере минимальной программы вы можете видеть 2 блока. В этом примере блоки называются определением функции . Функция - это просто блок кода с заданным именем, которым кто-то затем может пользоваться из-вне.

В данном случае у нас 2 функции с именами setup и loop . Их присутствие обязательно в любой программе на C++ для Arduino. Они могут ничего и не делать, как в нашем случае, но должны быть написаны. Иначе на стадии компиляции вы получите ошибку.

Классика жанра: мигающий светодиод

Давайте теперь дополним нашу программу так, чтобы происходило хоть что-то. На Arduino, к 13-му пину подключён светодиод. Им можно управлять, чем мы и займёмся.

void setup() { pinMode(13 , OUTPUT) ; } void loop() { digitalWrite(13 , HIGH) ; delay(100 ) ; digitalWrite(13 , LOW) ; delay(900 ) ; }

Скомпилируйте, загрузите программу. Вы увидите, что каждую секунду светодиод на плате помигивает. Разберёмся почему этот код приводит к ежесекундному миганию.

Каждое выражение - это приказ процессору сделать нечто. Выражения в рамках одного блока исполняются одно за другим, строго по порядку без всяких пауз и переключений. То есть, если мы говорим об одном конкретном блоке кода, его можно читать сверху вниз, чтобы понять что делается.

Теперь давайте поймём в каком порядке исполняются сами блоки, т.е. функции setup и loop . Не задумывайтесь пока что значат конкретные выражения, просто понаблюдайте за порядком.

    Как только Arduino включается, перепрошивается или нажимается кнопка RESET , «нечто» вызывает функцию setup . То есть заставляет исполняться выражения в ней.

    Как только работа setup завершается, сразу же «нечто» вызывает функцию loop .

    Как только работа loop завершается, сразу же «нечто» вызывает функцию loop ещё раз и так до бесконечности.

Если пронумеровать выражения по порядку, как они исполняются, получится:

void setup() { pinMode(13 , OUTPUT) ; ❶ } void loop() { digitalWrite(13 , HIGH) ; ❷ ❻ ❿ delay(100 ) ; ❸ ❼ … digitalWrite(13 , LOW) ; ❹ ❽ delay(900 ) ; ❺ ❾ }

Ещё раз напомним, что не стоит пытаться воспринимать всю программу, читая сверху вниз. Сверху вниз читается только содержимое блоков. Мы вообще можем поменять порядок объявлений setup и loop .

void loop() { digitalWrite(13 , HIGH) ; ❷ ❻ ❿ delay(100 ) ; ❸ ❼ … digitalWrite(13 , LOW) ; ❹ ❽ delay(900 ) ; ❺ ❾ } void setup() { pinMode(13 , OUTPUT) ; ❶ }

Результат от этого не изменится ни на йоту: после компиляции вы получите абсолютно эквивалентный бинарный файл.

Что делают выражения

Теперь давайте попробуем понять почему написанная программа приводит в итоге к миганию светодиода.

Как известно, пины Arduino могут работать и как выходы и как входы. Когда мы хотим чем-то управлять, то есть выдавать сигнал, нам нужно перевести управляющий пин в состояние работы на выход. В нашем примере мы управляем светодиодом на 13-м пине, поэтому 13-й пин перед использованием нужно сделать выходом.

Это делается выражением в функции setup:

PinMode(13 , OUTPUT) ;

Выражения бывают разными: арифметическими, декларациями, определениями, условными и т.д. В данном случае мы в выражении осуществляем вызов функции . Помните? У нас есть свои функции setup и loop , которые вызываются чем-то, что мы назвали «нечто». Так вот теперь мы вызываем функции, которые уже написаны где-то.

Конкретно в нашем setup мы вызываем функцию с именем pinMode . Она устанавливает заданный по номеру пин в заданный режим: вход или выход. О каком пине и о каком режиме идёт речь указывается нами в круглых скобках, через запятую, сразу после имени функции. В нашем случае мы хотим, чтобы 13-й пин работал как выход. OUTPUT означает выход, INPUT - вход.

Уточняющие значения, такие как 13 и OUTPUT называются аргументами функции . Совершенно не обязательно, что у всех функций должно быть по 2 аргумента. Сколько у функции аргументов зависит от сути функции, от того как её написал автор. Могут быть функции с одним аргументом, тремя, двадцатью; функции могут быть без аргументов вовсе. Тогда для их вызова круглые скобка открывается и тут же закрывается:

NoInterrupts() ;

На самом деле, вы могли заметить, наши функции setup и loop также не принимают никакие аргументы. И загадочное «нечто» точно так же вызывает их с пустыми скобками в нужный момент.

Вернёмся к нашему коду. Итак, поскольку мы планируем вечно мигать светодиодом, управляющий пин должен один раз быть сделан выходом и затем мы не хотим вспоминать об этом. Для этого идеологически и предназначена функция setup: настроить плату как нужно, чтобы затем с ней работать.

Перейдём к функции loop:

void loop() { digitalWrite(13 , HIGH) ; delay(100 ) ; digitalWrite(13 , LOW) ; delay(900 ) ; }

Она, как говорилось, вызывается сразу после setup . И вызывается снова и снова как только сама заканчивается. Функция loop называется основным циклом программы и идеологически предназначена для выполнения полезной работы. В нашем случае полезная работа - мигание светодиодом.

Пройдёмся по выражениям по порядку. Итак, первое выражение - это вызов встроенной функции digitalWrite . Она предназначена для подачи на заданный пин логического нуля (LOW , 0 вольт) или логической единицы (HIGH , 5 вольт) В функцию digitalWrite передаётся 2 аргумента: номер пина и логическое значение. В итоге, первым делом мы зажигаем светодиод на 13-м пине, подавая на него 5 вольт.

Как только это сделано процессор моментально приступает к следующему выражению. У нас это вызов функции delay . Функция delay - это, опять же, встроенная функция, которая заставляет процессор уснуть на определённое время. Она принимает всего один аргумент: время в миллисекундах, которое следует спать. В нашем случае это 100 мс.

Пока мы спим всё остаётся как есть, т.е. светодиод продолжает гореть. Как только 100 мс истекают, процессор просыпается и тут же переходит к следующему выражению. В нашем примере это снова вызов знакомой нам встроенной функции digitalWrite . Правда на этот раз вторым аргументом мы передаём значение LOW . То есть устанавливаем на 13-м пине логический ноль, то есть подаём 0 вольт, то есть гасим светодиод.

После того, как светодиод погашен мы приступаем к следующему выражению. И снова это вызов функции delay . На этот раз мы засыпаем на 900 мс.

Как только сон окончен, функция loop завершается. По факту завершения «нечто» тут же вызывает её ещё раз и всё происходит снова: светодиод поджигается, горит, гаснет, ждёт и т.д.

Если перевести написанное на русский, получится следующий алгоритм:

    Поджигаем светодиод

    Спим 100 миллисекунд

    Гасим светодиод

    Спим 900 миллисекунд

    Переходим к пункту 1

Таким образом мы получили Arduino с маячком, мигающим каждые 100 + 900 мс = 1000 мс = 1 сек.

Что можно изменить

Давайте пользуясь только полученными знаниями сделаем несколько вариаций программы, чтобы лучше понять принцип.

Вы можете подключить внешний светодиод или другое устройство, которым нужно «мигать» на другой пин. Например, на 5-й. Как в этом случае должна измениться программа? Мы должны всюду, где обращались к 13-му пину заменить номер на 5-й:

Компилируйте, загружайте, проверяйте.

Что нужно сделать, чтобы светодиод мигал 2 раза в секунду? Уменьшить время сна так, чтобы в сумме получилось 500 мс:

void setup() { pinMode(5 , OUTPUT) ; } void loop() { digitalWrite(5 , HIGH) ; delay(50 ) ; digitalWrite(5 , LOW) ; delay(450 ) ; }

Как сделать так, чтобы светодиод при каждом «подмигивании» мерцал дважды? Нужно поджигать его дважды с небольшой паузой между включениями:

void setup() { pinMode(5 , OUTPUT) ; } void loop() { digitalWrite(5 , HIGH) ; delay(50 ) ; digitalWrite(5 , LOW) ; delay(50 ) ; digitalWrite(5 , HIGH) ; delay(50 ) ; digitalWrite(5 , LOW) ; delay(350 ) ; }

Как сделать так, чтобы в устройстве были 2 светодиода, которые мигали бы каждую секунду поочерёдно? Нужно общаться с двумя пинами и работать в loop то с одним, то с другим:

void setup() { pinMode(5 , OUTPUT) ; pinMode(6 , OUTPUT) ; } void loop() { digitalWrite(5 , HIGH) ; delay(100 ) ; digitalWrite(5 , LOW) ; delay(900 ) ; digitalWrite(6 , HIGH) ; delay(100 ) ; digitalWrite(6 , LOW) ; delay(900 ) ; }

Как сделать так, чтобы в устройстве были 2 светодиода, которые переключались бы на манер железнодорожного светофора: горел бы то один то другой? Нужно просто не выключать горящий светодиод тут же, а дожидаться момента переключения:

void setup() { pinMode(5 , OUTPUT) ; pinMode(6 , OUTPUT) ; } void loop() { digitalWrite(5 , HIGH) ; digitalWrite(6 , LOW) ; delay(1000 ) ; digitalWrite(5 , LOW) ; digitalWrite(6 , HIGH) ; delay(1000 ) ; }

Можете проверить другие идеи самостоятельно. Как видите, всё просто!

О пустом месте и красивом коде

В языке C++ пробелы, переносы строк, символы табуляции не имеют большого значения для компилятора. Там где стоит пробел, может быть перенос строки и наоборот. На самом деле 10 пробелов подряд, 2 переноса строки и ещё 5 пробелов - это всё эквивалент одного пробела.

Пустое пространство - это инструмент программиста, с помощью которого можно или сделать программу понятной и наглядной, или изуродовать до неузнаваемости. Например, вспомним программу для мигания светодиодом:

void setup() { pinMode(5 , OUTPUT) ; } void loop() { digitalWrite(5 , HIGH) ; delay(100 ) ; digitalWrite(5 , LOW) ; delay(900 ) ; }

Мы можем изменить её так:

void setup( ) { pinMode(5 , OUTPUT) ; } void loop () { digitalWrite(5 ,HIGH) ; delay(100 ) ; digitalWrite(5 ,LOW) ; delay(900 ) ; }

Всё, что мы сделали - немного «поработали» с пустым пространством. Теперь можно наглядно видеть разницу между стройным кодом и нечитаемым.

Чтобы следовать негласному закону оформления программ, который уважается на форумах, при чтении другими людьми, легко воспринимается вами же, следуйте нескольким простым правилам:

1. Всегда, при начале нового блока между { и } увеличивайте отступ. Обычно используют 2 или 4 пробела. Выберите одно из значений и придерживайтесь его всюду.

Плохо:

void loop() { digitalWrite(5 , HIGH) ; delay(100 ) ; digitalWrite(5 , LOW) ; delay(900 ) ; }

Хорошо:

void loop() { digitalWrite(5 , HIGH) ; delay(100 ) ; digitalWrite(5 , LOW) ; delay(900 ) ; }

2. Как и в естественном языке: ставьте пробел после запятых и не ставьте до.

Плохо:

DigitalWrite(5 ,HIGH) ; digitalWrite(5 , HIGH) ; digitalWrite(5 ,HIGH) ;

Хорошо:

DigitalWrite(5 , HIGH) ;

3. Размещайте символ начала блока { на новой строке на текущем уровне отступа или в конце предыдущей. А символ конца блока } на отдельной строке на текущем уровне отступа:

Плохо:

void setup() { pinMode(5 , OUTPUT) ; } void setup() { pinMode(5 , OUTPUT) ; } void setup() { pinMode(5 , OUTPUT) ; }

Хорошо:

void setup() { pinMode(5 , OUTPUT) ; } void setup() { pinMode(5 , OUTPUT) ; }

4. Используйте пустые строки для разделения смысловых блоков:

Хорошо:

Ещё лучше:

void loop() { digitalWrite(5 , HIGH) ; delay(100 ) ; digitalWrite(5 , LOW) ; delay(900 ) ; digitalWrite(6 , HIGH) ; delay(100 ) ; digitalWrite(6 , LOW) ; delay(900 ) ; }

О точках с запятыми

Вы могли заинтересоваться: зачем в конце каждого выражения ставится точка с запятой? Таковы правила C++. Подобные правила называются синтаксисом языка . По символу; компилятор понимает где заканчивается выражение.

Как уже говорилось, переносы строк для него - пустой звук, поэтому ориентируется он на этот знак препинания. Это позволяет записывать сразу несколько выражений в одной строке:

void loop() { digitalWrite(5 , HIGH) ; delay(100 ) ; digitalWrite(5 , LOW) ; delay(900 ) ; }

Программа корректна и эквивалентна тому, что мы уже видели. Однако писать так - это дурной тон. Код гораздо сложнее читается. Поэтому если у вас нет 100% веских причин писать в одной строке несколько выражений, не делайте этого.

О комментариях

Одно из правил качественного программирования: «пишите код так, чтобы он был настолько понятным, что не нуждался бы в пояснениях». Это возможно, но не всегда. Для того, чтобы пояснить какие-то не очевидные моменты в коде его читателям: вашим коллегам или вам самому через месяц, существуют так называемые комментарии.

Это конструкции в программном коде, которые полностью игнорируются компилятором и имеют значение только для читателя. Комментарии могут быть многострочными или однострочными:

/* Функция setup вызывается самой первой, при подаче питания на Arduino А это многострочный комментарий */ void setup() { // устанавливаем 13-й пин в режим вывода pinMode(13 , OUTPUT) ; } void loop() { digitalWrite(13 , HIGH) ; delay(100 ) ; // спим 100 мс digitalWrite(13 , LOW) ; delay(900 ) ; }

Как видите, между символами /* и */ можно писать сколько угодно строк комментариев. А после последовательности / / комментарием считается всё, что следует до конца строки.

Итак, надеемся самые основные принципы составления написания программ стали понятны. Полученные знания позволяют программно управлять подачей питания на пины Arduino по определённым временны́м схемам. Это не так уж много, но всё же достаточно для первых экспериментов.

Состав языкаВ тексте на любом естественном языке можно выделить четыре
основных элемента: символы, слова, словосочетания и предложения.
Подобные элементы содержит и алгоритмический язык:
Алфавит языка, или его символы - это основные неделимые знаки, с
помощью которых пишутся все тексты на языке.
Лексема- минимальная единица языка, имеющая самостоятельный
смысл.
Выражение задает правило вычисления некоторого значения.
Оператор задает законченное описание некоторого действия.
Для описания сложного действия требуется последовательность
операторов. Операторы могут быть объединены в составной
оператор, или блок (блоком в языке С++ считается
последовательность операторов, заключенная в фигурные скобки { }).
В этом случае они рассматриваются как один оператор.
Каждый элемент языка определяется синтаксисом и семантикой.
Синтаксические определения устанавливают правила построения
элементов языка, а семантика определяет их смысл и правила
использования.
Объединенная единым алгоритмом совокупность описаний и
операторов образует программу на алгоритмическом языке.

Процесс выполнения программы

Для того чтобы выполнить программу, требуется перевести ее
на язык, понятный процессору - в машинные коды. Этот
процесс состоит из нескольких этапов:
Сначала программа передается препроцессору, который
подключает текстовые файлы, содержащие описание
используемых в программе элементов.
Получившийся полный текст программы поступает на вход
компилятора, который выделяет лексемы, а затем на основе
грамматики языка распознает выражения и операторы,
построенные из этих лексем. При этом компилятор выявляет
синтаксические ошибки и в случае их отсутствия строит
объектный модуль.
Компоновщик, или редактор связей, формирует
исполняемый модуль программы, подключая к объектному
модулю другие объектные модули. Если программа состоит
из нескольких исходных файлов, они компилируются по
отдельности и объединяются на этапе компоновки.
Исполняемый модуль имеет расширение.exe и может быть
запущен на выполнение.

Алфавит языка С++

В алфавит языка Си входят:
прописные и строчные буквы латинского алфавита (A,B,...,Z, а, b,..., z) и и
знак подчеркивания;
цифры: 0,1,2,3,4,5,6,7,8,9
специальные знаки: " , {} | () * + - / % \ ; " . :?< = >_ ! & # неотображаемые символы ("обобщенные пробельные символы"),
используемые для отделения лексем друг от друга (например, пробел,
табуляция, переход на новую строку).
Из символов алфавита
формируются лексемы языка:
идентификаторы;
ключевые (зарезервированные) слова;
знаки операций;
константы;
разделители (скобки, точка, запятая, пробельные символы).
Границы лексем определяются другими лексемами, такими, как
разделители или знаки операций.

Идентификаторы

Идентификатор - это имя программного объекта. В
идентификаторе могут использоваться латинские
буквы, цифры и знак подчеркивания. Прописные и
строчные буквы различаются. Первым символом
идентификатора может быть буква или знак
подчеркивания. При этом:
идентификатор не должен совпадать с ключевыми
словами и именами используемых стандартных
объектов языка;
не рекомендуется начинать идентификаторы с символа
подчеркивания;
Идентификаторы могут иметь любую длину, но
компилятор учитывает не более 31-го символа от
начала идентификатора;
Примеры идентификаторов:
КОМ_16, size88, _MIN, TIME, time

Ключевые слова

Ключевые слова - это зарезервированные идентификаторы, которые имеют
специальное значение для компилятора. Их можно использовать только в том
смысле, в котором они определены. Список ключевых слов С++ приведен в
таблице:
INT
CHAR
FLOAT
DOUBLE
STRUCT
UNION
LONG
SHORT
UNSIGNED
AUTO
CONST
TRUE
EXTERN
REGISTER
TYPEDEF
STATIC
GOTO
RETURN
SIZEOF
BREAK
CONTINUE
IF
VOID
NEW
ELSE
FOR
DO
WHILE
SWITCH
CASE
DEFAULT
ENTRY
AND
STRUCT
TYPEDEF
BOOL

Знаки операций

Знак операции - это один или более
символов, определяющих действие
над операндами. Внутри знака
операции пробелы не допускаются.
Операции делятся на унарные,
бинарные и тернарную по количеству
участвующих в них операндов.

Простые типы данных

Тип данных определяет:
внутреннее представление данных в памяти
компьютера;
множество значений, которые могут
принимать величины этого типа;
операции и функции, которые можно
применять к величинам этого типа.
В языке С++ определено шесть стандартных
простых типов данных для представления
целых, вещественных, символьных и
логических величин.

Типы данных
К спецификаторам типов относятся:
char
- символьный;
double - вещественный двойной точности с плавающей точкой;
float - вещественный с плавающей точкой;
int - целый;
long
- целый увеличенной длины (длинное целое);
short - целый уменьшенной длины (короткое целое);
signed - знаковый, т.е. целое со знаком (старший бит считается
знаковым);
unsigned - беззнаковый, т.е. целое без знака (старший бит не
считается знаковым);
void
- отсутствие значения;
bool - логический (могут принимать только значения true и false.
Внутренняя форма представления значения false - 0 (нуль).
Любое другое значение интерпретируется как true.)
Для описания констант используют служебное слово const перед
описанием типа. Например, const float g=9.8;

10. Структура Си-программы

Программа на языке С++ представляет собой
одну или несколько функций. Одна из функций
должна называться main () . Именно с этой
функции начинает выполняться программа, и из
этой функции, по мере необходимости,
вызываются другие функции.
Простейшее определение функции имеет следующий формат:
тип_возвращаемого_значения имя ([ параметры ])
{
операторы, составляющие тело функции
}
Как правило, функция используется для вычисления какого-либо
значения, поэтому перед именем функции указывается его тип. Если
функция не должна возвращать значение, указывается тип void.
При этом:
– Тело функции заключается в фигурные скобки.
– Функции не могут быть вложенными.
– Каждый оператор заканчивается точкой с запятой (кроме
составного оператора).

11. Структура Си-программы

Программа может состоять из нескольких модулей (исходных файлов) и, как правило,
содержит директивы препроцессора. Пример структуры программы, содержащей
функцииmain, f1 и f2:
директивы препроцессора
описания
int main()
{
операторы главной функции
}
int f1() {
операторы функции f1
}
int f2() {
операторы функции f2
}
/* Пример простой программы*/
#include
int main()
{
printf(“Hello World!”);
return 0;
}

12. функции ввода/вывода в стиле Си

Основные функции ввода/вывода в стиле С:
int scanf (const char* format...) // ввод
int printf(const char* format...) // вывод
Они выполняют форматированный ввод и вывод произвольного количества величин в соответствии со строкой
формата format. Строка формата содержит символы, которые при выводе копируются в поток (на экран) или
запрашиваются из потока (с клавиатуры) при вводе, и спецификации преобразования, начинающиеся со
знака %, которые при вводе и выводе заменяются конкретными величинами.
#include
int main() {
int i;
printf("Введите целое число\n");
scanf("%d", &i);
printf("Вы ввели число %d, спасибо!", i);
return 0; }
Первая строка этой программы - директива препроцессора, по которой в текст программы вставляется
заголовочный файл , содержащий описание использованных в программе функций ввода/вывод. Все
директивы препроцессора начинаются со знака #.
Третья строка - описание переменной целого типа с именем i .
Функция printf в четвертой строке выводит приглашение Введите целое число и переходит на новую строку в
соответствии с управляющей последовательностью \n.
Функция scanf заносит введенное с клавиатуры целое число в переменную i, а следующий оператор выводит на
экран указанную в нем строку, заменив спецификацию преобразования на значение этого числа.

13. функции ввода/вывода в стиле Си++

Та же программа с использованием библиотеки
классов С++ :
#include
using namespace std;
int main()
{
int i;
cout << "Введите целое число\n";
cin >> i;
cout << "Вы ввели число" << i << ", спасибо!"; return 0;
}

14. Стандартные библиотеки

Язык Си имеет богатую поддержку в виде
более 450 библиотечных подпрограмм функций и макросов, которые вы можете
вызывать из своих Си-программ для решения
широкого спектра задач, включая ввод/вывод
низкого и высокого уровня, работу со
строками и файлами, распределение памяти,
управление процессами, преобразование
данных, математические вычисления и
многое другое.

15. Директивы препроцессора

Препроцессором называется первая фаза
компилятора. Инструкции препроцессора
называются директивами. Они должны
начинаться с символа #, перед которым в
строке могут находиться только пробельные
символы.
Поиск файла, если не указан полный путь,
ведется в стандартных каталогах
включаемых файлов. Вместо угловых
скобок могут использоваться кавычки (" ")
- в этом случае поиск файла ведется в
каталоге, содержащем исходный файл, а
затем уже в стандартных каталогах.
Заголовочные файлы обычно имеют
расширение.h .

16. Директива препроцессора # include

Для подключения библиотек используется
директива препроцессора
# include [имя файла]
Директива #include <имя_файла> вставляет
содержимое указанного файла в ту точку
исходного файла, где она записана.
Например:
#include
#include “mylib.h”

17. Директива препроцессора #define

Директива #define определяет подстановку в тексте
программы. Она используется для определения
символических констант.
Формат определения символической константы:
#define имя текст_подстановки /*Все вхождения
имени заменяются на текст подстановки */
Примеры:
#define M 1000
#define Vasia “Василий Иванович”

18. Некоторые стандартные библиотеки

ALLOC.H
Описание функций управления памятью
(allocation, deallocation и др.)
BIOS.H
Описание различных функций, используемых при
обращении к подпрограммам BIOS (базовой
системе ввода-вывода).
CONIO.H Описание различных функций, используемых в
обращении к подпрограммам DOS ввода-вывода с
клавиатуры.
GRAPHICS.H Содержит прототипы графических функций.
MATH.H Содержит описание прототипов математических
функций
STDIO.H Определяет типы и макросы, необходимые для
стандартного пакета ввода-вывода. Определяет так же
стандартные потоки ввода-вывода stdin, stdout и
описывает подпрогpаммы ввода/вывода.
STDLIB.H Описывает некоторые подпрограммы общего назначения:
подпрограммы преобразования, поиска, сортировки и другие.
STRING.H
Описывает несколько подпрограмм обработки строк и
работы с памятью.

19. Функция форматного вывода PRINTF

Мы уже использовали наиболее употребительную
функцию вывода в Си - подпрограмму printf. Ее
целью является запись информации на экран.
Ее формат как прост, так и гибок:
printf(<строка формата>, <объект>, <объект>, ...);

20. Функция форматного ввода SCANF

Для интерактивного режима ввода, вероятно, можно использовать в
большинстве случаев функцию scanf. scanf это функция ввода, по смыслу
эквивалентная printf; ее формат выглядит так:
scanf(<строка формата>,<адрес>,<адрес>,...)
Однако scanf имеет одно очень важное отличие: объекты, следующие за
строкой формата, должны быть адресами, а не значениями. Например, в
программе содержится следующий вызов:
scanf("%d %d", &a, &b);
Этот вызов сообщает программе, что она должна ожидать от вас ввода
двух десятичных (целых) чисел, разделенных пробелом; первое будет
присвоено а, а второе b. Заметим, что здесь используется операция
адреса (&) для передачи адресов а и b функции scanf.

21. Строка формата

Строка формата - это строка, которая начинается
и заканчивается двойными кавычками ("как эта");
цель printf - запись этой строки на экран. Перед
выводом printf заменяет все дополнительно
перечисленные объекты в строке в соответствии
со спецификациями формата, указанными в
самой строке. Пример оператора printf:
printf(“ d= %f \n",d);

22. Строка формата

%f в строке формата - это спецификация формата. Все
спецификации формата начинаются с символа процента (%) и
(обычно) сопровождаются одной буквой, обозначающей тип
данных и способ их преобразования.
%f, используемое в спецификации, говорит о том, что ожидается
некоторое вещественное число. Вот несколько других общеиспользуемых спецификаций формата:
- %u целое число без знака
- %ld длинное целое число
- %p значение указателя
- %d целое число
- %e число с плавающей точкой в экспоненциальной форме
- %c cимвол
- %s строка
- %x или %X целое в шестнадцатиричном формате.

23. Строка формата

Вы можете задать ширину поля, помещая ее
между % и буквой, например, десятичное поле
шириной 4 задается, как %4d. Значение будет
напечатано сдвинутым вправо (впереди
пробелы), так что общая ширина поля равна 4.
Или например %6.2f будет обозначать что
отведено 6 позиций под вещественное число,
причем 2 – под дробную часть.
Если нужно напечатать знак %, то вставьте %%.

24. Строка формата

\n в строке не является спецификацией формата, а
употребляется (по историческим мотивам) как
управляющая (escape) последовательность, и представляет
специальный символ, вставляемый в строку. В этом случае
\n вставляет символ в начале новой строки, поэтому
после вывода строки курсор передвинется к началу новой
строки.
- \f (перевод формата или очистка экрана)
- \t (табуляция)
- \b (забой <-)
- \xhhh (вставка символа c кодом ASCII hhh, где hhh
содержит от 1 до 3 16-ричных цифр)
Если вам нужно напечатать обратную косую черту, то
вставьте \\.

25. Пример Си-программы

#include
#include
main()
{
float x1,y1,x2,y2;
printf("Введите два числа: ");
scanf("%f %f %f %f”,&x1,&y1,&x2,&y2);
float d = sqrt(pow((x2-x1),2)+pow((y2-y1),2));
printf(“d= %f \n", d);
}

26. Другие функции вывода PUTS, PUTCHAR

Имеются две другие функции вывода, которые могут вас
заинтересовать: puts и putchar. Функция puts выводит строку на
экран и завершает вывод символом новой строки.
Рассмотрим пример программы:
#include
main ()
{
puts("Привет, студент ВКИ НГУ");
}
Заметим, что в конце строки опущен \n; это не нужно, так как
puts сама добавляет этот символ.
Наоборот, функция putchar записывает единственный символ на
экран и не добавляет \n. Оператор putchar(ch) эквивалентен
printf("%c",ch).

27. Функции GETS, GETCH

main ()
{
char name ;
printf("Как вас зовут: ");
scanf (“%s”,name);

}
Если ввести фамилию и имя, то выведется только фамилия. Потому, что
введенный вами после имени пробел сигнализирует scanf о конце вводимой
строки.
Решить эту проблему можно, используя функцию gets.
main ()
{
char name ;
printf("Как вас зовут: ");
gets (name);
printf ("Привет, %s\n", name);
}

28. Функции GETS, GETCH

# include
# include
main ()
{
clrscr();
char name ;
printf("Как вас зовут: ");
gets (name);
printf ("Привет, %s\n", name);
getch();
}
Здесь функция getch ожидает ввода любого символа.
Функция getch читает единственный символ с клавиатуры, не выдавая
его на экран (в отличии от scanf и gets). Заметим, что у нее нет
параметра. Если же присвоить функцию символьной переменной, то
она получит значение нажатого символа.
Например: c=getch();

29. Операция присваивания

Самой общей операцией является присваивание,
например, p=a/b или ch = getch(). В Си
присваивание обозначается одним знаком
равенства (=); при этом значение справа от знака
равенства присваивается переменной слева.
Можно применять также последовательные
присваивания, например: sum=a= b. В таких
случаях присваивание производится справа
налево, то есть b будет присвоено a, которая в
свою очередь будет присвоена sum, так что все
три переменных получат одно и то же значение (а
именно, начальное значение b).

30. Арифметические операции. Инкремент. Декремент.

Си поддерживает обычный набор арифметических операций:
- умножение (*)
- деление (/)
- определение остатка от деления (%)
- сложение (+)
- вычитание (-)
Для увеличения значений переменной на единицу используют инкремент (++),
для уменьшения на единицу декремент (--).
Так:
x++; // увеличивает x на единицу
y--; // уменьшает y на единицу
Примеры постфиксных и префиксных операций:
a=2;
a=2;
x=18-2*a++;
x=18-2*(++a);
Получим:
a=3
a=3
x= 14
x=12

31. Комбинированные операции

Ниже приводятся некоторые примеры выражений
и способы их сокращения:
a = a + b; сокращается до a += b;
a = a - b; сокращается до a -= b;
a = a * b; сокращается до a *= b;
a = a / b; сокращается до a /= b;
a = a % b; сокращается до a %= b;

32. Пример 1

Вычислите X3 и X10 , используя четыре операции умножения для
заданного целого значения X.
#include
int x,x2,x3,x5,x10;
main() {
printf("\n Программа расчета X^3 и X^10\n");
puts("Введите значение X");
scanf("%i",&x);
x2=x*x;
x3=x*x2;
x5=x2*x3;
x10=x5*x5;
printf("%i в 3-ей степени = %i \n",x,x3);
printf("%i в 10-ой степени = %i",x,x10);
}

33. Пример 2

Дан угол в радианах. Вычислить синус и косинус угла.
#include
#include
float Angle,Result1,Result2;
main()
{
printf("\n Программа вычисления sin и сos угла\n");
puts("Задайте значение угла в радианах");
scanf("%f",&Angle);
Result1=sin(Angle);
Result2=cos(Angle);
printf("Синус угла равен %f \n",Result1);
printf("Косинус угла равен %f",Result2);


Top