Тернарная условная операцияТерна́рная усло́вная опера́ция (от лат. ternarius — «тройной») — реализованная во многих языках программирования операция, возвращающая свой второй или третий операнд в зависимости от значения логического выражения, заданного первым операндом. Аналогом тернарной условной операции в математической логике и булевой алгебре является условная дизъюнкция, которая записывается в виде и реализует алгоритм: «если , то , иначе ». Обычно тернарная условная операция ассоциируется с операцией Обычно в реализацию операции закладывается вычисление условия и только одного из выражений, что обеспечивает в ряде случаев расширенные возможности, например, выражение Примеры
Минимальное из чисел a и b:
Может быть использована в ситуации, не связанной с присваиванием: sprintf(
Title,
"%s %s",
tv_system == TV_PAL ?
"PAL" :
"SECAM",
tv_input ?
Tv_Name[ tv_input - 1 ]:
"TEST"
);
— в данном случае эквивалентная конструкция с использованием if-then-else потребовала бы записи вызова функции Си-подобные языкиВ базовом Си нет логического типа данных (в C99 появился логический тип _Bool), поэтому первый операнд должен быть числом (целым или вещественным) или указателем[2]; сначала вычисляется именно его значение и сравнивается с нулём, и, если оно не равно нулю, вычисляется и возвращается второй операнд, в случае равенства — третий. Второй и третий операнды могут быть различных типов (включая void). В C++ тернарная условная операция имеет тот же синтаксис, что и в Си[3], однако за счёт наличия разницы между инициализацией и присваиванием, бывают ситуации, когда операцию #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;
}
Здесь переменная Кроме того, тернарная условная операция может быть применена в левой части оператора присвоения: #include <iostream>
int main ()
{
int a=0, b=0;
const bool cond = ...;
(cond ? a : b) = 1;
std::cout << "a=" << a << ','
<< "b=" << b << '\n';
}
В этом примере, если логическая переменная cond в строке 5 будет содержать значение true, то значение 1 будет присвоено переменной a, иначе, оно будет присвоено переменной b. В C# на тернарную операцию накладываются дополнительные ограничения, связанные с типобезопасностью. Выражения 1 и 2 должны быть одного типа. Это приводит к следующему: int a = 1;
double b = 0.0;
int nMax = (a>b) ? a : b;
Такой исходный код не будет компилироваться несмотря на то, что в конечном итоге значение nMax будет равно а. Поскольку a и b должны быть одного и того же типа, a повысится до double, чтобы соответствовать b. Тип результирующего значения тернарной операции оказывается double, и этот тип должен быть понижен до int при присваивании:[4] int a = 1;
double b = 0.0;
int nMax;
// Можно поступить так:
nMax = (int) ((a>b) ? a : b) ;
// ...или так
nMax = (a>b) ? a : (int)b;
PythonВ Python используется синтаксис с применением ключевых слов a = 42
b = 41
result = a if a > b else b
assert result == 42
Также можно реализовать через список: [<выражение 1>, <выражение 2>][<условие>]
— будет возвращён результат выражения 1, если условие ложно; и выражения 2, если условие истинно. Если условие будет не булевым выражением, возможен выход за границы списка с исключением. PHPВ PHP используется си-подобный синтаксис: $a = $b==1 ? "first value" :
($b==2 ? "second value" :
($b==3 ? "result value" : "default value"));
Тернарный оператор в PHP эквивалентен более длинной конструкции if — else. Следующие два примера эквивалентны: //Первый пример
$result = isset($a) ? $a : 'DefaultValue';
//Второй пример
if (isset($a)) {
$result = $a;
} else {
$result = 'DefaultValue';
}
Такие конструкции часто применяются чтобы в любом случае проинициализировать переменную для последующих вычислений (иначе PHP выдаст ошибку уровня E_NOTICE). Начиная с версии 5.3 появилась возможность не указывать второй параметр операции. Например, две следующих записи эквивалентны: $Variable = $_GET['Parameter'] ? $_GET['Parameter'] : 'DefaultValue';
$Variable = $_GET['Parameter'] ?: 'DefaultValue';
Visual BasicВ классической версии Visual Basic существует тернарный оператор в виде функции Dim iCount As Long
Public Sub Main()
iCount = 1
MsgBox IIf(1 = 1, FuncYes, FuncNo)
'Переменная iCount будет содержать "3", т.к. обе функции будут выполнены
MsgBox iCount
End Sub
Public Function FuncYes() As String
iCount = iCount + 1
FuncYes = "Да"
End Function
Public Function FuncNo() As String
iCount = iCount + 1
FuncNo = "Нет"
End Function
Для замены функции If Expr Then TruePart Else FalsePart
С появлением VB.NET, в синтаксис языка был включен привычный тернарный оператор и записывается как Встроенный язык 1СВ языке конфигурирования платформы 1С:Предприятие тернарный оператор имеет синтаксис: ?(логическое выражение, выражение 1, выражение 2) Широко применяется в качестве сокращенной записи конструкций HaskellВ Haskell операция ветвления if является условным выражением: else-выражение является обязательным и должно совпадать по типу с then-выражением. Также в стандартной библиотеке Data.Bool[7] есть функция bool, возвращающая одно из двух выражений в зависимости от значения предиката. Тернарная операция в привычной форме может быть определена как инфиксная функция через сопоставление с образцом (указание типов не обязательно): (?) :: Bool -> a -> a -> a
(?) True a _ = a
(?) False _ b = b
или через любую операцию ветвления, например if или case of: (?) predicate thenExpr elseExpr = if predicate then thenExpr else elseExpr
(?) predicate thenExpr elseExpr = case predicate of {True -> thenExpr; _ -> elseExpr}
Поскольку (?) — инфиксная (бинарная) функция, то она принимает первые 2 аргумента и возвращает функцию одного аргумента. Для её применения к третьему аргументу используется аппликация ($): True ? "then" $ "else"
> "then"
False ? "then" $ "else"
> "else"
Примечания
Литература
|
Portal di Ensiklopedia Dunia