Ternární podmíněná operace (z latinského ternarius - „triple“) je operace implementovaná v mnoha programovacích jazycích , která vrací svůj druhý nebo třetí operand v závislosti na hodnotě logického výrazu daného prvním operandem. Obdobou ternární podmíněné operace v matematické logice a Booleově algebře je podmíněná disjunkce , která je zapsána ve tvaru a implementuje algoritmus: " if , then , else ".
Obvykle je ternární podmíněný operátor spojen s operátorem ?:používaným v programovacích jazycích podobných C. Ve skutečnosti podobné operace s odlišnou syntaxí existují v mnoha programovacích jazycích, které jsou v syntaxi daleko od C. Populární jazyky, které mají ve své syntaxi zabudovaný ternární podmíněný operátor, jsou C , C++ , JavaScript , Objective-C , C# , D , Java , ECMAScript , Perl , PHP , Python , Tcl , Ruby , Verilog, Turbo Basic . Tato operace vděčí za svůj vzhled přímo ve formě ternárního infixu jazyku Algol-60 , ve kterém měla syntaxi , a poté jazyku BCPL ( ) [1] namísto nyní známého . Prototyp této operace je zase podmíněná funkce jazyka Lisp , napsaná podle pravidel Lisp ve formě prefixů a mající libovolný počet argumentů. if o1 then o2 else o3o1 -> o2, o3o1 ? o2 : o3cond
Implementace operace obvykle zahrnuje výpočet podmínky a pouze jednoho z výrazů, což v některých případech poskytuje rozšířené možnosti, například výraz x > 0 ? 0 : sqrt(x)je považován za správný, a to navzdory skutečnosti, že kořen není převzat ze záporných čísel.
Minimum čísel a a b:
min = (a < b) ? a : bLze použít v situaci bez přiřazení:
sprintf ( titul , "%s %s" , tv_system == TV_PAL ? PAL : SECAM , tv_input ? Tv_Name [ tv_input - 1 ] : "TEST" );- v tomto případě by ekvivalentní konstrukce používající if-then-else vyžadovala, aby bylo volání funkce zapsáno sprintfčtyřikrát.
Basic C nemá datový typ boolean ( C99 zavedl typ boolean _Bool), takže první operand musí být číslo ( integer nebo real ) nebo ukazatel [2] ; nejprve se vypočítá jeho hodnota a porovná se s nulou , a pokud se nerovná nule, vypočítá se a vrátí druhý operand, v případě rovnosti - třetí. Druhý a třetí operand mohou být různých typů (včetně void ).
V C++ má ternární podmíněný operátor stejnou syntaxi jako v C [3] , nicméně kvůli rozdílu mezi inicializací a přiřazením nastávají situace, kdy operaci ?:nelze nahradit konstruktem if-then-else, jako například v následujícím případ:
#include <iostream> #include <fstream> #include <řetězec> pomocí jmenného prostoru std ; int main ( int argc , char ** argv ) { stringname ; _ outstream fout ; if ( argc > 1 && argv [ 1 ]) { jméno = argv [ 1 ]; fout . open ( name.c_str ( ), ios :: out | ios :: app ) ; } ostream & sout = jméno . prázdné () ? cout : fout ; návrat 0 ; }Zde je proměnná sout inicializována v okamžiku, kdy je deklarován výsledek ternární operace. Podobného efektu nebylo možné dosáhnout jednoduchým zadáním v tom či onom případě.
Navíc lze ternární podmíněný operátor použít na levé straně příkazu přiřazení:
#include <iostream> int main () { int a = 0 , b = 0 ; const bool cond = ...; ( podmínka a : b ) = 1 ; _ std :: cout << "a=" << a << ',' << "b=" << b << '\n' ; }Pokud v tomto příkladu booleovská proměnná cond na řádku 5 obsahuje hodnotu true, bude hodnota 1 přiřazena proměnné a, jinak bude přiřazena proměnné b.
V C# má ternární operátor další omezení související s bezpečností typu. Výrazy 1 a 2 musí být stejného typu. Výsledkem je následující:
int a = 1 ; dvojité b = 0,0 ; int nMax = ( a > b ) ? a : b ;Takový zdrojový kód se nezkompiluje navzdory skutečnosti, že nMax skončí jako . Protože aab musí být stejného typu, a bude povýšeno na dvojité, aby odpovídalo b . Typ výsledné hodnoty ternární operace je double a tento typ je nutné při přiřazení přehodit na int: [4]
int a = 1 ; dvojité b = 0,0 ; int nMax ; // Můžete to udělat: nMax = ( int ) (( a > b ) ? a : b ) ; // ...nebo tak nMax = ( a > b ) ? a : ( int ) b ;Python používá syntaxiif-else klíčových slov :
a = 42 b = 41 výsledek = a pokud a > b jinak b tvrzení výsledek == 42Může být také implementován prostřednictvím seznamu:
[ < výraz 1 > , < výraz 2 > ][ < podmínka > ]- výsledek výrazu 1 bude vrácen, pokud je podmínka nepravdivá; a výraz 2, pokud je podmínka pravdivá. Pokud podmínka není booleovský výraz, je možné seznam přeplnit výjimkou.
PHP používá syntaxi podobnou C :
$a = $b == 1 ? "první hodnota" : ( $b == 2 ? "druhá hodnota" : ( $b == 3 ? "výsledná hodnota" : "výchozí hodnota" ));Ternární operátor v PHP je ekvivalentní delší konstrukci if-else. Následující dva příklady jsou ekvivalentní:
//První příklad $result = isset ( $a ) ? $a : 'Výchozí hodnota' ; //Druhý příklad if ( isset ( $a )) { $vysledek = $a ; } else { $result = 'Výchozí hodnota' ; }Takové konstrukce se často používají k inicializaci proměnné pro následné výpočty (jinak PHP vyvolá chybu úrovně E_NOTICE).
Počínaje verzí 5.3 bylo možné nespecifikovat druhý parametr operace. Například následující dva záznamy jsou ekvivalentní:
$Variable = $_GET [ 'Parametr' ] ? $_GET [ 'Parametr' ] : 'Výchozí hodnota' ; $Variable = $_GET [ 'Parametr' ] ?: 'Výchozí hodnota' ;V klasické verzi jazyka Visual Basic existuje ternární operátor jako funkce IIf(Expr, TruePart, FalsePart). Tato funkce má vlastnost: při vyhodnocování výrazu Exprbude také vypočítána TrueParta FalsePartbez ohledu na výsledek výrazu: true nebo false. To může vést k neočekávaným výsledkům a někdy ke zpomalení provádění kódu, pokud jsou návratové hodnoty volání funkcí s dlouhými operacemi.
Dim iCount As Long Public Sub Main () iCount = 1 MsgBox IIf ( 1 = 1 , FuncYes , FuncNo ) 'Proměnná iCount bude obsahovat "3", protože obě funkce budou provedeny MsgBox iCount End Sub Veřejná funkce FuncYes () As String iCount = iCount + 1 FuncYes = "Ano" Koncová funkce Veřejná funkce FuncNo () As String iCount = iCount + 1 FuncNo = "Ne" End FunctionChcete-li nahradit funkci IIf, můžete přepsat výraz na jeden řádek, ale nebude to analog funkce, ale bude to jen krátká forma operátoru větve
If Expr Then TruePart Else FalsePartS příchodem VB.NET byl známý ternární operátor zahrnut do syntaxe jazyka a je zapsán jako If(Expr, TruePart, FalsePart). Tento operátor používá redukované výpočty, na rozdíl od funkce IIf, která je také k dispozici pro vývojáře kvůli kompatibilitě s předchozími verzemi. [5]
V konfiguračním jazyce platformy 1C:Enterprise má ternární operátor syntaxi:
? (logický výraz, výraz 1, výraz 2)Široce používané jako zkratka pro konstrukty Если <логическое выражение> Тогда ... Иначе ... КонецЕсли
Ve verzi platformy 7.7 bylo možné použít ternární operátor na pravé straně operátoru přiřazení [6] .
V Haskell je operátor větve if podmíněný výraz: výraz else je povinný a musí být stejného typu jako výraz then. Také ve standardní knihovně Data.Bool [7] je funkce bool, která vrací jeden ze dvou výrazů v závislosti na hodnotě predikátu.
Ternární operaci ve své obvyklé formě lze definovat jako infixovou funkci pomocí porovnávání vzorů (typy jsou volitelné):
( ? ) :: Bool -> a -> a -> a ( ? ) Pravda a _ = a ( ? ) Nepravda _ b = bnebo prostřednictvím jakékoli operace rozvětvení, jako například v případě:
( ? ) predikát thenVýraz jinakVýraz = if predikát thenVýraz jinak elseVýraz _ ( ? ) predikát thenVýraz elseVýraz = case predikát of { Pravda -> potomVýraz ; _ -> elseExpr }Protože (?) je infixová (binární) funkce, vezme první 2 argumenty a vrátí funkci jednoho argumentu. Chcete-li jej použít na třetí argument, použije se aplikace ($):
pravda ? "pak" $ "jinak" > "pak" falešné ? "pak" $ "else" > "jinak"