Основы программирования

Оператор switch (вычисляемый goto)


Оператор switch имеет следующий вид:

switch (выражение) { case значение_1: фрагмент_1; case значение_2: фрагмент_2; case значение_3: фрагмент_3; . . . default: // Необязательный фрагмент фрагмент_N; }

Выражение должно быть дискретного типа (целое число или указатель). Значения должны быть константами того же типа, что и выражение в заголовке. Оператор switch работает следующим образом:

  1. сначала вычисляется значение выражения в заголовке switch;
  2. затем осуществляется переход на метку "case L:", где константа L совпадает с вычисленным значением выражения в заголовке;
  3. если такого значения нет среди меток внутри тела switch, то
    • если есть метка "default:", то осуществляется переход на нее;
    • если метка "default:" отсутствует, то ничего не происходит.

Подчеркнем, что после перехода на метку "case L:" текст программы выполняется последовательно. Например, при выполнении фрагмента программы

int n, k; n = 2; switch (n) { case 1: k = 2; case 2: k = 4; case 3: k = 8; }

переменной k будет присвоено значение 8, а не 4. Дело в том, что при переходе на метку "case 2:" будут выполнена сначала строка

k = 4;

и затем строка

k = 8;

что делает приведенный фрагмент совершенно бессмысленным (оптимизирующий компилятор вообще исключит строки "k = 2;" и "k = 4;" из кода готовой программы!). Чтобы исправить этот фрагмент, следует использовать оператор

break;

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

int n, k; n = 2; switch (n) { case 1: k = 2; break; case 2: k = 4; break; case 3: k = 8; break; }

В результате выполнения этого фрагмента переменной k будет присвоено значение 4. Если бы значение n равнялось 1, то k было бы присвоено значение 2, если n равнялось бы 3, то 8. Если n не равно ни 1, ни 2, ни 3, то ничего не происходит.

Оператор switch иногда совершенно необосновано называют оператором выбора. На самом деле, для выбора следует использовать конструкцию if...else if..., см. раздел 3.5.3. Например, приведенный фрагмент лучше реализовать следующим образом:

if (n == 1) { k = 2; } else if (n == 2) { k = 4; } else if (n == 3) { k = 8; }

Оператор switch по сути своей является оператором перехода goto с вычисляемой меткой. Ему присущи многие недостатки goto, например, проблемы с инициализацией локальных переменных при входе в блок. Кроме того, switch не позволяет записывать условия в виде логических выражений, что ограничивает сферу его применения. Рекомендуется никогда не использовать оператор switch: выбор в стиле if...else if... во всех отношениях лучше!



Содержание раздела