IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Cours complet pour apprendre à programmer en D


précédentsommairesuivant

27. L'opérateur ternaire « ? »:

L'opérateur ternaire ? : a un fonctionnement très similaire de celui de l'instruction if-else :

 
Sélectionnez
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 :

 
Sélectionnez
/* 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électionnez
    int 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électionnez
    int 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électionnez
    int jours = 365;
     
    if (estAnneeBissextile) {
         ++jours;
    }
  • Affichage. Afficher un message différemment selon une condition :

     
    Sélectionnez
    writeln("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électionnez
    write("Le verre est à moitié ");
     
    if (estOptimiste) {
        writeln("plein.");
     
    } else {
        writeln("vide.");
    }
  • Ou alors, le message entier peut être affiché séparément :

     
    Sélectionnez
    if (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électionnez
    score += estGammon ? 2 : 1;
  • Transposition directe avec if :

     
    Sélectionnez
    if (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 :
 
Sélectionnez
++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 ?:

 
Sélectionnez
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é :

 
Sélectionnez
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.

La solutionL'opérateur ternaire « ? »: - Correction.


précédentsommairesuivant