Операторы циклов

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

Понятие цикла близко к понятию рекурсивной функции. И вправду многие циклы мы можем выразительно представить через рекурсию и рекуррентные отношения. Но цикл сам по себе более императивная вещь, которая буквально пытается представить алгоритм.

В C# мы имеем несколько операторов для представления циклов:

  1. while, do-while – нужны для повторения некоторых действий без четкого понимания, сколько действий потребуется. Есть только условие продолжения;
  2. for – нужен для циклов у которого заранее известно сколько итераций (выполнений) нам нужно сделать;
  3. foreach – более высокоуровневый цикл, который является встроенным в C# оператором для работы с некой сущностью “итератор”. При работе с ним мы перебираем некое множество элементов. Его мы рассмотрим в разделе с массивами и интерфейсом IEnumerable. ;

while

Простейший цикл, внешне схож с оператором if, но имеет другую семантику.

У него также есть условие и тело. Только в отличие от оператора if мы немного по-другому управляем программой. В случае с оператором if мы имеем условие и тело, которое выполняется, если условие верное. Далее в любом случае выполняются операторы после оператора if. А с циклом while есть одно интересное дополнение. Если условие верно, то после выполнения тела, мы опять возвращаемся к условию, если условие все еще верно то всё повторяется.

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

Фрагмент 1.8

int secretNumber = 250;
int userInput = 0;

while(userInput != secretNumber)
{
    Console.WriteLine("Введите секретное число:");
    userInput = Convert.ToInt32(Console.ReadLine());
}

Console.WriteLine("Вы ввели правильное секретное число!!!");

Если заменить в этом примере while на if, то программа скомпилируется и будет работать. Только у пользователя будет одна попытка ввести секретное число. И в любом случае программа выведет, что число было правильным. ¯\_(ツ)_/¯

for

Любой цикл можно описать с помощью цикла while. Даже цикл foreach в процессе трансляции преобразуется в цикл while. Но как было и с оператором goto, нам недостаточно только возможности. Нам нужен ещё и удобный уровень абстракции и специализированные инструменты.

Одним из таких инструментов является цикл for. Он невероятно удобен при итерировании (переборе) массивов, а также выполнении операций, число которых можно описать.

Его синтаксис выражает три основных блока, которые присущи подобным циклам:

  1. Инициализация счётчика;
  2. Условие;
  3. Изменение состояния (обычно инкремент);

Эти блоки мы перечисляем внутри круглых скобок оператора for через точку с запятой. Мы также вполне можем оставить этот блок пустым. Выполняются они в таком порядке:

  1. Инициализация;
  2. Условие, если верное, идём на шаг 3, если не верное уходим от оператора for;
  3. Тело цикла;
  4. Изменение состояния ;
  5. Переход на шаг 2;

Фрагмент 1.9

int userAge = 0;

for(int i = 0; i < userAge; i++)
{
    Console.WriteLine("Happy birthday!");
}

Данная программа поздравляет пользователя с днём рождения столько раз, сколько ему лет.

Вырожденные операторы

Бывают ситуации которые стоит избегать. Например когда тело оператора вырождается, это часто бывает с оператором while.

Бывает такой код некоторые пытаются уместить в одну строку.

int number = 2;
int delimeter = 2;

while(number % delimeter++ == 0) ;

Console.WriteLine(delimeter);

Данный алгоритм ищет ближайший делитель числа без остатка.

Записывать это в одну строку нет смысла только если вы не хотите запутать читателя или показать свой навык владения синтаксисом. Правильно будет так:

int number = 2;
int delimeter = 2;

while(number % delimeter == 0)
{
   delimeter++;
}

Console.WriteLine(delimeter);

Отдельно условие, отдельно действие.

Если вы нашли ошибку, пожалуйста выделите её и нажмите Ctrl+Enter.


Leave a Reply

Your email address will not be published. Required fields are marked *