Управляющие операторы и методы
switch
При описании синтаксиса оператора switch использована нотация Бэкуса-Наура (БНФ):
ОператорSWITCH ::= switch (switchВыражение){switchБлок}
switchВыражение ::= ВыражениеswitchВыражение может быть либо целочисленным, либо символьным. switchБлок не может быть пустым.
switchБлок ::= СписокCaseЭлементов
СписокCaseЭлементов ::= [СписокCaseЭлементов] CaseЭлемент
CaseЭлемент ::=
СписокРазделенныхМеток [СписокОператоров] ОператорТерминатор
СписокРазделенныхМеток ::= [СписокРазделенныхМеток] Метка РазделительМетки
РазделительМетки ::= :
Метка ::= case КонстантноеВыражение | default
ОператорТерминатор ::= breakОператор | gotoОператор | return [Выражение];
breakОператор ::= break;
gotoОператор ::= goto Метка;Таким образом, минимальный switch -оператор имеет следующий вид:
int val;
::::::::::
switch (val)
{
default: break; // Список операторов пуст.
}Более сложные образования:
int val;
::::::::::
switch (val)
{
case 0: break;
}
::::::::::
switch (val)
{
case 0: break;
default: break; // Список операторов пуст.
}
::::::::::
switch (val)
{
default: ... break; // default – равноправный элемент switch-оператора.
// может располагаться в любом месте switch-блока, поскольку
// НЕ БЛОКИРУЕТ (!!!) выполнение операторов всех нижележащих CaseЭлементов.
case 100: ... break;
}
::::::::::
switch (val)
{
default: // default НЕ БЛОКИРУЕТ выполнение операторов
// всех нижележащих CaseЭлементов.
// Операторы, входящие в CaseЭлемент под меткой 100, выполняются
// ПРИ ЛЮБЫХ значениях переменной val, отличных от 1 и 10.
case 100: ... break;
case 1: ... break;
case 10: ... break;
}Подтверждение равноправия CaseЭлемента с меткой default. При выполнении менять значение switchВыражения. Осознать происходящее:
using System;
namespace OperatorsTest
{
class Program
{
static void Main(string[] args)
{
int i = 1; // = 500; = 125; = 100; = 250;
switch (i)
{
case 15:
default:
case 100:
Console.WriteLine("default: Ha-Ha-Ha");
break;
case 1:
case 2:
Console.WriteLine("1: 2: Ha-Ha-Ha");
break;
case 125:
Console.WriteLine("125: Ha-Ha-Ha! Ha-Ha-Ha");
break;
case 250:
Console.WriteLine("250: Ha-Ha-Ha! Ha-Ha-Ha");
break;
}
}
}
}Поскольку при выполнении модуля выбор списков операторов для выполнения в рамках CaseЭлемента определяется значением константных выражений в case -метках, константные выражения ВСЕХ меток данного switchБлока должны различаться ПО СВОИМ ЗНАЧЕНИЯМ.
Следующий пример некорректен. Константные выражения в списках разделенных меток CaseЭлемента
case 1+1: case 2: ... break;
различаются ПО ФОРМЕ (1+1 и 2), а НЕ ПО ЗНАЧЕНИЮ!
По тем же причинам в рамках switch -оператора может быть не более одного вхождения метки default.
Списки операторов в CaseЭлементах НЕ могут включать операторы объявления. switchОператор строится на основе ОДНОГО блока, разделяемого метками на фрагменты, выполнение которых производится в зависимости от значений константных выражений в case -метках. Разрешение объявления констант и переменных в CaseЭлементе означает риск обращения к ранее необъявленной переменной:
switch (val)
{
case 0:
int XXX = 100; // Нельзя!
break;
case 1:
XXX += 125;
break;
}Каждый CaseЭлемент в обязательном порядке ЗАВЕРШАЕТСЯ оператором-терминатором, который является ОБЩИМ для ВСЕХ операторов данного CaseЭлемента:
int val, XXX;
:::::
switch (val)
{
case 0:
if (XXX == 25) {XXX *= –1; break;}
else XXX = 17;
goto default; // Терминатор.
case 1:
XXX += 125;
break; // Терминатор.
default:
return XXX; // Терминатор.
}while
ОператорWHILE ::= while (УсловиеПродолжения) Оператор УсловиеПродолжения ::= БулевоВыражение
Здесь
Оператор ::= Оператор ::= БлокОператоров
Правило выполнения этого итеративного оператора состоит в следующем: сначала проверяется условие продолжения оператора и в случае, если значение условного выражения равно true, соответствующий оператор (блок операторов) выполняется.
Невозможно построить операторWHILE на основе одиночного оператора объявления. Оператор
while (true) int XXX = 0;
с самого первого момента своего существования (еще до начала трансляции!) сопровождается предупреждением:
Embedded statement cannot be a declaration or labeled statement.