Урок 4. Циклы: for, while и do while
Цикл повторяет команды, пока выполняется условие. Без циклов, чтобы сложить сто чисел, пришлось бы написать сто строк. В C три вида циклов: while, for и do while.
Цикл while
while проверяет условие и, если оно верно, выполняет тело цикла — команды в фигурных скобках. Потом снова проверяет — и так до тех пор, пока условие не станет ложным.
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
printf("Сумма цифр: %d\n", sum);
return 0;
}2025Сумма цифр: 9Это сумма цифр числа: n % 10 — последняя цифра, n /= 10 отбрасывает её. Цикл идёт, пока у числа остаются цифры. Если условие ложно с самого начала (например, ввели 0), тело не выполнится ни разу.
Цикл for
Когда заранее известно, сколько раз повторять, удобнее for. В скобках три части через точку с запятой: начальное значение, условие продолжения и шаг.
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 5; i++) {
printf("%d ", i * i);
}
printf("\n");
return 0;
}1 4 9 16 25Порядок работы: сначала int i = 1 (один раз), затем проверка i <= 5, тело, шаг i++, снова проверка — и так, пока условие верно. Переменная i, объявленная в скобках for, существует только внутри цикла.
Шаг может быть любым: i += 2 — через одно, i-- — в обратную сторону:
#include <stdio.h>
int main(void) {
for (int i = 10; i > 0; i -= 3) {
printf("%d ", i);
}
printf("\n");
return 0;
}10 7 4 1Пример посложнее — сумма и факториал. Факториал быстро растёт, поэтому для него берётся long long:
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
long long sum = 0, fact = 1;
for (int i = 1; i <= n; i++) {
sum += i;
fact *= i;
}
printf("Сумма от 1 до %d: %lld\n", n, sum);
printf("%d! = %lld\n", n, fact);
return 0;
}15Сумма от 1 до 15: 120
15! = 1307674368000Факториал 15 в int уже не поместился бы: int хранит числа примерно до 2,1 миллиарда. А long long хватает до 20!.
Цикл do while
do while сначала выполняет тело, а потом проверяет условие — поэтому тело выполнится хотя бы один раз. Удобно, когда нужно повторять ввод, пока не введут подходящее значение:
#include <stdio.h>
int main(void) {
int x;
do {
scanf("%d", &x);
} while (x <= 0);
printf("Принято: %d\n", x);
return 0;
}-3
0
42Принято: 42После while (…) в конце do while точка с запятой обязательна.
break и continue
breakнемедленно выходит из цикла.continueпропускает остаток тела и переходит к следующему шагу.
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
continue;
}
if (i > 8) {
break;
}
printf("%d ", i);
}
printf("\n");
return 0;
}1 2 4 5 7 8Числа, кратные трём, пропущены через continue, а на 10 цикл остановил break (9 пропущено раньше, как кратное трём).
Вложенные циклы
Цикл внутри цикла: внутренний проходит целиком на каждом шаге внешнего. Так выводится таблица:
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 4; j++) {
printf("%4d", i * j);
}
printf("\n");
}
return 0;
} 1 2 3 4
2 4 6 8
3 6 9 12break во вложенном цикле выходит только из внутреннего цикла, внешний продолжает работать.
Чтение чисел до конца ввода
В задачах часто дают числа, но не говорят, сколько их. scanf возвращает количество прочитанных значений, а в конце ввода — особое значение EOF (end of file — «конец файла»). Поэтому цикл «пока число читается» пишется так:
#include <stdio.h>
int main(void) {
int x, count = 0, max = 0;
while (scanf("%d", &x) == 1) {
if (count == 0 || x > max) {
max = x;
}
count++;
}
printf("Чисел: %d, наибольшее: %d\n", count, max);
return 0;
}4 -2 17
8 3Чисел: 5, наибольшее: 17При вводе с клавиатуры конец ввода обозначается сочетанием Ctrl+D в Linux и macOS и Ctrl+Z, а затем Enter в Windows.
Частые ошибки
- Точка с запятой после заголовка цикла.
for (int i = 0; i < 5; i++);— у такого цикла пустое тело, а блок в фигурных скобках под ним выполнится один раз уже после цикла. С-Wallgcc обычно предупреждает:this 'for' clause does not guard.... - Лишний или недостающий шаг.
i <= nилиi < n— проверьте на маленьком примере, сколько раз выполнится тело. Дляfor (int i = 0; i < n; i++)— ровноnраз. - Бесконечный цикл. Если в
whileзабыть изменить переменную из условия, цикл не закончится никогда. Остановить программу можно сочетаниемCtrl+Cв терминале. - Переполнение. Сумма или произведение растут быстро; если ответ «странный» или отрицательный, возьмите
long long.
Коротко
while (условие)— пока условие верно; тело может не выполниться ни разу.for (начало; условие; шаг)— когда число повторов известно;for (int i = 0; i < n; i++)выполняетсяnраз.do { … } while (условие);— тело выполняется хотя бы один раз.break— выйти из цикла,continue— перейти к следующему шагу.while (scanf("%d", &x) == 1)читает числа до конца ввода.