Урок 4. Циклы: for, while и do while
Посчитать сумму чисел от 1 до 1000 можно тысячей строк сложения, а можно тремя строками цикла. Цикл повторяет блок команд, пока выполняется условие. Один проход цикла называют итерацией.
Цикл for
Самый частый цикл — когда заранее известно, сколько раз повторять:
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 5; i++) {
cout << i << " ";
}
cout << "\n";
return 0;
}1 2 3 4 5В скобках после for три части через ;:
int i = 1— начало: выполняется один раз перед циклом. Переменнаяi— счётчик цикла.i <= 5— условие: проверяется перед каждой итерацией; как только оно ложно, цикл заканчивается.i++— шаг: выполняется после каждой итерации.
Счётчик, объявленный внутри for, существует только в цикле: после закрывающей скобки i уже нет.
Шаг может быть любым: i += 2 — через одно, i-- — в обратную сторону:
#include <iostream>
using namespace std;
int main() {
for (int i = 10; i > 0; i -= 3) {
cout << i << " ";
}
cout << "\n";
return 0;
}10 7 4 1Сумма и счёт
Типичная задача: прочитать n, потом n чисел, и найти их сумму и количество положительных.
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
long long sum = 0;
int positive = 0;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
sum += x;
if (x > 0) {
positive++;
}
}
cout << sum << " " << positive << "\n";
return 0;
}5
3 -1 4 -1 510 3Переменные sum и positive объявлены до цикла и начинаются с нуля. Если объявить их внутри цикла, они будут обнуляться на каждой итерации. Сумму удобно держать в long long: так она не переполнится даже на миллионе больших чисел.
Запись for (int i = 0; i < n; i++) — привычный способ повторить ровно n раз. Счёт с нуля пригодится в следующем уроке: элементы массивов нумеруются с нуля.
Цикл while
while повторяет блок, пока условие истинно. Его берут, когда число повторений заранее неизвестно. Например, сумма цифр числа: последнюю цифру отрезают, пока число не станет нулём.
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int digits = 0;
while (n > 0) {
digits += n % 10; // последняя цифра
n /= 10; // отрезать её
}
cout << digits << "\n";
return 0;
}20248n % 10 — последняя цифра числа, n / 10 — число без последней цифры. Это приём, который встречается во многих задачах.
Условие проверяется до итерации: если оно ложно сразу, тело не выполнится ни разу. Например, для n = 0 программа выше выведет 0.
Цикл do while
У do while условие проверяется после итерации, поэтому тело выполнится хотя бы раз. Пример — спрашивать число, пока не введут положительное:
#include <iostream>
using namespace std;
int main() {
int x;
do {
cin >> x;
} while (x <= 0);
cout << "got " << x << "\n";
return 0;
}-5 0 12got 12После while (...) в конце do while ставится точка с запятой.
break и continue
breakсразу заканчивает цикл;continueпропускает остаток текущей итерации и переходит к следующей.
Пример: первый цикл ищет первое число больше 100, которое делится на 7, второй выводит нечётные числа до 9:
#include <iostream>
using namespace std;
int main() {
for (int i = 101; ; i++) {
if (i % 7 == 0) {
cout << i << "\n";
break;
}
}
for (int i = 1; i < 10; i++) {
if (i % 2 == 0) {
continue;
}
cout << i << " ";
}
cout << "\n";
return 0;
}105
1 3 5 7 9В первом цикле условие пропущено (for (int i = 101; ; i++)) — такой цикл бесконечный, и выйти из него можно только через break.
Вложенные циклы
Цикл внутри цикла: внешний выбирает строку, внутренний проходит по столбцам. Таблица умножения 3 на 4:
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 4; j++) {
cout << i * j << " ";
}
cout << "\n";
}
return 0;
}1 2 3 4
2 4 6 8
3 6 9 12Внутренний цикл полностью проходит при каждой итерации внешнего, поэтому тело выполняется 3 · 4 = 12 раз. Помните об этом на олимпиадах: два вложенных цикла по 100 000 — это 10¹⁰ действий, а за секунду компьютер успевает порядка 10⁸–10⁹ простых операций.
break во вложенном цикле выходит только из внутреннего цикла, а не из обоих.
Частые ошибки
- Бесконечный цикл: условие никогда не становится ложным, например забыли
n /= 10или написалиi--вместоi++. Программа «висит» — остановите еёCtrl+Cв консоли. - Точка с запятой после заголовка:
for (int i = 0; i < n; i++);— цикл с пустым телом, а блок под ним выполнится один раз. - На один больше или меньше:
i <= nвместоi < n. Проверяйте крайние значения на маленьком примере. - Счётчик или сумма внутри цикла — обнуляются на каждой итерации.
Коротко
for (начало; условие; шаг)— когда число повторений известно.while (условие)— пока условие истинно; проверка до итерации.do { ... } while (условие);— хотя бы одна итерация.break— выйти из цикла,continue— к следующей итерации.- Сумма и счётчики объявляются до цикла и начинаются с нуля.