Терна́рная усло́вная опера́ция (от лат. ternarius — «тройной») (обычно записывается как ?:
) — во многих языках программирования операция, возвращающая свой второй или третий операнд в зависимости от значения логического выражения, заданного первым операндом. Как можно судить из названия, тернарная операция принимает всего три указанных операнда. Аналогом тернарной условной операции в математической логике и булевой алгебре является условная дизъюнкция, которая записывается в виде [p, q, r] и реализует алгоритм: «Если q, то p, иначе r», что можно переписать как «p или r, в зависимости от q или не q».
Обычно тернарная условная операция ассоциируется с операцией ?:
, используемой в си-подобных языках программирования. На самом деле, подобные операции с другим синтаксисом имеются и во многих далёких по синтаксису от Си языках программирования. К наиболее популярным языкам, содержащим тернарную условную операцию, можно отнести C, C++, JavaScript, Objective-C, C#, D, Java, ECMAScript, Perl, PHP, Python,Tcl, Ruby, Verilog и другие. Своим появлением непосредственно в тернарной инфиксной форме эта операция обязана языку Алгол-60, в котором она имела синтаксис
и затем языку BCPL (o1 -> o2, o3
)[1] вместо привычного теперь o1 ? o2 : o3
. Прототипом же этой операции, в свою очередь, является условная функция cond
языка Лисп, записываемая по правилам Лиспа в префиксной форме и имеющая произвольное количество аргументов.
Определение
Безотносительно определённого языка программирования, тернарную операцию можно определить так:
логическое выражение ? выражение 1 : выражение 2
Алгоритм работы операции следующий:
- Вычисляется
логическое выражение
. - Если
логическое выражение
истинно, то вычисляется значение выражениявыражение 1
, в противном случае — значение выражениявыражение 2
. - Вычисленное значение возвращается.
Нужно обратить внимание, что вычисляется только одно из выражений: выражение 1
или выражение 2
. Это сделано для оптимизации и, в некотором смысле, соответствует принципу ленивых вычислений.
Использование и реализации
Тернарная условная операция используется в выражениях для получения одного из двух вариантов в зависимости от условия.
alarm_time = today in [SUNDAY, MONDAY] ? 12.00 : 8.00
В этом примере условному программируемому электронному будильнику проставляется время, в которое он должен звонить, в зависимости от текущего дня недели. Нужно заметить, что пример снова приведён для некоторого абстрактного алгоритмического языка программирования.
В следующем примере вычисляется значение простейшего дельта-символа.
y = x == 0 ? 1 : 0
В действительности, немедленное присваивание результата тернарной условной операции редко оправдано с точки зрения стиля программирования, так как подобные операторы компактно переписываются в виде эквивалентной конструкции if-then-else. Более оправдано использование данной операции в более сложных конструкциях, не связанных с присваиванием, например в фактических параметрах вызова функции:
sprintf(Title, "%s %s", tv_system == TV_PAL ? "PAL" : "SECAM", tv_input == 0 ? "TEST" : Tv_Name[tv_input-1]);
В данном случае эквивалентная конструкция с использованием if-then-else потребовала бы записи вызова функции sprintf четыре раза. Либо, в качестве альтернативы, потребовалось бы написать аналогичный по назначению (но формально не эквивалентный) код с использованием двух дополнительных временных переменных, либо нескольких последовательных вызовов sprintf.
Си
В Си тернарная операция имеет следующий синтаксис:[2]
Как известно, в Си нет логического типа данных (в C99 появился логический тип _Bool). Поэтому операнд o1
должен быть числом (целым или вещественным) или указателем. Сначала вычисляется именно его значение. Оно сравнивается с нулём и, если оно не равно нулю, вычисляется и возвращается o2
, в случае равенства — o3
. Операнды o2
и o3
могут быть различных, вообще говоря, несовпадающих типов, включая void.
В следующем примере вычисляется минимальное из чисел a и b:
C++
В C++ тернарная условная операция имеет тот же синтаксис, что и в Си.[3] Однако за счёт наличия разницы между инициализацией и присваиванием, бывают ситуации, когда операцию ?:
нельзя заменить конструкцией if-then-else
, как, например, в следующем случае:
#include <iostream> #include <fstream> #include <string> using namespace std; int main(int argc, char** argv) { string name; ofstream fout; if (argc > 1 && argv[1]) { name = argv[1]; fout.open(name.c_str(), ios::out | ios::app); } ostream& sout = name.empty() ? cout : fout; return 0; }
Здесь переменная sout
инициализируется в момент объявления результатом работы тернарной операции. Подобного эффекта не удалось бы достичь простым присваиванием в том или ином случае.
Кроме того, тернарная условная операция может быть применена в левой части оператора присвоения:
0. #include <iostream> 1. int main () 2. { 3. int a=0, b=0; 4. 5. const bool cond = ...; 6. (cond ? a : b) = 1; 7. std::cout << "a=" << a << ',' 8. << "b=" << b << '\n'; 9. }
В этом примере, если логическая переменная cond в строке 5 будет содержать значение true, то значение 1 будет присвоено переменной a, иначе, оно будет присвоено переменной b.
Python
b = 3 a = 1 if b==1 else \ 2 if b==2 else \ 3 assert a==3
PHP
$a = 1==0 ? "first value" : (2==0 ? "second value" : (3==3 ? "result value" : "default value"));
Начиная с версии 5.3 появилась возможность не указывать второй параметр операции. Например, две следующих записи эквивалентны:
$Variable = $_GET['Parameter'] ? $_GET['Parameter'] : 'DefaultValue'; $Variable = $_GET['Parameter'] ?: 'DefaultValue';
C#
На тернарную операцию накладываются дополнительные ограничения, связанные с типобезопасностью. Выражения 1 и 2 должны быть одного типа. Это приводит к следующему:
int a = 1; double b = 0.0; int nMax = (a>b) ? a : b;
Такой исходный код не будет компилироваться несмотря на то, что в конечном итоге значение nMax будет равно
int a = 1; double b = 0.0; int nMax; // Можно поступить так: nMax = (int) ((a>b) ? a : b) ; // ...или так nMax = (a>b) ? a : (int)b;
Примечания
Литература
Стефан Рэнди Дэвис, Чак Сфер Глава 4. Операторы // C# 2005 для «чайников» = C# 2005 for dummies / под редакцией Т. Г. Сковородниковой. — М.-Спб.: Wiley, Диалектика, 2006. — С. 83. — ISBN 5-8459-1068-4
ОПЕРАЦИЯ УСЛОВИЯ: ?:. Язык Си
ОПЕРАЦИЯ УСЛОВИЯ: ?:
В языке Си имеется короткий способ записи одного из видов оператора if-else. Он называется «условным выражением» и использует операцию условия — ?:. Эта операция состоит из двух частей и содержит три операнда. Ниже приводится пример оператора с помощью которого находится абсолютное значение числа:
x = (y < 0 )? -y : y;
Все, что находится между знаком = и символом «точка с занятой» представляет собой условное выражение. Смысл этого оператора заключается в следующем: если у меньше 0, то х = — у; в противном случае х = у. В терминах оператора if-else данный оператор мог выглядеть так:
if(у < 0) x = (y < 0 )? -y : y;
х = -у;
else
х = у;
В общем виде условное выражение можно записать следующим образом:
выражение1 ? выражение2 : выражение3
Если выражение1 истинно (больше нуля), то значением всего условного выражения является величина выражения2
если выражение1 ложно (равно 0), то значение всего условного выражения — величина выражения3.
Условное выражение удобно использовать в тех случаях, когда имеется некоторая переменная, которой можно присвоить одно из двух возможных значений. Типичным примером является присваивание переменной значения большей из двух величин:
mах = (а > b)? а : b;
Вообще говоря, использование условных выражений не являетcя обязательным, поскольку тех же результатов можно достичь при помощи операторов if-else. Однако условные выражения более компактны, и их применение обычно приводит к получению более компактного машинного кода.
Поделитесь на страничке Следующая глава >Операции в языке Си имеют либо один операнд (унарные операции), либо два операнда (бинарные операции), либо три (тернарная операция). Операция присваивания может быть как унарной, так и бинарной (см. раздел 4.4).
Существенным свойством любой операции является ее ассоциативность. Ассоциативность определяет порядок выполнения в том случае, когда подряд применено несколько операций одного вида. Ассоциативность «слева направо» означает, что первой будет выполняться операция, знак которой записан левее остальных. Например, выражение
b << 2 << 2
выполняется как (b << 2) << 2, а не как b << (2 << 2). Ассоциативность «справа налево» означает, что первой будет выполняться операция, знак которой записан правее остальных.
В языке Си реализованы следующие унарные операции:
Знак операции | Наименование |
— | унарный минус |
+ | унарный плюс |
~ | обратный код |
! | логическое отрицание |
& | адресация |
* | косвенная адресация |
sizeof | определение размера |
Примечание. Операция унарного плюса реализована полностью только в СП ТС. В СП MSC версии 4 она отсутствует, а в версии 5 реализована только синтаксически.
Унарные операции предшествуют своему операнду и ассоциируются справа налево.
В языке Си реализованы следующие бинарные операции:
Знак | Наименование |
* / % | мультипликативные операции |
+ — | аддитивные операции |
<< >> | операции сдвига |
< > <= >= == != | операции отношения |
& | ^ | поразрядные операции |
&& || | логические операции |
, | операция последовательного вычисления |
Бинарные операции ассоциируются слева направо. В языке Си имеется одна тернарная операция — условная, обозначаемая ?:. Она ассоциируется справа налево.
Поделитесь на страничкеСледующая глава >
Тернарная условная операция Википедия
Терна́рная усло́вная опера́ция (от лат. ternarius — «тройной») (обычно записывается как ?:
) — во многих языках программирования операция, возвращающая свой второй или третий операнд в зависимости от значения логического выражения, заданного первым операндом. Как можно судить из названия, тернарная операция принимает всего три указанных операнда. Аналогом тернарной условной операции в математической логике и булевой алгебре является условная дизъюнкция, которая записывается в виде [p, q, r] и реализует алгоритм: «Если q, то p, иначе r», что можно переписать как «p или r, в зависимости от q или не q».
Обычно тернарная условная операция ассоциируется с операцией ?:
, используемой в си-подобных языках программирования. На самом деле, подобные операции с другим синтаксисом имеются и во многих далёких по синтаксису от Си языках программирования. К наиболее популярным языкам, содержащим тернарную условную операцию, можно отнести C, C++, JavaScript, Objective-C, C#, D, Java, ECMAScript, Perl, PHP, Python,Tcl, Ruby, Verilog, Turbo Basic и другие. Своим появлением непосредственно в тернарной инфиксной форме эта операция обязана языку Алгол-60, в котором она имела синтаксис if o1 then o2 else o3
и затем языку BCPL (o1 -> o2, o3
)[1] вместо привычного теперь o1 ? o2 : o3
. Прототипом же этой операции, в свою очередь, является условная функция cond
языка Лисп, записываемая по правилам Лиспа в префиксной форме и имеющая произвольное количество аргументов.
Определение[ | ]
Безотносительно к определённому языку программирования тернарную операцию можно определить так:
логическое выражение ? выражение 1 : выражение 2
Алгоритм работы операции следующий:
- Вычисляется
логическое выражение
. - Если
логическое выражение
истинно, то вычисляется значение выражениявыражение 1
, в противном случае — значение выражениявыражение 2
. - Вычисленное значение возвращается.
Нужно обратить внимание, что вычисляется только одно из выражений: выражение 1
или выражение 2
. Это соответствует принципу ленивых вычислений, и сделано не столько для оптимизации, сколько для расширения возможностей: так, выражение x < 0 ? 0 : sqrt(x)
абсолютно корректно, несмотря на то, что из отрицательных чисел корень не берётся.
Использование и реализации[ | ]
Тернарная условная операция используется в выражениях для получения одного из двух вариантов в зависимости от условия.
alarm_time = today in [SUNDAY, MONDAY] ? 12.00 : 8.00
В этом примере условному программируемому электронному будильнику проставляется время, в которое он должен звонить, в зависимости от текущего дня недели. Нужно заметить, что пример снова приведён для некоторого абстрактного алгоритмического языка программирования.
В следующем примере вычисляется значение простейшего дельта-символа.
y = x == 0 ? 1 : 0
В следующем примере данная операция использована в ситуации, не связанной с присваиванием:
Условная операция с + = в C ++
Переполнение стека- Товары
- Клиенты
- Случаи использования
- Переполнение стека Публичные вопросы и ответы
- Команды Частные вопросы и ответы для вашей команды
- предприятие Частные вопросы и ответы для вашего предприятия
- работы Программирование и связанные с ним технические возможности карьерного роста
- Талант Нанимать технический талант
- реклама Связаться с разработчиками по всему миру
Загрузка…
,C условных операторов — C Programming
Условные операторы [?:]: Оператор троичного оператора в C
- Их также называют Тернарным Оператором.
- Их еще называют как?: Оператор
- Ternary Operators принимает 3 аргумента
Синтаксис:
выражение 1? выражение 2: выражение 3
, где
- expression1 is Состояние
- выражение2 является оператором, если условие истинно
- выражение2 является оператором, если условие ложно
Условное заявление в C Программирование на Lanuage
Значение синтаксиса:
- Expression1 — не что иное, как логическое условие i.В результате получается либо ИСТИНА, либо ЛОЖЬ .
- Если результат expression1 равен TRUE, тогда expression2 выполняется
- Выражение1 считается ИСТИННЫМ, если его результат НЕ НУЛЬ
- Если результат expression1 равен FALSE, то expression3 выполняется
- Выражение1 называется ЛОЖНЫМ, если его результат НУЛЬ
Live: Проверьте, является ли число нечетным или четным
#includeint main () { int num; printf («Введите номер:»); зсапЕ ( "% d", & Num); flag = ((num% 2 == 0)? 1: 0); если (флаг == 0) Е ( "\ NEven"); еще Е ( "\ nOdd"); }
Более просто мы можем написать эту программу как —
#includeint main () { int num; printf («Введите номер:»); зсапЕ ( "% d", & Num); (NUM% 2 == 0) Е ( "Даже"): Е ( "Одд");? }
Большая нота: троичный оператор
Оператор, который работает с 3 операндами, называется третичным оператором. Тернарный оператор. Прочитайте правила использования Ternary Operator в C. [Статья в вики: http://en.wikipedia.org/wiki/Ternary_operation]
,
стандарт :: условно — cppreference.com
шаблон | (начиная с C ++ 11) | |
Предоставляет элемент typedef , тип
, который определяется как T
, если B
имеет значение true во время компиляции, или как F
, если B
равен false.
Поведение программы, которая добавляет специализации для условного
, не определено.
[править] Типы участников
Тип пользователя | Определение |
тип | T , если B == true, F , если B == false |
[править] Типы помощников
шаблон | (начиная с C ++ 14) | |
[править] Возможная реализация
шаблон |
[править] Пример
#include#include #include int main () { typedef std :: conditional :: type Type1; typedef std :: conditional :: type Type2; typedef std :: conditional = sizeof (double), int, double> :: type Type3; std :: cout << typeid (Type1).name () << '\ n'; std :: cout << typeid (Type2) .name () << '\ n'; std :: cout << typeid (Type3) .name () << '\ n'; }
Возможный вывод:
[редактировать] См. Также
скрывает перегрузку функции или специализацию шаблона на основе логического значения времени компиляции (шаблон класса) [править] |
5.5 - Запятые и условные операторы
Оператор запятой
Оператор | Символ | Форма | Операция |
---|---|---|---|
Запятая | , | х, у | Оценить х затем у, возвращает значение у |
Оператор запятой (,) позволяет вам вычислять несколько выражений, где бы ни было разрешено одно выражение. Оператор запятой оценивает левый операнд, затем правый операнд и затем возвращает результат правого операнда.
Например:
#include int main () { int x {1}; int y {2}; std :: cout << (++ x, ++ y); // увеличиваем x и y, вычисляем правый операнд return 0; } |
Сначала оценивается левый операнд оператора запятой, который увеличивается с x с 1 до 2 .Затем оценивается правый операнд, который увеличивает y с 2 до 3 . Оператор запятой возвращает результат правого операнда ( 3 ), который впоследствии выводится на консоль.
Обратите внимание, что запятая имеет самый низкий приоритет среди всех операторов, даже ниже, чем присвоение. Из-за этого следующие две строки кода делают разные вещи:
z = (а, б); // сначала вычисляем (a, b), чтобы получить результат b, затем присваиваем это значение переменной z. z = a, b; // оценивается как "(z = a), b", поэтому z получает присвоенное значение a, а b оценивается и отбрасывается. |
Это делает оператор запятой несколько опасным для использования.
Практически в каждом случае оператор, написанный с использованием оператора запятой, лучше записать как отдельный оператор. Например, приведенный выше код может быть записан как:
#include int main () { int x {1}; int y {2}; ++ x; std :: cout << ++ y; возврат 0; } |
Большинство программистов вообще не используют оператор запятой, за исключением одного внутри для циклов , где его использование довольно распространено.Мы обсуждаем циклы в будущем уроке 5.7 - Для утверждений (Не в этой главе 5, но в L.5. Пожалуйста, извините за непересекающуюся нумерацию уроков.).
Избегайте использования оператора запятой, за исключением для циклов .
Запятая как разделитель
В C ++ символ запятой часто используется в качестве разделителя, и в этих случаях оператор запятой не вызывается. Некоторые примеры разделительных запятых:
void foo (int x, int y) // Запятая используется для разделения параметров в определении функции { add (x, y); // Запятая используется для разделения аргументов в вызове функции int z (3), w (5); // Запятая используется для разделения нескольких переменных, определяемых в одной строке (не делайте этого) } |
Нет необходимости избегать разделительных запятых (кроме случаев объявления нескольких переменных, чего не следует делать).
Условный оператор
Оператор | Символ | Форма | Операция |
---|---|---|---|
Условно | ?: | с? х: у | Если c ненулевое (true), тогда вычислить x, иначе вычислить y |
Условный оператор (? 🙂 (также иногда называемый «арифметическим оператором if») является троичным оператором (он принимает 3 операнда). Поскольку исторически это был единственный троичный оператор C ++, его также иногда называют «троичным оператором».
Оператор?: Предоставляет сокращенный метод для выполнения определенного типа оператора if / else. Пожалуйста, просмотрите урок 4.10 - Введение в утверждения if, если вам нужно освежить в памяти if / else, прежде чем продолжить.
Оператор if / else принимает следующую форму:
если (условие) statement1; еще оператор2;
Если условие оценивается как истинное , то выполняется оператор1 , в противном случае выполняется оператор2 .
Оператор?: Принимает следующую форму:
(состояние) ? выражение1: выражение2;
Если условие оценивается как истинное , то выполняется выражение1 , в противном случае выполняется выражение2 . Обратите внимание, что expression2 не является обязательным.
Рассмотрим оператор if / else, который выглядит следующим образом:
, если (x> y) больше = x; остальное больше = y; |
можно переписать как:
больше = (x> у)? х: у; |
В таких случаях условный оператор может помочь сжать код без потери читаемости.
Заключение в скобки условного оператора
Обычно принято ставить условную часть операции в круглые скобки, чтобы облегчить чтение, а также чтобы убедиться, что приоритет является правильным. Другие операнды оцениваются так, как если бы они были в скобках, поэтому явная скобка для них не требуется.
Обратите внимание, что оператор?: Имеет очень низкий приоритет. Если вы делаете что-либо кроме присвоения результата переменной, весь оператор?: Также должен быть заключен в скобки.
Например, чтобы вывести на экран большее из значений x и y, мы могли бы сделать это:
if (x> y) std :: cout << x; остальное std :: cout << y; |
Или мы можем использовать условный оператор для этого:
std :: cout << ((x> y)? X: y); |
Давайте рассмотрим, что произойдет, если мы не заключим в скобки весь условный оператор в приведенном выше случае.
Потому что
std :: cout << (x> y)? х: у; |
оценил бы как:
(std :: cout << (x> y))? х: у; |
Это вывело бы 1 (true), если x> y, или 0 (false) в противном случае!
Всегда заключайте в скобки условную часть условного оператора и также подумайте о заключении в скобки всей этой вещи.
Условный оператор оценивает как выражение
Поскольку операнды условного оператора являются выражениями, а не операторами, условный оператор может использоваться в некоторых местах, где if / else не может.
Например, при инициализации переменной const:
#include int main () { bool inBigClassroom {false}; const int classSize {inBigClassroom? 30:20}; std :: cout << "Размер класса:" << classSize; возврат 0; } |
Для этого нет удовлетворительного утверждения if / else.Вы можете подумать попробовать что-то вроде этого:
#include int main () { bool inBigClassroom {false}; if (inBigClassroom) const int classSize {30}; иначе const int classSize {20}; std :: cout << "Размер класса:" << classSize; возврат 0; } |
Однако, это не скомпилируется, и вы получите сообщение об ошибке, что classSize не определен.Так же, как переменные, определенные внутри функций, умирают в конце функции, переменные, определенные внутри оператора if или else, умирают в конце оператора if или else. Таким образом, classSize уже уничтожен к тому времени, когда мы пытаемся его напечатать.
Если вы хотите использовать if / else, вам нужно сделать что-то вроде этого:
1 2 3 4 5 6 7 8 9 10 11 12 13 160003 140003 14000000 | #include int getClassSize (bool inBigClassroom) { if (inBigClassroom) return 30; остальное возврат 20; } int main () { const int classSize {getClassSize (false)}; std :: cout << "Размер класса:" << classSize; возврат 0; } |
Это работает, потому что мы не определяем переменные внутри , если или или , мы просто возвращаем значение вызывающей стороне, которая затем может использоваться в качестве инициализатора.
Это много дополнительной работы!
Тип выражений должен соответствовать или быть конвертируемым
Чтобы должным образом соответствовать проверке типов в C ++, оба выражения в условном выражении должны либо совпадать, либо второе выражение должно быть преобразовано в тип первого выражения.
Итак, хотя вы можете ожидать, что сможете сделать что-то вроде этого:
#include int main () { int x = 5; std :: cout << (x! = 5? X: "x равно 5"); // не компилируется return 0; } |
Приведенный выше пример не скомпилируется.Одно из выражений является целым числом, а другое - строковым литералом. Компилятор попытается найти способ преобразовать строковый литерал в целое число, но, поскольку он не знает как, он выдаст ошибку. В таких случаях вам придется использовать if / else.
Итак, когда вы должны использовать условный оператор?
Условный оператор дает нам удобный способ сжать некоторые операторы if / else. Это наиболее полезно, когда нам нужен условный инициализатор (или присваивание) для переменной или для передачи условного значения в функцию.
Его не следует использовать для сложных операторов if / else, поскольку он быстро становится нечитаемым и подверженным ошибкам.
Используйте условный оператор только для простых условных выражений, где вы используете результат и где он улучшает читабельность.
,