355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Герберт Шилдт » C# 4.0: полное руководство » Текст книги (страница 9)
C# 4.0: полное руководство
  • Текст добавлен: 6 апреля 2017, 04:00

Текст книги "C# 4.0: полное руководство"


Автор книги: Герберт Шилдт



сообщить о нарушении

Текущая страница: 9 (всего у книги 83 страниц)

Использование пробелов и круглых скобок

В выражении на C# допускается наличие символов табуляции и пробелов, благодаря которым оно становится более удобным для чтения. Например, оба приведенных ниже выражения, по существу, одинаковы, но второе читается легче.

х=10/у*(127+х) ;

х = 10 / у * (127 + х) ;

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

х = у/3-34*temp+127;

х = (у/3) – (34*temp) + 127;


Предшествование операторов

В табл. 4.2 приведен порядок предшествования всех операторов в С#: от самого высокого до самого низкого. В таблицу включен ряд операторов, рассматриваемых далее в этой книге.

Таблица 4.2. Предшествование операторов в C#



ГЛАВА 5 Управляющие операторы

В этой главе речь пойдет об операторах, управляющих ходом выполнения программы на С#. Управляющие операторы разделяются на три категории: операторы выбора, к числу которых относятся операторы if и switch, итерационные операторы, в том числе операторы цикла for, while, do-while и foreach, а также операторы перехода: break, continue, goto, return и throw. За исключением оператора throw, который является неотъемлемой частью встроенного в C# механизма обработки исключительных ситуаций, рассматриваемого в главе 13, все остальные управляющие операторы представлены в этой главе.


Оператор if

Оператор if уже был представлен в главе 2, а здесь он рассматривается более подробно. Ниже приведена полная форма этого оператора:

if (условие) оператор; else оператор;

где условие – это некоторое условное выражение, а оператор – адресат операторов if и else. Оператор else не является обязательным. Адресатом обоих операторов, if и else, могут также служить блоки операторов. Ниже приведена общая форма оператора if, в котором используются блоки операторов.

if (условие)

{

последовательность операторов

}

else

{

последовательность операторов

}

Если условное выражение оказывается истинным, то выполняется адресат оператора if. В противном случае выполняется адресат оператора else, если таковой существует. Но одновременно не может выполняться и то и другое. Условное выражение, управляющее оператором if, должно давать результат типа bool.

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

// Определить, является ли числовое значение положительным или отрицательным.

using System;

class PosNeg {

  static void Main() {

    int i;

    for(i=-5; i <= 5; i++) {

      Console.Write("Проверка " + i + ": ");

      if(i < 0)

        Console.WriteLine(«отрицательное число»);

      else

        Console.WriteLine(«положительное число»);

    }

  }

}

Результат выполнения этой программы выглядит следующим образом.

Проверка -5: отрицательное число

Проверка -4: отрицательное число

Проверка -3: отрицательное число

Проверка -2: отрицательное число

Проверка -1: отрицательное число

Проверка 0: положительное число

Проверка 1: положительное число

Проверка 2: положительное число

Проверка 3: положительное число

Проверка 4: положительное число

Проверка 5: положительное число

Если в данном примере значение переменной i оказывается меньше нуля, то выполнятся адресат оператора if. В противном случае выполняется адресат оператора else, одновременно они не выполняются.


Вложенные операторы if

Вложенным называется такой оператор if, который является адресатом другого оператора if или же оператора else. Вложенные операторы if очень часто применяются в программировании. Что же касается их применения в С#, то не следует забывать, что любой оператор else всегда связан с ближайшим оператором if, т.е. с тем оператором if, который находится в том же самом блоке, где и оператор else, но не с другим оператором else. Рассмотрим следующий пример.

if (i == 10) {

  if (j < 20) -a = b;

  if(k > 100) с = d;

  else a = с; // этот оператор else связан с оператором if(k > 100)

}

else a = d; // этот оператор else связан с оператором if(i == 10)

Как следует из комментариев к приведенному выше фрагменту кода, последний оператор else не связан с оператором if (j < 20), поскольку они не находятся в одном и том же блоке, несмотря на то, что этот оператор является для него ближайшим оператором if без вспомогательного оператора else. Напротив, последний оператор else связан с оператором if (i == 10). А внутренний оператор else связан с оператором i f (k > 100), поскольку этот последний является для него ближайшим оператором if в том же самом блоке.

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

// Определить, является ли числовое значение

// положительным, отрицательным или нулевым.

using System;

class PosNegZero {

  static void Main() {

    int i;

    for(i=-5; i <= 5; i++) {

      Console.Write("Проверка " + i + ": ");

      if(i < 0)

        Console.WriteLine(«отрицательное число»);

      else

        if(i == 0)

          Console.WriteLine(«число без знака»);

        else

          Console.WriteLine(«положительное число»);

    }

  }

}

Ниже приведен результат выполнения этой программы.

Проверка -5: отрицательное число

Проверка -4: отрицательное число

Проверка -3: отрицательное число

Проверка -2: отрицательное число

Проверка -1: отрицательное число

Проверка 0: число без знака

Проверка 1: положительное число

Проверка 2: положительное число

Проверка 3: положительное число

Проверка 4: положительное число

Проверка 5: положительное число


Конструкция if-else-if

В программировании часто применяется многоступенчатая конструкция if-else-if, состоящая из вложенных операторов if. Ниже приведена ее общая форма.

if(условие)

  оператор;

else  if  (условие)

  оператор;

else  if (условие)

  оператор;

.

.

.

else

  оператор;

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

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

В приведенном ниже примере программы демонстрируется применение многоступенчатой конструкции if-else-if. В этой программе обнаруживается наименьший множитель заданного целого значения, состоящий из одной цифры.

// Определить наименьший множитель заданного

// целого значения, состоящий из одной цифры.

using System;

class Ladder {

  static void Main() {

    int num;

    for(num = 2; num < 12; num++) {

      if((num % 2) == 0)

        Console.WriteLine("Наименьший множитель числа " + num + « равен 2.»);

      else if((num % 3) == 0)

        Console.WriteLine("Наименьший множитель числа " + num + « равен 3.»);

      else if((num % 5) == 0)

        Console.WriteLine("Наименьший множитель числа " + num + « равен 5.»);

      else if((num % 7) == 0)

        Console.WriteLine("Наименьший множитель числа " + num + « равен 7.»);

      else

        Console.WriteLine(num + « не делится на 2, 3, 5 или 7.»);

    }

  }

}

Вот к какому результату приводит выполнение этой программы.

Наименьший множитель числа 2 равен 2.

Наименьший множитель числа 3 равен 3.

Наименьший множитель числа 4 равен 2.

Наименьший множитель числа 5 равен 5.

Наименьший множитель числа 6 равен 2.

Наименьший множитель числа 7 равен 7.

Наименьший множитель числа 8 равен 2.

Наименьший множитель числа 9 равен 3.

Наименьший множитель числа 10 равен 2.

11 не делится на 2, 3, 5 или 7.

Как видите, последний оператор else выполняется лишь в том случае, если не удается выполнить ни один из предыдущих операторов.


Оператор switch

Вторым оператором выбора в C# является оператор switch, который обеспечивает многонаправленное ветвление программы. Следовательно, этот оператор позволяет сделать выбор среди нескольких альтернативных вариантов дальнейшего выполнения программы. Несмотря на то что многонаправленная проверка может быть организована с помощью последовательного ряда вложенных операторов if, во многих случаях более эффективным оказывается применение оператора switch. Этот оператор действует следующим образом. Значение выражения последовательно сравнивается с константами выбора из заданного списка. Как только будет обнаружено совпадение с одним из условий выбора, выполняется последовательность операторов, связанных с этим условием. Ниже приведена общая форма оператора switch.

switch(выражение) {

case константа1:

  последовательность операторов

  break;

case константа2:

  последовательность операторов

  break;

case константаЗ:

  последовательность операторов

  break;

.

.

.

default:

  последовательность операторов 

  break;

}

Заданное выражение в операторе switch должно быть целочисленного типа (char, byte, short или int), перечислимого или же строкового. (О перечислениях и символьных строках типа string речь пойдет далее в этой книге.) А выражения других типов, например с плавающей точкой, в операторе switch не допускаются. Зачастую выражение, управляющее оператором switch, просто сводится к одной переменной. Кроме того, константы выбора должны иметь тип, совместимый с типом выражения. В одном операторе switch не допускается наличие двух одинаковых по значению констант выбора.

Последовательность операторов из ветви default выполняется в том случае, если ни одна из констант выбора не совпадает с заданным выражением. Ветвь default не является обязательной. Если же она отсутствует и выражение не совпадает ни с одним из условий выбора, то никаких действий вообще не выполняется. Если же происходит совпадение с одним из условий выбора, то выполняются операторы, связанные с этим условием, вплоть до оператора break.

Ниже приведен пример программы, в котором демонстрируется применение оператора switch.

// Продемонстрировать применение оператора switch.

using System;

class SwitchDemo {

  static void Main() {

    int i;

    for(i=0; i<10; i++)

      switch(i) {

      case 0:

        Console.WriteLine(«i равно нулю»);

        break;

      case 1:

        Console.WriteLine(«i равно единице»);

        break;

      case 2:

        Console.WriteLine(«i равно двум»);

        break;

      case 3:

        Console.WriteLine(«i равно трем»);

        break;

      case 4:

        Console.WriteLine («i равно четырем»);

        break;

      default:    

        Console.WriteLine(«i равно или больше пяти»);

        break;

      }

  }

}

Результат выполнения этой программы выглядит следующим образом.

i равно нулю.

i равно единице.

i равно двум.

i равно трем.

i равно четырем.

i равно или больше пяти

i равно или больше пяти

i равно или больше пяти

i равно или больше пяти

i равно или больше пяти

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

В приведенном выше примере оператором switch управляла переменная i типа int. Как пояснялось ранее, для управления оператором switch может быть использовано выражений любого целочисленного типа, включая и char. Ниже приведен пример применения выражения и констант выбора типа char в операторе switch.

// Использовать элементы типа char для управления оператором switch.

using System;

class SwitchDemo2 {

  static void Main() {

    char ch;

    for(ch='A'; ch<= 'E'; ch++)

      switch (ch) {

      case 'A':

        Console.WriteLine(«ch содержит A»);

        break;

      case 'B':

        Console.WriteLine(«ch содержит В»);

        break;

      case 'C':

        Console.WriteLine(«ch содержит С»);

        break;

      case 'D' :

        Console.WriteLine(«ch содержит D»);

        break;

      case 'E':

        Console.WriteLine(«ch содержит E»);

        break;

      }

  }

}

Вот какой результат дает выполнение этой программы.

ch содержит А

ch содержит В

ch содержит С

ch содержит D

ch содержит Е

Обратите в данном примере внимание на отсутствие ветви default в операторе switch. Напомним, что ветвь default не является обязательной. Когда она не нужна, ее можно просто опустить.

Переход последовательности операторов, связанных с одной ветвью case, в следующую ветвь case считается ошибкой, поскольку в C# должно непременно соблюдаться правило недопущения «провалов» в передаче управления ходом выполнения программы. Именно поэтому последовательность операторов в каждой ветви case оператора switch оканчивается оператором break. (Избежать подобных «провалов», можно также с помощью оператора безусловного перехода goto, рассматриваемого далее в этой главе, но для данной цели чаще применяется оператор break.) Когда в последовательности операторов отдельной ветви case встречается оператор break, происходит выход не только из этой ветви, но из всего оператора switch, а выполнение программы возобновляется со следующего оператора, находящегося за пределами оператора switch. Последовательность операторов в ветви default также должна быть лишена ''провалов", поэтому она завершается, как правило, оператором break.

Правило недопущения "провалов" относится к тем особенностям языка С#, которыми он отличается от С, C++ и Java. В этих языках программирования одна ветвь case может переходить (т.е. «проваливаться») в другую. Данное правило установлено в C# для ветвей case по двум причинам. Во-первых, оно дает компилятору возможность свободно изменять порядок следования последовательностей операторов из ветвей case для целей оптимизации. Такая реорганизация была бы невозможной, если бы одна ветвь case могла переходить в другую. И во-вторых, требование завершать каждую ветвь case явным образом исключает непроизвольные ошибки программирования, допускающие переход одной ветви case в другую.

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

// Пример «проваливания» пустых ветвей case.

using System;

class EmptyCasesCanFall {

  static void Main() {

    int i;

    for(i=1; i < 5; i++)

      switch(i) {

      case 1:

      case 2:

      case 3:

        Console.WriteLine("i равно 1, 2 или 3");

        break;

      case 4:

        Console.WriteLine(«i равно 4»);

        break;

      }

  }

}

Ниже приведен результат выполнения этой программы.

i равно 1, 2 или 3

i равно 1, 2 или 3

i равно 1, 2 или 3

i равно 4

Если значение переменной i в данном примере равно 1, 2 или 3, то выполняется первый оператор, содержащий вызов метода WriteLine(). Такое расположение нескольких меток ветвей case подряд не нарушает правило недопущения «провалов»; поскольку во всех этих ветвях используется одна и та же последовательность операторов.

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


Вложенные операторы switch

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

switch(ch1) {

case 'A':

  Console.WriteLine("Эта ветвь А – часть " +

             «внешнего оператора switch.»);

  switch(ch2) {

  case 'A':

    Console.WriteLine("Эта ветвь A – часть " +

              «внутреннего оператора switch»);

    break;

  case 'В': // ...

  } // конец внутреннего оператора switch

  break;

case 'В': // ...


Оператор цикла for

Оператор for уже был представлен в главе 2, а здесь он рассматривается более подробно. Вас должны приятно удивить эффективность и гибкость этого оператора. Прежде всего, обратимся к самым основным и традиционным формам оператора for.

Ниже приведена общая форма оператора for для повторного выполнения единственного оператора.

for{инициализация; условие; итерация) оператор;

А вот как выглядит его форма для повторного выполнения кодового блока:

for(инициализация; условие; итерация)

{

последовательность операторов;

}

где инициализация; как правило, представлена оператором присваивания, задающим первоначальное значение переменной, которая выполняет роль счетчика и управляет циклом; условие – это логическое выражение, определяющее необходимость повторения цикла; а итерация – выражение, определяющее величину, на которую должно изменяться значение переменной, управляющей циклом, при каждом повторе цикла. Обратите внимание на то, что эти три основные части оператора цикла for должны быть разделены точкой с запятой. Выполнение цикла for будет продолжаться до тех пор, пока проверка условия дает истинный результат. Как только эта проверка даст ложный результат, цикл завершится, а выполнение программы будет продолжено с оператора, следующего после цикла for.

Цикл for может продолжаться как в положительном, так и в отрицательном направлении, изменяя значение переменной управления циклом на любую величину. В приведенном ниже примере программы выводятся числа; постепенно уменьшающиеся от 100 до -100 на величину 5.

// Выполнение цикла for в отрицательном направлении.

using System;

class DecrFor {

  static void Main() {

    int x;

    for(x = 100; x > -100; x -= 5)

    Console.WriteLine(x);

  }

}

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

for(count=10; count < 5; count++)

x += count; // этот оператор не будет выполняться

Данный цикл вообще не будет выполняться, поскольку первоначальное значение переменной count, которая им управляет, сразу же оказывается больше 5. Это означает, что условное выражение count < 5 оказывается ложным с самого начала, т.е. еще до выполнения первого шага цикла.

Оператор цикла for – наиболее полезный для повторного выполнения операций известное число раз. В следующем примере программы используются два цикла for для выявления простых чисел в пределах от 2 до 20. Если число оказывается непростым, то выводится наибольший его множитель.

// Выяснить, является ли число простым. Если оно

// непростое, вывести наибольший его множитель.

using System;

class FindPrimes {

  static void Main() {

    int num;

    int i;

    int factor;

    bool isprime;

    for(num = 2; num < 20; num++) {

      isprime = true;

      factor = 0;

      // Выяснить, делится ли значение переменной num нацело.

      for(i=2; i <= num/2; i++) {

        if((num % i) == 0) {

          // Значение переменной num делится нацело.

          // Следовательно, это непростое число,

          isprime = false;

          factor = i;

        }

      }

      if(isprime)

        Console.WriteLine(num + « – простое число.»);

      else

        Console.WriteLine("Наибольший множитель числа " + num + " равен " + factor);

    }

  }

}

Ниже приведен результат выполнения этой программы.

2    – простое число

3    – простое число

Наибольший множитель числа 4 равен 2

5 – простое число

Наибольший множитель числа 6 равен 3

7 – простое число

Наибольший множитель числа 8 равен 4

Наибольший множитель числа 9 равен 3

Наибольший множитель числа 10 равен 5

11 – простое число

Наибольший множитель числа 12 равен 6

13 – простое число

Наибольший множитель числа 14 равен 7

Наибольший множитель числа 15 равен 5

Наибольший множитель числа 16 равен 8

17 – простое число

Наибольший множитель числа 18 равен 9

19 – простое число


Некоторые разновидности оператора цикла for

Оператор цикла for относится к самым универсальным операторам языка С#, поскольку он допускает самые разные варианты своего применения. Некоторые разновидности оператора цикла for рассматриваются ниже.


***Применение нескольких переменных управления циклом

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

// Использовать запятые в операторе цикла for.

using System;

class Comma {

  static void Main() {

    int i, j;

    for(i=0, j = 10; i < j; i++, j–)

      Console.WriteLine("i и j: " + i + " " + j) ;

  }

}

Выполнение этой программы дает следующий результат.

i и j : 0 10

i и j : 1 9

i и j : 2 8

i и j : 3 7

i и j : 4 6

В данном примере запятыми разделяются два оператора инициализации и еще два итерационных выражения. Когда цикл начинается, инициализируются обе переменные, i и j. Всякий раз, когда цикл повторяется, переменная i инкрементируется, а переменная j декрементируется. Применение нескольких переменных управления циклом нередко оказывается удобным, упрощая некоторые алгоритмы. Теоретически в операторе цикла for может присутствовать любое количество операторов инициализации и итерации, но на практике цикл получается слишком громоздким, если применяется более двух подобных операторов.

Ниже приведен практический пример применения нескольких переменных управления циклом в операторе for. В этом примере программы используются две переменные управления одним циклом for для выявления наибольшего и наименьшего множителя целого числа (в данном случае – 100). Обратите особое внимание на условие окончания цикла. Оно опирается на обе переменные управления циклом.

// Использовать запятые в операторе цикла for для

// выявления наименьшего и наибольшего множителя числа.

using System;

class Comma {

  static void Main() {

    int i, j;

    int smallest, largest;

    int num;

    num = 100;

    smallest = largest = 1;

    for(i=2, j=num/2; (i <= num/2) & (j >= 2); i++, j–) {

      if((smallest == 1) & ((num % i) == 0)) smallest = i;

      if ((largest == 1) & ((num % j) == 0)) largest = j;

    }

    Console.WriteLine("Наибольший множитель: " + largest);

    Console.WriteLine("Наименьший множитель: " + smallest);

  }

}

Ниже приведен результат выполнения этой программы.

Наибольший множитель: 50

Наименьший множитель: 2

Благодаря применению двух переменных управления циклом удается выявить наименьший и наибольший множители числа в одном цикле for. В частности, управляющая переменная i служит для выявления наименьшего множителя. Первоначально ее значение устанавливается равным 2 и затем инкрементируется до тех пор, пока не превысит половину значения переменной num. А управляющая переменная j служит для выявления наибольшего множителя. Ее значение первоначально устанавливается равным половине значения переменной num и затем декрементируется до тех пор, пока не станет меньше 2. Цикл продолжает выполняться до тех пор, пока обе переменные, i и j, не достигнут своих конечных значений. По завершении цикла оба множителя оказываются выявленными.


Условное выражение

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

// Условием выполнения цикла может служить любое выражение типа bool.

using System;

class forDemo {

  static void Main() {

    int i, j;

    bool done = false;

    for(i=0, j=100; !done; i++, j–) {

      if(i*i >= j) done = true;

      Console.WriteLine("i, j: " + i + " " + j);

    }

  }

}

Ниже приведен результат выполнения этой программы.

i, j: 0 100

i, j: 1 99

i, j: 2 98

i, j: 3 97

i, j: 4 96

i, j: 5 95

i, j: 6 94

i, j: 7 93

i, j: 8 92

i, j: 9 91

i, j: 10 90

В данном примере цикл for повторяется до тех пор, пока значение переменной done типа не окажется истинным (true). Истинное значение переменной done устанавливается в цикле, когда квадрат значения переменной i оказывается больше или равным значению переменной j.


Отсутствующие части цикла

Ряд интересных разновидностей цикла for получается в том случае, если оставить пустыми отдельные части определения цикла. В C# допускается оставлять пустыми любые или же все части инициализации, условия и итерации в операторе цикла for. В качестве примера рассмотрим такую программу.

// Отдельные части цикла for могут оставаться пустыми.

using System;

class Empty {

  static void Main() {

    int i;

    for (i = 0; i < 10; )  {

      Console.WriteLine(«Проход №» + i);

      i++; // инкрементировать переменную управления циклом

    }

  }

}

В данном примере итерационное выражение в определении цикла for оказывается пустым, т.е. оно вообще отсутствует. Вместо этого переменная i, управляющая циклом, инкрементируется в теле самого цикла. Это означает, что всякий раз, когда цикл повторяется, значение переменной i проверяется на равенство числу 10, но никаких других действий при этом не происходит. А поскольку переменная i инкрементируется в теле цикла, то сам цикл выполняется обычным образом, выводя приведенный ниже результат.

Проход №0

Проход №1

Проход №2

Проход №3

Проход №4

Проход №5

Проход №6

Проход №7

Проход №8

Проход №9

В следующем примере программы из определения цикла for исключена инициализирующая часть.

// Исключить еще одну часть из определения цикла for.

using System;

class Empty2 {

  static void Main() {

    int i;

    i = 0; // исключить инициализацию из определения цикла

    for(; i < 10; ) {

      Console.WriteLine(«Проход №» + i);

      i++; // инкрементировать переменную управления циклом

    }

  }

}

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


Бесконечный цикл

Если оставить пустым выражение условия в операторе цикла for, то получится бесконечный цикл, т.е. такой цикл, который никогда не заканчивается. В качестве примера в следующем фрагменте кода показано, каким образом в C# обычно создается бесконечный цикл.

for(;;) // цикл, намеренно сделанный бесконечным {

  //. . .

}

Этот цикл будет выполняться бесконечно. Несмотря на то что бесконечные циклы требуются для решения некоторых задач программирования, например при разработке командных процессоров операционных систем, большинство так называемых «бесконечных» циклов на самом деле представляет собой циклы со специальными требованиями к завершению. (Подробнее об этом – в разделе "Применение оператора break для выхода из цикла" далее в этой главе.)


Циклы без тела

В C# допускается оставлять пустым тело цикла for или любого другого цикла, поскольку пустой оператор с точки зрения синтаксиса этого языка считается действительным. Циклы без тела нередко оказываются полезными. Например, в следующей программе цикл без тела служит для получения суммы чисел от 1 до 5.

// Тело цикла может быть пустым,

using System;

class Empty3 {

  static void Main() {

    int i;

    int sum = 0;

    // получить сумму чисел от 1 до 5

    for(i = 1; i <= 5; sum += i++);

    Console.WriteLine("Сумма равна " + sum);

  }

}

Выполнение этой программы дает следующий результат.

Сумма равна 15

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

sum += i++

Подобные операторы не должны вас смущать. Они часто встречаются в программах, профессионально написанных на С#, и становятся вполне понятными, если разобрать их по частям. Дословно приведенный выше оператор означает следующее: сложить со значением переменной sum результат суммирования значений переменных sum и i, а затем инкрементировать значение переменной i. Следовательно, данный оператор равнозначен следующей последовательности операторов.

sum = sum + i;

i + + ;


Объявление управляющих переменных в цикле for

Нередко переменная, управляющая циклом for, требуется только для выполнения самого цикла и нигде больше не используется. В таком случае управляющую переменную можно объявить в инициализирующей части оператора цикла for. Например, в приведенной ниже программе вычисляется сумма и факториал чисел от 1 до 5, а переменная i, управляющая циклом for, объявляется в этом цикле.


    Ваша оценка произведения:

Популярные книги за неделю