Циклы в C: for, while, do-while, вложенные циклы и операторы управления (break, continue, goto)
Зачем нужны циклы
Циклы позволяют выполнять блок кода многократно. В C есть три основных вида циклов и операторы для управления их выполнением.
1. Цикл while — с предусловием
Условие проверяется перед каждой итерацией. Если ложно с начала — тело не выполняется ни разу.
while (условие) {
// тело цикла
}
Пример: сумма чисел от 1 до n
int n = 10, sum = 0, i = 1;
while (i <= n) {
sum += i;
i++;
}
printf("Сумма: %d\n", sum); // 55
Пример: чтение до EOF
int c;
while ((c = getchar()) != EOF) {
putchar(c);
}
2. Цикл for — с инициализацией, условием и шагом
Самый частый цикл для известного числа итераций.
for (инициализация; условие; шаг) {
// тело
}
Эквивалент:
инициализация;
while (условие) {
// тело
шаг;
}
Все три части необязательны. for (;;) — бесконечный цикл.
Примеры
// Классический
for (int i = 0; i < 10; i++) {
printf("%d ", i);
}
// Множественные переменные (C99: объявление в init)
for (int i = 0, j = 10; i < j; i++, j--) {
printf("i=%d, j=%d\n", i, j);
}
// Бесконечный цикл с выходом внутри
for (;;) {
int cmd = get_command();
if (cmd == QUIT) break;
process(cmd);
}
// Обход массива
int arr[] = {1,2,3,4,5};
for (size_t i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) {
printf("%d ", arr[i]);
}
3. Цикл do-while — с постусловием
Тело выполняется хотя бы один раз, условие проверяется после.
do {
// тело
} while (условие);
Пример: меню
int choice;
do {
printf("1. Option A\n2. Option B\n0. Exit\nChoice: ");
scanf("%d", &choice);
switch (choice) {
case 1: do_a(); break;
case 2: do_b(); break;
}
} while (choice != 0);
Вложенные циклы
Цикл внутри цикла. Внешний итератор меняется медленнее.
// Таблица умножения
for (int i = 1; i <= 10; i++) {
for (int j = 1; j <= 10; j++) {
printf("%4d", i * j);
}
printf("\n");
}
Операторы управления циклом
break — немедленный выход из цикла (или switch)
for (int i = 0; i < 100; i++) {
if (data[i] == target) {
found = i;
break; // выходим из for
}
}
continue — пропуск текущей итерации
Переходит к проверке условия (while/do-while) или к шагу (for).
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) continue; // пропускаем чётные
printf("%d ", i); // 1 3 5 7 9
}
goto — безусловный переход к метке
Использовать с крайней осторожностью! Полезен для выхода из глубоко вложенных циклов или обработки ошибок (идиома «goto cleanup»).
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (error_condition) goto error_cleanup;
}
}
error_cleanup:
free(resources);
return ERROR;
Бесконечные циклы
Намеренные бесконечные циклы — нормальная практика для серверов, игровых циклов, event loops.
// Идиоматичные способы:
for (;;) { ... } // классика C
while (1) { ... } // понятно
do { ... } while (1); // редко
Выход: break, return, exit(), longjmp(), сигнал (Ctrl+C → SIGINT).
Сравнение циклов
| Цикл | Проверка условия | Минимум итераций | Типичное применение |
|---|---|---|---|
while | Перед | 0 | Неизвестное число итераций, чтение до EOF |
for | Перед | 0 | Известное число, счетчики, обход массивов |
do-while | После | 1 | Меню, ввод с валидацией, хотя бы одна итерация |
Оптимизация циклов (советы)
- Выносите инварианты за цикл:
int limit = compute_limit(); for (i=0; i. - Используйте
size_tдля индексов массивов (беззнаковый, размер указателя). - Предпочитайте
++iвместоi++для итераторов (в C разницы нет, в C++ — есть). - Распаковка циклов (loop unrolling) — делайте только если профайлер покажет узкое место; компилятор делает это лучше (
-O3 -funroll-loops). - Избегайте тяжелых вычислений в условии:
for (i=0; i— O(n²)! Сохраните длину: size_t len = strlen(s); for (i=0; i.
Пример: поиск простых чисел (Решето Эратосфена)
#define LIMIT 1000
bool is_prime[LIMIT + 1];
for (int i = 2; i <= LIMIT; i++) is_prime[i] = true;
for (int p = 2; p * p <= LIMIT; p++) {
if (is_prime[p]) {
for (int mult = p * p; mult <= LIMIT; mult += p) {
is_prime[mult] = false;
}
}
}
for (int i = 2; i <= LIMIT; i++) {
if (is_prime[i]) printf("%d ", i);
}
Язык C
- Фазово-синхронизационные петли (PLL): основы, применение и лучшие практики проектирования
- Освоение оператора switch в C#: синтаксис, примеры и лучшие практики
- Циклы while и do-while в C#: синтаксис, примеры и лучшие практики
- Цикл for в C#: синтаксис, поток выполнения и практические примеры
- Оператор break в C#: как и когда использовать
- Оператор continue в C#: как эффективно пропускать итерации циклов
- Цикл foreach в C#: перебор массивов и коллекций легко
- Освоение цикла for в C++: пошаговое руководство
- Освоение циклов Python: for, while, break, continue и enumerate
- Базовый синтаксис C: токены, идентификаторы, ключевые слова и пробелы