Операторы switch и case помогают управлять сложными условными операциями и операциями ветвления. Оператор switch передает управление в оператор внутри своего тела.
Синтаксис
selection-statement :
switch ( expression ) statement
labeled-statement :
case constant-expression : statement
default : statement
Комментарии
Оператор switch передает управление одному из labeled-statement в своем теле в зависимости от значения expression .
Значения expression и значение каждого constant-expression должны иметь целочисленный тип. Выражение constant-expression должно иметь однозначное константное целочисленное значение во время компиляции.
Управление передается оператору case , значение constant-expression которого соответствует значению выражения expression . Оператор switch может содержать неограниченное число экземпляров case . Однако значения ни одной из пар выражений constant-expression в одном операторе switch не должны совпадать. Выполнение тела оператора switch начинается с первого соответствующего оператора labeled-statement или после него. Выполнение продолжается до конца тела оператора или пока оператор break не передаст управление за пределы тела.
C Programming Tutorial 61 — How to Write a Switch Statement
Оператор switch обычно используется следующим образом:
switch ( expression ) < // declarations // . . . case constant_expression: // statements executed if the expression equals the // value of this constant_expression break; default: // statements executed if expression does not equal // any case constant_expression >
Оператор break можно использовать для завершения обработки определенного оператора с меткой в операторе switch . Он выполняет ветвление до конца оператора switch . Без оператора break выполнение программы продолжается до следующего оператора с меткой. Операторы будут выполняться до достижения оператора break или конца всего оператора. В некоторых случаях может требоваться именно такое поведение.
Оператор default выполняется, если ни одно из значений case constant-expression не равно значению expression . Если оператор default не указан и соответствующий вариант case не найден, ни один из операторов в теле оператора switch не выполняется. Допускается не более одного оператора default . Оператор default не обязательно должен находиться в конце. Он может располагаться в любом месте тела оператора switch . Метка case или default может располагаться только внутри оператора switch .
Выражения switch expression и case constant-expression должны быть целочисленного типа. Значение каждого case constant-expression в теле оператора должно быть уникальным.
Метки case и default тела оператора switch имеют значения только при начальной проверке, которая определяет, с какого места тела оператора начинается выполнение. Операторы switch могут быть вложенными. Любые статические переменные инициализируются до выполнения любых операторов switch .
Объявления могут располагаться в начале составного оператора, образующего тело оператора switch , но инициализации, включенные в объявления, не выполняются. Оператор switch передает управление непосредственно на выполняемый оператор в теле, минуя все строки, содержащие инициализации.
C++ switch structure
В следующих примерах кода показаны операторы switch :
switch( c )
В этом примере, если переменная c равна ‘A’ , выполняются все три оператора тела switch , так как оператор break перед следующим оператором case отсутствует. Управления передается первому оператору ( capital_a++; ) и продолжается по-порядку во всей остальной части тела. Если переменная c равна ‘a’ , увеличиваются значения переменных letter_a и total . Если переменная c не равна ‘A’ или ‘a’ , увеличивается только значение переменной total .
switch( i )
В этом примере оператор break указан после каждого оператора тела switch . Оператор break вызывает принудительный выход из тела оператора после выполнения одного оператора. Если переменная i равна –1, увеличивается только значение переменной n . Оператор break после оператора n++; передает управление за пределы тела оператора, минуя оставшиеся операторы. Аналогично, если переменная i равна 0, увеличивается только значение переменной z ; если переменная i равна 1, увеличивается только значение переменной p . Заключительный оператор break , строго говоря, не требуется, так как управление передается из тела в конце составного оператора. Он добавлен для единообразия.
Один оператор может содержать несколько меток case , как показано в следующем примере:
switch( c )
В этом примере, если constant-expression значение равно любой букве между ‘a’ и ‘f’ , convert_hex вызывается функция .
Специально для систем Майкрософт
Microsoft C не ограничивает количество значений case в операторе switch . Это число ограничивается только объемом доступной памяти. ANSI C требует, чтобы в операторе switch можно было использовать не менее 257 меток case .
В Microsoft C расширения Майкрософт по умолчанию (default) включены. Используйте параметр компилятора /Za для отключения этих расширений.
Источник: learn.microsoft.com
Примеры программ с switch
Конструкция switch-case позволяет сравнить некоторое выражение с набором значений. Она имеет следующую форму:
switch(выражение)
После ключевого слова switch в скобках идет сравниваемое выражение. Значение этого выражения последовательно сравнивается со значениями после оператора сase . И если совпадение будет найдено, то будет выполняться определенный блок сase .
Стоит отметить, что сравниваемое выражение в switch должно представлять один из целочисленных или символьных типов или перечисление (рассматриваются далее).
В конце конструкции switch может стоять блок default . Он необязателен и выполняется в том случае, если значение после switch не соответствует ни одному из операторов case. Например:
#include int main() < int x ; switch(x) < case 1: std::cout >
Чтобы избежать выполнения последующих блоков case/default, в конце каждого блока ставится оператор break . То есть в данном случае будет выполняться оператор
case 2: std::cout
После выполнения оператора break произойдет выход из конструкции switch..case, и остальные операторы case будут проигнорированы. Поэтому на консоль будет выведена следующая строка
x = 2
Стоит отметить важность использования оператора break . Если мы его не укажем в блоке case , то после этого блока выполнение перейдет к следующему блоку case. Например, уберем из предыдущего примера все операторы break:
#include int main() < int x ; switch(x) < case 1: std::cout >
В этом случае опять же будет выполняться оператор case 2: , так как переменная x=2. Однако так как этот блок case не завершается оператором break, то после его завершения будет выполняться набор инструкций после case 3: даже несмотря на то, что переменная x по прежнему равна 2. В итоге мы получим следующий консольный вывод:
x = 2 x = 3 x is undefined
Совмещение условий
Можно определять для нескольких меток case один набор инструкций:
#include int main() < int x ; switch(x) < case 1: case 2: std::cout >
Переменные в блоках case
Определение переменных в блоках case , возможно, встречается нечасто. Однако может вызвать затруднения. Так, если переменная определяется в блоке case, то все инструкции блока помещаются в фигурные скобки (для блока default это не требуется):
#include int main() < int x ; switch(x) < case 1: < int a; std::cout case 2: < int b; std::cout default: int c; std::cout >
Блок switch с инициализацией переменной
Иногда в конструкции switch для различных промежуточных вычислений необходимо определить переменную. Для этой цели начиная со стандарта C++17 язык С++ поддерживает особую форму конструкции switch :
switch(инициализация; выражение) < // . >
Подобная форма также принимает выражение, значение которого сравнивается с константами после операторов case . Но теперь перед выражением еще может идти определение и инициализация переменной. Например:
#include int main() < char op = ‘+’; int n = 10; switch(int k; op) < case ‘+’: std::cout >
В данном случае в конструкции switch определяется переменная k , которая доступна только в рамках этой конструкции switch . В качестве выражения используется значение переменной op , которая представляет знак операции. И в зависимости от этого значения, выполняем определенную операцию с переменными n и k.
Источник: metanit.com
Оператор switch (C++)
Позволяет выбирать между несколькими разделами кода в зависимости от значения целочисленного выражения.
Синтаксис
selection-statement :
switch ( init-statement opt C++17 condition ) statement
labeled-statement :
case constant-expression : statement
default : statement
Комментарии
Оператор switch передает управление одному из labeled-statement в своем теле в зависимости от значения condition .
Должен condition иметь целочисленный тип или быть типом класса, который имеет однозначное преобразование в целочисленный тип. Целочисленное повышение выполняется, как описано в разделе Стандартные преобразования.
Тело switch инструкции состоит из ряда case меток и optметки ional default . Является labeled-statement одной из этих меток и следующих операторов. Помеченные операторы не являются синтаксическими требованиями, но switch без них оператор не имеет смысла. Никакие два constant-expression значения в case инструкциях не могут иметь одинаковое значение. Метка default может появиться только один раз. Оператор default часто помещается в конце, но он может отображаться в любом месте текста инструкции switch . Метка case или default может располагаться только внутри оператора switch .
В каждой constant-expression case метке преобразуется в константное значение того же типа, что и condition . Затем это сравнивается с condition для равенства. Элемент управления передается первому оператору case constant-expression после значения, соответствующего значению condition . Поведение, полученное в результате, показано в следующей таблице.
switch поведение инструкции
Преобразованное значение соответствует значению выражения управления с повышенным уровнем. | Управление передается оператору, следующему за этой меткой. |
Ни одна из констант не соответствует констант в case метках; метка default присутствует. | Элемент управления передается в метку default . |
Ни одна из констант не совпадает с константами в case метках; метка отсутствует default . | Управление передается оператору после switch оператора . |
Если найдено соответствующее выражение, выполнение может продолжаться позже case или default с метками. Оператор break используется для остановки выполнения и передачи управления оператору после switch оператора . break Без оператора выполняется каждый оператор от сопоставленной case метки до конца switch , включая default , . Например:
// switch_statement1.cpp #include int main() < const char *buffer = «Any character stream»; int uppercase_A, lowercase_a, other; char c; uppercase_A = lowercase_a = other = 0; while ( c = *buffer++ ) // Walks buffer until NULL < switch ( c ) < case ‘A’: uppercase_A++; break; case ‘a’: lowercase_a++; break; default: other++; >> printf_s( «nUppercase A: %dnLowercase a: %dnTotal: %dn», uppercase_A, lowercase_a, (uppercase_A + lowercase_a + other) ); >
В приведенном выше примере увеличивается, uppercase_A если является верхним ‘A’ case. c Оператор break после uppercase_A++ завершает выполнение тела инструкции switch и передает управление циклу while . break Без оператора выполнение будет «переходить» к следующему оператору с меткой, поэтому lowercase_a и other также будут увеличиваться. Аналогичная цель выполняется оператором break для case ‘a’ . Если c является более низкимcase ‘a’ , lowercase_a увеличивается, и break оператор завершает текст инструкции switch . Если c не ‘a’ является или ‘A’ , default выполняется инструкция .
Visual Studio 2017 и более поздних версий (доступно в /std:c++17 режиме и более поздних [[fallthrough]] версиях): атрибут указан в стандарте C++17. Его можно использовать в операторе switch . Компилятору или любому, кто читает код, намекает на то, что падающее поведение является преднамеренным. Компилятор Microsoft C++ в настоящее время не предупреждает о поведении с ошибками, поэтому этот атрибут не влияет на поведение компилятора. В этом примере атрибут применяется к пустому оператору в операторе без пометки. Иными словами, точка с запятой необходима.
int main() < int n = 5; switch (n) < case 1: a(); break; case 2: b(); d(); [[fallthrough]]; // I meant to do this! case 3: c(); break; default: d(); break; >return 0; >
Visual Studio 2017 версии 15.3 и более поздних версий (доступно в /std:c++17 режиме и более поздних версиях). Оператор switch может содержать init-statement предложение, которое заканчивается точкой с запятой. Он вводит и инициализирует переменную, область действия которой ограничена блоком инструкции switch :
switch (Gadget gadget(args); auto s = gadget.get_status()) < case status::good: gadget.zip(); break; case status::bad: throw BadGadget(); >;
Внутренний блок инструкции switch может содержать определения с инициализаторами, если они доступны, то есть не обходят все возможные пути выполнения. Имена, добавленные с помощью этих объявлений, имеют локальную область видимости. Например:
// switch_statement2.cpp // C2360 expected #include using namespace std; int main(int argc, char *argv[]) < switch( tolower( *argv[1] ) ) < // Error. Unreachable declaration. char szChEntered[] = «Character entered was: «; case ‘a’ : < // Declaration of szChEntered OK. Local scope. char szChEntered[] = «Character entered was: «; cout break; case ‘b’ : // Value of szChEntered undefined. cout >
Оператор switch может быть вложенным. При вложении case метки или default связываются с ближайшим switch оператором, который их заключает.
Поведение в системах Майкрософт
Microsoft C++ не ограничивает количество значений case в инструкции switch . Это число ограничивается только объемом доступной памяти.
Источник: learn.microsoft.com