Управляющие операторы и методы
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.