Ternární podmíněný provoz

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.

Příklady

Symbol Kronecker :

y = x == 0 ? 1 : 0.

Minimum čísel a a b:

min = (a < b) ? a : b

Lze 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.

Jazyky podobné C

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

Python používá syntaxiif-else klíčových slov :

a = 42 b = 41 výsledek = a pokud a > b jinak b tvrzení výsledek == 42

Můž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

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' ;

Visual Basic

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 Function

Chcete-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 FalsePart

S 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]

Vložený jazyk 1C

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] .

Haskell

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 = b

nebo 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"

Poznámky

  1. Ternární operátor BCPL (strana 15) (odkaz není k dispozici) . Referenční příručka BCPL . Získáno 8. května 2009. Archivováno z originálu dne 31. března 2012. 
  2. Yu. Yu. Gromov , S. I. Tatarenko . 1.3.12. Podmíněný provoz // Programování v jazyce C / Recenzent: Profesor A. P. Afanasiev . Archivováno 14. dubna 2009 na Wayback Machine
  3. B. Stroustrup . 7.13. Podmíněný provoz // Referenční příručka C++ . Archivováno 12. května 2009 na Wayback Machine
  4. Operátor ?: (C#) // https://msdn.microsoft.com/en-us/library/ty67wk28.aspx Archivováno 2. dubna 2015 na Wayback Machine
  5. Prohlášení If (Visual Basic) // https://msdn.microsoft.com/en-us/library/bb513985.aspx Archivováno 2. dubna 2015 na Wayback Machine
  6. Operátor? 1C 7,7 | operátor . Staženo 25. února 2018. Archivováno z originálu 25. února 2018.
  7. Data.Bool . hackage.haskell.org. Získáno 29. dubna 2018. Archivováno z originálu dne 29. dubna 2018.

Literatura

  • Stefan Randy Davis, Chuck Sfer. Kapitola 4. Operátoři // C# 2005 for dummies = C# 2005 for dummies / edited by T. G. Skovorodnikova. - M.-St. Petersburg: Wiley, Dialektika, 2006. - S. 83. - ISBN 5-8459-1068-4 .