Операторы ветвления в языке C: if-else, тернарный, switch
if-else
В языке программирования C синтаксис оператора ветвления if-else
выглядит так:
if (логич_выражение) выражение1; else выражение2;
Как и в других языках ветка else
не является обязательной.
В языке С в простых логических выражениях используются следующие знаки операторов: >
, <
, >=
, <=
, ==
, !=
.
В случае если тело той или иной ветки состоит из нескольких выражений, разделяемых точкой с запятой, тело заключается в фигурные скобки:
if (логич_выражение) { выражение1; выражение2; … } else { выражениеN; … }
В C можно использовать вложенные конструкции if-else
. При этом рекомендуют вкладывать во внешнюю ветку else
, а не if
, т.к. это позволяет избегать неоднозначности толкования инструкции. Посмотрите на такую конструкцию:
if (…) if (…) …; else …; else if (…) …; else …;
Для более легкого восприятия человеком отступами подчеркнуто, что куда вложено. Однако для компилятора отступы никакой роли не играют, и принадлежность первой ветки else
не очевидна. Ее можно было бы ошибочно отнести к первому if
, в результате чего второе else
было бы вообще неуместным, т.к. не относилось бы ни к какому if
. В данном случае такой ошибки не будет, т.к. компилятор руководствуется правилом: ветка else
относится к ближайшему к ней сверху if
, у которого еще нет ветки else
. Именно поэтому здесь первое else
относится ко второму if
(т.к. оно к нему ближе), а второе else
к первому if
, т.к. второе if
уже "покрыто" предыдущим else
.
Теперь рассмотрим такую конструкцию:
if (…) if (…) …; else if (…) …; else …;
Программист отступами показал, что первое else
относится к внешнему if
. Однако компилятор, руководствуясь правилом сопоставления веток else
, видит конструкцию иначе (если перевести на удобство чтения ее человеком):
if (…) if (…) …; else if (…) …; else …;
В результате программа будет делать не то, что хотел программист: если в выражении при первом if
будет возвращаться ложь, ни один else
просто не сработает. Однако из таких неоднозначных случаев есть выход ‒ это использование фигурных скобок, даже если тело условной инструкции состоит всего из одного выражения:
if (…) { if (…) …; } else if (…) …; else …;
В таком случае программа будет восприниматься компилятором именно так, как задумал программист.
Чаще всего на практике используется подобная конструкция множественного ветвления:
if (…) { … } else if (…) { … } else if (…) { … } else { … }
Здесь с точки зрения компилятора каждое else
относится к предыдущему if
, но выравнивание делается таким, как будто в Си есть условный оператор множественного ветвления. Результат работы конструкции таков, что выполняется хотя бы одна ветка. И как только она выполняется, вся конструкция завершает работу.
Условное выражение
В языке программирования C существует сокращенная запись инструкции if-else
в виде условного выражения, которое относится к тернарным операторам. Результат такого выражения может быть присвоен переменной:
(логич_выражение) ? выражение1 : выражение2
Переводится это так. Если логич_выражение
вернуло истину, то все выражение возвращает выражение1
; если логич_выражение
вернуло ложь, то все выражение возвращает выражение2
. Например:
x = 12; y = 16; z = (x > y) ? x - 1 : y - 1;
Здесь z получит значение 15. Такое условное выражение бывает очень удобно, однако область его применения ограничена простейшими случаями ветвления, т. к. невозможно создавать сложные "тела" в такой конструкции.
Операторы И (&&) и ИЛИ (||)
Как известно логическое выражение может быть сложным. Логические операторы И и ИЛИ в языке программирования C обозначаются соответственно парными знаками амперсанда &&
и вертикальной черты ||
. Их приоритет меньше, чем у простых логических операторов, поэтому простые логические операции при их объединении в сложные логические выражения можно не заключать в скобки. Пример сложного логического выражения:
a > 100 && b != 0
Следует отметить, что в чистом Си как такового логического типа данных со значениями true
и false
нет. Вместо этого используются целые числа. Так в результате выполнения выражений ниже на экран будут выведены числа 0 и 1.
int a = 3, b = 0, c = -4, d = -1; printf("%d\n", a == b && c < d); printf("%d\n", c < d);
Оператор switch
При организации множественного выбора, когда проверяется значение переменной на соответствие тому или иному значению, бывает удобно использовать не условный оператор if-else
, а оператор переключения switch
. Его синтаксис можно описать так:
switch (целочисленная_переменная) { case константа1: операции; case константа2: операции; …. default: операции; }
В скобках после слова switch
может стоять не только переменная, но и выражение, в результате выполнения которого возвращается целое значение или символ. Константы при case
также могут быть результатом выполнения выражений. Константы можно группировать, например, case 12, 13, 18
. Ветка default
не обязательна.
При выполнении оператора switch
, заданное значение в круглых скобках сравнивается с константами. Как только совпадение будет найдено, все последующие вложенные во все case
операции начинают выполняться. Другими словами, выполняется не только кейс, где произошло совпадение, но и все нижележащие ветки case
(и default
тоже), константы которых не совпадают со значением при switch
. Например, в результате выполнения вот такой программы:
int a = 1; switch (a) { case 0: printf("%d ", 0); case 1: printf("%d ", 1); case 2: printf("%d ", 2); default: printf("%d ", -1); } printf("\n");
на экране будет выведено:
1 2 -1
, т. к. как только совпадение было обнаружено, все нижеследующие инструкции были выполнены.
Чтобы этого не происходило, в конце операций, принадлежащих определенному case
, дописывают оператор break
, который осуществляет принудительный выход из всей конструкции (в данном случае switch
). Например:
int a=1; switch (a) { case 0: printf("%d\n", 0); break; case 1: printf("%d\n", 1); break; case 2: printf("%d\n", 2); break; default: printf("%d\n", -1); }
выведет только единицу, т. к. выполнение всей инструкции switch
прервется после выполнения инструкции break
при case 1
.
Курс с решением задач:
pdf-версия