La operación condicional ternaria (del latín ternarius - "triple") es una operación implementada en muchos lenguajes de programación que devuelve su segundo o tercer operando según el valor de la expresión lógica dada por el primer operando. Un análogo de la operación condicional ternaria en lógica matemática y álgebra booleana es la disyunción condicional , que se escribe en la forma e implementa el algoritmo: "si , entonces , de otra manera ".
Por lo general, el operador condicional ternario se asocia con el operador ?:utilizado en lenguajes de programación tipo C. Los lenguajes populares que tienen el operador condicional ternario integrado en su sintaxis son C , C++ , JavaScript , Objective-C , C# , D , Java , ECMAScript , Perl , PHP , Python , Tcl , Ruby , Verilog , Turbo Basic . Esta operación debe su aparición directamente en forma de infijo ternario al lenguaje Algol-60 , en el que tenía una sintaxis , y luego al lenguaje BCPL ( ) [1] en lugar del ahora familiar . El prototipo de esta operación, a su vez, es una función condicional del lenguaje Lisp , escrita según las reglas de Lisp en forma de prefijo y con un número arbitrario de argumentos. if o1 then o2 else o3o1 -> o2, o3o1 ? o2 : o3cond
Por lo general, la implementación de la operación incluye el cálculo de la condición y solo una de las expresiones, lo que en algunos casos brinda capacidades extendidas, por ejemplo, la expresión x > 0 ? 0 : sqrt(x)se considera correcta, a pesar de que la raíz no se toma de números negativos.
Mínimo de números a y b:
min = (a < b) ? a : bSe puede utilizar en una situación de no asignación:
carrera de velocidad ( titulo , "%s%s" , sistema_tv == TV_PAL ? amigo : SECAM , entrada_tv ? Nombre_TV [ entrada_tv - 1 ] : "PRUEBA" );- en este caso, la construcción equivalente usando if-then-else requeriría que la llamada a la función se escribiera sprintfcuatro veces.
C básico no tiene un tipo de datos booleano ( C99 introdujo el tipo booleano _Bool), por lo que el primer operando debe ser un número ( entero o real ) o un puntero [2] ; primero, se calcula su valor y se compara con cero , y si no es igual a cero, se calcula y devuelve el segundo operando, en caso de igualdad, el tercero. Los operandos segundo y tercero pueden ser de varios tipos (incluido void ).
En C++ , el operador condicional ternario tiene la misma sintaxis que en C [3] , sin embargo, debido a la diferencia entre inicialización y asignación , hay situaciones en las que la operación ?:no puede ser reemplazada por una construcción if-then-else, como, por ejemplo, en la siguiente caso:
#incluir <iostream> #incluir <fstream> #incluir <cadena> utilizando el espacio de nombres estándar ; int principal ( int argc , char ** argv ) { nombre de la cadena ; _ outstream fout ; si ( argc > 1 && argv [ 1 ]) { nombre = argv [ 1 ]; fuera _ abrir ( nombre.c_str ( ), ios :: fuera | ios :: aplicación ) ; } ostream & sout = nombre . vacío () ? cout : fuera ; devolver 0 ; }Aquí la variable sout se inicializa en el momento en que se declara el resultado de la operación ternaria. Un efecto similar no podría lograrse mediante una simple cesión en un caso u otro.
Además, el operador condicional ternario se puede aplicar en el lado izquierdo de una instrucción de asignación:
#incluir <iostream> int principal () { int a = 0 , b = 0 ; const bool cond = ...; ( cond ? a : b ) = 1 ; std :: cout << "a=" << a << ',' << "b=" << b << '\n' ; }En este ejemplo, si la variable booleana cond en la línea 5 contiene el valor verdadero, entonces el valor 1 se asignará a la variable a; de lo contrario, se asignará a la variable b.
En C# , el operador ternario tiene restricciones adicionales relacionadas con la seguridad de tipos. Las expresiones 1 y 2 deben ser del mismo tipo. Esto da como resultado lo siguiente:
int a = 1 ; doble b = 0,0 ; int nMax = ( a > b ) ? un : b ;Dicho código fuente no se compilará a pesar de que nMax terminará siendo un archivo . Dado que a y b deben ser del mismo tipo, a se promocionará al doble para que coincida con b .
int a = 1 ; doble b = 0,0 ; int nMáx ; // Puedes hacer esto: nMax = ( int ) (( a > b ) ? a : b ) ; // ...más o menos nMax = ( a > b ) ? a : ( int ) b ;Python usa sintaxis deif-else palabras clave :
a = 42 b = 41 resultado = a si a > b sino b afirmar resultado == 42También se puede implementar a través de una lista:
[ < vista 1 > , < vista 2 > ][ < vista > ]- se devolverá el resultado de la expresión 1 si la condición es falsa; y la expresión 2 si la condición es verdadera. Si la condición no es una expresión booleana, es posible desbordar la lista con una excepción.
PHP usa una sintaxis similar a C :
$a = $b == 1 ? "primer valor" : ( $b == 2 ? "segundo valor" : ( $b == 3 ? "valor de resultado" : "valor predeterminado" ));El operador ternario en PHP es equivalente a la construcción if-else más larga. Los dos ejemplos siguientes son equivalentes:
//Primer ejemplo $resultado = isset ( $a ) ? $a : 'Valor predeterminado' ; //Segundo ejemplo if ( isset ( $a )) { $resultado = $a ; } else { $resultado = 'ValorPredeterminado' ; }Tales construcciones se usan a menudo para inicializar una variable de todos modos para cálculos posteriores (de lo contrario, PHP arrojará un error de nivel E_NOTICE).
A partir de la versión 5.3, se hizo posible no especificar el segundo parámetro de la operación. Por ejemplo, las dos entradas siguientes son equivalentes:
$_GET [ 'Parámetro' ] : 'ValorPredeterminado' ;En la versión clásica de Visual Basic , el operador ternario existe como una función IIf(Expr, TruePart, FalsePart). Esto puede conducir a resultados inesperados y, en ocasiones, a una ejecución lenta del código, si los valores devueltos son llamadas a funciones con operaciones largas. ExprTruePartFalsePart
Dim iCuento tan largo Public Sub Main () iCount = 1 MsgBox IIf ( 1 = 1 , FuncYes , FuncNo ) 'La variable iCount contendrá "3" porque ambas funciones serán ejecutadas MsgBox iCount End Sub Función pública FuncYes () As String iCount = iCount + 1 FuncYes = "Sí" Función final Función pública FuncNo () As String iCount = iCount + 1 FuncNo = "No" End FunctionPara reemplazar una función IIf, puede reescribir la expresión en una línea, pero esto no será un análogo de la función, sino que será solo una forma abreviada del operador de rama
If Expr Entonces TruePart Else FalsePartCon la llegada de VB.NET , el conocido operador ternario se incluyó en la sintaxis del lenguaje y se escribe como If(Expr, TruePart, FalsePart). Este operador utiliza cálculos reducidos, en contraste con la función IIf, que también está disponible para el desarrollador por compatibilidad con versiones anteriores. [5]
En el lenguaje de configuración de la plataforma 1C:Enterprise, el operador ternario tiene la sintaxis:
?(expresión booleana, expresión 1, expresión 2)Ampliamente utilizado como abreviatura de construcciones Если <логическое выражение> Тогда ... Иначе ... КонецЕсли
En la versión 7.7 de la plataforma, era posible utilizar un operador ternario en el lado derecho de un operador de asignación [6] .
En Haskell , el operador de bifurcación if es una expresión condicional: se requiere la expresión else y debe ser del mismo tipo que la expresión then. También en la biblioteca estándar Data.Bool [7] hay una función bool que devuelve una de dos expresiones dependiendo del valor del predicado.
Una operación ternaria en su forma habitual se puede definir como una función infija a través de la coincidencia de patrones (los tipos son opcionales):
( ? ) :: Bool -> a -> a -> a ( ? ) Verdadero a _ = a ( ? ) Falso _ b = bo a través de cualquier operación de sucursal, tal como si o caso de:
( ? ) predicado entonces Expr otra vez Expr = si predicado entonces luego Expr otra cosa otra Expr ( ? ) predicado entoncesExpr elseExpr = caso predicado de { Verdadero - > entoncesExpr ; _ -> otraExpr }Dado que (?) es una función infija (binaria), toma los primeros 2 argumentos y devuelve una función de un argumento. Para aplicarlo al tercer argumento se utiliza la aplicación ($):
verdad ? "entonces" $ "más" > "entonces" falso ? "entonces" $ "más" > "más"