C. Урок 11. Тернарный оператор



Кроме условных операторов if, else и else if также существует ещё и тернарный оператор.

Данный оператор порой бывает удобен в случаях, если при выполнении какого-то условия или его невыполнении нам нужно присвоить строго определённое значение какой-либо переменной. Хотя такая ситуация и не столь частая, но в случае её возникновения тернарный оператор намного удобнее и читабельнее нежели конструкция IF.

Тернарный оператор (от латинского слова ternarius — тройной)- это оператор, состоящий из двух символов ? и :, который формирует условную тернарную операцию, возвращающую свой второй или третий операнд в зависимости от выполнения или невыполнения определённого условия, или другими словами от результата логического выражения.

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

 

if (x > y)

{

   z = x;

}

else

{

   z = y;

}

 

Вроде бы незатейливая у нас конструкция. В случае если x>y, то z будет равен x, а если не так, то z будет равен y.

Тем самым мы определяем максимальное значение из двух возможных чисел и присваиваем его переменной z.

Теперь посмотрим вот такой вариант записи исходного кода, имеющий тот же результат

 

z = (x > y) ? x : y;

 

Не правда ли, запись намного упростилась.

После всего этого попробуем всё это красиво нарисовать

 

 

Теперь, глядя на диаграмму, попытаюсь ещё раз объяснить поподробнее. В случае использования условной тернарной операции, когда заданное условие выполнятся, то переменной присваивается значение выражения 1, а если не выполняется, то значение выражения 2.

Теперь, надеюсь, всё стало понятно. Если нет, то отработаем понимание в практической части.

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

Например, напишем вот такой код

 

avg = (x > y) ? (x > z) ? (z > y) ? z : y : x : (y > z) ? (z > x) ? z : x : y;

 

Данный код вычисляет среднее значение (не средне-арифметическое, а именно среднее по значению из возможных) из трёх чисел — x, y и z.

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

Так или иначе, такая конструкция имеет право на существование и подчёркивает возможность вложенности тернарных операций.

Только если мы напишем её вот так

 

if (x > y)

{

  if (x > z)

  {

    if (z > y)

    {

      avg = z;

    }

    else

    {

      avg = y;

    }

  }

  else

  {

    avg = x;

  }

}

else

{

  if (y > z)

  {

    if (z > x)

    {

      avg = z;

    }

    else

    {

      avg = x;

    }

  }

  else

  {

    avg = y;

  }

}

 

То она станет гораздо читабельнее, хотя и будет громоздкой.

 

 

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

Давайте к ней и приступим.

Проект сделаем из проекта MYPROG10 прошлого занятия и имя ему было присвоено MYPROG11.

Откроем файл main.c и в функции main(), как обычно, удалим весь код тела кроме возврата нуля, останется от него вот это

 

int main()

{

   return 0; //Return an integer from a function

}

Добавим в тело функции main() следующий код

 

 

Мы объявили три переменных. Две для выражений и одну для результата.

Затем мы просим пользователя ввести целое число и запишем его в одну переменную. Потом просим ввести ещё одно число и присвоим его другой переменной.

Далее мы используем тернарный оператор для того, чтобы вычислить максимальное из введенных число. Если n больше m, то в результат занесём n, а если нет — то m.

Кто-то скажет, что везде используется один и тот же пример для объяснения работы тернарного оператора, я это тоже знаю, просто лучшего примера для этого я придумать не смог. Поэтому остановимся в этот раз на классике.

Испытаем наш код в консоли

 

 

 

Всё отлично работает. По-хорошему, надо бы обработать случай ввода одинаковых значений, но мы этого не будем делать, чтобы не отвлекаться на мелочи.

Закомментируем введённый код и добавим следующий

 

 

Данный код вычисляет модуль введённого числа. Число записывается в переменную n, затем тернарная операция спрашивает, больше ли нуля наше число или равно, если больше, то возвращает это число, а если нет, то возвращает модуль, используя знак минус.

Проверим работу нашего кода

 

 

Отлично! И этот код работает.

Добавим теперь вот такой код, закомментировав, конечно, сначала предыдущий

 

 

Здесь мы уже используем нашу тернарную операцию внутри вызова функции prinf, то есть результат тернарной операции будет аргументом функции (или параметром).

 

 

Мы проверяем введённое значение и присвоенного его переменной a, чтобы оно было больше 10. Если это так то возвращаем одну строку, а если нет, то другую. Затем возвращённая строка подставится в строку, стоящую в первом аргументе вместо модификатора %s.

Проверим работу кода

 

 

Закомментируем наш код и немного его усовершенствуем

 

 

Здесь происходит всё наподобие, как и в предыдущем примере, только мы уже применили вложенность, которая дала нам возможность отследить случай равенства 10 значения нашей переменной. В этом случае мы уже вставляем пустую строку, останется только «is». То есть мы сначала исследуем на «больше», если больше, то выдаём строку, если нет, то продолжаем исследовать на равенство, если равно, то пустая строка, если нет, то значит «меньше» и возвращаем соответствующую строку.

Проверим, как это работает

 

 

Всё работает.

Подключим ещё одну стандартную библиотеку в наш исходный файл

 

 

Теперь, закомментировав предыдущий код в функции main(), ещё усложним наш код. данный код число, введённое пользователем в диапазоне от 0 до 10 прописью

 

 

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

Мы обернули наш оператор в цикл типа while, который проверит, входит ли введённое число в нужный диапазон, если нет, то выведется соответствующее сообщение заcчёт последнего выражения в тернарной конструкции и мы выйдем из цикла.

Также мы здесь использовали выделение памяти в количестве 10 байт с помощью функции стандартной библиотеки malloc. Так как мы использовали указатель, то память под массив строк, на который он будет указывать, не каждый компилятор выделит автоматически.

Попробуем работу нашего кода

 

Всё правильно работает.

На этом, думаю, пора завершать нашу практическую часть, а также и урок. Что-то мы даже, я бы сказал, слишком увлеклись практической проработкой. Но, по большому счёту, это же неплохо!

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

Всем спасибо за внимание!

 

 

Предыдущий урок Программирование на C Следующий урок

 

Исходный код

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

C Тернарный оператор

7 комментариев на “C. Урок 11. Тернарный оператор
  1. Илья:

    Отлично объясняете! Спасибо Вам! С нетерпением жду продолжения.

  2. Вадим:

    avg = (x > y) ? (x > z) ? (z > y) ? z : y : x : (y > z) ? (z > x) ? z : x : y;
    никак не могу разобраться в вашем примере. какая здесь последовательность? как программа понимает, какая переменная является средней?

  3. Vladimir:

    Cпасибо большое!

  4. Иван:

    после использования malloc не надо использовать free?

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

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

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

*