Contrôle de flux en C++

C++C++Beginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, vous allez apprendre les instructions de contrôle de flux en C++. Vous allez apprendre à utiliser les instructions if-else, les instructions switch, les boucles while, les boucles do-while et les boucles for.

Aperçu du contenu

Il existe trois constructions de contrôle de flux de base - séquentielle, conditionnelle (ou décisionnelle), et boucle (ou itération). La structure séquentielle : le processus d'exécution est ligne par ligne, du haut en bas. La structure conditionnelle utilise l'instruction if-else pour vérifier si une instruction satisfait une condition spécifique et ensuite faire un choix. La structure de boucle est utilisée pour exécuter une opération logique plusieurs fois.

image desc

Contrôle de flux séquentiel

Un programme est une séquence d'instructions. Le flux séquentiel est le plus courant et le plus simple, où les instructions de programmation sont exécutées dans l'ordre dans lequel elles sont écrites - du haut en bas de manière séquentielle.

Contrôle de flux conditionnel

Il existe plusieurs types de conditions, if-then, if-then-else, if imbriqué (if-elseif-elseif-...-else), switch-case et expression conditionnelle.

#include <iostream>
using namespace std;

int main(){

	int mark;

	cout<<"Entrez un nombre [0-100] : ";
	cin>>mark;
    // if
    if (mark >= 50) {
       cout << "Félicitations!" << endl;
       cout << "Maintenez le bon travail!" << endl;
    }

    cout<<"Entrez un nombre [0-100] : ";
	cin>>mark;
    // if-else
    if (mark >= 50) {
       cout << "Félicitations!" << endl;
       cout << "Maintenez le bon travail!" << endl;
    } else {
       cout << "Essayez plus fort!" << endl;
    }

	cout<<"Entrez un nombre [0-100] : ";
	cin>>mark;
    // if imbriqué
    if (mark >= 80) {
       cout << "A" << endl;
    } else if (mark >= 70) {
       cout << "B" << endl;
    } else if (mark >= 60) {
       cout << "C" << endl;
    } else if (mark >= 50) {
       cout << "D" << endl;
    } else {
       cout << "F" << endl;
    }

    // switch-case
    char oper;
    int num1 = 1, num2 = 2, result = 0;
    cout<<"Entrez un char [+ - / *] : ";
    cin>> oper;
    switch (oper) {
       case '+':
          result = num1 + num2;
          break;
       case '-':
          result = num1 - num2;
          break;
       case '*':
          result = num1 * num2;
          break;
       case '/':
          result = num1 / num2;
          break;
       default:
          cout << "Opérateur inconnu" << endl;
    }
    cout<<num1<<oper<<num2<<"="<<result;
    return 0;
}

Sortie :

Entrez un nombre [0-100] : 50
Félicitations!
Maintenez le bon travail!
Entrez un nombre [0-100] : 40
Essayez plus fort!
Entrez un nombre [0-100] : 85
A
Entrez un char [+ - / *] : +
1+2=3
image desc

Opérateur conditionnel : Un opérateur conditionnel est un opérateur ternaire (à 3 opérandes), de la forme booleanExpr? trueExpr : falseExpr. Selon la valeur de booleanExpr, il évalue et renvoie la valeur de trueExpr ou de falseExpr.

// renvoie soit "PASS" soit "FAIL", et l'affiche
cout << (mark >= 50)? "PASS" : "FAIL" << endl;

max = (a > b)? a : b;   // Le membre droit renvoie a ou b
abs = (a > 0)? a : -a;  // Le membre droit renvoie a ou -a

Accolades : Vous pouvez omettre les accolades { } si le bloc ne contient qu'une seule instruction. Par exemple,

if (mark >= 50)
   cout << "PASS" << endl;   // Une seule instruction, on peut omettre { } mais pas recommandé
else {                       // Plusieurs instructions, il faut { }
   cout << "FAIL" << endl;
   cout << "Essayez plus fort!" << endl;
}

Cependant, il est recommandé de conserver les accolades, même si le bloc ne contient qu'une seule instruction, pour améliorer la lisibilité de votre programme.

Contrôle de flux de boucle

Encore une fois, il existe plusieurs types de boucles : boucle for, while-do et do-while.

// boucle for
int sum = 0;
for (int number = 1; number <= 100; ++number) {
   sum += number;
}

// while-do
int sum = 0, number = 1;
while (number <= 100) {
   sum += number;
   ++number;
}

// do-while
int sum = 0, number = 1;
do {
   sum += number;
   ++number;
} while (number <= 100);

Demandez à l'utilisateur une borne supérieure. Calculez la somme des entiers de 1 à une borne supérieure donnée et calculez sa moyenne.

/*
 * Somme de 1 à une borne supérieure donnée et calculez leur moyenne.
 */
#include <iostream>
using namespace std;

int main() {
   int sum = 0;     // Stocke la somme accumulée
   int upperbound;
   cout << "Entrez la borne supérieure : ";
   cin >> upperbound;

   // Somme de 1 à la borne supérieure
   for (int number = 1; number <= upperbound; ++number) {
      sum += number;
   }
   cout << "La somme est " << sum << endl;
   cout << "La moyenne est " << (double)sum / upperbound << endl;

   // Somme seulement des nombres impairs
   int count = 0;     // Compte des nombres impairs
   sum = 0;           // réinitialise la somme
   for (int number=1; number <= upperbound; number=number+2) {
      ++count;
      sum += number;
   }
   cout << "La somme des nombres impairs est " << sum << endl;
   cout << "La moyenne est " << (double)sum / count << endl;
}

Sortie :

Entrez la borne supérieure : 15
La somme est 120
La moyenne est 8
La somme des nombres impairs est 64
La moyenne est 8
image desc

Interrompre le flux de boucle - "break" et "continue"

L'instruction break sort et quitte la boucle actuelle (la plus interne).

L'instruction continue interrompt l'itération actuelle et passe à l'itération suivante de la boucle actuelle (la plus interne).

break et continue sont des structures peu recommandées car elles sont difficiles à lire et à suivre. Utilisez-les seulement si c'est absolument nécessaire. Vous pouvez toujours écrire le même programme sans utiliser break et continue.

Le programme suivant liste les nombres non premiers entre 2 et une borne supérieure.

/*
 *  Liste les nombres non premiers de 1 à une borne supérieure.
 */
#include <iostream>
#include <cmath>
using namespace std;

int main() {
   int upperbound;
   cout << "Entrez la borne supérieure : ";
   cin >> upperbound;
   for (int number = 2; number <= upperbound; ++number) {
      // Pas un nombre premier, s'il existe un facteur entre 2 et sqrt(number)
      int maxFactor = (int)sqrt(number);
      for (int factor = 2; factor <= maxFactor; ++factor) {
         if (number % factor == 0) {   // Est-ce un facteur?
            cout << number << " ";
            break;   // Un facteur a été trouvé, pas besoin de chercher d'autres facteurs
         }
      }
   }
   cout << endl;
   return 0;
}

Sortie :

Entrez la borne supérieure : 20
4 6 8 9 10 12 14 15 16 18 20
image desc

Reprenons le programme ci-dessus pour lister tous les nombres premiers à la place. Un drapeau boolean appelé isPrime est utilisé pour indiquer si le number actuel est premier. Il est ensuite utilisé pour contrôler l'affichage.

/*
 *  Liste les nombres premiers de 1 à une borne supérieure.
 */
#include <iostream>
#include <cmath>
using namespace std;

int main() {
   int upperbound;
   cout << "Entrez la borne supérieure : ";
   cin >> upperbound;
   for (int number = 2; number <= upperbound; ++number) {
      // Pas un nombre premier, s'il existe un facteur entre 2 et sqrt(number)
      int maxFactor = (int)sqrt(number);
      bool isPrime = true;  // Drapeau boolean pour indiquer si number est premier
      for (int factor = 2; factor <= maxFactor; ++factor) {
         if (number % factor == 0) {   // Est-ce un facteur?
            isPrime = false;   // number n'est pas un nombre premier
            break;   // Un facteur a été trouvé, pas besoin de chercher d'autres facteurs
         }
      }
      if (isPrime) cout << number << " ";
   }
   cout << endl;
   return 0;
}

Sortie :

Entrez la borne supérieure : 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
image desc

Examinez le programme suivant utilisant break et continue.

/* Une série mystérieuse */
#include <iostream>
using namespace std;

int main() {
   int number = 1;
   while (true) {
      ++number;
      if ((number % 3) == 0) continue;
      if (number == 53) break;
      if ((number % 2) == 0) {
         number += 3;
      } else {
         number -= 3;
      }
      cout << number << " ";
   }
   cout << endl;
   return 0;
}

Sortie :

5 4 2 7 11 10 8 13 17 16 14 19 23 22 20 25 29 28 26 31 35 34 32 37 41 40 38 43 47 46 44 49 53 52
image desc

Terminer un programme

Il existe plusieurs façons de terminer votre programme, avant d'avoir atteint la fin des instructions de programmation.

exit() : Vous pouvez invoquer la fonction exit(int exitCode), dans <cstdlib> (porté de "stdlib.h" de C), pour terminer le programme et renvoyer le contrôle au Système d'exploitation. Par convention, un code de retour égal à zéro indique une terminaison normale ; tandis qu'un exitCode non nul (-1) indique une termination anormale. Par exemple,

abort() : Le fichier d'en-tête <cstdlib> fournit également une fonction appelée abort(), qui peut être utilisée pour terminer le programme de manière anormale.

if (errorCount > 10) {
   cout << "trop d'erreurs" << endl;
   exit(-1);  // Termine le programme
              // OU abort();
}

Boucles imbriquées

Le diagramme suivant illustre une boucle for imbriquée, c'est-à-dire une boucle for interne à l'intérieur d'une boucle for externe.

image desc
/*
 *  Affiche un motif triangulaire.
 */
#include <iostream>
using namespace std;

int main() {
   int size = 8;
   for (int row = 1; row <= size; ++row) {     // Boucle externe pour afficher toutes les lignes
      for (int col = 1; col <= size-row+1; ++col) {  // Boucle interne pour afficher toutes les colonnes de chaque ligne
         cout << "## ";
      }
      cout << endl;   // Une ligne est terminée, déplace le curseur à la ligne suivante
   }

   return 0;
}

Sortie :

## ## ## ## ## ## ## #
## ## ## ## ## ## #
## ## ## ## ## #
## ## ## ## #
## ## ## #
## ## #
## #
#
image desc

La construction suivante est couramment utilisée :

while (true) { ...... }

Cela semble être une boucle sans fin (ou boucle infinie), mais elle est généralement terminée via une instruction break ou return à l'intérieur du corps de la boucle. Ce type de code est difficile à lire - évitez-le si possible en réécrivant la condition.

Sommaire

Nous avons présenté trois structures de contrôle dans cette section. Elles sont très utiles. Vous pouvez les combiner. Faites attention avec les boucles, vérifiez la condition de terminaison, pour éviter les boucles infinies.