Перейти к основному содержимому

Циклы

Что такое цикл

Цикл — это конструкция, которая позволяет повторять блок кода несколько раз. Вместо копирования одинаковых инструкций используем цикл.

// Без цикла (неэффективно)
printf("Привет!\n");
printf("Привет!\n");
printf("Привет!\n");

// С циклом (эффективно)
for (int i = 0; i < 3; i++) {
printf("Привет!\n");
}

Цикл for

Используется когда заранее известно количество повторений.

Базовый синтаксис

for (инициализация; условие; изменение) {
// тело цикла
}

Простые примеры

#include <stdio.h>

int main() {
printf("Считаем от 1 до 10:\n");

for (int i = 1; i <= 10; i++) {
printf("%d ", i);
}
printf("\n");

return 0;
}

Вычисления в цикле

#include <stdio.h>

int main() {
int sum = 0;

printf("Сумма чисел от 1 до 100:\n");

for (int i = 1; i <= 100; i++) {
sum += i; // Накапливаем сумму
}

printf("Результат: %d\n", sum); // 5050

return 0;
}

Цикл while

Выполняется пока условие истинно. Количество повторений заранее неизвестно.

Базовое использование

#include <stdio.h>

int main() {
int countdown = 5;

printf("Запуск ракеты через:\n");

while (countdown > 0) {
printf("%d...\n", countdown);
countdown--; // Уменьшаем счетчик
}

printf("Старт! 🚀\n");

return 0;
}

Накопление данных

#include <stdio.h>

int main() {
int number = 1234;
int sum = 0;

printf("Сумма цифр числа %d:\n", number);

while (number > 0) {
int digit = number % 10; // Последняя цифра
sum += digit; // Добавляем к сумме
printf("Цифра: %d\n", digit);
number /= 10; // Убираем последнюю цифру
}

printf("Сумма всех цифр: %d\n", sum); // 10

return 0;
}

Цикл do-while

Выполняется минимум один раз, условие проверяется в конце.

#include <stdio.h>

int main() {
int attempts = 0;
int maxAttempts = 3;
int correctCode = 1234;
int userCode = 0000; // Имитация ввода пользователя

do {
attempts++;
printf("Попытка %d из %d\n", attempts, maxAttempts);
printf("Введенный код: %d\n", userCode);

if (userCode == correctCode) {
printf("✅ Код верный! Доступ разрешен\n");
break; // Выходим из цикла
} else {
printf("❌ Неверный код\n");
userCode = 1234; // Имитация нового ввода
}

} while (attempts < maxAttempts && userCode != correctCode);

if (attempts >= maxAttempts && userCode != correctCode) {
printf("🔒 Доступ заблокирован\n");
}

return 0;
}

Управление циклами

Оператор break

Прерывает выполнение цикла досрочно.

#include <stdio.h>

int main() {
printf("Поиск первого четного числа:\n");

for (int i = 1; i <= 10; i++) {
printf("Проверяем %d... ", i);

if (i % 2 == 0) {
printf("найдено четное число!\n");
break; // Выходим из цикла
}

printf("нечетное, продолжаем\n");
}

return 0;
}

Оператор continue

Пропускает текущую итерацию и переходит к следующей.

printf("Нечетные числа от 1 до 10:\n");

for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue; // Пропускаем четные числа
}
printf("%d ", i);
}
printf("\n");

Вложенные циклы

Цикл внутри другого цикла для работы с двумерными структурами.

Таблица умножения

#include <stdio.h>

int main() {
printf("Таблица умножения 5×5:\n");
printf(" ");

// Заголовок столбцов
for (int j = 1; j <= 5; j++) {
printf("%4d", j);
}
printf("\n");

// Строки таблицы
for (int i = 1; i <= 5; i++) {
printf("%2d:", i); // Номер строки

for (int j = 1; j <= 5; j++) {
printf("%4d", i * j);
}
printf("\n");
}

return 0;
}

Поиск в двумерной структуре

#include <stdio.h>

int main() {
int matrix[3][4] = {
{1, 5, 9, 13},
{2, 6, 10, 14},
{3, 7, 11, 15}
};

int target = 10;
int found = 0;

printf("Поиск числа %d в матрице:\n", target);

for (int row = 0; row < 3 && !found; row++) {
for (int col = 0; col < 4 && !found; col++) {
printf("Проверяем [%d][%d] = %d\n", row, col, matrix[row][col]);

if (matrix[row][col] == target) {
printf("✅ Найдено в позиции [%d][%d]\n", row, col);
found = 1;
}
}
}

if (!found) {
printf("❌ Число не найдено\n");
}

return 0;
}

Практические примеры

Генератор паролей

#include <stdio.h>

int main() {
int passwordLength = 8;
char characters[] = "0123456789ABCDEF";
int charCount = 16;

printf("Сгенерированный пароль: ");

for (int i = 0; i < passwordLength; i++) {
// Простая имитация случайного выбора
int index = (i * 7 + 3) % charCount;
printf("%c", characters[index]);
}
printf("\n");

return 0;
}

Статистика текста

#include <stdio.h>

int main() {
char text[] = "Hello World 123!";
int letters = 0, digits = 0, others = 0;
int i = 0;

printf("Анализируем текст: \"%s\"\n", text);

while (text[i] != '\0') { // До конца строки
char ch = text[i];

if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
letters++;
} else if (ch >= '0' && ch <= '9') {
digits++;
} else {
others++;
}

i++;
}

printf("Статистика:\n");
printf("Букв: %d\n", letters);
printf("Цифр: %d\n", digits);
printf("Других символов: %d\n", others);
printf("Общая длина: %d\n", letters + digits + others);

return 0;
}

Бесконечные циклы и их контроль

Намеренный бесконечный цикл

#include <stdio.h>

int main() {
int choice;

printf("=== ПРОСТОЕ МЕНЮ ===\n");

while (1) { // Бесконечный цикл
printf("\n1. Показать время\n");
printf("2. Показать дату\n");
printf("0. Выход\n");

choice = 1; // Имитация ввода пользователя

if (choice == 0) {
printf("Выход из программы\n");
break; // Выходим из цикла
} else if (choice == 1) {
printf("⏰ Текущее время: 14:30\n");
} else if (choice == 2) {
printf("📅 Сегодня: 29 августа 2025\n");
} else {
printf("❌ Неверный выбор\n");
}

// Для демонстрации выходим после одной итерации
break;
}

return 0;
}

Сравнение типов циклов

Тип циклаКогда использоватьПроверка условия
forИзвестно количество итерацийВ начале
whileНеизвестно количество итерацийВ начале
do-whileНужно выполнить минимум один разВ конце

Один алгоритм — разные циклы

// Сумма чисел от 1 до 10
int sum = 0;

for (int i = 1; i <= 10; i++) {
sum += i;
}

printf("Сумма: %d\n", sum);

Практические применения

Обработка массива

#include <stdio.h>

int main() {
int temperatures[] = {18, 22, 25, 19, 16, 28, 24};
int days = 7;
int sum = 0;
int maxTemp = temperatures[0];
int minTemp = temperatures[0];

printf("Температуры за неделю:\n");

for (int i = 0; i < days; i++) {
int temp = temperatures[i];
printf("День %d: %d°C\n", i + 1, temp);

sum += temp;

if (temp > maxTemp) {
maxTemp = temp;
}

if (temp < minTemp) {
minTemp = temp;
}
}

float average = (float)sum / days;

printf("\n=== СТАТИСТИКА ===\n");
printf("Средняя температура: %.1f°C\n", average);
printf("Максимальная: %d°C\n", maxTemp);
printf("Минимальная: %d°C\n", minTemp);

return 0;
}

Валидация ввода

#include <stdio.h>

int main() {
int password = 1234;
int userInput;
int attempts = 0;
int maxAttempts = 3;
int success = 0;

printf("Введите пароль (у вас %d попытки):\n", maxAttempts);

while (attempts < maxAttempts && !success) {
attempts++;
userInput = (attempts == 1) ? 1111 :
(attempts == 2) ? 2222 : 1234; // Имитация ввода

printf("Попытка %d: %d\n", attempts, userInput);

if (userInput == password) {
printf("✅ Пароль правильный!\n");
success = 1;
} else {
int remaining = maxAttempts - attempts;
if (remaining > 0) {
printf("❌ Неверно. Осталось попыток: %d\n", remaining);
}
}
}

if (!success) {
printf("🔒 Доступ заблокирован\n");
}

return 0;
}

Вложенные циклы

Рисование треугольника

#include <stdio.h>

int main() {
int height = 5;

printf("Треугольник высотой %d:\n", height);

for (int row = 1; row <= height; row++) {
// Пробелы для выравнивания
for (int space = height - row; space > 0; space--) {
printf(" ");
}

// Звездочки
for (int star = 1; star <= row; star++) {
printf("* ");
}

printf("\n");
}

return 0;
}

Поиск простых чисел

#include <stdio.h>

int main() {
printf("Простые числа от 2 до 20:\n");

for (int num = 2; num <= 20; num++) {
int isPrime = 1; // Предполагаем что простое

// Проверяем делители от 2 до num-1
for (int divisor = 2; divisor < num; divisor++) {
if (num % divisor == 0) {
isPrime = 0; // Нашли делитель - не простое
break;
}
}

if (isPrime) {
printf("%d ", num);
}
}
printf("\n");

return 0;
}

Оптимизация циклов

Вынос вычислений из цикла

#include <stdio.h>

int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = 5; // Вычисляем размер заранее

printf("Удваиваем каждое число:\n");

// ✅ Хорошо: size вычислен до цикла
for (int i = 0; i < size; i++) {
int doubled = numbers[i] * 2;
printf("%d * 2 = %d\n", numbers[i], doubled);
}

return 0;
}

Частые ошибки

Распространенные проблемы
// ❌ Бесконечный цикл из-за ошибки в условии
for (int i = 0; i < 10; i--) { // i уменьшается вместо увеличения!
printf("%d\n", i);
}

// ❌ Выход за границы массива
int arr[5];
for (int i = 0; i <= 5; i++) { // i=5 выйдет за границы!
arr[i] = i;
}

// ❌ Изменение счетчика внутри цикла
for (int i = 0; i < 10; i++) {
printf("%d\n", i);
i += 2; // Непредсказуемое поведение!
}

// ❌ Лишняя точка с запятой
for (int i = 0; i < 5; i++); // Пустое тело цикла из-за ;
{
printf("Выполнится только один раз\n");
}
Важные моменты
  • Всегда проверяйте границы массивов
  • Убедитесь, что условие цикла когда-нибудь станет ложным
  • Не изменяйте счетчик цикла внутри тела for
  • Используйте осмысленные имена для переменных циклов

Выбор подходящего цикла

Рекомендации

Используйте for:

  • Когда знаете точное количество итераций
  • Для обхода массивов
  • Для счетчиков

Используйте while:

  • Когда количество итераций зависит от условия
  • Для обработки пользовательского ввода
  • Для поиска значений

Используйте do-while:

  • Когда нужно выполнить код минимум один раз
  • Для меню и интерактивных программ
  • Для валидации ввода

Циклы — мощный инструмент для автоматизации повторяющихся операций и обработки больших объемов данных.