Условные операторы позволяют управлять потоком выполнения программы, чтобы не выполнялась каждая строка кода, как она следует в программе. Давайте рассмотрим все условные операторы языка C#:
Оператор if
Для организации условного ветвления язык C# унаследовал от С и С++ конструкцию if...else. Ее синтаксис должен быть интуитивно понятен для любого, кто программировал на процедурных языках:
if (условие)
оператор (операторы)
else
оператор (операторы)
Если по каждому из условий нужно выполнить более одного оператора, эти операторы должны быть объединены в блок с помощью фигурных скобок {...}. (Это также касается других конструкций C#, в которых операторы могут быть объединены в блок - таких как циклы for и while .)
Стоит обратить внимание, что в отличие от языков С и С++, в C# условный оператор if может работать только с булевскими выражениями, но не с произвольными значениями вроде -1 и 0.
В операторе if могут применяться сложные выражения, и он может содержать операторы else, обеспечивая выполнение более сложных проверок. Синтаксис похож на применяемый в аналогичных ситуациях в языках С (С++) и Java. При построении сложных выражений в C# используется вполне ожидаемый набор логических операторов . Давайте рассмотрим следующий пример:
Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { string myStr; Console.WriteLine("Введите строку: "); myStr = Console.ReadLine(); if (myStr.Length = 5) && (myStr.Length
Как видите количество else if, добавляемых к единственному if, не ограничено. Один момент, который следует отметить касательно if: фигурные скобки применять не обязательно, если в условной ветви присутствует только один оператор, как показано в исходном примере.
Оператор switch
Вторым оператором выбора в C# является оператор switch , который обеспечивает многонаправленное ветвление программы. Следовательно, этот оператор позволяет сделать выбор среди нескольких альтернативных вариантов дальнейшего выполнения программы. Несмотря на то что многонаправленная проверка может быть организована с помощью последовательного ряда вложенных операторов if, во многих случаях более эффективным оказывается применение оператора switch. Этот оператор действует следующим образом. Значение выражения последовательно сравнивается с константами выбора из заданного списка. Как только будет обнаружено совпадение с одним из условий выбора, выполняется последовательность операторов, связанных с этим условием. Ниже приведена общая форма оператора switch:
switch(выражение) { case константа1: последовательность операторов break; case константа2: последовательность операторов break; case константаЗ: последовательность операторов break; ... default: последовательность операторов break; }
Хотя оператор switch...case должен быть знаком программистам на С и С++, в C# он немного безопаснее, чем его эквивалент С++. В частности, он запрещает "сквозные" условия почти во всех случаях. Это значит, что если часть case вызывается в начале блока, то фрагменты кода за последующими частями case не могут быть выполнены, если только не используется явно оператор goto для перехода к ним. Компилятор обеспечивает это ограничение за счет того, что требует, чтобы за каждой частью case следовал оператор break , в противном случае он выдает ошибку.
Важно отметить, что заданное выражение в операторе switch должно быть целочисленного типа (char, byte, short или int), перечислимого или же строкового . А выражения других типов, например с плавающей точкой, в операторе switch не допускаются. Зачастую выражение, управляющее оператором switch, просто сводится к одной переменной. Кроме того, константы выбора должны иметь тип, совместимый с типом выражения. В одном операторе switch не допускается наличие двух одинаковых по значению констант выбора.
Теги: си switch, c switch, switch break, default, порядок ветвей оператора switch.
Оператор Switch
Р ассмотрим пример из темы "ветвления". Программа выводит название дня недели по порядковому номера
#include
Этот код состоит из семи идущих друг за другом операторов if . Его код можно упростить с помощью оператора switch
#include
Оператор switch принимает в качестве аргумента число, и в зависимости от его значения выполняет те или иные команды.
Switch (<переменная>) { case <значение 1>: <ветвь 1> }
Если значение переменной не соответствует ни одному case
, то выполняется default
ветвь. Она может отсутствовать, тогда вообще ничего не выполняется.
В примере выше каждая ветвь оканчивается оператором break
. Это важно. Когда компьютер видит оператор break
, он выходит из оператора switch
. Если бы он отсутствовал, то программа "провалилась" бы дальше, и стала выполнять следующие ветви.
#include
Введите значение, например 3, и вы увидите, что программа выведет
WednesdayThursdayFridaySaturday
то есть все ветви, после найденной.
Операторы каждой из ветвей могут быть обрамлены фигурными скобками (и так даже лучше).
Тогда каждая из ветвей будет отдельным блоком, в котором можно определять свои переменные.
Пример программы, которая запрашивает у пользователя число, оператор и второе число и выполняет действие.
#include
Если ввести
1 + 2
то будет выведен результат операции 1 + 2 = 3
Хочу обратить внимание, что литеры типа "+" и т.п. воспринимаются в качестве чисел, поэтому их можно использовать в операторе switch.
В этой программе использовалась функция exit из библиотеки stdlib. Функция останавливает работу программы и возвращает результат её работы. Если возвращается истина (ненулевое значение), то это значит, что программа была выполнена с ошибкой.
Ветвь default может располагаться в любом месте, не обязательно в конце. Этот код также будет нормально работать
Switch (day) { case 0: printf("Sunday"); break; case 1: printf("Monday"); break; case 2: printf("Tuesday"); break; case 3: printf("Wednesday"); break; case 4: printf("Thursday"); break; default: printf("Saturday"); break; case 5: printf("Friday"); break; }
default здесь также нуждается в операторе break, как и другие ветви, иначе произойдёт сваливание вниз. Несмотря на то, что так можно писать, это плохой стиль программирования. Ветвь default логически располагается в конце, когда других вариантов больше нет.
Возможные значения аргумента оператора switch могут располагаться в любом порядке, но должны быть константными значеними. Это значит, что следующий код не заработает
#include
switch (выражение) { [объявление] : [ case константное-выражение1]: [ список-операторов1] [ case константное-выражение2]: [ список-операторов2] : : [ default: [ список операторов ]] }
Выражение, следующее за ключевым словом switch в круглых скобках, может быть любым выражением, допустимыми в языке СИ, значение которого должно быть целым. Отметим, что можно использовать явное приведение к целому типу, однако необходимо помнить о тех ограничениях и рекомендациях, о которых говорилось выше.
Значение этого выражения является ключевым для выбора из нескольких вариантов. Тело оператора smitch состоит из нескольких операторов, помеченных ключевым словом case с последующим константным-выражением. Следует отметить, что использование целого константного выражения является существенным недостатком, присущим рассмотренному оператору.
Так как константное выражение вычисляется во время трансляции, оно не может содержать переменные или вызовы функций. Обычно в качестве константного выражения используются целые или символьные константы.
Все константные выражения в операторе switch должны быть уникальны. Кроме операторов, помеченных ключевым словом case, может быть, но обязательно один, фрагмент помеченный ключевым словом default .
Список операторов может быть пустым, либо содержать один или более операторов. Причем в операторе switch не требуется заключать последовательность операторов в фигурные скобки.
Отметим также, что в операторе switch можно использовать свои локальные переменные, объявления которых находятся перед первым ключевым словом case, однако в объявлениях не должна использоваться инициализация.
Схема выполнения оператора switch следующая:
- вычисляется выражение в круглых скобках;
- вычисленные значения последовательно сравниваются с константными выражениями, следующими за ключевыми словами case;
- если одно из константных выражений совпадает со значением выражения, то управление передается на оператор, помеченный соответствующим ключевым словом case;
— если ни одно из константных выражений не равно выражению, то управление передается на оператор, помеченный ключевым словом default , а в случае его отсутствия управление передается на следующий после switch оператор.
Отметим интересную особенность использования оператора switch: конструкция со словом default может быть не последней в теле оператора switch . Ключевые слова case и default в теле оператора switch существенны только при начальной проверке, когда определяется начальная точка выполнения тела оператора switch . Все операторы, между начальным оператором и концом тела, выполняются вне зависимости от ключевых слов, если только какой-то из операторов не передаст управления из тела оператора switch . Таким образом, программист должен сам позаботится о выходе из case , если это необходимо. Чаще всего для этого используется оператор break .
Для того, чтобы выполнить одни и те же действия для различных значений выражения, можно пометить один и тот же оператор несколькими ключевыми словами case .
Пример:
1 2 3 4 5 6 7 8 9 | int i= 2 ; switch (i) { case 1 : i += 2 ; case 2 : i *= 3 ; case 0 : i /= 2 ; case 4 : i -= 5 ; default : ; } |
int i=2; switch (i) { case 1: i += 2; case 2: i *= 3; case 0: i /= 2; case 4: i -= 5; default: ; }
Выполнение оператора switch начинается с оператора, помеченного case 2 . Таким образом, переменная i получает значение, равное 6, далее выполняется оператор, помеченный ключевым словом case 0 , а затем case 4, переменная i примет значение 3, а затем значение -2. Оператор, помеченный ключевым словом default, не изменяет значения переменной.
Рассмотрим ранее приведенный пример, в котором иллюстрировалось использование вложенных операторов if, переписанной теперь с использованием оператора switch .
1 2 3 4 5 6 7 8 9 10 | char ZNAC; int x, y, z; switch (ZNAC) { case "+" : x = y + z; break ; case "-" : x = y - z; break ; case "*" : x = y * z; break ; case "/" : x = u / z; break ; default : ; } |
char ZNAC; int x,y,z; switch (ZNAC) { case "+": x = y + z; break; case "-": x = y - z; break; case "*": x = y * z; break; case "/": x = u / z; break; default: ; }
Использование оператора break позволяет в необходимый момент прервать последовательность выполняемых операторов в теле оператора switch, путем передачи управления оператору, следующему за switch .
Отметим, что в теле оператора switch можно использовать вложенные операторы switch , при этом в ключевых словах case можно использовать одинаковые константные выражения. case 2 : f-= 9 ; break ; } case 3 : b-= c; break ; : }
: switch (a) { case 1: b=c; break; case 2: switch (d) { case 0: f=s; break; case 1: f=9; break; case 2: f-=9; break; } case 3: b-=c; break; : }
1.4.6. Оператор break
Оператор break обеспечивает прекращение выполнения самого внутреннего из объединяющих его операторов switch, do, for, while
. После выполнения оператора break управление передается оператору, следующему за прерванным.
Оператор выбора switch является очень удобной заменой множественного использования . Оператор switch сравнивает значение одной переменной с несколькими константами. Основной формат для использования оператора множественного выбора switch case показан — ниже. Значение переменной указанной в условии switch сравнивается со значениями, которые следуют за ключевым словом case . Когда значение в переменной, соответствует значению в строке с оператором case , компьютер продолжит выполнение программы с этого места.
Switch (/*variable*/) { case const1: /*Тут находится код, который необходимо выполнить, если переменная variable будет равна const1*/ break; case const2: /*этот код выполнится, если variable будет равна const2*/ break; /*...*/ default: /*Код, который выполнится, если ниодно из константых значению не соответствует значение в переменной variable*/ break; }
Когда сравниваемое значение в переменной variable совпадет с первым значением оператора case , программа начнет выполнять код, который находится между текущим оператором case и . Оператор break используется для того, чтобы прерывать ход программы в операторе switch и передавать управление следующему оператору, после switch . Если не использовать оператор break , то, сразу после того, как выполнится один блок кода, программа переключится на выполнения следующего case , даже, если константное значение не будет равно значению в переменной variable . Поэтому, в операторе выбора switch , блоки кода после case всегда должны предваряться оператором break .
Также стоит обратить в нимание на ключевое слово default , оно не является обязательным, но в то же время оно необходимо для обработки неожидынных ситуаций. Например, когда значение переменной не совпадает ни с одним из значений case , в таком случае выполнится код, который находится в ветке default . Это может быть полезно, в случае, если мы не ожидаем, что ниодно из значений case не совпало со значением переменной в условии switch . В таком случае, мы увидем, что сработал код в ветке default .
Чтобы, все ранее сказанное понять и запомнить, давайте перейдем к рассмотрению простой программы с использованием оператора выбора switch . Хотя, возможно этот пример не самый удачный, но в нем наглядно показывается весь функционал оператора switch .
#include
Итак, как же работает этот код? Для начала, мы сделали небольшое меню (строки5 — 10 ), чтобы как-то информировать пользователя, что необходимо водить в программу. Как вы уже поняли, необходимо ввести число — 1, 2, 3 или 4. В зависимости от введенного числа, программа будет срабатывать поразному. В данном примере очень хорошо видно, что вводимое значение сохраняется в переменную input , и после этого, значение в этой переменной передается в оператор switch , строка 13 .В строках 13 — 29 объявлен оператор множественного выбора switch . Какже он работает? Очень просто, по порядку программа сравнивает переменную input со значениями 1, 2, 3 и 4 . Например, если мы ввели число 3, топрограмма выполнит код, который находится в строках 21-22 , при вводе единицы, программа напечатает сообщение из строки 15.Думаю суть вы уловили. Ну, а, если мы ввели другое число, отличное от заданных, выполнится блок кода в строке 27 . Смотрим результат работы программы. Я ввел значение — 3, сегодня буду смотреть — Ходячих!
Что бы сегодня посмотреть? 1. Стрела(Arrow) 2. Сверхъестественное(Supernatural) 3. Ходячие мертвецы(Walking Dead) 4. Выход Ваш выбор: 3 «Fight the dead. Fear the living»
Вы можете поместить данное меню и ввод значени пользователя в цикл, тогда сможете в цикле делать выбор столько раз, сколько сами захотите. Надеюсь, что описал весь процесс достаточно понятно, тема не сложная, но для закрепления материала, поэксперементируйте с этим кодом. Удачи!
Хотя конструкция if-else-if может выполнять многочисленные проверки, она не очень элегантна. Код очень труден для восприятия и в нем может запутаться даже автор через некоторое время. С этой целью С имеет оператор принятия решений switch, выполняющий действия, основываясь на сравнении значения со списком констант символов или целых чисел. При обнаружении совпадения выполняется оператор или операторы, ассоциированные с данным значением. Оператор switch имеет следующий вид:
switch (выражение) {
case константа1:
break;
case константа2:
последовательность операторов
break;
case константа3:
последовательность операторов break;
...
default:
последовательность операторов
}
Оператор default выполняется, если не найдено соответствий, default необязателен и, если его нет, то в случае отсутствия совпадений ничего не происходит. Когда обнаруживается совпадение, операторы, ассоциированные с соответствующим case, выполняются до тех пор, пока не встретится оператор break. В случае default (или последнего case, если отсутствует default), оператор switch заканчивает работу при обнаружении конца.
Следует знать о трех важных моментах оператора switch:
- switch отличается от if тем, что он может выполнять только операции проверки строгого равенства, в то время как if может вычислять логические выражения и отношения.
- Не может быть двух констант в одном операторе switch, имеющих одинаковые значения. Конечно, оператор switch, включающий в себя другой оператор switch, может содержать аналогичные константы.
- Если в операторе switch используются символьные константы, они автоматически преобразуются к целочисленным значениям.
Оператор switch часто используется для обработки команд клавиатуры типа работа с меню. Как показано ниже, функция menu() отображает меню для программы проверки орфографии и вызывает соответствующие процедуры:
Void menu(void)
{
char ch;
Printf("1. Check Spelling\n");
printf("2. Correct Spelling Errors\n");
printf("3. Display Spelling Errors\n");
printf("Strike Any Other Key to Skip\n");
printf (" Enter your choice: ");
Ch = getche(); /* чтение клавиатуры */
Switch(ch) {
case "1":
check_spelling();
break;
case "2":
correct_errors();
break;
case "3";
display_errors();
break;
default:
printf("No option selected");
}
}
С технической точки зрения операторы break являются необязательными в операторе switch. Они используются для окончания работы последовательности операторов, ассоциированных с данной константой. Если оператор break отсутствует, продолжают выполняться операторы следующего раздела, пока не будет достигнут оператор break или конец оператора switch. О константах выбора можно думать как о метках. Выполнение начинается с метки, соответствующей искомому значению, и продолжается, пока не будет достигнут break или конец оператора switch. Например, функция, показанная ниже, использует данную особенность оператора case для упрощения кода обработчика ввода драйвера устройства:
Void inp_handler(void)
{
int ch, flag;
ch = read_device(); /* чтение какого-то устройства */
flag = -1;
switch(ch) {
case 1: /* данные случаи имеют общую последовательность */
case 2: /* операторов */
case 3:
flag = 0;
break;
case 4:
flag = 1;
case 5:
error(flag);
break;
default:
process(ch);
}
}
Данная подпрограмма иллюстрирует две грани оператора switch. Во-первых, можно иметь пустые условия. В данном случае первые три условия приводят к выполнению одних и тех же операторов:
Во-вторых, выполнение переходит к следующему case, если отсутствует break. Если ch соответствует 4, то flag устанавливается в 1, и, поскольку отсутствует оператор break, выполнение продолжается и выполняется оператор error(flag). В данном случае flag имеет значение 1. Если ch равно 5, то вызывается error(flag), а значение flag будет равно - 1. Способность запускать несколько операторов, соответствующих нескольким условиям при отсутствии оператора break, позволяет создавать эффективный код, поскольку это избавляет от необходимости дублировать код.
Важно понять, что операторы, ассоциированные с каждой меткой, являются не блоками кода, а скорее последовательностью операторов. (Сам оператор switch определяет блок.) Понимание этого необходимо в некоторых специфических ситуациях. Например, следующий фрагмент кода содержит ошибку и не будет компилироваться, поскольку невозможно объявить переменную в последовательности операторов:
/* неверно */
Switch(с) {
case 1:
int t;
...
Тем не менее переменная может быть добавлена:
/* верно */
switch(с) {
int t;
case 1:
...
Имеется возможность создания блока кода как одного из операторов в последовательности и объявление в нем переменной, как показано ниже:
/* Это также корректно */
switch (с) {
case 1:
{ /* create a block */
int t;
...
}