Вы исследуете, какие части заголовка for можно изменять, как сохранить значение счётчика после цикла и как выполнить обратный отсчёт. Сравнивайте примеры по тому, насколько легко понять порядок их выполнения.
Переменная цикла после завершения
Если объявить i внутри заголовка for, обратиться к ней после цикла нельзя. Если значение нужно дальше, объявите переменную перед циклом:
int i;
for (i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
Console.WriteLine("Индекс после цикла: " + i);
Что выведет программа?
Ответ
0
1
2
3
4
Индекс после цикла: 5
После последнего выполнения тела i++ увеличивает значение до 5. Затем проверка i < 5 возвращает false.
Область видимости определяет, где можно обратиться к переменной по имени. Локальная переменная, объявленная внутри блока { ... }, недоступна за его пределами. У переменной, объявленной в заголовке for, область видимости ограничена этим циклом. Объявляйте переменную перед циклом, только если она нужна и после него.
Несколько переменных в одном заголовке
Можно объявить и инициализировать несколько переменных одного типа, а затем обновлять их через запятую:
for (int i = 0, j = 10; i < j; i++, j--)
{
Console.WriteLine($"i = {i}, j = {j}");
}
На каждом повторении i увеличивается, а j уменьшается. Последняя выведенная пара — i = 4, j = 6. После обновления оба значения равны 5, поэтому i < j становится ложным.
Запись $"i = {i}, j = {j}" называется интерполяцией строк: C# подставляет значения выражений из фигурных скобок. Это удобная альтернатива соединению строк оператором +.
Составное условие и несколько обновлений
В средней части по-прежнему одно логическое выражение, но его можно составить с помощью && или ||:
int a = 0, b = 10;
for (; a < 5 && b > 5; a++, b -= 2)
{
Console.WriteLine($"a={a}, b={b}");
}
Здесь обе части условия должны быть истинны. Получатся пары 0, 10, 1, 8 и 2, 6. После следующего обновления b станет равным 4, и цикл завершится.
Пропуск инициализации
Если переменная уже получила начальное значение, первую часть заголовка можно оставить пустой. Точку с запятой сохраняем:
int i = 3;
for (; i < 6; i++)
{
Console.WriteLine(i);
}
Программа выведет 3, 4, 5.
Обновление внутри тела
Третью часть заголовка тоже можно оставить пустой и перенести обновление в тело:
for (int i = 0; i < 3;)
{
Console.WriteLine(i);
i++; // Обновление находится внутри тела.
}
Такой код допустим, но теперь изменение i нужно искать внутри цикла. Для обычного отсчёта яснее оставить i++ в заголовке.
Изменение i для повторного ввода
Рассмотрим программу, которая принимает три положительных числа. При вводе нуля или отрицательного числа она просит повторить ввод:
for (int i = 0; i < 3; i++)
{
Console.Write("Введите положительное число: ");
int n = int.Parse(Console.ReadLine());
if (n <= 0)
{
Console.WriteLine("Число не подходит. Попробуйте ещё раз.");
i--; // Компенсируем предстоящее i++ в заголовке.
}
}
Если n <= 0, уменьшение i внутри тела и увеличение в заголовке взаимно компенсируются. Поэтому неудачный ввод не засчитывается. Программа предполагает ввод целых чисел; буквенный ввод требует отдельной проверки.
Изменение счётчика внутри тела делает число повторений менее очевидным. В этом примере цикл может запрашивать ввод больше трёх раз и будет продолжаться, пока не получит три положительных числа. В собственных программах выбирайте форму цикла, в которой это поведение видно сразу.
continue: пропуск оставшейся части тела
continue пропускает оставшиеся команды текущего повторения. В цикле for после этого выполняется обновление из заголовка, затем снова проверяется условие:
for (int i = 0; i < 5; i++)
{
if (i % 2 == 0)
continue; // Пропускаем вывод чётного числа.
Console.WriteLine(i);
}
Будут выведены 1 и 3. Для этой задачи можно сразу перебирать только нечётные числа:
for (int i = 1; i < 5; i += 2)
{
Console.WriteLine(i);
}
Вторая версия прямо показывает, какие значения нужны. Используйте continue, когда пропуск оставшейся части тела действительно помогает понять решение.
Обратный отсчёт
Для движения от большего значения к меньшему используйте i-- и подходящее условие:
for (int i = 3 - 1; i >= 0; i--)
{
Console.WriteLine(i);
}
В Visual Studio шаблон обратного цикла можно вставить сокращением forr, затем дважды нажать Tab.
Сколько раз выполнится тело? Какие числа появятся на экране?
Ответ
Три раза:
2
1
0
После вывода 0 значение уменьшается до -1, и условие i >= 0 становится ложным.
Как читать разные формы for
| Форма записи | Значение и что проверить |
|---|---|
| Несколько переменных через запятую | Они объявляются с одним типом. Проследите изменение каждой переменной. |
for (; i < 10;) |
Инициализация и обновление отсутствуют в заголовке. Проверьте, где i получает и меняет значение. |
for (int i = 0;; i++) |
Условие отсутствует и считается истинным. Без выхода из тела цикл сам не остановится. |
i-- внутри тела |
Изменяет обычный ход счётчика. Учитывайте и это изменение, и обновление в заголовке. |
continue |
Пропускает остаток тела, затем выполняются обновление и проверка условия. |
for (int i = 2; i >= 0; i--) |
Обратный отсчёт от 2 до 0 включительно. |
Допустимый синтаксис ещё не гарантирует понятный код. Для обычного повторения действий используйте привычную форму с начальным значением, условием и обновлением в заголовке. Читателю должно быть легко увидеть, какие значения перебираются и почему цикл завершится.