Ternær betinget operation

Ternær betinget operation (fra latin  ternarius  - "tredobbelt") er en operation implementeret i mange programmeringssprog, der returnerer sin anden eller tredje operand afhængigt af værdien af ​​det logiske udtryk givet af den første operand. En analog til den ternære betingede operation i matematisk logik og boolsk algebra er den betingede disjunktion , som er skrevet i formen og implementerer algoritmen: "hvis , så ellers ".

Typisk er den ternære betingede operator forbundet med den operator, der ?:bruges i C-lignende programmeringssprog. Faktisk findes lignende operationer med en anden syntaks i mange programmeringssprog, der er langt fra C i syntaks . Populære sprog, der har den ternære betingede operator indbygget i deres syntaks, er C , C++ , JavaScript , Objective-C , C# , D , Java , ECMAScript , Perl , PHP , Python , Tcl , Ruby , Verilog, Turbo Basic . Denne operation skylder sin optræden direkte i den ternære infiksform til Algol-60- sproget , hvor det havde en syntaks , og derefter til BCPL -sproget ( ) [1] i stedet for det nu velkendte . Prototypen af ​​denne operation er til gengæld en betinget funktion af Lisp-sproget , skrevet i henhold til reglerne i Lisp i præfiksform og har et vilkårligt antal argumenter. if o1 then o2 else o3o1 -> o2, o3o1 ? o2 : o3cond

Normalt omfatter implementeringen af ​​operationen beregningen af ​​betingelsen og kun et af udtrykkene, hvilket i nogle tilfælde giver udvidede muligheder, for eksempel anses udtrykket x > 0 ? 0 : sqrt(x)for at være korrekt, på trods af at roden ikke er taget fra negative tal.

Eksempler

Kronecker symbol :

y = x == 0 ? 1 : 0.

Minimum af tallene a og b:

min = (a < b) ? a : b

Kan bruges i en ikke-opgavesituation:

sprintf ( titel , "%s %s" , tv_system == TV_PAL ? PAL : SECAM , tv_indgang ? Tv_Name [ tv_input - 1 ] : "PRØVE" );

- i dette tilfælde ville den ækvivalente konstruktion ved hjælp af if-then-else kræve, at funktionskaldet skrives sprintffire gange.

C-lignende sprog

Basic C har ikke en boolesk datatype ( C99 introducerede den booleske _Bool-type), så den første operand skal være et tal ( heltal eller reelt ) eller en pointer [2] ; først beregnes dens værdi og sammenlignes med nul , og hvis den ikke er lig med nul, beregnes den anden operand og returneres, i tilfælde af lighed - den tredje. Den anden og tredje operand kan være af forskellige typer (inklusive void ).

I C++ har den ternære betingede operator samme syntaks som i C [3] , men på grund af forskellen mellem initialisering og tildeling er der situationer, hvor operationen ?:ikke kan erstattes af en konstruktion if-then-else, som for eksempel i det følgende sag:

#include <iostream> #include <fstream> #inkluder <streng> bruger navneområde std ; int main ( int argc , char ** argv ) { strengnavn ; _ udstrøms fout ; if ( argc > 1 && argv [ 1 ]) { navn = argv [ 1 ]; fout . åben ( navn.c_str ( ), ios :: ud | ios :: app ) ; } ostream & sout = navn . tom () ? cout : fout ; returnere 0 ; }

Her initialiseres variablen sout i det øjeblik, resultatet af den ternære operation erklæres. En lignende effekt kunne ikke opnås ved en simpel opgave i det ene eller det andet tilfælde.

Derudover kan den ternære betingede operator anvendes i venstre side af en tildelingserklæring:

#include <iostream> int main () { int a = 0 , b = 0 ; const bool cond = ...; ( kond a : b ) = 1 ; _ std :: cout << "a=" << a << ',' << "b=" << b << '\n' ; }

I dette eksempel, hvis den boolske variabel cond på linje 5 indeholder værdien sand, vil værdien 1 blive tildelt variabel a, ellers vil den blive tildelt variabel b.

I C# har den ternære operatør yderligere begrænsninger relateret til typesikkerhed. Udtryk 1 og 2 skal være af samme type. Dette resulterer i følgende:

int a = 1 ; dobbelt b = 0,0 ; int nMax = ( a > b ) ? a : b ;

En sådan kildekode vil ikke kompilere på trods af, at nMax ender med at blive en . Da a og b skal være af samme type, vil a blive rykket op til dobbelt for at matche b . Typen af ​​den resulterende værdi af den ternære operation er dobbelt, og denne type skal nedkastes til int ved tildeling: [4]

int a = 1 ; dobbelt b = 0,0 ; int nMax ; // Du kan gøre dette: nMax = ( int ) (( a > b ) ? a : b ) ; // ...eller så nMax = ( a > b ) ? a : ( int ) b ;

Python

Python bruger søgeordssyntaksif-else :

a = 42 b = 41 resultat = a hvis a > b andet b hævde resultat == 42

Det kan også implementeres via en liste:

[ < udtryk 1 > , < udtryk 2 > ][ < betingelse > ]

- resultatet af udtryk 1 vil blive returneret, hvis betingelsen er falsk; og udtryk 2, hvis betingelsen er sand. Hvis betingelsen ikke er et boolesk udtryk, er det muligt at overløbe listen med en undtagelse.

PHP

PHP bruger en C -lignende syntaks:

$a = $b == 1 ? "første værdi" : ( $b == 2 ? "anden værdi" : ( $b == 3 ? "resultatværdi" : "standardværdi" ));

Den ternære operator i PHP svarer til den længere if-else-konstruktion. Følgende to eksempler er ækvivalente:

//Første eksempel $result = isset ( $a ) ? $a : 'DefaultValue' ; //Andet eksempel if ( isset ( $a )) { $result = $a ; } else { $result = 'DefaultValue' ; }

Sådanne konstruktioner bruges ofte til at initialisere en variabel alligevel til efterfølgende beregninger (ellers vil PHP afgive en E_NOTICE-niveaufejl).

Fra version 5.3 blev det muligt ikke at angive den anden parameter for operationen. For eksempel er følgende to poster ækvivalente:

$Variable = $_GET [ 'Parameter' ] ? $_GET [ 'Parameter' ] : 'DefaultValue' ; $Variable = $_GET [ 'Parameter' ] ?: 'DefaultValue' ;

Visual Basic

I den klassiske version af Visual Basic eksisterer den ternære operator som en funktion IIf(Expr, TruePart, FalsePart). Denne funktion har en funktion: når udtrykket evalueres Expr, vil det også blive beregnet TruePartog FalsePart, uanset resultatet af udtrykket: sandt eller falsk. Dette kan føre til uventede resultater og nogle gange til langsom kodeudførelse, hvis returværdierne er opkald til funktioner med lange operationer.

Dim iCount As Long Offentlig underhoved ( ) iCount = 1 MsgBox IIf ( 1 = 1 , FuncYes , FuncNo ) 'Variablen iCount vil indeholde "3" fordi begge funktioner vil blive udført MsgBox iCount End Sub Offentlig funktion FuncYes () Som streng iCount = iCount + 1 FuncYes = "Ja " Slutfunktion Offentlig funktion FuncNo () Som streng iCount = iCount + 1 FuncNo = "Nej " Slutfunktion

For at erstatte en funktion IIf, kan du omskrive udtrykket i én linje, men dette vil ikke være en analog af funktionen, men vil kun være en kort form af grenoperatoren

If Expr Then TruePart Else FalsePart

Med fremkomsten af ​​VB.NET blev den velkendte ternære operator inkluderet i sprogets syntaks og er skrevet som If(Expr, TruePart, FalsePart). Denne operatør bruger reducerede beregninger i modsætning til funktionen IIf, som også er tilgængelig for udvikleren for kompatibilitet med tidligere versioner. [5]

Indlejret sprog 1C

I konfigurationssproget på 1C:Enterprise-platformen har den ternære operatør syntaksen:

?(boolesk udtryk, udtryk 1, udtryk 2)

Udbredt som en stenografi for konstruktioner Если <логическое выражение> Тогда ... Иначе ... КонецЕсли
I platformversion 7.7 var det muligt at bruge en ternær operatør på højre side af en tildelingsoperatør [6] .

Haskell

I Haskell er if-grenoperatoren et betinget udtryk: else-udtrykket er påkrævet og skal være af samme type som det daværende udtryk. Også i standardbiblioteket Data.Bool [7] er der en bool-funktion, der returnerer et af to udtryk afhængigt af prædikatets værdi.

En ternær operation i sin sædvanlige form kan defineres som en infix-funktion via mønstermatchning (typer er valgfri):

( ? ) :: Bool -> a -> a -> a ( ? ) Sandt a _ = a ( ? ) Falsk _ b = b

eller gennem enhver forgreningsoperation, såsom hvis eller tilfælde af:

( ? ) prædikat thenExpr elseExpr = hvis prædikat thenExpr elseExpr _ ( ? ) prædikat thenExpr elseExpr = kasusprædikat af { True - > thenExpr ; _ -> andetUdtryk }

Da (?) er en infix (binær) funktion, tager den de første 2 argumenter og returnerer en funktion af et argument. For at anvende det på det tredje argument, bruges applikationen ($):

sandt ? "så" $ "andet" > "så" Falsk ? "så" $ "andet" > "andet"

Noter

  1. BCPL ternær operatør (side 15) (link ikke tilgængeligt) . BCPL referencemanual . Hentet 8. maj 2009. Arkiveret fra originalen 31. marts 2012. 
  2. Yu. Yu. Gromov , S. I. Tatarenko . 1.3.12. Betinget drift // Programmering i C-sprog / Bedømmer: Professor A. P. Afanasiev . Arkiveret 14. april 2009 på Wayback Machine
  3. B. Stroustrup . 7.13. Betinget betjening // C++ referencemanual . Arkiveret 12. maj 2009 på Wayback Machine
  4. Operatør ?: (C#) // https://msdn.microsoft.com/en-us/library/ty67wk28.aspx Arkiveret 2. april 2015 på Wayback Machine
  5. If-erklæring (Visual Basic) // https://msdn.microsoft.com/en-us/library/bb513985.aspx Arkiveret 2. april 2015 på Wayback Machine
  6. Operatør? 1C 7,7 | operatør . Hentet 25. februar 2018. Arkiveret fra originalen 25. februar 2018.
  7. Data.Bool . hackage.haskell.org. Hentet 29. april 2018. Arkiveret fra originalen 29. april 2018.

Litteratur

  • Stefan Randy Davis, Chuck Sfer. Kapitel 4. Operatører // C# 2005 for dummies = C# 2005 for dummies / redigeret af T. G. Skovorodnikova. - M.-St. Petersburg: Wiley, Dialectics, 2006. - S. 83. - ISBN 5-8459-1068-4 .