A hármas feltételes művelet (a latin ternarius szóból - „hármas”) egy sok programozási nyelvben megvalósított művelet, amely az első operandus által adott logikai kifejezés értékétől függően a második vagy harmadik operandust adja vissza . A háromtagú feltételes művelet analógja a matematikai logikában és a Boole-algebrában a feltételes diszjunkció , amely a következő formában van írva, és megvalósítja az algoritmust: " ha , akkor , különben ".
Általában a hármas feltételes operátor a C-szerű programozási nyelvekben ?:használt operátorhoz kapcsolódik. Valójában hasonló, eltérő szintaxisú műveletek léteznek sok olyan programozási nyelvben, amelyek szintaxisában távol állnak a C -től . Azok a népszerű nyelvek, amelyek szintaxisába hármas feltételes operátor van beépítve: C , C++ , JavaScript , Objective-C , C# , D , Java , ECMAScript , Perl , PHP , Python , Tcl , Ruby , Verilog , Turbo Basic . Ez a művelet közvetlenül az Algol-60 nyelvnek köszönheti megjelenését a háromtagú infix formában, amelyben szintaxisa volt , majd a BCPL nyelvnek ( ) [1] a már megszokott helyett . Ennek a műveletnek a prototípusa viszont a Lisp nyelv feltételes függvénye, amelyet a Lisp szabályai szerint írnak előtag formában, és tetszőleges számú argumentummal rendelkezik. if o1 then o2 else o3o1 -> o2, o3o1 ? o2 : o3cond
Általában a művelet végrehajtása magában foglalja a feltétel kiszámítását és csak az egyik kifejezést, ami bizonyos esetekben kiterjesztett lehetőségeket biztosít, például a kifejezés x > 0 ? 0 : sqrt(x)helyesnek tekinthető, annak ellenére, hogy a gyökér nem negatív számokból származik.
Az a és b számok minimuma:
min = (a < b) ? a : bHasználható nem hozzárendelési helyzetben:
sprintf ( cím , "%s %s" , tv_system == TV_PAL ? PAL : SECAM , tv_input ? Tv_Name [ tv_input - 1 ] : "TESZT" );sprintf- ebben az esetben az if-then-else használatával ekvivalens konstrukció a függvényhívás négyszeres megírását igényelné .
A Basic C - nek nincs logikai adattípusa ( a C99 bevezette a logikai _Bool típust), ezért az első operandusnak számnak ( egész vagy valós szám ) vagy mutatónak kell lennie [2] ; először kiszámítja az értékét és összehasonlítja a nullával , és ha nem egyenlő nullával, a második operandust kiszámítja és visszaadja, egyenlőség esetén a harmadikat. A második és harmadik operandus különféle típusú lehet (beleértve a void ).
A C++ -ban a hármas feltételes operátor szintaxisa megegyezik a C-vel [3] , azonban az inicializálás és a hozzárendelés közötti különbség miatt vannak olyan helyzetek, amikor a művelet ?:nem helyettesíthető konstrukcióval if-then-else, mint például az alábbiakban ügy:
#include <iostream> #include <fstream> #include <karakterlánc> névtér használata std ; int main ( int argc , char ** argv ) { karakterláncnév ; _ outstream fout ; if ( argc > 1 && argv [ 1 ]) { név = argv [ 1 ]; fout . open ( name.c_str ( ), ios :: out | ios :: app ) ; } ostream & sout = név . üres () ? cout : fout ; return 0 ; }Itt a változó sout a hármas művelet eredményének deklarálása pillanatában inicializálódik. Hasonló hatást egyik vagy másik esetben nem lehetett elérni egyszerű feladattal.
Ezenkívül a hármas feltételes operátor alkalmazható egy hozzárendelési utasítás bal oldalán:
#include <iostream> int main () { int a = 0 , b = 0 ; const bool cond = ...; ( feltétel ? a : b ) = 1 ; std :: cout << "a=" << a << ',' << "b=" << b << '\n' ; }Ebben a példában, ha a cond logikai változó az 5. sorban tartalmazza a true értéket, akkor az 1-es érték az a változóhoz lesz hozzárendelve, ellenkező esetben a b változóhoz lesz hozzárendelve.
A C# nyelven a hármas operátornak további korlátozásai vannak a típusbiztonsággal kapcsolatban. Az 1. és 2. kifejezésnek azonos típusúnak kell lennie. Ennek eredménye a következő:
int a = 1 ; kettős b = 0,0 ; int nMax = ( a > b ) ? a : b ;Az ilyen forráskód nem fordítható le annak ellenére, hogy az nMax végül egy . Mivel a -nak és b -nek azonos típusúaknak kell lenniük, a- t a rendszer megduplázza, hogy megfeleljen b -nek . A hármas művelet eredő értékének típusa dupla, és ezt a típust hozzárendeléskor int-re kell csökkenteni: [4]
int a = 1 ; kettős b = 0,0 ; int nMax ; // Ezt megteheti: nMax = ( int ) (( a > b ) ? a : b ) ; // ...vagy nMax = ( a > b ) ? a : ( int ) b ;A Python kulcsszó szintaxistif-else használ :
a = 42 b = 41 eredmény = a, ha a > b különben b állítás eredmény == 42Listán keresztül is megvalósítható:
[ < kifejezés 1 > , < kifejezés 2 > ][ < feltétel > ]- az 1. kifejezés eredménye hamis feltétel esetén kerül visszaadásra; és a 2. kifejezést, ha a feltétel igaz. Ha a feltétel nem logikai kifejezés, akkor lehetséges a lista túlcsordulása egy kivétellel.
A PHP C - szerű szintaxist használ:
$a = $b == 1 ? "első érték" : ( $b == 2 ? "második érték" : ( $b == 3 ? "eredményérték" : "alapértelmezett érték" ));A PHP háromtagú operátora egyenértékű a hosszabb if-else konstrukcióval. A következő két példa egyenértékű:
//Első példa $result = isset ( $a ) ? $a : 'DefaultValue' ; //Második példa if ( isset ( $a )) { $eredmény = $a ; } else { $result = 'DefaultValue' ; }Az ilyen konstrukciókat gyakran használják egy változó inicializálására a későbbi számításokhoz (ellenkező esetben a PHP E_NOTICE szintű hibát dob ki).
Az 5.3-as verziótól kezdve lehetővé vált, hogy ne adjuk meg a művelet második paraméterét. Például a következő két bejegyzés egyenértékű:
$Variable = $_GET [ 'Paraméter' ] ? $_GET [ 'Parameter' ] : 'DefaultValue' ; $Variable = $_GET [ 'Parameter' ] ?: 'DefaultValue' ;A Visual Basic klasszikus verziójában a háromtagú operátor függvényként létezik IIf(Expr, TruePart, FalsePart). Ennek a függvénynek van egy tulajdonsága: a kifejezés kiértékelésekor a Exprrendszer is kiszámítja , TruePartés FalseParta kifejezés eredményétől függetlenül: igaz vagy hamis. Ez váratlan eredményekhez, és néha lassú kódvégrehajtáshoz vezethet, ha a visszatérési értékek hosszú műveleteket tartalmazó függvények hívásai.
Dim iCount As Long Nyilvános al - fő () iCount = 1 MsgBox IIf ( 1 = 1 , FuncYes , FuncNo ) 'Az iCount változó "3"-at fog tartalmazni, mert mindkét funkció végrehajtásra kerül MsgBox iCount End Sub Nyilvános függvény FuncYes () Karakterláncként iCount = iCount + 1 FuncYes = "Igen " Funkció befejezése Nyilvános függvény FuncNo () Karakterláncként iCount = iCount + 1 FuncNo = " Nem " VégfüggvényEgy függvény lecseréléséhez IIfátírhatja a kifejezést egy sorban, de ez nem lesz a függvény analógja, hanem csak az elágazás operátorának rövid formája
If Expr then TruePart Else FalsePartA VB.NET megjelenésével az ismerős háromtagú operátor bekerült a nyelv szintaxisába, és így íródott If(Expr, TruePart, FalsePart). Ez az operátor csökkentett számításokat használ, ellentétben a funkcióval IIf, amely szintén elérhető a fejlesztő számára a korábbi verziókkal való kompatibilitás érdekében. [5]
Az 1C:Enterprise platform konfigurációs nyelvében a hármas operátor szintaxisa:
?(logikai kifejezés, 1. kifejezés, 2. kifejezés)Konstrukciók rövidítéseként széles körben használatos Если <логическое выражение> Тогда ... Иначе ... КонецЕсли
A 7.7-es platformverzióban lehetőség nyílt egy háromtagú operátor használatára a hozzárendelési operátor jobb oldalán [6] .
A Haskellben az if branch operátor feltételes kifejezés: az else kifejezés kötelező, és ugyanolyan típusúnak kell lennie, mint a then kifejezés. A Data.Bool [7] szabványos könyvtárban is található egy bool függvény, amely a predikátum értékétől függően két kifejezés egyikét adja vissza.
Egy hármas művelet a szokásos formájában infix függvényként definiálható mintaillesztésen keresztül (a típusok nem kötelezőek):
( ? ) :: Bool -> a -> a -> a ( ? ) Igaz a _ = a ( ? ) Hamis _ b = bvagy bármely elágazási műveleten keresztül, például ha:
( ? ) predikátum thenExpr elseExpr = if predikátum , thenExpr else elseExpr ( ? ) predikátum thenExpr elseExpr = { True - > thenExpr eset predikátuma ; _ -> elseExpr }Mivel (?) egy infix (bináris) függvény, az első 2 argumentumot veszi fel, és egy argumentum függvényét adja vissza. A harmadik argumentumra való alkalmazáshoz a ($) alkalmazást kell használni:
igaz ? "akkor" $ "egyéb" > "akkor" Hamis ? "akkor" $ "egyéb" > "egyéb"