Переход последовательности операторов, связанных с одной ветвью 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(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
{