Циклы while и do while в C#
Цикл while в C# повторяет блок кода, пока условие истинно, а do while делает то же самое, но проверяет условие после выполнения тела. Разберём синтаксис обоих операторов, отличия между ними, управление через break и continue, бесконечные циклы и типичные примеры с вводом пользователя.

Содержание
Цикл while: синтаксис и принцип работы
Оператор while называют циклом с предусловием. Сначала вычисляется логическое выражение в скобках, и только если оно равно true, выполняется тело. После этого условие проверяется снова, и так до тех пор, пока оно не станет false. Если при первой проверке условие ложно, тело не выполнится ни разу.
int i = 1;
while (i <= 5)
{
Console.WriteLine($"Шаг {i}");
i++;
}
Console.WriteLine("Цикл завершён");
В этом примере переменная i служит счётчиком. Её нужно объявить до цикла, а изменять внутри тела: если забыть строку i++, условие всегда будет истинным, и программа зависнет. Это самая частая ошибка у новичков при работе с while.
Условие должно быть выражением типа bool. В отличие от некоторых других языков, число или строка в качестве условия не подойдут. Для составных условий используйте логические операторы, о которых подробнее написано в материале про логические операторы C#.
Цикл do while: проверка после тела
Цикл do while называют циклом с постусловием. Тело выполняется минимум один раз, а затем проверяется условие. В конце конструкции обязательно ставится точка с запятой, чего многие не замечают.
int number;
do
{
Console.Write("Введите число от 1 до 10: ");
number = int.Parse(Console.ReadLine()!);
}
while (number < 1 || number > 10);
Console.WriteLine($"Вы ввели {number}");
Такая форма удобна, когда действие нужно выполнить хотя бы раз, а затем решить, повторять ли его. Типичные случаи: запрос данных у пользователя, повтор меню, попытка подключения к ресурсу. Тот же код на while пришлось бы писать с дублированием первого запроса или с лишним флагом.
Чем while отличается от do while
Главное различие - момент проверки условия. Это легко увидеть, если запустить оба цикла с заведомо ложным условием.
int x = 10;
while (x < 5)
{
Console.WriteLine("while: выполнился");
}
do
{
Console.WriteLine("do while: выполнился");
}
while (x < 5);
Первый цикл не напечатает ничего, второй напечатает строку один раз. Сводка отличий выглядит так.
| Признак | while | do while |
|---|---|---|
| Когда проверяется условие | до тела | после тела |
| Минимум итераций | 0 | 1 |
| Точка с запятой в конце | не нужна | обязательна |
| Типичное применение | обработка, пока есть данные | запрос ввода, повтор действия |
Операторы break и continue
Оператор break немедленно завершает ближайший цикл, а управление переходит к первой строке после него. Оператор continue пропускает остаток текущей итерации и переходит к проверке условия. Обратите внимание: в while перед continue нужно успеть изменить счётчик, иначе получится бесконечный цикл.
int n = 0;
while (n < 10)
{
n++;
if (n % 2 == 0)
continue; // чётные числа пропускаем
if (n > 7)
break; // после 7 выходим
Console.WriteLine(n); // 1, 3, 5, 7
}
Оба оператора действуют только на самый внутренний цикл. Чтобы выйти сразу из двух вложенных циклов, используют флаг, вынос логики в отдельный метод с return либо оператор goto. Как работает return, описано в статье про оператор return.
Бесконечные циклы и безопасный выход
Бесконечный цикл иногда нужен намеренно: консольное меню, ожидание команд, обработка очереди сообщений. Его записывают как while (true) или do while (true), а выход делают через break, return или исключение.
while (true)
{
Console.Write("Команда (help, exit): ");
string? cmd = Console.ReadLine();
if (cmd == "exit")
break;
if (cmd == "help")
Console.WriteLine("Доступные команды: help, exit");
else
Console.WriteLine("Неизвестная команда");
}
Console.WriteLine("Программа завершена");
Ненамеренный бесконечный цикл случается по трём причинам: счётчик не меняется, условие записано неверно (например, i >= 0 при увеличении i) или изменение происходит в ветке, которая не выполняется. При отладке полезно вывести значения переменных условия внутри тела и проверить, меняются ли они вообще.
Примеры с вводом пользователя
Циклы while и do while чаще всего встречаются там, где число повторений заранее неизвестно. Классический пример - проверка корректности ввода. Метод int.TryParse возвращает false, если строка не является числом, поэтому исключений не будет.
int age;
Console.Write("Сколько вам лет? ");
while (!int.TryParse(Console.ReadLine(), out age) || age < 0 || age > 120)
{
Console.Write("Некорректное значение, повторите: ");
}
Console.WriteLine($"Возраст: {age}");
Другой пример - сумма чисел до тех пор, пока пользователь не введёт ноль. Количество повторений заранее неизвестно, поэтому for здесь неудобен.
int sum = 0;
int value;
do
{
Console.Write("Число (0 - закончить): ");
int.TryParse(Console.ReadLine(), out value);
sum += value;
}
while (value != 0);
Console.WriteLine($"Сумма: {sum}");
Ещё один распространённый случай - угадывание числа с подсказками. Случайное число загадывается один раз, а цикл крутится до верной догадки.
var rnd = new Random();
int secret = rnd.Next(1, 101);
int attempts = 0;
int guess;
do
{
Console.Write("Ваш вариант: ");
int.TryParse(Console.ReadLine(), out guess);
attempts++;
if (guess < secret) Console.WriteLine("Больше");
else if (guess > secret) Console.WriteLine("Меньше");
}
while (guess != secret);
Console.WriteLine($"Угадали за {attempts} попыток");
Подробнее о чтении данных с клавиатуры и разборе чисел можно прочитать в материале про приведение типов.
Вычисления без известного числа шагов
Ещё одна область для while - численные алгоритмы, где нужно продолжать, пока не достигнута точность или результат. Например, алгоритм Евклида для наибольшего общего делителя выполняется до тех пор, пока остаток не станет нулевым, и заранее сказать, сколько шагов потребуется, нельзя.
int a = 48, b = 18;
while (b != 0)
{
int t = b;
b = a % b;
a = t;
}
Console.WriteLine($"НОД = {a}"); // 6
Так же пишут подсчёт цифр числа, разворот числа и поиск первой степени двойки, превышающей заданную границу. Во всех случаях логика строится вокруг условия, а не вокруг счётчика, и это сигнал выбрать while.
int num = 90210;
int digits = 0;
while (num > 0)
{
num /= 10;
digits++;
}
Console.WriteLine(digits); // 5
Сравнение с for и foreach
Все три цикла умеют повторять код, но предназначены для разных ситуаций. Цикл for удобен, когда известны начало, конец и шаг, поскольку инициализация, условие и изменение счётчика собраны в одной строке. Подробности есть в статье про цикл for. Цикл foreach перебирает элементы коллекции без индексов, о нём рассказано в руководстве по foreach.
| Цикл | Когда выбирать | Пример задачи |
|---|---|---|
| for | число повторений известно заранее | вывести числа от 1 до 100 |
| foreach | нужно пройти по всем элементам коллекции | обработать каждый элемент списка |
| while | повторять, пока выполняется условие | читать данные, пока они есть |
| do while | тело должно выполниться хотя бы раз | запрашивать ввод до верного значения |
Технически любой for можно переписать через while, и наоборот. Разница в читаемости: если счётчик есть и он очевиден, берите for; если есть только условие продолжения, берите while. Выбор по смыслу делает код понятнее без лишних комментариев.
Типичные ошибки
- Забытое изменение переменной условия, из-за чего цикл не заканчивается.
- Точка с запятой сразу после while (условие); - тело становится пустым, а блок в фигурных скобках выполняется один раз уже после цикла.
- Отсутствие точки с запятой после while в конструкции do while.
- Использование continue до изменения счётчика.
- Сравнение вещественных чисел через == в условии: из-за погрешности цикл может не остановиться.
- Использование int.Parse для пользовательского ввода без проверки: лучше TryParse.
Если в цикле вызывается код, который может выбросить исключение, оберните его в try-catch, как показано в статье про блоки try-catch.
Частые вопросы
Что будет, если условие while всегда истинно?
Цикл будет работать бесконечно, пока вы не выйдете из него через break, return или исключение, либо пока процесс не будет остановлен. Для консольных программ можно прервать выполнение сочетанием Ctrl+C.
Можно ли вложить один while в другой?
Да, вложенность не ограничена. При этом break и continue действуют только на внутренний цикл, а переменные внешнего цикла доступны во внутреннем. Следите за читаемостью и при глубокой вложенности выносите логику в методы.
Нужна ли точка с запятой после do while?
Да. Конструкция do { ... } while (условие); обязательно заканчивается точкой с запятой. Без неё компилятор выдаст ошибку.
Какой цикл быстрее: for, while или do while?
Разница в скорости ничтожна и на практике определяется телом цикла, а не его видом. Выбирайте оператор по смыслу задачи и читаемости, а не по скорости.
Как выйти из двух вложенных циклов сразу?
Самый чистый способ - вынести циклы в отдельный метод и использовать return. Альтернативы: булев флаг, проверяемый в условии внешнего цикла, или оператор goto с меткой. Break прерывает только один уровень.
Чем while (true) отличается от for (;;)?
Ничем по результату: оба записывают бесконечный цикл, и компилятор обрабатывает их одинаково. Вариант while (true) читается проще, поэтому встречается чаще.





