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