Какого типа могут быть константные выражения используемые в операторе switch
Перейти к содержимому

Какого типа могут быть константные выражения используемые в операторе switch

  • автор:

Какие условные операторы существуют в языке С#? 2. Для чего используется оператор if? 3. Как в операторе if проверить сразу

Пожалуйста, войдите или зарегистрируйтесь для публикации ответа на этот вопрос.

решение вопроса

Связанных вопросов не найдено

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

поделиться знаниями или
запомнить страничку

  • Все категории
  • экономические 43,679
  • гуманитарные 33,657
  • юридические 17,917
  • школьный раздел 612,508
  • разное 16,911

Популярное на сайте:

Как быстро выучить стихотворение наизусть? Запоминание стихов является стандартным заданием во многих школах.

Как научится читать по диагонали? Скорость чтения зависит от скорости восприятия каждого отдельного слова в тексте.

Как быстро и эффективно исправить почерк? Люди часто предполагают, что каллиграфия и почерк являются синонимами, но это не так.

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

  • Обратная связь
  • Правила сайта

Оператор switch

Вторым оператором выбора в C# является оператор switch , который обеспечивает многонаправленное ветвление программы. Следовательно, этот оператор позволяет сделать выбор среди нескольких альтернативных вариантов дальнейшего выполнения программы. Несмотря на то, что многонаправленная проверка может быть организована с помощью последовательного ряда вложенных операторов if , во многих случаях более эффективным оказывается применение оператора switch . Этот оператор действует следующим образом. Значение выражения последовательно сравнивается с константами выбора из заданного списка. Как только будет обнаружено совпадение с одним из условий выбора, выполняется последовательность операторов, связанных с этим условием. Ниже приведена общая форма оператора switch .

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

Заданное выражение в операторе switch должно быть целочисленного типа ( char , byte , short или int ), перечислимого или же строкового. (О перечислениях и символьных строках типа string речь пойдет далее в этом курсе.) А выражения других типов, например с плавающей точкой, в операторе switch не допускаются.

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

Последовательность операторов из ветви default выполняется в том случае, если ни одна из констант выбора не совпадает с заданным выражением. Ветвь default не является обязательной. Если же она отсутствует и выражение не совпадает ни с одним из условий выбора, то никаких действий вообще не выполняется. Если же происходит совпадение с одним из условий выбора, то выполняются операторы, связанные с этим условием, вплоть до оператора break .

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

// Продемонстрировать применение оператора switch, using System; class SwitchDemo < static void Main() < int i; for (i = 0; i < 10; i++) switch (i) < case 0: Console.WriteLine("i равно нулю"); break; case 1: Console.WriteLine("i равно единице"); break; case 2: Console.WriteLine("i равно двум"); break; case 3: Console.WriteLine("i равно трем"); break; case 4: Console.WriteLine("i равно четырем"); break; default: Console.WriteLine("i равно или больше пяти"); break; >> >

Результат выполнения этой программы выглядит следующим образом.

i равно нулю i равно единице i равно двум i равно трем i равно четырем i равно или больше пяти i равно или больше пяти i равно или больше пяти i равно или больше пяти i равно или больше пяти

Как видите, на каждом шаге цикла выполняются операторы, связанные с совпадающей константой выбора, в обход всех остальных операторов. Когда же значение переменной i становится равным или больше пяти, то оно не совпадает ни с одной из констант выбора, а следовательно, выполняются операторы из ветви default .

В приведенном выше примере оператором switch управляла переменная i типа int . Как пояснялось ранее, для управления оператором switch может быть использовано выражение любого целочисленного типа, включая и char . Ниже приведен пример применения выражения и констант выбора типа char в операторе switch .

// Использовать элементы типа char для управления оператором switch, using System; class SwitchDemo2 < static void Main() < char ch; for (ch = 'A'; ch > >

Вот какой результат дает выполнение этой программы.

ch содержит A ch содержит B ch содержит C ch содержит D ch содержит E

Обратите в данном примере внимание на отсутствие ветви default в операторе switch . Напомним, что ветвь default не является обязательной. Когда она не нужна, ее можно просто опустить.

Переход последовательности операторов, связанных с одной ветвью case , в следующую ветвь case считается ошибкой, поскольку в C# должно непременно соблюдаться правило недопущения «провалов» в передаче управления ходом выполнения программы. Именно поэтому последовательность операторов в каждой ветви case оператора switch оканчивается оператором break . (Избежать подобных «провалов», можно также с помощью оператора безусловного перехода goto , рассматриваемого далее в этой главе, но для данной цели чаще применяется оператор break .)

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

Правило недопущения «провалов» относится к тем особенностям языка C#, которыми он отличается от C, C++ и Java. В этих языках программирования одна ветвь case может переходить (т. е. «проваливаться») в другую. Данное правило установлено в C# для ветвей case по двум причинам.

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

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

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

// Пример "проваливания" пустых ветвей case. using System; class EmptyCasesCanFall < static void Main() < int i; for (i = 1; i < 5; i++) switch (i) < case 1: case 2: case 3: Console.WriteLine("i равно 1, 2 или 3"); break; case 4: Console.WriteLine("i равно 4"); break; >> >

Ниже приведен результат выполнения этой программы.

i равно 1, 2 или 3 i равно 1, 2 или 3 i равно 1, 2 или 3 i равно 4

Если значение переменной i в данном примере равно 1, 2 или 3, то выполняется первый оператор, содержащий вызов метода WriteLine() . Такое расположение нескольких меток ветвей case подряд не нарушает правило недопущения «провалов»; поскольку во всех этих ветвях используется одна и та же последовательность операторов.

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

Оператор 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

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

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