Читать в оригинале

<< Предыдущая Оглавление Следующая >>


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

5.6.1. Цикл for

Оператор цикла for обобщает известную конструкцию цикла типа арифметической прогрессии. Его синтаксис:

for (инициализаторы; условие; список_выражений) оператор

Оператор, стоящий после закрывающей скобки, задает тело цикла. В большинстве случаев телом цикла является блок. Инициализаторы задают начальное значение одной или нескольких переменных, часто называемых счетчиками или просто переменными цикла. Условие задает условие окончания цикла, соответствующее выражение при вычислении должно получать значение true или false. Список выражений, записанный через запятую, показывает, как меняются счетчики цикла на каждом шаге выполнения. Если условие цикла истинно, то выполняется тело цикла, затем изменяются значения счетчиков и снова проверяется условие. Как только условие становится ложным, цикл завершает свою работу. В нормальной ситуации тело цикла выполняется конечное число раз. Счетчики цикла зачастую объявляются непосредственно в инициализаторе и соответственно являются переменными, локализованными в цикле.

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

В качестве примера рассмотрим классическую задачу: является ли строка текста палиндромом. Для ее решения цикл for подходит наилучшим образом.

Здесь используются два счетчика - один возрастающий, другой убывающий. Вот текст соответствующей процедуры:

/// <summary>
/// Определение палиндромов. Демонстрация цикла for
/// </summary>
/// <param name="str"> текст</param>
/// <returns> true - если текст является палиндромом</returns>
public bool Palindrom(string str) {
          for (int i = 0, j = str.Length - 1; i < j; i++, j--)
                if (str[i] != str[j]) return (false);
          return (true);
} //Palindrom

5.6.2. Циклы While

Цикл while (выражение) является универсальным видом цикла, включаемым во все языки программирования. Тело цикла выполняется до тех пор, пока остается истинным выражение while. В языке C# у этого вида цикла две модификации - с проверкой условия в начале и в конце цикла. Первая модификация имеет следующий синтаксис:

while(выражение) оператор

Эта модификация соответствует циклу с предусловием. Тело такого цикла может ни разу не выполняться. В нормальной ситуации каждое выполнение тела цикла - это очередной шаг к завершению цикла.

Цикл, проверяющий условие завершения в конце, соответствует циклу с постусловием. Тело такого цикла выполняется, по меньшей мере, один раз. Вот синтаксис этой модификации:

do
оператор
while(выражение);

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

/// <summary>
/// Два цикла: с проверкой в конце и в начале.
/// Внешний цикл - образец многократно решаемой задачи.
/// Завершение цикла определяется в диалоге с пользователем.
/// </summary>
public void Loop() {
          // начало процедуры string answer, text;
          do {      
            // начало внешнего цикла
            Console.WriteLine("Введите слово");
            text = Console.ReadLine();
            int i = 0, j = text.Length - 1;
            while ((i < j) && (text[i] == text[j])) {
                        // внутренний цикл
                        i++; j-- ;
            }
            if (text[i] == text[j]) Console.WriteLine(text + " - это палиндром!");
            else Console.WriteLine(text + " - это не палиндром!");
            Console.WriteLine("Продолжим? (yes/no)");
            answer = Console.ReadLine();
          } while (answer == "yes"); // конец внешнего цикла
} //Loop

5.6.3. Цикл forEach

Новым видом цикла, не унаследованным от С++, является цикл foreach, удобный при работе с массивами, коллекциями и другими подобными контейнерами данных. Его синтаксис:

foreach (тип идентификатор in контейнер) оператор

Цикл работает в полном соответствии со своим названием - тело цикла выполняется для каждого элемента в контейнере. Тип идентификатора должен быть согласован с типом элементов, хранящихся в контейнере данных. Предполагается также, что элементы контейнера (массива, коллекции) упорядочены. На каждом шаге цикла идентификатор, задающий текущий элемент контейнера, получает значение очередного элемента в соответствии с порядком, установленным на элементах контейнера. С этим текущим элементом и выполняется тело цикла - выполняется столько раз, сколько элементов находится в контейнере. Цикл заканчивается, когда полностью перебраны все элементы контейнера. Серьезным недостатком циклов foreach в языке C# является то, что цикл работает только на чтение, но не на запись элементов. Так что наполнять контейнер элементами приходится с помощью других операторов цикла.

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

/// <summary>
/// Демонстрация цикла foreach.
/// Вычисление суммы, максимального и минимального элементов
/// трехмерного массива, заполненного случайными числами.
/// </summary>
public void SumMinMax() {
          int[,,] arr3d = new int[10,10,10];
          Random rnd = new Random();
          for (int i = 0; i < 10; i++)
            for (int j = 0; j < 10; j++)
                        for (int k = 0; k < 10; k++)
                                   arr3d[i, j, k] = rnd.Next(100);
          long sum = 0;
          int min = arr3d[0, 0, 0], max = arr3d[0, 0, 0];
          foreach (int item in arr3d) {
            sum += item;
            if (item > max) max = item;
            else if (item < min) min = item;
          }
          Console.WriteLine("sum = {0}, min = {1}, max = {2}", sum, min, max);
} //SumMinMax

 

 



<< Предыдущая Оглавление Следующая >>