Управляющие конструкции
if (условие) и ==, !=, (операторы сравнения)
if используется в комбинации с операторами сравнения для проверки истинности условий. Например, превышает ли входное значение заданное число. Формат оператора if следующий:
Этот код сравнивает значение variableN и число 50 — если текущее значение переменной действительно больше 50, выполняются определенные действия. Иначе говоря, если выражение в круглых скобках истинно, выполняются операторы внутри фигурных скобок. В противном случае, фрагмент в фигурных скобках будет пропущен.
Сами фигурные скобки лишь логически группируют несколько строк в один блок и могут отсутствовать. В этом случае только следующая за оператором if строка (до точки с запятой) становится оператором, выполняемым (или не выполняемым) по условию if.
Выражения, которые вычисляются внутри круглых скобок, могут состоять из одного или нескольких операторов:
Операторы сравнения
x == y (x равно y)
x != y (x не равно y)
x y (x больше y)
x = y (x больше или равно y)
Отличайте знак простого равенства ‘=’ от оператора сравнения ‘==’. Использование знака равенства в операторе if может дать совершенно другой результат — например, if (y = 40) совершенно не тоже самое, что if (y==40). Знак равенства – это оператор присваивания, который устанавливает значение переменной х равным 40 (заносит значение 40 в переменную y, а не проверяет ее значение на равенство 40!). Старайтесь не забывать всегда использовать в операторе if знак двойного равенства, который является оператором сравнения и проверяет в данном случае х на равенство 10. Выражение (y=10) всегда истинно, в то время как (y==10) истинно только при условии равенства значения переменной десяти.
if/else
Конструкция if..else предоставляет больший контроль над выполнением скетча, чем простой оператор if, позволяя определить в одном месте действия не только для случая, когда выражение в скобках истинно, но и для противоположного (когда значение выражения ложно). В примере ниже, после сравнения переменной и числа 500 аналогового входа набор Действий ОДИН выполнится, если переменная меньше, а набор Действий ДВА — если она больше или равна 500:
за else может следовать еще один if, и таким образом можно создать цепочку последовательных взаимоисключающих проверок. В этом случае проверки будут выполняться одна за другой до тех пор, пока не встретится выражение со значением ИСТИНА . После этого будет выполнен следующий за ним блок кода, а проверка остальных условий будет пропущена — вплоть до завершения текущей конструкции if/else. Если не вычислено ни одного истинного выражения, исполняется самый последний блок else по умолчанию (если он существует).
Отметим, что конструкция else if может быть использована с или без заключительного else, и наоборот. Допускается неограниченное число таких переходов else if.
switch / case
Подобно оператору if, switch. case управляет ходом выполнения программы, позволяя исполнять разные операторы, в зависимости от текущих условий. Выражение, указанное в строке switch, последовательно сравнивается со значениями в строках case. Если значения совпадают, начинают выполняться следующие за этим case операторы.
Ключевое слово break завершает это выполнение, и обычно используется в конце каждого блока case. Если его опустить, выполнение будет продолжаться через все последующие блоки case до тех пор, пока где-нибудь не встретится break или не закончится сам оператор switch.
Arduino условные переходы
Дата: 13 Марта 2015. Автор: Алексей
(Если непонятно, то ничего страшного. Я отдельно напишу статью для работы с логическими операторами и станет все понятно. пока просто примите как есть.)
Далее идет наш оператор if которому мы передаем условие. Если предыдущее значение экодера не равно
текущему, то выполняем группу операторов, иначе возвращаемся к чтению пинов. Если данные разнились, input отличается от buf, значит энкодер повернули. Отлично, берем текущее значение и передаем его в switch. Тот в свое время начинает искать варианты, а у нас их всего четыре, либо 1, либо 0, либо 2, либо 3. Найдя нужный вариант смотрим куда повернули энкодер и в зависимости от направления либо увеличим переменную data, либо уменьшим. После выходим из switch и сохранем в buf значения input. И в конце выводим значение data в порт. Прибавление 0x30 нужно для перевода числа в ASCII код. data_old = data; нужно сугубо для удержания от дублирования одинаковых крайних чисел в терминале. При обработке переменной data без терминала, data_old = data; можно выкинуть. Для проверки работы кода, после загрузки запускаете терминал с тем же портом что и при прошивке, а скорость выбираете 9600.
Для самых ленивых готовый Скетч.
Если все таки возникли непонятки, пишите, разберемся. В следующий раз будем разбирать циклы.
Arduino — управляющие операторы
Каждый язык программирования имеет набор команд управления, обеспечивающих многократное выполнение одного и того же кода (цикл), выбор подходящего фрагмента кода (условия) и инструкции для выхода из текущего фрагмента кода.
Arduino IDE позаимствовал с C/C++ большинство необходимых элементов управления. Их синтаксис идентичен с C. Ниже мы в двух словах опишем их синтаксис.
Оператор if
Оператор if позволяет выполнить определенный фрагмент программы в зависимости от результата проверки определенного условия. Если условие выполняется, то код программы будет выполнен, если же условие не выполняется, то код программы будет пропущен. Синтаксис команды if выглядит следующим образом:
[slh lang=»php»] if(условие)
<
инструкция1;
инструкция2;
>
[/slh] Условием может быть любое сравнение переменной или значения, возвращаемое функцией. Основным критерием условия if является то, что ответ всегда должен быть или истина (true) или ложь (false). Примеры условий для оператора if:
[slh lang=»php»] if(a!=2)
<
>
if(x Подробнее
Часто переменная, используемая в цикле объявляется там же:
[slh lang=»php»] for(int i=0;i 0;i—)
<
Serial.print(i); // отправятся номера 10,9,8,7,6,5,4,3,2,1
>
[/slh]
Оператор while
Цикл for идеально подходит там, где мы хотим выполнить подсчет. В ситуации, когда необходимо выполнить определенные действия в результате какого-то события, которое не обязательно является предсказуемым (например, мы ждем нажатия кнопки), то мы можем использовать оператор while, который выполняет блок оператора до тех пор, пока выполняется условие. Синтаксис оператора while выглядит следующим образом:
[slh lang=»php»] while(условие)
<
// блок инструкций для выполнения
>
[/slh] Важно, чтобы проверка состояния происходила в начале цикла. Может случиться так, что инструкции внутри цикла while не исполняться никогда. Кроме того, возможно создание бесконечного цикла. Давайте посмотрим два примера:
[slh lang=»php»] int x=2;
while(x>5)
<
Serial.print(x);
>
—————————————-
int y=5;
while(y>0)
<
Serial.print(y);
>
[/slh] Первый блок операторов, расположенный внутри while не выполнится никогда. Переменная x имеет значение два и она не станет больше 5. Во втором примере мы имеем дело с бесконечным циклом. Переменная «y» имеет занчение 5, т. е. больше нуля. Внутри цикла не происходит никакого изменения переменной «y», поэтому цикл никогда не будет завершен.
Это распространенная ошибка, когда мы забываем об изменении параметра, вызывающего прекращение цикла. Ниже приведено два правильных примера применения цикла while:
[slh lang=»php»] int x=0;
while(x 0);
—————————————-
do
<
// блок инструкций
if(условие) break;
>
while(true);
[/slh]
Оператор break
Оператор break позволяет выйти из цикла (do…while, for, while) и выйти из опции switch. В следующем примере рассмотрим выполнение команды break:
[slh lang=»php»] for(i=0;i 400) < // чтение аналогового входа
return 1; // Для значений больше 400 возвращается 1
else <
return 0; // для других возвращается 0
>
>
[/slh] Как вы можете видеть, в одной функции можно использовать несколько операторов return, но сработает всегда только один из них. Допустимо использование оператора return без параметров. Это позволяет досрочно прекратить работу функции, которая не возвращает никакого значения.
[slh lang=»php»] void имя_функции()
<
инструкция1;
if(x==0) return;
инструкция2;
инструкция3;
>
[/slh] В приведенном выше примере инструкция1 будет выполнять всегда, когда вызывается функция. Выполнение же инструкция2 и инструкция3 зависит от результата команды if. Если условие будет выполнено (true), то будет выполнена команда return и функция завершит работу.
В случае, когда условие не выполнено команда return так же не выполняется, а выполняются инструкции инструкция2 и инструкция3, и после этого функция завершает свою работу.
Сравнения, условия и выбор
В языке C++ есть такое понятие, как логическая величина, которая принимает два значения: правда и ложь, true и false , 1 и 0. Для хранения логических величин у нас есть тип данных boolean ( bool ), который может принимать значения 0 ( false ) или 1 ( true ). Логические переменные часто называют флагами: если переменная равна true – флаг поднят, если false – опущен.
Сравнение
Два числа можно сравнить при помощи операторов сравнения:
- == равенство ( a == b )
- != неравенство ( a != b )
- >= больше или равно ( a >= b )
- меньше или равно ( a )
- > больше ( a > b )
- меньше ( a )
В рассмотренных выше абстрактных примерах с a и b мы получаем логическое значение, которое является результатом сравнения чисел. Пусть a = 10 и b = 20 , тогда скобка (a > b) вернёт значение false , потому что a меньше b . А вот (a != b) вернёт true , т.к. а действительно не равно b .
Для связи нескольких логических величин используются логические операторы:
- ! логическое НЕ, отрицание. Есть аналог – оператор not
- && логическое И. Есть аналог – оператор and
- || логическое ИЛИ. Есть аналог – оператор or
Сравнение float
Со сравнением float чисел всё не так просто из за особенности самой модели “чисел с плавающей точкой” – вычисления иногда производятся с небольшой погрешностью, из за этого сравнение может работать неверно! Пример из урока про вычисления:
Будьте внимательны при сравнении float чисел, особенно со строгими операциями : результат может быть некорректным и нелогичным!
Условный оператор if
Условный оператор if (англ. “если”) позволяет разветвлять выполнение программы в зависимости от логических величин, т.е. результатов работы операторов сравнения и логических переменных.
Оператор else (англ. “иначе”) работает в паре с оператором if и позволяет предусмотреть действие на случай невыполнения if :
Также есть третья конструкция, позволяющая ещё больше разветвить код, называется она else if :
Посмотрим на все эти операторы в действии в большом примере:
Оператор if позволяет управлять программой и создавать разветвлённые действия в зависимости от разных условий. Обратите внимание на последний блок в примере выше, там где используется else if для выбора действия в зависимости от значения одной и той же переменной. Существует оператор выбора switch , позволяющий сделать код более красивым. О нём поговорим чуть ниже.
Особенность bool
В уроке о типах данных я упоминал о том, что bool принимает значение true , если присвоить ему отличное от нуля число, то есть оператору if можно скормить любое число, и он вернёт true в любом случае, кроме нуля. Это бывает удобно в некоторых случаях, но также может и приводить к ошибкам, которые трудно отловить. if (50) <> – код в фигурных скобках будет выполнен.
Порядок условий
Порядок условий играет очень большую роль: логические выражения и переменные проверяются слева направо, и если результат всего выражения в скобках будет однозначно определён после проверки первого выражения – остальные выражения проверяться не будут. Например если в выражении if (a && b && c) хотя бы а имеет значение false , проверка остальных выражений ( b и c ) уже не выполняется, потому что всё выражение заведомо будет false .
Или наоборот: если в выражении if (a || b || c) хотя бы а будет true – всё выражение также будет true и b с c не будут проверяться.
Это может помочь в оптимизации кода: например, есть какой-то флаг и выражение, которое вычисляется прямо в условии и сразу проверяется. Если флаг опущен, микроконтроллер не будет тратить время на лишние вычисления и сразу покинет условие. Например:
Тернарный оператор ?
Оператор знак вопроса ? , или тернарный оператор, является более коротким аналогом для записи конструкции if else . Действие с оператором ? имеет следующий вид:
условие ? выражение1 : выражение2
Это работает так: вычисляется условие, если оно истинно, то всё действие возвращает значение выражения 1, а если оно ложно, то всё действие возвращает значение выражения 2. Пример:
Аналогичная конструкция на if-else
Ещё вариант с вычислением:
Аналогичным образом можно использовать оператор ? для вывода данных и текста в последовательный порт (подробнее о нём в другом уроке):
Важный момент: если результат присваивается или передаётся в функцию, тип данных должен быть одинаковый! То есть код Serial.println((a > 9) ? 9 : «меньше 9»); приведёт к ошибке, так как мы пытаемся передать или int или char* , что не будет работать.
Также можно получать значения из функций, если они имеют одинаковый возвращаемый тип данных:
А можно ли сделать на операторе ? более сложную конструкцию, типа else if ? Можно!
Оператор выбора
Оператор выбора switch позволяет создать разветвление кода в зависимости от значения одной переменной. Синтаксис такой:
Наличие оператора default необязательно. Наличие оператора break обязательно, иначе сравнение пойдёт дальше, как показано для case 2, 3 и 4.
При помощи условных операторов и операторов выбора строится логика работы программы. Условный оператор поможет сравнить значение с датчика и принять решение, что делать дальше. Оператор выбора отлично справится с изменяющимися режимами работы программы или опросом кнопок, нажатых на ИК пульте.
Также конструкция на switch работает быстрее, чем аналогичная на else if : происходит выбор варианта и моментальный переход на нужный блок кода, а в else if в каждой строке производится проверка логического выражения.
ВАЖНОЕ ЗАМЕЧАНИЕ
Нужно быть крайне внимательным при работе с оператором switch , потому что код, находящийся внутри фигурных скобок switch() < >, является одним блоком кода для всех кейсов. Соответственно кейсы case – всего лишь ярлыки перехода между участками этого блока. Почему это так важно: все кейсы находятся в одной области видимости, то есть внутри switch не могут быть объявлены локальные переменные с одинаковыми именами:
Более того, крайне не рекомендуется создавать локальные переменные внутри кейсов, так как это может сломать код!
Что делать, если очень хочется? Обернуть содержимое кейса в блок при помощи фигурных скобок: