En programmation informatique, l'opérateur conditionnel ternaire est un opérateur ternaire qui renvoie l'une de deux valeurs en fonction d'une expression booléenne. Cet opérateur est également connu sous les noms dopérateur conditionnel, si ternaire, si immédiat ou si en ligne (iif). Bien que de nombreux opérateurs ternaires soient théoriquement possibles, l'opérateur conditionnel est couramment utilisé et les autres opérateurs ternaires sont rares ; c'est pourquoi la variante conditionnelle est généralement désignée comme « l'opérateur ternaire ».
La syntaxe type d'une expression utilisant l'opérateur est la suivante : ou . On peut le lire à haute voix ainsi : « si a, alors b ; sinon c ». La forme est la plus courante, mais il existe d'autres syntaxes. Par exemple, Raku utilise la syntaxe pour éviter toute confusion avec les opérateurs infixes et , alors qu'en Visual Basic, cela prend la forme .
Cette construction apparaît pour la première fois dans CPL, où une syntaxe équivalente pour est a → b, c.
Motifs Tâche La valeur de l'opérateur peut être assignée à une variable. Dans un langage à typage faible, le type de données de la valeur sélectionnée peut déterminer le type de la valeur assignée. Dans un langage à typage fort, les deux expressions de valeur doivent donner lieu à un type compatible avec la variable cible.
Cet opérateur fonctionne de manière similaire aux expressions conditionnelles (if-then-else) dans les langages de programmation fonctionnelle, tels que Scheme, ML, Haskell et XQuery, car dans ces langages, la structure if-then-else constitue une expression et non une instruction.
L'opérateur permet d'initialiser une variable à l'aide d'une seule instruction, alors qu'il faudrait autrement plusieurs instructions. Son utilisation lors de l'affectation d'une variable réduit le risque de bogue lié à une affectation erronée, car la variable affectée n'est déclarée qu'une seule fois.
Par exemple, en Python :
x: str = 'foo' if b else 'bar'
au lieu de :
x: str if b: x = 'foo' else: x = 'bar'
Dans un langage à portée de bloc, une variable doit être déclarée avant l'instruction if-else. Par exemple :
std::string s; if (b) { s = "foo"; } else { s = "bar"; }
L'utilisation de l'opérateur conditionnel simplifie cela :
std::string s = b ? "foo" : "bar";
De plus, comme l'initialisation fait désormais partie de la déclaration, et non plus d'une instruction distincte, l'identificateur peut être une constante. Par exemple :
const std::string s = b ? "foo" : "bar";
Sélecteur de cas L'opérateur conditionnel peut être utilisé pour les sélecteurs de cas. Par exemple :
véhicule = arg == 'B' ? bus : arg == 'A' ? avion : arg == 'T' ? train : arg == 'C' ? car : arg == 'H' ? cheval : pied ;
Variations La syntaxe et la sémantique de l'opérateur varient selon le langage.
Parmi les principales différences, on peut citer la possibilité pour les expressions d'avoir des effets de bord et la présence ou non, dans le langage, d'une sémantique d', selon laquelle seule l'expression sélectionnée est évaluée.
Si un langage prend en charge les expressions ayant des effets de bord mais ne spécifie pas d'évaluation par court-circuit, il existe alors une distinction supplémentaire quant à l'expression qui est évaluée en premier. Si aucun ordre n'est garanti, il faut déterminer si le résultat est alors considéré comme indéterminé (la valeur obtenue selon « un certain » ordre) ou indéfini (n'importe quelle valeur choisie au gré du compilateur face aux effets de bord, voire un plantage).
Si un langage n'autorise pas les effets de bord dans les expressions (ce qui est courant dans les langages fonctionnels), l'ordre d'évaluation n'a alors aucune incidence sémantique — même s'il peut néanmoins déterminer si une récursion infinie s'achève ou avoir d'autres implications en termes de performances (dans un langage fonctionnel utilisant des expressions de correspondance, l'évaluation en court-circuit est inhérente, et les utilisations naturelles de l'opérateur ternaire sont moins fréquentes ; ce point n'est donc pas très préoccupant).
C'est pourquoi, dans certaines langues, la forme de l'énoncé peut avoir une sémantique légèrement différente de celle de la forme conditionnelle en bloc .
Dans presque toutes les langues de programmation, l'opérateur ternaire est à droite, de sorte que se lit intuitivement comme . Cela signifie qu'il peut être enchaîné de la même manière qu'une chaîne if ... else if ... else if ... else. La principale exception est PHP, où l'association se fait par la gauche (de sorte que la même expression donne , ce qui correspond rarement à ce à quoi s'attend le programmeur) avant la version 8, et est non associative par la suite..
De plus, dans tous les langages de la famille C et dans bien d'autres, l'opérateur conditionnel ternaire a une faible priorité.
Équivalence binaire L'opérateur ternaire peut également être considéré comme une opération de correspondance binaire.
En R — et dans d'autres langages prenant en charge les tuples d'expressions littérales, on peut simuler l'opérateur ternaire à l'aide d'une expression R du type (cette expression est légèrement plus naturelle dans les langages utilisant des indices à base 0). Les expressions ternaires imbriquées peuvent être simulées comme suit : où la fonction renvoie l'index de la première valeur vraie dans le vecteur de conditions. Il convient de noter que ces deux équivalents de la fonction map sont des opérateurs binaires, ce qui montre que l'opérateur ternaire est ternaire sur le plan syntaxique, et non sémantique. Ces constructions peuvent être considérées comme une forme atténuée de curryfication reposant sur la concaténation de données plutôt que sur la composition de fonctions.
Si le langage propose un mécanisme de futures ou de promesses, l'évaluation par court-circuit peut parfois être simulée dans le cadre d'une opération de mappage binaire.
Exemples Ada L'édition 2012 d'Ada a introduit les expressions conditionnelles (utilisant et ), dans le cadre d'un ensemble élargi d'expressions comprenant les expressions quantifiées et les fonctions d'expression. La justification d'Ada 2012 explique pourquoi Ada ne les avait pas encore intégrés auparavant, ainsi que les raisons pour lesquelles ils sont désormais ajoutés, notamment pour prendre en charge les « contrats » (une autre nouveauté).
Pay_per_Hour := (if Day = Sunday then 12.50 else 10.00);
Lorsque la valeur d'un if_expression est elle-même de type booléen, alors peut être omis, la valeur étant vraie. Plusieurs conditions peuvent être enchaînées à l'aide de .
Algol 60 Algol 60 a introduit les expressions conditionnelles (conditions ternaires) dans les langages de programmation impérative.
Cette instruction conditionnelle :
integer opening_time; if day = Sunday then opening_time := 12; else opening_time := 9;
On peut l'écrire autrement en utilisant l'opérateur conditionnel :
integer opening_time; opening_time := if day = Sunday then 12 else 9;
Algol 68 Les clauses de sélection d'Algol 68 (clauses « if » et « case ») prennent en charge les éléments suivants :
Clause « single if » ou en forme brève : ( condition | statements | statements )
Clause « if choice » enchaînée ou en forme brève : ( condition1 | statements |: condition2 | statements | statements ).
Bash Il existe un véritable opérateur ternaire pour les expressions arithmétiques :
((result = condition ? value_if_true : value_if_false))
Pour les chaînes de caractères, il existe des solutions de contournement, comme par exemple :
result=$(if condition ; then echo "value_if_true" ; else echo "value_if_false" ; fi)
peut être n'importe quelle commande Bash. Si elle se termine avec succès, la première commande echo est exécutée ; dans le cas contraire, c'est la seconde qui est exécutée.
Famille C Le code C suivant attribue à la valeur de x si a > b, et, par ailleurs, d'une valeur de y. Cette syntaxe est identique à celle de nombreux langages apparentés, notamment le C++, Java, JavaScript et Dart.
result = a > b ? x : y;
Seule l'expression sélectionnée est évaluée. Dans cet exemple, x et y ne nécessitent aucune évaluation, mais peuvent être des expressions ayant des effets de bord. Seul l'effet de bord correspondant à la valeur de l'expression sélectionnée se produiraISO.IEC 9899:1999 (E) 6.5.15.4Java 7 Specification: 15.25 Conditional Operator ? : .
Si x et y sont du même type de données, l'expression conditionnelle est généralement de ce type. Sinon, les règles régissant le type de données résultant varient légèrement d'un langage à l'autre : En C++, les conversions de types arithmétiques habituelles sont effectuées pour convertir x et y en un type commun. Si les deux sont des types de pointeur ou de référence, ou si l'un est un type de pointeur et l'autre une expression constante dont la valeur est 0, des conversions de pointeur ou de référence sont effectuées pour les convertir en un type commun. En C#, si une expression est implicitement convertible vers le type de l'autre, c'est ce type qui est utilisé. Dans le cas contraire, une erreur de compilation se produit. Dans les langages à typage dynamique, l'expression évaluée a le type de l'expression sélectionnée.
De plus, en C++, une expression conditionnelle peut être utilisée comme si à la fois x et y sont des L-lvalues, même si cela est rarement utilisé dans la pratique: (foo ? bar : baz) = frink;
Common Lisp Affectation à l'aide d'une expression conditionnelle en Common Lisp :
(setq result (if (> a b) x y))
Forme alternative :
(if (> a b) (setq result x) (setq result y))
dBASE Dans dBase, la fonction conditionnelle iif(<expL>, <expT>, <expF>) s'appelle « Immediate IF ». Il utilise l'évaluation par raccourci (il n'évalue qu'une seule des ou ).
Fortran Dans le cadre de la norme Fortran 90, l'opérateur ternaire a été intégré à Fortran sous la forme d'une fonction intrinsèque :
variable = merge(x,y,a>b)
Notez que x et y sont tous deux évalués avant que la fonction ne renvoie l'un ou l'autre des résultats. Ici, x est renvoyé si la condition est vraie, et y dans le cas contraire.
Fortran-2023 a introduit des expressions conditionnelles qui évaluent l'une ou l'autre des expressions en fonction de l'expression conditionnelle :
variable = ( a > b ? x : y )
Kotlin Kotlin ne propose pas la syntaxe de l'opérateur ternaire traditionnel , cependant, peut être utilisé comme une expression à laquelle on peut attribuer une valeur et obtenir les mêmes résultats.
val max = if (a > b) a else b
Lua Lua ne dispose pas d'un opérateur conditionnel classique. Cependant, le comportement de court-circuit des opérateurs et permet d'émuler ce comportement. Ce qui suit équivaut à : var = cond ? a : b.
var = cond and a or b
Cela fonctionnera, sauf si est logiquement fausse ; dans ce cas, l'expression donnera toujours . Si on ne tient pas compte de cela, cela peut entraîner des comportements inattendus.
Il existe également d'autres variantes, mais elles sont généralement plus longues :
var = (
[true] = a, [false] = b
)[not not cond]
Luau, un dialecte de Lua, propose des expressions ternaires qui ressemblent à des instructions « if », mais contrairement à celles-ci, elles ne comportent aucun mot-clé , et la clause est requise. On peut, si on le souhaite, ajouter les clauses . Il est conçu pour remplacer l'idiome et devrait fonctionner correctement dans tous les cas.
-- in Luau var = if cond then a else b
-- with elseif clause sign = if var < 0 then -1 elseif var == 0 then 0 else 1
Pascal Pascal constituait à la fois une simplification et une extension d'Algol 60 (principalement pour la gestion des types définis par l'utilisateur). L'une de ces simplifications consistait à supprimer l'expression conditionnelle, car le même résultat pouvait être obtenu à l'aide de la forme moins concise de l'instruction conditionnelle.