
6.6. Переключатель
Переключатель является наиболее удобным средством для организации множественного (мульти-) ветвления. Синтаксис переключателя таков:
switch (переключающее_выражение)
{ case константное_выражение_1:
операторы_1;break;
case константное_выражение_2:
операторы_2;break;
…
case константное_выражение_n:
операторы_n;
default:
операторы;break;
}
В переключателях используют 4 служебных слова: switch, case, break, default и обязательные фигурные скобки, ограничивающие тело переключателя. Конструкция
case константное_выражение:
называется меткой переключателя. Константное выражение может быть целочисленным, может быть символом, строкой или элементом перечисления. (О перечислениях речь пойдет в главе 15).
Заголовок, то есть управляющая конструкция
switch {переключающее выражение),
передает управление к тому из помеченных с помощью case операторов, для которого значение константного выражения совпадает со значением переключающего выражения. Значение переключающего выражения должно быть целочисленным или иметь тип char, string, тип перечисления, или приводиться к целому. Переключающее выражение не может иметь вещественный тип и не может быть десятичным (decimal).
Метка переключателя вводит ветвь или раздел переключателя -последовательность операторов, завершаемая оператором break или goto case i или goto default. (В приведённом формате переключателя указаны только операторы break, так как они используются наиболее часто.) Назначение оператора break - завершить выполнения переключателя. Операторы goto case i или goto default обеспечивают переход к другой "ветке" переключателя...
Значения константных выражений, помещаемых за служебными словами case, приводятся к типу переключающего выражения. В одном переключателе все константные выражения должны иметь различные значения, но быть одного типа. Любой из операторов, помещенных в фигурных скобках после конструкции switch(...), может быть помечен или одной или несколькими метками переключателя. То есть отдельный раздел переключателя может начинаться несколькими метками...
Если значение переключающего выражения не совпадает ни с одним из константных выражений, то выполняется переход к оператору, отмеченному меткой default. В каждом переключателе может быть не больше одной метки default, и операторы, размещённые вслед за ней, выполняются всегда. Если метка default отсутствует, то при несовпадении переключающего выражения ни с одним из константных выражений, помещаемых вслед за case, в переключателе не выполняется ни один из операторов.
Если между несколькими метками переключателя нет операторов, то там нет необходимости помещать операторы break или goto. Таким образом, несколько меток могут помечать один раздел переключателя.
В качестве примера приведём программу перевода оценки в баллах при десятибалльной шкале в аттестационную (четырех бальную) оценку.
Соответствие: 1, 2, 3 балла - неудовлетворительно;
4, 5 - удовлетворительно;
6, 7 - хорошо;
8, 9, 10 - отлично.
// 06_05.cs - переключатель
public static void Main()
{
int ball; // оценка в баллах:
do
Console.Write("Введите оценку в баллах: ");
while (!int.TryParse(Console.ReadLine(), out ball) || ball <= 0 || ball > 10);
switch (ball)
{
case 1:
case 2:
case 3:
Console.WriteLine("Неудовлетворительно");
break;
case 4:
case 5:
Console.WriteLine("Удовлетворительно");
break;
case 6:
case 7:
Console.WriteLine("Xopoшo");
break;
case 8:
case 9:
case 10:
Console.WriteLine("Отлично");
break;
default: Console.WriteLine("Ошибка в данных");
break;
} // Конец переключателя
}
Результат выполнения программы:
Введите оценку в баллах: rr<ENTER> Введите оценку в баллах: -9<ENTER> Введите оценку в баллах: 0<ENTER> ведите оценку в баллах: 9<ENTER> Отлично
Обратите внимание на обязательность оператора break в каждой ветви переключателя. С его помощью управление всегда передаётся оператору, размещённому за переключателем.
В переключателе могут находиться описания и определения объектов, т.е. тело переключателя и каждый оператор, входящий в переключатель, может быть блоком. В этом случае нужно избегать ошибок "перескакивания" через определения:
int n=1;
switch (n)
{
char d='D'; // Никогда не обрабатывается
case 1:
double f = 3.14; // Обрабатывается только для n == 1
case 2:
if ((int)d != (int)f) ; // Ошибка: d и/или f не определены
break;
}
Если в переключателе при некотором значении переключающего выражения необходимо выполнить более одного раздела, то программист может заранее выбрать последовательность обхода ветвей, применяя оператор перехода goto case i или goto default.
Пример программы с переключателем, где выводятся названия нечетных целых цифр, не меньших заданной.
// переключатель с внутренними переходами
public static void Main()
{
int ic = 5; string line = "";
switch (ic)
{
case 0:
case 1: line += "one, ";
goto case 2;
case 2:
case 3: line += "three, ";
goto case 4;
case 4:
case 5: line += "five, ";
goto case 6;
case 6:
case 7: line += "seven, ";
goto case 8;
case 8:
case 9: line += "nine.";
break;
default: line = "Error! It is not digit!";
break;
}
Console.WriteLine("Цифры: " + line);
}
Результат выполнения программы: Цифры: five, seven, nine.