for, while и do-while
Чему вы научитесь:
- повторять действие циклами
for,whileиdo-while; - считать, сколько раз выполнится цикл, и не ошибаться на единицу;
- проходить по списку значений циклом по диапазону;
- досрочно выходить из цикла через
breakи пропускать итерацию черезcontinue.

Чтобы напечатать числа от 1 до 5, можно написать пять строк с std::cout. Для тысячи чисел понадобилась бы тысяча строк. Вместо этого пишут цикл — конструкцию, которая повторяет действие, пока выполняется условие.
Представьте бегуна на стадионе. Тренер говорит: «Бегай круги, пока не пробежишь пять».
Бегун встаёт на линию старта. Перед каждым кругом он пробегает под контрольной аркой, и та проверяет, сколько кругов уже сделано. Потом бегун пробегает круг и ставит отметку в блокноте. Цикл устроен так же:
#include <iostream>
int main() {
for (int i = 1; i <= 5; ++i) {
std::cout << i << ' '; // 1 2 3 4 5
}
std::cout << '\n';
}Как работает цикл for
В заголовке for три части через точку с запятой. Каждая похожа на свою часть стадиона, и выполняются они в таком порядке:
- Инициализация
int i = 1выполняется один раз, до начала цикла. Это линия старта. - Условие
i <= 5проверяется перед каждым проходом. Это контрольная арка: если условие истинно, выполняется тело, а если ложно, цикл заканчивается. - Тело в фигурных скобках выполняется. Это сам круг.
- Шаг
++iвыполняется после тела. Это отметка в блокноте. Затем цикл возвращается к пункту 2.
В виджете тот же цикл с условием i <= 3: нажмите «Следующий шаг» и следите, когда выполняется каждая часть заголовка.
1–2#include <iostream>3int main() {4 for (int i = 1; i <= 3; ++i) {5 std::cout << i << "\n";6 }7 std::cout << "end\n";8}
Инициализация int i = 1 выполняется один раз
Один проход тела называют итерацией. Здесь аналогия заканчивается: настоящий бегун сам знает, сколько пробежал, а цикл помнит только значение i.
Когда i становится равной 6, условие ложно, и цикл заканчивается. Переменная i объявлена в заголовке, поэтому видна только внутри цикла. После закрывающей фигурной скобки тела цикла имени i уже нет.
Сколько итераций
Цикл выполняется столько раз, сколько значений принимает счётчик i. В for (int i = 0; i < 5; ++i) это значения от 0 до 4, то есть пять итераций. Знак < не пускает i к самой границе.
Если заменить < на <=, i дойдёт и до 5, и итераций станет шесть. Цикл, который выполняется на один раз больше или меньше нужного, содержит ошибку на единицу. На собеседовании такие циклы часто дают с вопросом «сколько раз выполнится тело?».
Циклы while и do-while
У for все три части стоят в заголовке. Два других вида цикла устроены проще.
Цикл while
Цикл while проверяет условие перед каждой итерацией, как for, но инициализации и шага в нём нет. Переменную объявляют до цикла, а меняют в теле. Его выбирают, когда число итераций заранее неизвестно. Так можно посчитать, сколько раз 100 нужно разделить нацело на 2, чтобы осталась 1:
int n = 100;
int steps = 0;
while (n > 1) {
n = n / 2;
++steps;
}
std::cout << steps << '\n'; // 6Значения n идут так: 100, 50, 25, 12, 6, 3, 1. Делений шесть, и на 1 условие n > 1 становится ложным.
Цикл do-while
Цикл do-while сначала выполняет тело и только потом проверяет условие. Поэтому его тело выполняется хотя бы один раз, даже если условие ложно с самого начала. Сравните два цикла с одним и тем же ложным условием:
int n = 10;
while (n < 5) {
std::cout << n << '\n';
++n;
}
do {
std::cout << n << '\n'; // 10
++n;
} while (n < 5);Давайте разберём, что происходит:
whileсразу проверяет10 < 5. Условие ложно, тело не выполняется, и ничего не печатается.doвыполняет тело: печатает10и делаетnравной11.- Только теперь проверяется
n < 5. Условие ложно, и цикл заканчивается.
Цикл do-while заканчивается точкой с запятой после while (n < 5). Без неё программа не скомпилируется.
Частая ошибка
Счётчик типа unsigned в цикле обратного отсчёта:
for (unsigned i = 3; i >= 0; --i) { // ✗
std::cout << i << '\n';
}Значение unsigned не бывает отрицательным, поэтому условие i >= 0 истинно всегда. Если вычесть единицу из 0, получится наибольшее значение unsigned, и цикл печатает числа без конца. GCC с флагом -Wextra предупреждает, что сравнение всегда истинно, а Clang даже с -Wextra молчит. Для отсчёта до нуля объявите счётчик как int: после 0 он станет равен -1, и условие окажется ложным.
Главное
- Части заголовка
forвыполняются по порядку: инициализация один раз, затем условие, тело, шаг и снова условие. - Цикл с
i = 0и условиемi < nвыполняетсяnраз, а с<=— на один раз больше. whileпроверяет условие до тела, аdo-while— после, поэтому его тело выполняется хотя бы раз.- Счётчик
unsignedникогда не станет меньше нуля, и условиеi >= 0с ним истинно всегда.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.