Циклы
Что такое цикл
Цикл — это конструкция, которая позволяет повторять блок кода несколько раз. Вместо копирования одинаковых инструкций используем цикл.
// Без цикла (неэффективно)
printf("Привет!\n");
printf("Привет!\n");
printf("Привет!\n");
// С циклом (эффективно)
for (int i = 0; i < 3; i++) {
printf("Привет!\n");
}
Цикл for
Используется когда заранее известно количество повторений.
Базовый синтаксис
for (инициализация; условие; изменение) {
// тело цикла
}
Простые примеры
- Счет от 1 до 10
- Обратный счет
- С шагом
#include <stdio.h>
int main() {
printf("Считаем от 1 до 10:\n");
for (int i = 1; i <= 10; i++) {
printf("%d ", i);
}
printf("\n");
return 0;
}
printf("Обратный отсчет:\n");
for (int i = 10; i >= 1; i--) {
printf("%d ", i);
}
printf("Пуск! 🚀\n");
printf("Четные числа от 0 до 20:\n");
for (int i = 0; i <= 20; i += 2) {
printf("%d ", i);
}
printf("\n");
Вычисления в цикле
#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;
}
int target = 7;
int current = 1;
int found = 0;
printf("Поиск числа %d:\n", target);
while (current <= 10 && !found) {
printf("Проверяем %d... ", current);
if (current == target) {
printf("Найдено!\n");
found = 1;
} else {
printf("нет\n");
current++;
}
}
if (!found) {
printf("Число не найдено\n");
}
Цикл 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");
int scores[] = {95, 45, 78, 62, 88, 35, 92};
int size = 7;
int passCount = 0;
printf("Проходные баллы (≥70):\n");
for (int i = 0; i < size; i++) {
if (scores[i] < 70) {
continue; // Пропускаем низкие баллы
}
printf("Студент #%d: %d баллов\n", i + 1, scores[i]);
passCount++;
}
printf("Всего прошли: %d из %d\n", passCount, size);
Вложенные циклы
Цикл внутри другого цикла для работы с двумерными структурами.
Таблица умножения
#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 | Нужно выполнить минимум один раз | В конце |
Один алгоритм — разные циклы
- Цикл for
- Цикл while
- Цикл do-while
// Сумма чисел от 1 до 10
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
}
printf("Сумма: %d\n", sum);
// Тот же алгоритм через while
int sum = 0;
int i = 1;
while (i <= 10) {
sum += i;
i++;
}
printf("Сумма: %d\n", sum);
// Тот же алгоритм через do-while
int sum = 0;
int i = 1;
do {
sum += i;
i++;
} while (i <= 10);
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;
}
Поиск простых чисел
- Простые числа до 20
- Факториал
#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;
}
printf("Факториалы чисел от 1 до 10:\n");
for (int n = 1; n <= 10; n++) {
long factorial = 1;
for (int i = 1; i <= n; i++) {
factorial *= i;
}
printf("%d! = %ld\n", n, factorial);
}
Оптимизация циклов
Вынос вычислений из цикла
#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:
- Когда нужно выполнить код минимум один раз
- Для меню и интерактивных программ
- Для валидации ввода
Циклы — мощный инструмент для автоматизации повторяющихся операций и обработки больших объемов данных.