Что значит тернарный оператор
Секреты тернарного оператора
Каждый уважающий себя программист С\С++ знает что такое тернарный оператор и большинство использовало его хотя бы раз в своих программах. Но знаете ли вы все секреты тернарного оператора? Какие потенциальные опасности сопряжены с его использованием и какие, казалось бы не связанные с его прямым предназначением, возможности в нем таятся? Эта статья дает вам возможность проверить свои знания и, возможно, узнать что-то новое.
Начнем с небольшого теста.
Скомпилируется ли следующий код? Объясните почему.
1.
Какой будет вывод у следующего кусочка? Почему?
6.
Какие значения будут у переменных a, b и c в результате выполнения следующего кода? Почему?
7.
Объяснение
Итак, начнем. Тернарный оператор выделяется из ряда других операторов в С++. Его называют «conditional expression«. Ну а так как это expression, выражение, то как у каждого выражения, у него должен быть тип и value category. Собственно, ответив на вопросы какой тип и value category у тернарных операторов в каждом из первых семи вопросов теста, мы легко решим поставленные задачи.
Здесь начинается самое интересное. Оказывается типом тернарного оператора будет наиболее общий тип его двух последних операндов. Что значит наиболее общий? Это легче всего пояснить на примерах. У int и short общим типом будет int.
У A и B в следующем фрагменте общим типом будет также int.
Т.е. наиболее общий тип это такой тип, к которому могу быть приведены оба операнда. Вполне могут быть ситуации, когда общего типа нет. Например у
общего типа нет, и следующий фрагмент вообще не скомпилируется
Так. С типом тернарного оператора мы немного разобрались. Осталось решить вопрос с value category. Тут действует следующее правило: если в тернарном операторе происходит преобразование типов к наиболее общему, то тернарный оператор — rvalue. Если же нет, то lvalue. Теперь когда мы знаем то, что мы знаем, мы легко ответим на первые 7 вопросов.
Ответы
1. и 2. — Да. Преобразования типов не происходит, а lvalue вполне можно присваивать значение.
3. — Нет. Здесь происходит преобразование типов. Значит value category у выражения слева от знака «=» — rvalue. А rvalue, как известно, нельзя присваивать.
4. — Да. Все мы так делали не раз.
5. — Нет. Здесь все дело в том, что в С++ statement не может разбивать expression.
6. Программа выведет «57 9». В данном фрагменте из-за того, что 2ой и 3ий операнд имеют разные типы, происходит преобразование к наиболее общему типу. В данном случае int. А ‘9’, как известно, имеет ASCII код 57.
7. В этом вопросе кроется еще одна особенность тернарного оператора. А именно, вычисляется только тот операнд из второго и третьего, до которого доходит поток выполнения. Впрочем такое же поведение можно наблюдать у if<. >else<. >. Соответственно, значения переменных a, b и с будут 2, 2, 1.
Где нельзя использовать if <. >else<. >, но можно тернарный оператор?
Например, в списке инициализации конструктора. Вы не может написать так:
Но вполне можно вот так:
При инициализации ссылки в зависимости от условия. Как известно, нельзя объявлять не инициализированную ссылку, поэтому следующий фрагмент не скомпилируется:
А вот следующий скомпилируется успешно:
В С++11 тернарный оператор применяется гораздо чаще. Связано это с тем, что в constexpr функциях не должно быть ничего кроме return `expression`. А `expression` вполне может представлять из себя тернарный оператор.
В качестве примера приведу классический алгоритм определения простоты числа
В этом же примере, кстати, видно использование каскадных тернарных операторов, которые могут быть неограниченной вложенности и заменять собой множественные if <. >else<. >.
Опасности тернарного оператора
Допустим у нас есть класс String
И использовать мы его можем, например, так:
Как нам уже известно, второй и третий операнд тернарного оператора приводятся к наиболее общему типу. В данном случае это const char*. Но объект String(«dcba») уничтожится в конце выражения и s будет указывать на невалидную память. В лучшем случае программа упадет при попытке в дальнейшем использовать s. В худшем будет выдавать неверные результаты, вызывая недовольство у заказчика и головную боль у программиста.
«Необычное» использование тернарного оператора
Тернарный оператор можно использовать для определения общего типа двух и более типов. А это, в свою очередь, можно использовать, например, для определения приводится ли один тип к другому.
На самом деле, если знать свойства тернарного оператора, такое использование практически напрашивается само собой. Необычным здесь, пожалуй является лишь то, что он используется не по прямому назначению, т.е. не для выбора одного значения из двух в зависимости от условия.
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.
Теперь посмотрим вот такой вариант записи исходного кода, имеющий тот же результат
Не правда ли, запись намного упростилась.
После всего этого попробуем всё это красиво нарисовать
Теперь, глядя на диаграмму, попытаюсь ещё раз объяснить поподробнее. В случае использования условной тернарной операции, когда заданное условие выполнятся, то переменной присваивается значение выражения 1, а если не выполняется, то значение выражения 2.
Теперь, надеюсь, всё стало понятно. Если нет, то отработаем понимание в практической части.
Также возможна вложенность условий, правда это используется нечасто, так как очень сильно страдает читабельность кода.
Например, напишем вот такой код
Данный код вычисляет среднее значение (не средне-арифметическое, а именно среднее по значению из возможных) из трёх чисел — 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() следующий код
Урок №41. Условный тернарный оператор, оператор sizeof и Запятая
Обновл. 11 Сен 2021 |
На этом уроке мы рассмотрим условный тернарный оператор, оператор Запятую и вспомним оператор sizeof в языке C++.
Оператор sizeof
Мы уже рассматривали оператор sizeof на уроке №30.
Оператор | Символ | Пример | Операция |
sizeof | sizeof | sizeof(тип) sizeof(переменная) | Возвращает размер типа данных или переменной в байтах |
Тогда мы использовали его для определения размера конкретных типов данных. Но также sizeof можно использовать и с переменными:
Оператор Запятая
Оператор Запятая (или «оператор Comma») позволяет обрабатывать несколько выражений (в то время, когда, обычно, позволяется только одно).
Оператор | Символ | Пример | Операция |
Запятая | , | x, y | Вычисляется x, затем вычисляется y, а затем возвращается значение y |
Выражение, в котором находится этот оператор, будет иметь значение правого операнда. Например:
Почти в каждом случае, стейтмент, в котором есть оператор Запятая, лучше записывать в виде отдельных инструкций. Вышеприведенный код корректнее будет записать следующим образом:
Обратите внимание, оператор Запятая имеет самый низкий приоритет из всех операторов (даже ниже, чем в оператора присваивания), поэтому следующие две строки кода делают не одно и то же:
Большинство программистов не используют оператор Comma вообще (разве что только в циклах for).
Обратите внимание, запятая, которая используется в вызовах функций, не является оператором Comma:
Аналогично, при объявлении нескольких переменных в одной строке, запятая используется как разделитель, а не как оператор:
Правило: Избегайте использования оператора Comma (исключением являются циклы for).
Условный тернарный оператор
if (условие)
выражение;
else
другое_выражение;
Можно записать как:
Обратите внимание, операнды условного оператора должны быть выражениями (а не стейтментами).
Например, ветвление if/else, которое выглядит следующим образом:
if (условие)
x = значение1;
else
x = значение2;
Можно записать как:
Большинство программистов предпочитают последний вариант, так как он читабельнее.
Обычно, часть с условием помещают внутри скобок, чтобы убедиться, что приоритет операций корректно сохранен и так удобнее читать.
Или с помощью тернарного оператора:
Будет обрабатываться как:
Совет: Всегда заключайте в скобки условную часть тернарного оператора, а лучше весь тернарный оператор.
Условный тернарный оператор — это удобное упрощение ветвления if/else, особенно при присваивании результата переменной или возврате определенного значения. Но его не следует использовать вместо сложных ветвлений if/else, так как в таких случаях читабельность кода резко ухудшается и вероятность возникновения ошибок только растет.
Правило: Используйте условный тернарный оператор только в тривиальных случаях.
Условный тернарный оператор вычисляется как выражение
Тернарный оператор в JavaScript
Тернарный (или условный) оператор существует во многих языках программирования — например, в C++, Java, Python, PHP и других. Разберёмся, как он работает в JavaScript.
Все операторы различаются по количеству аргументов, к которым они применяются. Например, существует оператор «-», который меняет знак числа на противоположный. Если такой оператор применяется к одному числу, то есть у него один аргумент — он называется унарным.
Кроме унарных операторов, существуют операторы с двумя аргументами — бинарные. Например, бинарный «+» складывает два аргумента:
И, наконец, тернарный оператор:
Это единственный оператор с тремя аргументами, что отражено в названии. Первый аргумент — это условие. Если оно истинно (равно true ), оператор вернёт второй аргумент — выражение1. В ином случае он вернёт третий аргумент — выражение2.
По сути оба фрагмента кода выполняют одно и то же действие — проверяют условие, а затем присваивают переменной первое или второе выражение в зависимости от истинности этого условия. Разница лишь в форме записи.
Варианты использования
Значение, возвращаемое тернарным оператором, можно записать в переменную — этот вариант мы уже рассмотрели в примере выше. Кроме этого, его можно использовать в функциях при возвращении значения с помощью return :
Также возможно использование множественных тернарных операций. В этом случае несколько операторов «?» будут идти подряд:
Что выбрать: тернарный оператор или if
При выборе за основной показатель нужно взять читабельность кода. Чем код понятнее, нагляднее, тем удобнее его рефакторить и поддерживать. Тернарный оператор может как сделать код проще, так и необоснованно его усложнить. Это зависит от ситуации.
Посмотрим ещё раз на самый первый вариант, уже разобранный выше. Здесь переменной присваивается значение в зависимости от условия, и это пример грамотного использования тернарного оператора. В таком случае он позволяет избавиться от громоздкой условной конструкции и сделать код проще и короче.
Но есть варианты, когда использование оператора усложняет код. В большинстве случаев это относится к множественным тернарным операциям, о которых речь шла выше. Ещё к таким вариантам стоит отнести использование тернарного оператора для выполнения целых фрагментов кода в зависимости от условия, а не простого присвоения значения переменной. Рассмотрим пример:
Тем не менее не стоит отказываться от тернарного оператора. Он может помочь сделать код понятным и лаконичным. Главное — знать, в каких конкретно ситуациях его полезно использовать, и не злоупотреблять.
Примеры применения тернарного оператора Java
Тернарный(тройной) оператор Java является единственным условным оператором, который принимает три операнда. Используется как замена одного оператора if-then-else и часто применяется в Java-программировании.
В одной строке кода троичный оператор позволяет вам присвоить значение переменной на основе логического выражения — либо логического поля, либо оператора, который оценивает логический результат.
Примеры простых тернарных операторов
Одним из применений тернарного оператора в Java является назначение минимального (или максимального) значения двух переменных третьей переменной, по существу заменяя вызов метода Math.min (a, b) или Math.max (a, b).
Вот пример, который присваивает минимуму из двух переменных, a и b, третьей переменной с именем minVal:
В этом коде, если переменная a меньше, чем b, minVal присваивается значение a; в противном случае minVal присваивается значение b.
Далее приведен пример, в котором условный оператор встроен в строку, по существу используемый для правильного построения String в зависимости от того, является ли x единственным или множественным числом:
Пример, демонстрирующих аналогичную операцию в String, на этот раз для правильного вывода приветствия для определенного пола человека:
Вот исходный код класса Java, который я использовал для тестирования некоторых примеров, показанных в этом руководстве:
Средняя оценка / 5. Количество голосов:
Или поделись статьей
Видим, что вы не нашли ответ на свой вопрос.