27. L'opérateur ternaire « ? »: ▲
L'opérateur ternaire ? : a un fonctionnement très similaire de celui de l'instruction if-else :
if
(
/* condition */
) {
/* ... expression(s) à exécuter si vrai */
}
else
{
/* ... expression(s) à exécuter si faux */
}
L'instruction if exécute soit le bloc correspondant au cas où la condition est vraie, soit le bloc correspondant au cas où la condition est fausse. Comme vous devez vous en rappeler, étant une instruction, elle n'a pas de valeur ; if affecte principalement l'exécution des blocs de code.
En revanche, l'opérateur ? : est une expression. En plus de fonctionner d'une manière similaire à l'instruction if-else, il produit une valeur. Ce qui suit est un équivalent du code ci-dessus :
/* condition */
? /* expression si vrai */
: /* expression si faux */
L'opérateur ? : utilise trois expressions, d'où son nom d'opérateur ternaire.
La valeur qui est produite par cet opérateur est soit la valeur de l'expression si vrai, soit celle de l'expression si faux. Du fait que c'est une expression, il peut être utilisé partout où les expressions peuvent être utilisées.
Les exemples suivants comparent l'opérateur ? : et l'instruction if-else. L'opérateur ternaire est plus concis dans les cas similaires à ces exemples.
-
Initialisation. Pour initialiser à 366 s'il s'agit d'une année bissextile, à 365 sinon :
Sélectionnezint
jours=
estAnneeBissextile ?366
:365
; -
Avec if, une façon de faire est de définir la variable sans valeur initiale explicite et d'affecter la valeur voulue :
Sélectionnezint
jours;if
(
estAnneeBissextile){
jours=
366
;}
else
{
jours=
365
;}
-
Une variante avec if est d'initialiser la variable avec la valeur des années non bissextiles et de l'incrémenter s'il s'agit d'une année bissextile :
Sélectionnezint
jours=
365
;if
(
estAnneeBissextile){
++
jours;}
-
Affichage. Afficher un message différemment selon une condition :
Sélectionnezwriteln
(
"Le verre est à moitié "
, estOptimiste ?"plein."
:"vide."
); -
Avec if, la première et la dernière parties peuvent être affichées séparément :
Sélectionnezwrite
(
"Le verre est à moitié "
);if
(
estOptimiste){
writeln
(
"plein."
);}
else
{
writeln
(
"vide."
);}
-
Ou alors, le message entier peut être affiché séparément :
Sélectionnezif
(
estOptimiste){
writeln
(
"Le verre est à moitié plein."
);}
else
{
writeln
(
"Le verre est à moitié vide."
);}
-
Calcul. Augmenter le score d'un gagnant au backgammon de 2 points ou 1 point selon que le jeu s'est fini sur un gammon ou pas :
Sélectionnezscore
+=
estGammon ?2
:1
; -
Transposition directe avec if :
Sélectionnezif
(
estGammon){
score+=
2
;}
else
{
score+=
1
;}
- Ou alors, on peut d'abord incrémenter de 1 et incrémenter une seconde fois s'il y a eu gammon :
++
score;
if
(
estGammon) {
++
score;
}
Comme on peut le voir dans les exemples précédents, le code est plus concis et plus clair avec l'opérateur ternaire dans certaines situations.
27-1. Les types des expressions de sélection doivent correspondre▲
La valeur de l'opérateur ? : est soit la valeur de l'expression si vrai, soit la valeur de l'expression si faux. Les types de ces expressions n'ont pas besoin d'être les mêmes, mais ils doivent correspondre. Par exemple, ils peuvent être tous deux de type entier comme int et long, mais ne peuvent pas être de types qui ne se correspondent pas, comme int et string.
Dans les exemples précédents, les valeurs sélectionnées selon la valeur de estAnneeBissextile étaient 366 et 365. Les deux valeurs sont du type int et se correspondent.
Pour voir une erreur de compilation causée par des valeurs des expressions ne correspondant pas, considérons la composition d'un message qui rapporte le nombre d'objets à expédier. Affichons « Une douzaine » quand la valeur est 12 : « Une douzaine d'objets seront expédiés ». Dans les autres cas, on affiche le nombre exact : « 3 objets seront expédiés ».
On pourrait penser que la partie variable du message peut être sélectionnée avec l'opérateur ?:
writeln
((
nombre ==
12
) ? "Une douzaine d'"
: nombre, // ← ERREUR de compilation
" objets seront expédiés."
);
Les expressions ne correspondent pas parce que le type de "Une douzaine d'" est string et le type de nombre est int.
Une solution est de convertir nombre en string. La fonction to!string du module std.conv donne une valeur de type string depuis le paramètre donné :
import
std.conv;
// ...
writeln
((
nombre ==
12
) ? "Une douzaine d'"
: to!
string
(
nombre),
" objets seront expédiés."
);
Maintenant que les expressions de sélection de l'opérateur ? sont toutes deux du type string, le code compile et affiche le message attendu.
27-2. Exercice▲
Le programme doit lire une valeur nette de type int. Quand cette valeur est positive, on l'interprète comme un gain et quand elle est négative, on l'interprète comme une perte.
Le programme doit afficher un message qui contient « gagnés » ou « perdus », selon que la quantité est positive ou négative. Par exemple, « 100 € gagnés » ou « 70 € perdus ». Même s'il se peut que ce soit plus approprié, n'utilisez pas l'instruction if dans cet exercice.