Les structures conditionnelles (if et switch) en C++ (C++17 et C++20)

18 Mar 2022 18 Mar 2022 4787 vues ESSADDOUKI Mostafa 10 min de lecture
Introduction et syntaxe de base
1 Introduction au langage C++ 2 Entrée-sortie en C++ - cin et cout 3 Inférence de type avec le mot-clé auto en C++ 4 Classe std::string et les chaînes de caractères en C++ 5 Les structures conditionnelles (if et switch) en C++ (C++17 et C++20) 6 Les boucles en C++ (C++17 et C++20) 7 La gestion des fichiers en C++
Pointeurs et fonctions
8 Introduction aux pointeurs en C++ - Déclaration et interêts 9 Les références en C++ - déclaration et interêts 10 Les tableaux en C++ - Déclaration et interêts 11 Introduction aux fonctions en C++ 12 Passer des arguments à une fonction en C++ 13 Déclarer un paramètre const en C++ 14 Les fonctions Lambda en C++ 15 Fonctions utiles (Mathématiques et caractères) en C++
Programmation OO
16 Classes et objets en C++ 17 Spécificateurs d'accès en C++ 18 Constructeurs et destructeur d'une classe en C++ 19 Fonctions membres en C++ 20 Membres statiques d'une classe en C++ 21 Fonctions en ligne en C++ - inline 22 Fonctions et classes amies en C++ - friend 23 Surcharge des fonctions en C++ 24 Surcharge des opérateurs en C++ 25 Héritage en C++ 26 La gestion d'exceptions en C++ : déclaration, utilisation et personnalisation 27 fonctions et classes templates en C++ 28 Les nouveautés C++20 pour améliorer les templates en C++
Structures de données
29 Introduction aux structures de données 30 Les structures en C++ et la différence avec les structures en C 31 Les listes chaînées en C++ 32 Les piles en C++ 33 File d'attente en C++ 34 Arbre binaire de recherche : définition et mise en oeuvre en C++
La bibliothèque standard (STL)
35 Introduction à la bibliothèque de Template Standard STL 36 Les itérateurs en C++ - définition, déclaration et exemples 37 La classe array en C++ (bibliothèque STL) <array> 38 La classe vector de la bibliothèque STL <vector> 39 La classe deque en C++ ( Bibliothèque STL) 40 La classe list en C++ (bibliothèque STL) <list> 41 La classe stack (Pile) en C++ (bibliothèque STL) <stack> 42 La classe queue (File d'attente) en C++ (bibliothèque STL) <queue> 43 La file d'attente prioritaire (classe priority_queue) - Bibliothèque STL 44 Les ensembles en C++ (Classe set <set> - Bibliothèque STL) 45 Les dictionnaires en C++ : Classe map (Bibliothèque STL) 46 Introduction aux algorithmes de la bibliothèque STL (programmation compétitive) 47 Tri et méthodes associées en C++ - Bibliothèque STL 48 Recherche dichotomique et méthodes associées en C++ - Bibliothèque STL 49 Appliquer un prédicat ou une fonction aux éléments d'une séquence en C++ - Bibliothèque STL 50 Recherche dans une séquence et méthodes associées en C++ - Bibliothèque STL

Les structures de contrôle conditionnelles

Pourquoi des conditions ?

Certains problèmes ne peuvent pas être résolus avec seulement une séquence d'instructions simples. Parfois, nous devons tester une condition. Si le résultat du test est vrai, nous suivons une séquence d'instructions ; s'il est faux, nous suivons une séquence d'instructions différente.

C'est ce qu'on appelle la construction conditionnelle (ou décisionnelle).

1. Structure de contrôle if-else

Principe

L'instruction if ne s'exécutera que si l'expression entre parenthèses est évaluée comme étant true.

En C++, il n'est pas nécessaire que ce soit une expression booléenne. Il peut s'agir de n'importe quelle expression qui évalue un nombre :

  • zéro (0) est considéré comme false
  • tous les autres nombres sont considérés comme true

Syntaxe de base

   
Syntaxe if simple C++
if (/* expression */) {
    /* Exécuté uniquement si l'expression est vraie */
}

Exemple 1 : if simple

if (x > 1) {
    cout << x << " > 1";
}

Extension avec else if

Pour tester d'autres conditions, l'instruction if peut être étendue par n'importe quel nombre d'instructions else if.

Exemple 2 : else if

else if (x < 1) {
    cout << x << " < 1";
}

Clause else finale

L'instruction if peut avoir une instruction else facultative à la fin, qui s'exécutera si toutes les conditions précédentes sont fausses.

Exemple 3 : else

else {
    cout << x << " = 1";
}

Syntaxe complète

   
Syntaxe complète if-else C++
if (condition-1) {
    // Exécuté seulement si condition-1 est vraie
} else if (condition-2) {  // optionnel
    // Exécuté seulement si condition-2 est vraie
}
    // ... autant de "else if" que souhaité
} else {  // optionnel
    // Exécuté seulement si aucune condition n'est vraie
}

Exemple 4 : Structure complète

if (x < 1)
    cout << x << " < 1";
else if (x > 1)
    cout << x << " > 1";
else
    cout << x << " == 1";
À propos des accolades

Les accolades peuvent être omises si une seule instruction doit être exécutée de manière conditionnelle. Cependant, il est considéré comme une bonne pratique de les inclure car elles améliorent la lisibilité du code et évitent les erreurs.

Nouveauté C++17 : if avec initialiseur

Introduction C++17

Avec la norme C++17, la syntaxe de if a été modifiée par l'introduction de l'instruction init. Vous pouvez lier la portée d'un objet à une instruction if en ajoutant une instruction init.

   
Syntaxe if avec initialiseur C++17
if (init; condition-1) {
    // Exécuté seulement si condition-1 est vraie
} else if (init; condition-2) { 
    // Exécuté seulement si condition-2 est vraie
}

La partie init est facultative. Si elle est manquante, nous avons la forme traditionnelle.

Exemple 5 : Avant C++17

#include <iostream>
#include <cstdlib>

using namespace std;

int main() {
    srand(time(NULL));
    int nombre_alea = rand();

    if (nombre_alea % 2 == 0) {
        cout << nombre_alea << " est pair\n";
    } else {
        cout << nombre_alea << " est impair\n";
    }
    
    return 0;
}

Dans cet exemple, la variable nombre_alea est accessible en dehors de la portée if-else.

Exemple 6 : Avec C++17

#include <iostream>
#include <cstdlib>

using namespace std;

int main() {
    srand(time(NULL));
    
    if (int nombre_alea = rand(); nombre_alea % 2 == 0) {
        cout << nombre_alea << " est pair\n";
    } else {
        cout << nombre_alea << " est impair\n";
    }

    return 0;
}

La variable nombre_alea est maintenant confinée à la portée de l'instruction if.

Explication :

Une déclaration de la forme if(init; condition) est équivalente à :

init;
if(condition)
    instructions;

Les variables déclarées dans init sont disponibles dans l'instruction if et dans toutes les instructions else-if qui en découlent.

Exemple 7 : Variables dans else-if

if (int a = val1(); a > 0)
    cout << "a > 0 \n";
else if (float b = val2(); b > 0)
    cout << "b > 0 \n";

val1() et val2() sont deux fonctions qui renvoient respectivement un int et un float.

Exemple 8 : Équivalent transformé

int a = val1();
if (a > 0)
    cout << "a > 0 \n";
else {
    float b = val2();
    if (b > 0)
        cout << "b > 0 \n";
}
Exercices

Pour vous entraîner davantage sur if-else : Voir des exercices corrigés

2. Structure de contrôle switch

Principe du switch

L'instruction switch vérifie l'égalité entre un entier et une série d'étiquettes de cas (case), puis passe l'exécution au cas correspondant.

Contrairement à if-else qui n'a que deux alternatives (vrai/faux), switch peut gérer plusieurs alternatives.

Types acceptés

L'expression testée dans l'instruction switch peut être :

  • de type int (un nombre entier)
  • de type char (un caractère)

Syntaxe de switch

   
Syntaxe switch-case C++
switch(expression)
{
    case val1:
        instruction1;
        instruction2;
        ...
        break;
    case val2:
        instruction3;
        instruction4;
        ...
        break;
    default:
        instruction7;
        ...
        break;
}

Fonctionnement

  1. L'expression dans switch() est évaluée une fois.
  2. Sa valeur est comparée aux valeurs de chaque case.
  3. Si une correspondance est trouvée, l'exécution commence à ce case.
  4. L'exécution continue jusqu'à ce qu'un break soit rencontré.
  5. Si aucun case ne correspond, le default (optionnel) est exécuté.

Exemple 9 : Expressions valides et invalides

int addition(int x, int y){
    return x + y;
}

int a;
float b;
char c;

switch(a){       // valide (int)
}

switch(c){       // valide (char)
}

switch(b){       // invalide (float - nombre réel)
}

switch(2+3){     // valide (résultat int)
}

switch(a+c){     // valide (promotion de char vers int)
}

switch("nom"){   // invalide (chaîne de caractères)
}

switch(addition(a,2)){  // valide (retourne int)
}

Exemple 10 : Jours de la semaine

#include <iostream>

using namespace std;

int main(void){
    int jour;

    cin >> jour;

    switch(jour){
        case 1 : cout << "Lundi \n"; break;
        case 2 : cout << "Mardi \n"; break;
        case 3 : cout << "Mercredi \n"; break;
        case 4 : cout << "Jeudi \n"; break;
        case 5 : cout << "Vendredi \n"; break;
        case 6 : cout << "Samedi \n"; break;
        case 7 : cout << "Dimanche \n"; break;
        default: cout << "Jour invalide \n"; break;
    }

    return 0;
}
Exemple d'exécution
Entrée : 3
Sortie : Mercredi

Entrée : 8
Sortie : Jour invalide
Ne pas oublier break !

Sans l'instruction break, l'exécution continue dans le case suivant ("fall-through"). Cela peut être intentionnel, mais c'est souvent une erreur.

Nouveauté C++17 : switch avec initialiseur

Comme pour l'instruction if-else, l'instruction switch peut également avoir un initialiseur à partir de la norme C++17.

   
Syntaxe switch avec initialiseur C++17
switch (init; variable) {
    // cas...
}

Exemple 11 : switch avec initialiseur

#include <iostream>

using namespace std;

int lireValeur(){
    int a;
    cin >> a;
    return a;
}

int main(void){
    switch(int a = lireValeur(); a){
        case 1 : cout << "Lundi \n"; break;
        case 2 : cout << "Mardi \n"; break;
        case 3 : cout << "Mercredi \n"; break;
        case 4 : cout << "Jeudi \n"; break;
        case 5 : cout << "Vendredi \n"; break;
        case 6 : cout << "Samedi \n"; break;
        case 7 : cout << "Dimanche \n"; break;
        default: cout << "Jour invalide \n"; break;
    }

    return 0;
}

La variable a est déclarée et initialisée dans l'en-tête du switch, et sa portée est limitée au switch lui-même.

Exercices

Pour vous entraîner davantage sur switch-case : Voir des exercices corrigés

Comparaison if-else vs switch

Caractéristiqueif-elseswitch
Type de conditionExpression booléenne (ou convertible)Égalité avec des constantes entières/char
Nombre de branchesPlusieurs (else if)Plusieurs (case)
Complexité des conditionsConditions complexes (>, <, &&, ||, etc.)Uniquement égalité (==)
Types supportésTous types (convertibles en bool)int, char, enum (types intégraux)
PerformanceÉvaluations séquentiellesPeut utiliser une table de saut (plus rapide)
 Exercice pratique

Calculatrice simple

 Niveau : Débutant

Écrire un programme qui demande deux nombres et un opérateur (+, -, *, /) et affiche le résultat de l'opération.

Contraintes :

  1. Utiliser une structure switch pour choisir l'opération.
  2. Si l'opérateur n'est pas valide, afficher un message d'erreur.
  3. Si l'utilisateur demande une division par zéro, afficher une erreur.
Points clés à retenir
  • Les structures conditionnelles permettent d'exécuter différents blocs selon une condition.
  • if-else : idéal pour des conditions complexes (comparaisons, combinaisons logiques).
  • switch : idéal pour tester une expression contre plusieurs valeurs constantes (int/char).
  • En C++, zéro est false, toute autre valeur numérique est true.
  • En C++17, if et switch peuvent avoir un initialiseur, limitant la portée des variables.
  • Dans switch, ne pas oublier break pour éviter le "fall-through" accidentel.
  • Le cas default dans switch est optionnel mais recommandé pour traiter les valeurs inattendues.
  • Les accolades pour if/else sont optionnelles pour une seule instruction, mais les inclure améliore la lisibilité et la maintenabilité.

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.