Условное тернарное выражение

Практический курс по C/C++: https://stepik.org/course/193691

На этом занятии мы познакомимся с условной тернарной операцией, которая имеет следующий синтаксис:

<выражение 1> ? <выражение 2> : <выражение 3>

Если выражение 1 истинно, то возвращается значение выражения 2, иначе – значение выражения 3. Давайте поясню его работу на конкретном примере. Предположим, у нас имеются две переменные:

double a = 7.5, b = -3.43;

и мы хотим определить максимальное значение. Используя имеющиеся знания, это можно было бы сделать так:

double max_ab;
if(a > b)
    max_ab = a;
else
    max_ab = b;

А с использованием тернарной условной операции это можно реализовать гораздо изящнее:

double max_ab = a > b ? a : b;

Видите, какая простая, понятная и компактная запись в итоге получилась. Это одно из удобств данного оператора. Но, все же, между предыдущей программой с условным оператором if и тернарной операцией есть одно принципиальное отличие. Тернарная операция возвращает результат. В данном примере – это или переменная a или переменная b. Тогда как обычный условный оператор предназначен для выполнения блока кода по определенному условию и сам по себе не возвращает никаких значений.

Второе важное отличие – в тернарной условной операции нет внутренних блоков, где бы мы могли записывать несколько операторов. Вместо a и b можно указывать только одну какую-либо конструкцию. Часто это некое значение, или результат работы операторов, например, арифметических:

double res = (a > b) ? a + 2 : b - 5;

Так делать вполне допустимо. И, обратите внимание, я поместил условие в круглые скобки, чтобы визуально выделить его в этой конструкции. Конечно, делать это не обязательно, так как приоритет операций ? и : выше только операций присваивания и запятой, поэтому сначала будут вычислены операции сравнения и только потом осуществляется проверка условия.

Также в качестве выражений в тернарной операции можно использовать функции, например, так:

double res_abs = (a < b) ? fabs(a) : fabs(b);
printf("res_abs = %.2f\n", res_abs);

Забегая вперед, я здесь использовал функцию fabs() для вычисления модуля вещественного числа. Чтобы воспользоваться этой функцией вначале программы нужно подключить заголовочный файл math.h:

#include <math.h>

Из этого последнего примера хорошо видно, что в зависимости от истинности условия будет вызвана либо первая функция fabs(a), либо вторая fabs(b). И это очень важный момент. Следует всегда помнить, что в тернарной условной операции вычисляется только одно из двух последних выражений, но не оба вместе.

Так как тернарная операция – это операция, а не оператор, то ее можно прописывать как аргумент при вызове функций. Например:

#include <stdio.h>
 
int main(void)
{
    int x = 8;
    printf("x is %s digit\n", (x % 2 == 0) ? "even" : "odd");
 
    return 0;
}

Здесь тернарная операция записана как аргумент функции printf() и возвращает строковый литерал в зависимости от четности числа.

Вложенная тернарная операция

Так как внутри тернарной условной операции можно использовать любые конструкции языка Си, то что нам мешает вложить одну тернарную операцию в другую, например, так:

#include <stdio.h>
 
int main(void)
{
    int a = 2, b = 3, c = -4;
    int max = (a > b) ? ((a > c) ? a : c) : (b > c) ? b : c;
 
    printf("max = %d\n", max);
 
    return 0;
}

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

Работает приведенная программа следующим образом. Сначала проверяется условие a > b. Если это так, то далее с помощью вложенного тернарной операции возвращается максимально из двух переменных a и c. Иначе, максимум из переменных b и c. В результате получаем максимальное из трех чисел a, b, c.

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

Еще раз отмечу, что таких вложений в практике программирования следует избегать, так как в ней очень легко запутаться и допустить ошибку. Да и потом разбираться, что здесь было написано не так то просто. Поэтому в 99% случаях условную тернарную операцию используют без каких либо вложений.

Практический курс по C/C++: https://stepik.org/course/193691

Видео по теме