Оператор выбора switch

 

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

 

int key;

printf(RUS("\nВыберите команду (F, M or Q): ")); // Вывести подсказку.

key = getch(); // Прочитать символ.

key = toupper(key); // Преобразовать в верхний регистр.

// блок определения команды...

if (key == 'F')

printf(RUS("\nВыбрана команда \"F\" – означает Файл.\n"));

else if (key == 'M')

printf(RUS("\nВыбрана команда \"M\" – означает сообщение.\n"));

else if (key == 'Q')

printf(RUS("\nВыбрана команда \"Q\" – означает Выход.\n"));

else

printf(RUS("\nНеправиьная клавиша!"));

 

Условия операторов if содержат проверку кода нажатой клавиши на равенство одному из допустимых символов. Если код клавиши не соответствует никакой команде, выводится сообщение об ошибке.

Для подобных случаев в С существует специальная, более удобная, конструкция выбора switch. Выглядит она так:

 

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

{

case константное_выражение: группа_операторов

case константное_выражение: группа_операторов

[default: группа операторов]

}

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

Под группой _операторов подразумевается просто один или несколько произвольных операторов. Группа здесь вовсе не обязана быть блоком, т. е. заключать ее в операторные скобки не требуется.

И еще одна особенность, о которой следует помнить при написании структур switch. Если найдена метка case, совпадающая со значением проверяемого выражения, то выполняется группа_операторов данного case. Однако дело на этом не заканчивается, поскольку, если не принять никаких дополнительных мер, управление “провалится” ниже, на следующую по порядку метку case и т. д., и в результате будут выполнены все операторы до самого конца блока switch. Если это нежелательно (как чаще всего и бывает), в конце группы_операторов case нужно поставить оператор break. Он прерывает выполнение блока c совпавшей меткой и передает управление оператору, непосредственно следующему за блоком switch.

Для иллюстрации мы перепишем предыдущий пример “меню”, оформив его в виде законченной программы, и продемонстрируем попутно еще один управляющий оператор С.

Демонстрация структуры switch:

 

int key;

loop:

//здесь можно добавить программу, выполняемую каждый раз

//после выбора команд F, M or Q

printf(RUS("\nВыберите команду (F, M or Q): "));

key = getche(); // Прочитать клавишу.

// Определение команды...

switch (key)

{

case 'f':

case 'F':

printf(RUS("\nВыбрана команда \"Файл\".\n"));break;

case 'm':

case 'M':

printf (RUS("\nВыбрана команда \"Message\".\n"));break;

case 'q':

case 'Q':

printf(RUS("\nВыбрана команда \"Quit\".\n"));

printf(RUS("Нажмите любую клавишу для завершения программы ...\n"));

getch() ;

return 0; // Возврат в Windows.

default:

printf(RUS("\nНеправиьная клавиша!"));

}

goto loop; // переход в начало программы на метку loop

 

Мы организовали в программе простейший “бесконечный” цикл, который все время просит пользователя ввести команду – до тех пор, пока не будет нажата клавиша “Q”. В этом случае происходит возврат в операционную систему.

Чтение команды производится функцией getche(). Она, как и getch(), возвращает код нажатой клавиши, однако в отличие от getch() отображает введенный символ на экране.

Для реализации цикла мы использовали оператор goto, исполнение которого приводит к передаче управления на метку, указанную в операторе. В примере метка с именем loop стоит в самом начале программы. Таким образом, дойдя до конца функции main (), управление возвращается к ее началу и все повторяется снова.

 

Результат работы программы: