Циклы позволяют в зависимости от определенных условий выполнять определенное действие множество раз. В языке Dart есть следующие виды циклов:
for
while
do...while
for-each
Цикл for имеет следующее формальное определение:
for (инициализатор; условие; действие) { // тело цикла }
инициализатор выполняется один раз при начале выполнения цикла и представляет установку начальных условий, как правило, это инициализация счетчиков - специальных переменных, которые используются для контроля за циклом.
условие представляет условие, при соблюдении которого выполняется цикл. Как правило, в качестве условия используется операция сравнения, и если она
возвращает ненулевое значение (то есть условие истинно), то выполняется тело цикла, а затем выполняется действие
.
действие выполняется после каждого завершения блока цикла и задает изменение параметров цикла. Обычно здесь происходит увеличение счетчиков цикла.
Рассмотрим стандартный цикл for:
for (int i = 1; i < 9; i++){ print("$i * $i = ${i *i} \n"); }
Первая часть объявления цикла - int i = 1
создает и инициализирует счетчик i. То есть перед выполнением цикла значение счетчика будет равно 1. В данном
случае это то же самое, что и объявление переменной.
Вторая часть - условие, при котором будет выполняться цикл. В данном случае цикл будет выполняться, пока i не достигнет 9.
И третья часть - приращение счетчика на единицу. Опять же нам необязательно увеличивать на единицу. Можно уменьшать: i--
, можно выполнять другие действия.
В итоге блок цикла сработает 8 раз, пока значение i не станет равным 9. Каждый такой проход цикла называется итерацией. И после каждого прохода (каждой итерации) значение переменной i будет увеличиваться на 1.
В итоге на консоль будут выведены квадраты чисел от 1 до 8:
1 * 1 = 1 2 * 2 = 4 3 * 3 = 9 4 * 4 = 16 5 * 5 = 25 6 * 6 = 36 7 * 7 = 49 8 * 8 = 64
Нам необязательно указывать все три элемента при объявлении цикла. Например, можно опустить ряд блоков:
void main (){ int i = 1; for (; i<9;){ print("$i * $i = ${i *i} \n"); i++; } }
Этот пример эквивалентен первому примеру: у нас также есть счетчик, только создан он вне цикла. У нас есть условие выполнения цикла. И есть приращение счетчика уже в самом блоке for.
Цикл for может определять сразу несколько переменных и управлять ими:
void main (){ for(int i=1, j = 1; i < 10 && j < 10; i++, j++){ print(i * j); } }
Здесь определяются две переменных - i и j. В качестве условия используется выражение i < 10 && j < 10
. То есть цикл будет продолжаться, пока обе переменных
одновременно меньше 10. В третьей части заголовка цикла увеличиваем обе переменных на единицу i++, j++
. И поскольку обе переменных изначально равны 1 и с каждой итерацией синхронно увеличиваются
на 1, то на консоль будут выведены по сути квадраты чисел.
Выше все примеры циклов имели тело - набор инструкций в фигурных скобках. Но мы можем эти инструкции опустить. Например, нам надо вычислить сумму чисел от 1 до 9:
void main (){ int sum = 0; for(int i=1; i < 10; sum +=i, i++); // цикл не имеет тела print(sum); }
Здесь для хранения суммы чисел определена переменная sum. Для перебора всех чисел от 1 до 9 определена переменная-счетчик i. И пока она не станет равна 10, в третьей части цикла
выполняем два действия: увеличиваем переменную sum (sum +=i
) и увеличиваем переменную i (i++
).
Цикл do сначала выполняет код цикла, а потом проверяет условие в инструкции while. И пока это условие истинно, цикл повторяется. Например:
void main (){ int n = 0; do{ print(n); n++; } while (n < 5); }
В данном случае код цикла сработает 5 раз, пока n не окажется равным 5. Важно отметить, что цикл do гарантирует хотя бы однократное выполнение действий, даже если условие в инструкции while не будет истинно. Так, мы можем написать:
void main (){ int n = 6; do{ print(n); n++; } while (n < 5); }
Хотя здесь переменная n изначально больше 5, цикл все равно один раз выполнится.
Цикл while
сразу проверяет истинность некоторого условия, и если условие истинно, то код цикла выполняется:
void main (){ int n = 0; while (n < 5){ print(n); n++; } }
Здесь цикл выполняется, пока переменная n не станет равна 5.
Оператор continue позволяет сразу перейти к следующей итерации. Например, нам надо вывести все четные числа от 0 до 10:
void main (){ for(int i=0; i <= 10; i++) { if(i%2==1) // если остаток от деления на 2 - 1, то есть число нечетное { continue; // переходим к следующей итерации } print(i); } }
Для проверки числа делим его на 2. Если остаток от деления равен 1, то число нечетное. Тогда вызываем оператор continue, который перейдет к следующей итерации.
То есть пройзойдет увеличение счетчика i. А вывод на консоль после оператора continue
выполняться не будет.
Если число четное, то оператор continue
не вызывается, а выполняется функция print
, которая выводит число на консоль. Консольный вывод программы:
0 2 4 6 8 10
Оператор break позволяет выйти из цикла в любой его момент, даже если цикл не закончил свою работу. Например, подсчитаем сумму чисел от 1 до 10, но если сумму вдруг окажется на каком-то этапе больше 10, перестанем считать и выйдем из цикла:
void main (){ int sum = 0; for(int i=0; i<10; i++) { sum += i; if(sum > 10) // если сумма больше 10 { break; // выходим из цикла } } print(sum); // 15 }
Когда переменная sum станет больше 10, сработает оператор break, и цикл завершится.