Как осуществляется выход из оператора switch
Перейти к содержимому

Как осуществляется выход из оператора switch

  • автор:

Оператор switch

Некоторые программы предусматривают разветвление алгоритма по нескольким вариантам. В подобных случаях очень удобно использовать оператор switch, особенно, когда количество вариантов достигает десятков или сотен, а при использовании множества вложенных операторов if код получается очень громоздким.

Формат оператора switch

Оператор switch состоит из заголовка и исполняемого тела. Заголовок содержит название оператора и Выражение, обрамлённое круглыми скобками. Тело оператора содержит один или несколько вариантов case и один вариант default.

Каждый из вариантов case состоит из ключевого слова case, Константы, «:» (знака «двоеточие’) и операторов. Количество вариантов case не ограничено.

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

switch ( Выражение ) // Заголовок оператора 
// Открывающая фигурная скобка
case Константа: Операторы // Один из вариантов case
case Константа: Операторы // Один из вариантов case
.
[default: Операторы] // Вариант без параметра
> // Закрывающая фигурная скобка

Значениями Выражения и Параметров могут быть только значения целого типа. В качестве Выражения может использоваться константа, переменная, вызов функции или выражение. Каждый вариант case может быть помечен целой константой, символьной константой или константным выражением. Константное выражение не может включать переменные или вызовы функций.

Правило исполнения оператора switch

Передать управление первому из операторов, следующих за «:» (знаком двоеточия) того варианта case, значение Константы которого совпадет со значением Выражения, и далее последовательно исполнить все операторы, составляющие тело оператора switch. Проверка условия равенства Выражения и Константы производится в направлении сверху вниз и слева направо. Совпадение значений Констант разных вариантов case не допускается. Оператор break прекращает исполнение оператора switch и передаёт управление оператору, следующему за оператором switch.

Легко понять, что запись case Константа: представляет просто метку, на которую передаётся управление; и, начиная с этой метки, исполняются все операторы, составляющие тело оператора switch. Если же алгоритм программы предполагает исполнение группы операторов, соответствующих только одному из вариантов case, то последним в списке операторов, соответствующих одному варианту case, следует указать оператор break. Проследим работу оператора switch на примере.

Примеры применения оператора switch

Задача 18. Составить программу, в которой реализуются следующие условия: если курс поднялся выше заданного уровня, то выдать сообщение, в котором словами обозначено превышение над уровнем (до 10 пунктов); в остальных случаях сообщить, что курс не превышает заданный уровень.

Решение задачи с использованием оператора switch (эксперт pricealert.mq4):

//--------------------------------------------------------------------
// pricealert.mq4
// Предназначен для использования в качестве примера в учебнике MQL4.
//--------------------------------------------------------------------
int start() // Спец. функция start

double Level=1.3200; // Задан. уровень цены
int Delta=NormalizeDouble((Bid-Level) Point,0); // Превышение
if (Delta0) // Цена не выше уровня

Alert("Цена ниже уровня"); // Сообщение
return; // Выход из start()
>
//--------------------------------------------------------------------
switch(Delta) // Заголовок switch
// Начало тела switch
case 1 : Alert("Плюс один пункт"); break;// Варианты..
case 2 : Alert("Плюс два пункта"); break; case 3 : Alert("Плюс три пункта"); break; case 4 : Alert("Плюс четыре пункта"); break;//Здесь представлено
case 5 : Alert("Плюс пять пунктов"); break;//10 вариантов case,
case 6 : Alert("Плюс шесть пунктов"); break;//но в общем случае
case 7 : Alert("Плюс семь пунктов"); break;//количество case
case 8 : Alert("Плюс восемь пунктов");break;//не ограничено
case 9 : Alert("Плюс девять пунктов");break; case 10: Alert("Плюс десять пунктов");break; default: Alert("Более десяти пунктов"); // С case не совпало
> // Конец тела switch
//--------------------------------------------------------------------
return; // Выход из start()
>
//--------------------------------------------------------------------

В данном варианте решения задачи используется оператор switch, в каждом варианте case которого используется оператор break. В зависимости от значения переменной Delta управление передаётся на один из вариантов case, в результате чего исполняются операторы, соответствующие этому варианту: функция Alert() и оператор break. Оператор break прекращает исполнение оператора switch, т.е. передаёт управление за его пределы, а именно — оператору return, завершающему работу специальной функции start(). Таким образом, в зависимости от значения переменной Delta, срабатывает один из вариантов case, а остальные варианты оказываются не затронутыми.

Эта программа — эксперт, значит она будет запускаться в работу на каждом тике, всякий раз отображая сообщения, соответствующие текущей ситуации. Разумеется, для демонстрации работы программы в окне финансового инструмента необходимо подобрать значение Level, близкое к текущему курсу.

Рис. 49. Функциональная схема оператора switch в эксперте pricealert.mq4.

На функциональной схеме хорошо видно, что благодаря наличию в каждом варианте case оператора break, после исполнения операторов любого из вариантов управление передаётся за пределы оператора switch. Подобный принцип построения алгоритма с применением оператора switch использован и в файле stdlib.mq4, поставляемом в составе клиентского терминала (..\experts\libraries\stdlib.mq4).

Рассмотрим другой случай, не предусматривающий использование break в каждом варианте case.

Задача 19. Дано 10 баров. Сообщить номера всех баров, начиная с n-го.

Закодировать решение этой задачи достаточно просто (скрипт barnumber.mq4):

//--------------------------------------------------------------------
// barnumber.mq4
// Предназначен для использования в качестве примера в учебнике MQL4.
//--------------------------------------------------------------------
int start() // Специальная функция start()

int n = 3; // Заданный номер
Alert("Номера баров, начиная с ", n,":");// Не зависит от n
//--------------------------------------------------------------------
switch (n) // Заголовок оператора switch
// Начало тела switch
case 1 : Alert("Бар 1"); // Варианты..
case 2 : Alert("Бар 2"); case 3 : Alert("Бар 3"); case 4 : Alert("Бар 4"); // Здесь представлено 10 ..
case 5 : Alert("Бар 5"); // ..вариантов case, но в ..
case 6 : Alert("Бар 6"); // ..общем случае количество..
case 7 : Alert("Бар 7"); // ..case не ограничено
case 8 : Alert("Бар 8"); case 9 : Alert("Бар 9"); case 10: Alert("Бар 10");break; default: Alert("Задан неправильный номер");// С case не совпало
> // Конец тела switch
//--------------------------------------------------------------------
return; // Оператор выхода из start()
>
//--------------------------------------------------------------------

В операторе switch будет производиться перебор вариантов case до тех пор, пока не обнаружится равенство Выражения и Константы. Когда значение Выражения (здесь — это целое число 3) совпадает с одной из Констант (в данном случае — case 3), то исполнятся все операторы, которые следуют за двоеточием (case 3:), а именно: оператор вызова функции Alert(«Бар 3»), следующие за ним Alert(«Бар 4»), Alert(«Бар 5») и т.д., пока не встретится оператор break, завершающий работу оператора switch.

В случае если значение Выражения не совпадает ни с одной из Констант, управление передаётся оператору, соответствующую варианту default:

Рис. 50. Функциональная схема оператора switch в скрипте barnumber.mq4.

В отличие от алгоритма, реализованного в предыдущей программе, в данном случае (рис. 50) в каждом варианте case не используется оператор break. Поэтому при совпадении значения Выражения со значением одной из Констант будут исполнены все операторы, начиная с операторов соответствующего варианта case. Использование оператора break в последнем варианте case имеет другую цель — не допустить исполнение операторов, соответствующих варианту default. Если же среди значений Констант не найдётся ни одной, равной Выражению, то управление будет передано оператору, соответствующему метке default.

Таким образом, если значение заданной переменной n находится в интервале значений от 1 до 10, то будут напечатаны номера всех баров, начиная с n, а если значение n находится за пределами указанного диапазона, то будет выдано сообщение о несоответствии.

Обратите внимание, Константы вариантов case не обязательно должны быть указаны в программе в порядке возрастания. Порядок следования вариантов case с соответствующими Константами определяется необходимостью программного алгоритма.

Оператор switch

В отличие от операторов if-then и if-then-else, оператор switch применим к известному числу возможных ситуаций. Можно использовать простые типы byte, short, char, int. Также можно использовать Enum и String (начиная с JDK7), и специальные классы, которые являются обёрткой для примитивных типов: Character, Byte, Short, Integer.

Дублирование значений case не допускается. Тип каждого значения должен быть совместим с типом выражения.

Команду switch часто называют командой выбора. Выбор осуществляется в зависимости от целочисленного выражения. Форма команды выглядит так:

switch(ВыражениеДляСравнения)

Параметр ВыражениеДляСравнения — выражение, в результате вычисления которого получается целое число (как правило). Команда switch сравнивает результат ВыражениеДляСравнения с каждым последующим Совпадением. Если обнаруживается совпадение, то исполняется команда или набор команд, которые прописаны за данным оператором. Если совпадений не будет, то исполняется команда после ключевого слова default. Однако оператор default не является обязательным. В этом случае при отсутствии совпадений программа не выполняет никаких действий.

Каждая секция case обычно заканчивается командой break, которая передаёт управление к концу команды switch.

Рассмотрим простейший пример с месяцами. Запустим наш учебный проект и добавим код в обработчик нажатия кнопки:

 int month = 3; String monthString; switch (month) < case 1: monthString = "Январь"; break; case 2: monthString = "Февраль"; break; case 3: monthString = "Март"; break; case 4: monthString = "Апрель"; break; case 5: monthString = "Май"; break; case 6: monthString = "Июнь"; break; case 7: monthString = "Июль"; break; case 8: monthString = "Август"; break; case 9: monthString = "Сентябрь"; break; case 10: monthString = "Октябрь"; break; case 11: monthString = "Ноябрь"; break; case 12: monthString = "Декабрь"; break; default: monthString = "Не знаем такого"; break; >mInfoTextView.setText(monthString); 

Запустите проект и нажмите кнопку — в текстовом поле появится слово Март (любимый месяц котов).

При желании, можно переписать пример с использованием if-then-else:

 int month = 3; if (month == 1) < mInfoTextView.setText("Январь"); >else if (month == 2) < mInfoTextView.setText("Февраль"); >. // и так далее 

В каждом блоке case имеется оператор break, который прерывает свой блок кода. Его нужно использовать обязательно, иначе выполнение кода продолжится. Хотя иногда это и используется.

 java.util.ArrayList futureMonths = new java.util.ArrayList(); int month = 8; switch (month) < case 1: futureMonths.add("January"); case 2: futureMonths.add("February"); case 3: futureMonths.add("March"); case 4: futureMonths.add("April"); case 5: futureMonths.add("May"); case 6: futureMonths.add("June"); case 7: futureMonths.add("July"); case 8: futureMonths.add("August"); case 9: futureMonths.add("September"); case 10: futureMonths.add("October"); case 11: futureMonths.add("November"); case 12: futureMonths.add("December"); break; default: break; >if (futureMonths.isEmpty()) < mInfoTextView.setText("Invalid month number"); >else < for (String monthName : futureMonths) < mInfoTextView.setText(monthName); >> 

Если код в блоках case совпадает, то блоки можно объединить. Например, код для подсчёта дней в месяце:

 int month = 2; int year = 2012; int numDays = 0; switch (month) < case 1: case 3: case 5: case 7: case 8: case 10: case 12: numDays = 31; break; case 4: case 6: case 9: case 11: numDays = 30; break; case 2: if (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0)) numDays = 29; else numDays = 28; break; default: mInfoTextView.setText("Несуществующий месяц"); break; >mInfoTextView.setText("Число дней if.php">if мы рассматривали пример с временами года. Перепишем его с использованием оператора switch:

 int month = 3; String season; switch (month) < case 12: case 1: case 2: season = "Зимушка-зима"; break; case 3: case 4: case 5: season = "Весна"; break; case 6: case 7: case 8: season = "Лето"; break; case 9: case 10: case 11: season = "Осень"; break; default: season = "Вы с какой планеты?"; >mInfoTextView.setText("Мартовские песни коты поют, когда на дворе " + season); 

Следующий пример случайным образом генерирует английские буквы. Программа определяет, гласные они или согласные:

 Random random = new Random(); for (int i = 0; i < 100; i++) < int c = random.nextInt(26) + 'a'; mInfoTextView.setText((char)c + ", " + c + ": "); switch (c) < case 'a': case 'e': case 'i': case 'o': case 'u': mInfoTextView.setText("Гласная"); break; case 'y': case 'w': mInfoTextView.setText("Условная гласная"); break; default: mInfoTextView.setText("Согласная"); break; >> 

Так как метод Random.nextInt(26) генерирует значение между 0 и 26, для получения символа нижнего регистра остаётся прибавить смещение 'a', при этом символ a автоматически преобразуется к типу int. Символы в секциях case также представляют собой целочисленные значения, используемые для сравнения.

Чтобы вывести переменную c в символьном виде, её необходимо преобразовать к типу char, иначе значение будет выведено в числовом виде.

В Java SE 7 появилась возможность использовать объект String в операторе switch. Возможно, это будет работать и на Android в будущем (Upd.: вроде уже работает):

 public class StringSwitchDemo < public static int getMonthNumber(String month) < int monthNumber = 0; if (month == null) < return monthNumber; >switch (month.toLowerCase()) < case "january": monthNumber = 1; break; case "february": monthNumber = 2; break; case "march": monthNumber = 3; break; case "april": monthNumber = 4; break; case "may": monthNumber = 5; break; case "june": monthNumber = 6; break; case "july": monthNumber = 7; break; case "august": monthNumber = 8; break; case "september": monthNumber = 9; break; case "october": monthNumber = 10; break; case "november": monthNumber = 11; break; case "december": monthNumber = 12; break; default: monthNumber = 0; break; >return monthNumber; > public static void main(String[] args) < String month = "August"; int returnedMonthNumber = StringSwitchDemo.getMonthNumber(month); if (returnedMonthNumber == 0) < System.out.println("Invalid month"); >else < System.out.println(returnedMonthNumber); >> > 

Допустимы вложенные операторы switch, но на практике я не сталкивался с таким кодом.

Запомните важные свойства оператора switch:

  • Оператор switch отличается от оператора if тем, что может выполнять проверку только равенства, а оператор if может вычислять результат булева выражения любого типа.
  • Две константы case в одном и том же операторе switch не могут иметь одинаковые значения
  • Оператор switch эффективнее набора вложенных операторов if

C++. Оператор выбора switch

Оператор выбора switch позволяет выбрать один вариант хода решения задачи из нескольких в зависимости от значения выражения. Таким образом, обеспечивается многонаправленное разветвление в программе.

Оператор switch может быть заменен оператором if . Однако, в некоторых случаях использование оператора switch может быть более эффективным, чем использование оператора if .

2. Общая форма описания оператора выбора switch . Ключевые слова switch , case , break , default

Общая форма записи оператора switch следующая

switch (выражение) < case константа1: последовательность_операторов1; break; case константа2: последовательность_операторов2; break; . case константаN: последовательность_операторовN; break; default последовательность_операторов; >
  • выражение – некоторое выражение целочисленного ( int ) или символьного типа ( char );
  • константа1 , константа2 , …, константаN – константные значения, с которыми сравнивается значение выражения. Константные значения должны быть целочисленного или символьного типа;
  • последовательность_операторов1 , последовательность_операторов2 , …, последовательность_операторовN – соответствующая последовательность операторов (инструкций), которые связаны с соответствующим условием;
  • последовательность_операторов – последовательность операторов, которая выполняется в случае, если не найдено ни одно совпадение значения выражения со значением констант.

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

Ключевое слово case используется для того, чтобы указать значение константы, при совпадении с которой значения выражения, будет выполняться соответствующая последовательность операторов.

Операция break прерывает (заканчивает) выполнение кода, который определен инструкцией switch .

Операции, которые размещены после ключевого слова default , выполняются в том случае, если ни одна из case-констант не совпадает с результатом вычисления switch -выражения.

Ключевое слово default и соответствующая последовательность операторов могут быть опущены. В этом случае, если не выполняется ни одна из ветвей после слова case , выполнение передается следующему оператору, который следует за оператором switch .

3. Примеры использования оператора выбора switch

Пример 1. Даны значения n = 1..7, что есть номером дня недели. По значению n определить, выходной этот день или рабочий. Результат записать в переменную fDayOff типа bool .

Фрагмент кода, который решает данную задачу.

int day; bool fDayOff; day = 3; switch (day) < case 1: fDayOff = false; break; case 2: fDayOff = false; break; case 3: fDayOff = false; break; case 4: fDayOff = false; break; case 5: fDayOff = false; break; case 6: fDayOff = true; break; case 7: fDayOff = true; break; >

Другой, более компактный вариант решения данной задачи.

int day; bool fDayOff; day = 7; switch (day) < case 1: case 2: case 3: case 4: case 5: fDayOff = false; break; case 6: case 7: fDayOff = true; break; >

Еще один вариант решения данной задачи

int day; bool fDayOff; day = 7; switch (day) < case 6: case 7: fDayOff = true; break; default: fDayOff = false; >

Пример 2. Дано целое число n = 1..3, которое есть номером функции. По значению переменной n вычислить значение соответствующей функции:

1) -2x2-4; 2) 5x+2; 3) 15-3x.

Фрагмент кода, который решает данную задачу с помощью сокращенной формы оператора switch .

int n; float f, x; n = 3; x = 3; switch (n) < case 1: f = -2*x*x-4; break; case 2: f = 5*x+2; break; case 3: f = 15-3*x; break; >
4. Особенности использования операции break в операторе switch

В операторе switch операция break не является обязательной.

Если операция break присутствует, то происходит выход из оператору switch и выполнение следующего за ним оператора. Если операция break в case -ветви отсутствует, тогда выполняются все операторы, которые связаны с данной case -ветвью, а также все операторы, которые следуют сразу после нее до тех пор, пока не встретится другая инструкция break или не будет достигнут конец switch -оператора.

5. Вложенные инструкции switch . Общая форма описания

Оператор switch может иметь разные типы вложения. В этом случае вложенный оператор (нижнего уровня) switch используется как часть case -последовательности внешнего (верхнего уровня) оператора switch .

Общая форма описания вложенной инструкции switch :

switch (выражение) < case константа1: последовательность_операторов1; break; case константа2: последовательность_операторов2; break; . case константаK; switch (выражение) < . >break; . case константаN: последовательность_операторовN; break; default последовательность_операторов; >

Связанные темы

  • C#. Оператор выбора switch
  • C++. Оператор условного перехода if
  • C++. Операция sizeof . Операция ? :

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 поведение оператора

Condition Действие
Преобразованное значение соответствует значению выражения управления с повышенным уровнем. Управление передается оператору, следующему за этой меткой.
Ни одна из констант не соответствует константам в 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: %d\nLowercase a: %d\nTotal: %d\n", 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 . Это число ограничивается только объемом доступной памяти.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *