
Циклы в Arduino
Начнем с того что с циклами вы уже по-любому сталкивались: это конечно же основной цикл любой программы loop()
. Цикл это грубо говоря рамки, код внутри которых выполняется сверху вниз и повторяется с начала, когда достигает конца. Продолжается это дело до тех пор, пока выполняется какое то условие. Есть два основных цикла, с которыми мы будем работать, это for
и while
.
Цикл for
Цикл for
, в простонародии счётчик, в различных видах этот цикл есть и в других языках программирования, но на C++ он имеет очень гибкую настройку. При создании цикл принимает три “значения” (настройки): инициализация, условие и изменение. Цикл for обычно содержит переменную, которая изменяется на протяжении работы цикла, мы можем пользоваться её меняющимся значением в своих целях. Переменная является локальной для цикла, если она создаётся при инициализации.
- Инициализация – здесь обычно присваивают начальное значение переменной цикла. Например:
int i = 0;
- Условие – здесь задаётся условие, при котором выполняется цикл. Как только условие нарушается, цикл завершает работу. Например:
i < 100;
- Изменение – здесь указывается изменение переменной цикла на каждой итерации. Например:
i++;
Объединим три предыдущих пункта в пример:
for (int i = 0; i < 100; i++) { // тело цикла }
В теле цикла мы можем пользоваться значением переменной i
, которая примет значения от 0 до 99 на протяжении работы цикла, после этого цикл завершается. Как это использовать? Вспомним предыдущий урок про массивы и рассмотрим следующий пример:
// создадим массив на 100 ячеек byte myArray[100]; for (int i = 0; i < 100; i++) { // заполним все ячейки значением 25 myArray[i] = 25; }
Именно при помощи цикла for
очень часто работают с массивами. Можно, например, сложить все элементы массива для поиска среднего арифметического:
// создадим массив данных byte myVals[] = {5, 60, 214, 36, 98, 156}; // переменная для хранения суммы // обязательно инициализируем в 0 int sum = 0; for (int i = 0; i < 6; i++) { // суммируем весь массив в sum sum += myVals[i]; } // разделим sum на количество элементов // и получим среднее арифметическое! sum /= 6; // получилось 94!
Что касается особенностей использования for
в языке C++: любая его настройка является необязательной, то есть её можно не указывать для каких-то особенных алгоритмов. Например вы не хотите создавать переменную цикла, а использовать для этого другую имеющуюся переменную. Пожалуйста! Но не забывайте, что разделители настроек (точка с запятой) обязательно должны присутствовать на своих местах, даже если настроек нет!
// есть у нас какая-то переменная int index = 0; for (; index < 60; index += 10) { // переменная index принимает значения // 0, 10, 20, 30, 40, 50 }
В цикле for можно сделать несколько счётчиков, несколько условий и несколько инкрементов, разделяя их при помощи оператора запятая, , смотрите пример:
// объявить i и j // прибавлять i+1 и j+2 for (byte i = 0, j = 0; i < 10; i++, j += 2) { // тут i меняется от 0 до 9 // и j меняется от 0 до 18 }
Также в цикле может вообще не быть настроек, и такой цикл можно считать вечным, замкнутым:
for (;;) { // выполняется вечно... }
Использование замкнутых циклов не очень приветствуется, но иногда является очень удобным способом поймать какое-то значение, или дать программе “зависнуть” при наступлении ошибки. Но, как мы знаем, нет ничего вечного, поэтому из цикла таки можно выйти при помощи оператора break
.
Оператор break
Оператор break
(англ. “ломать”) позволяет досрочно покинуть цикл, использовать его можно как по условию, так и как-угодно-удобно. Например давайте досрочно выйдем из цикла при достижении какого-то значения:
for (int i = 0; i < 100; i++) { // покинуть цикл при достижении 50 if (i == 50) break; }
Или вот такой абстрактный пример, покинем “вечный” цикл при нажатии на кнопку:
for (;;) { if (кнопка нажата) break; }
Выход из цикла является не единственным интересным инструментом, ещё есть оператор пропуска – continue
Оператор continue
Оператор continue
(англ. “продолжить”) досрочно завершает текущую итерацию цикла и переходит к следующей. Например давайте заполним массив, как делали выше, но пропустим один элемент:
// создадим массив на 100 ячеек byte myArray[100]; for (int i = 0; i < 100; i++) { // если i равно 10, пропускаем if (i == 10) continue; // заполним все ячейки значением 25 myArray[i] = 25; }
Таким образом элемент под номером 10 не получит значения 25, итерация завершится до операции присваивания.
Цикл while
Цикл while
(англ. “пока”), он же называется цикл с предусловием, выполняется до тех пор, пока верно указанное условие. Если условие сразу неверно, цикл даже не начнёт свою работу и будет полностью пропущен. Объявляется очень просто: ключевое слово while
, далее условие в скобках, и вот уже тело цикла:
int i = 0; while (i < 10) { i++; }
Хммм, вам не кажется знакомым действие этого примера? Всё верно, это полный аналог цикла for
с настройками (int i = 0; i < 10; i++)
. Единственное отличие в том, что на последней итерации i
примет значение 10
, так как на значении 9
цикл разрешит выполнение.
Ещё интересный вариант, который можно встретить на просторах чужого кода. Работает на основе того факта, что любое число кроме нуля обрабатывается логикой как true
:
byte a = 5; while (a--) { // выполнится 5 раз }
Цикл while
тоже удобно использовать как вечный цикл, например, ожидая наступление какого-либо события (нажатие кнопки):
// выполняется, пока не нажата кнопка while (кнопка не нажата);
Пока условие не произойдёт, код не пойдёт дальше, застрянет на этом цикле. Как вы уже поняли, оператор if
тут не нужен, нужно указывать именно логическое значение, можно даже вот так:
while (true);
Всё, вертимся здесь бесконечно! Если не предусмотрим break
, конечно же…
Помимо цикла с предусловием есть ещё цикл с постусловием, так называемый do while
Цикл do while
do while
– “делать пока”, работа этого цикла полностью аналогична циклу while
за тем исключением, что здесь условие задаётся после цикла, т.е. цикл выполнится один раз, затем проверит условие, а не наоборот. Пример:
do { // тело цикла } while (условие);
Где применять? Да где угодно, по ходу написания собственных программ вы почувствуете, где удобнее использовать тот или иной цикл.
Видео
Важные страницы
- Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
- Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
- Полная документация по языку Ардуино, все встроенные функции и макро, все доступные типы данных
- Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
- Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете
- Поддержать автора за работу над уроками
- Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту (alex@alexgyver.ru)
- Articles coming soon