Conditions

Jusque là nos programmes suivent un cours linéaire : les instructions sont exécutées les unes à la suite des autres, sans aucune variation possible dans le scénario.

Pour remédier à cela, il faut commencer par apprendre comment distinguer entre plusieurs situations. On y parvient en écrivant des conditions : des expressions qui peuvent donner un résultat soit vrai, soit faux.

Les conditions les plus simples sont les comparaisons.

int test = x < 0.0;
Dans ce fragment de code source, si la valeur placée dans la variable x est positive, la condition est fausse. La variable test reçoit alors 0. Dans le cas contraire, la condition est vraie, et test reçoit 1.

Remarque Le résultat d'une condition est toujours de type int, même si on compare des réels. Un int qui vaut 0 est considéré comme faux. Un int qui ne vaut pas 0 est considéré comme vrai.

Il existe six opérateurs de comparaison :

test = x <  0.0;    /* inférieur         */
test = x <= 0.0;    /* inférieur ou égal */
test = x >  0.0;    /* supérieur         */
test = x >= 0.0;    /* supérieur ou égal */
test = x == 0.0;    /* égal              */
test = x != 0.0;    /* différent         */
Ils peuvent servir à comparer n'importe quelles expressions, mais le résultat de l'expression de gauche doit être du même type que le résultat de l'expression de droite (comme pour les autres opérateurs).

Les opérateurs logiques servent à combiner plusieurs conditions pour en former une seule.

test = (x <= 2.0) && (x >= 1.0);
Le && désigne le «et logique», à ne surtout pas confondre avec le «et bit-à-bit» (noté &). Ici, le test ne sera vrai que si les deux sous-conditions sont vraies.

Le «ou logique» est noté ||, et le «non logique» est noté !.

test = !((x > 2.0) || (x < 1.0));

Nous savons à présent construire une condition, il est temps de voir à quoi cela peut servir.

int m = (n < 0) ? -n : n;
La valeur affectée à m est le résultat d'une expression conditionnelle. Le symbole ? et le symbole : forment un opérateur ternaire, c'est à dire un opérateur à trois opérandes. La première opérande (placée avant le ?) est une condition qui doit être évaluée. Au cas où la condition est vraie, le résultat de toute l'expression est égal au résultat de l'expression qui est immédiatement après le ? (le deuxième opérande). Dans le cas contraire, il est égal au résultat de l'expression immédiatement après le : (le troisième opérande).

Dans cet exemple, il est facile de voir que m recevra ainsi dans tous les cas la valeur absolue de n.

Ceci permet de choisir entre deux formules en fonction de la situation. On peut en théorie combiner plusieurs opérateurs ternaires pour distinguer plus de deux cas, mais cela devient vite illisible.

Si l'opérateur conditionnel permet de choisir entre deux expressions, la structure conditionnelle permet de choisir entre deux instructions.

if (n < 0) 
  printf("négatif");
else
  printf("positif");
Dans le cas où la variable n contient une valeur négative, le programme affichera négatif. Si au contraire n est de valeur positive ou nulle, le programme affichera positif. Il n'existe aucune circonstance où les deux mots seront affichés. C'est soit l'un, soit l'autre.

Dans la structure conditionnelle, on trouve :

  • le mot-clé if (si en anglais)
  • une condition (obligatoirement entre parenthèses)
  • une instruction à exécuter seulement si la condition est vraie (la conséquence)
  • le mot-clé else (sinon en anglais)
  • une instruction à exécuter seulement si la condition est fausse (l'alternative)
Vous pouvez omettre les deux derniers éléments si vous n'avez rien besoin d'exécuter au cas où la condition est fausse.
if (note >= 10.0f) 
  printf("Vous êtes diplômé !");

Le défaut de la structure conditionnelle, c'est que l'on ne peut mettre qu'une seule instruction comme conséquence ou comme alternative. Nous allons contourner cette limitation en utilisant des blocs.

if (note >= 10.0f) { 
  printf("Vous êtes diplômé !\n");
  printf("Félicitations !\n");
}
Un bloc commence par { et se termine par }. Entre les deux, vous pouvez placer autant d'instructions que vous voulez. Le tout ne compte que comme une seule instruction.

Remarque Nous utilisons déjà des accolades dans nos programmes pour délimiter la partie qui contient les instructions. C'est exactement le même principe.

Chaque début de bloc peut accueillir des déclarations de variables. Cependant, une variable définie dans un bloc n'existe que dans ce bloc : la mémoire correspondante est réservée en entrant dans le bloc, et libérée en le quittant.

  1. Billevesées. Compilez et exécutez le programme suivant. Pouvez-vous expliquer ce qui se passe ?

    int main(void) {
      int x=3;               
     
      if (x=2) {
        printf("x vaut 2\n");   
      } else {
        printf("x est different de 2\n");              
      }
     
      printf("%d\n", x);                                          
     
      if (x=0) {
        printf("x vaut 0\n");                                         
      } else {
        printf("x est different de 0\n");          
      }
     
      printf("%d\n", x);                                          
     
      return EXIT_SUCCESS;
    }

  2. Triple. Écrivez un programme qui demande un entier naturel, puis affiche le multiple de 3 dont il est le plus proche.

  3. Produit. Écrivez un programme qui demande deux réels, puis affiche le signe de leur produit sans faire la multiplication.

  4. Ordre. Écrivez un programme qui demande trois valeurs entières, puis les affiche dans l'ordre croissant.

    Combien de comparaisons faut-il au maximum à votre programme pour trouver le bon ordre ? Améliorez votre code de façon à ne jamais en utiliser plus de trois par exécution.

  5. Bissextile. Écrivez un programme qui affiche si une année est bissextile. On supposera que l'année à considérer est disponible dans une constante du préprocesseur. Pour simplifier, une année sera considérée comme bissextile si elle est multiple de 4 mais pas de 100, ou si elle est multiple de 400.

    Deux versions du programme sont demandées. Dans la première version, vous ne devez pas employer d'opérateur logique. Dans la deuxième version, les opérateurs logiques sont admis mais vous ne devez employer qu'un seul if.

retour à la page d'accueil

retour au sommet