3.3 - for

Boucle for … :

Syntaxe

for (<expr. 1 initialisation>; <expr. condition de boucle>; <expr. de boucle>)
   instruction

for for

L’instruction à répéter peut être simple, composée ou structurée.

L’expr. 1 initialisation est une expression d’initialisation;

L’expr. 2 condition de boucle est une expression logique, une condition pour continuer la répétition et celle-ci est évaluée avant chaque itération de la boucle;

L’expr. 3 de boucle est une expression d’incrémentation ou de décrémentation qui s’exécute à chaque itération de la boucle.

Illustration de la syntaxe :

for (i = 1; i <= 10; i++)
   printf("Bonsoir!\n");

Cette boucle fait afficher 10 lignes qui contient le message Bonsoir!

Fonctionnement

Initialiser la variable de contrôle de la boucle.

Tant que la condition pour continuer vaut vrai, faire :

  • Exécuter l’instruction à répéter;

  • Ajuster la valeur de la variable de contrôle (incrémenter ou décrémenter).

Domaines d’utilisation

On utilise la boucle for quand on sait à l’avance le nombre de fois que l’on répète le même traitement. C’est le cas des valeurs consécutives entre deux bornes données. On l’utilise aussi fréquemment pour parcourir les indices d’un tableau (les tableaux seront vus plus tard dans le cours).

Exemple 1

Écrire des blocs d’instructions qui permettent d’afficher :

6  7  8  9 10 11 ...   19 20
19 17 15 13 11 ...    3  1
ABCDEFGH....YZ
zy....      ba

Solution

#include <stdio.h>

void main()
{
   int  i;
   char lettre;

   /* afficher la première ligne : */
   for (i = 5; i <= 20; i++)
      printf("%3d", i);

   printf("\n");

   /* afficher la deuxième ligne : */
   for (i = 19; i >= 1; i -= 2)
      printf("%3d", i);
   printf("\n");

   /* afficher la troisième ligne : */
   for (lettre = 'A'; lettre <= 'Z'; lettre++)
      printf("%c", lettre);

   printf("\n");

   /* afficher la quatrième ligne : */
   for (lettre = 'z'; lettre >= 'a'; lettre--)
      printf("%c", lettre);

   printf("\n");
}

Exécution

6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
19 17 15 13 11  9  7  5  3  1
ABCDEFGHIJKLMNOPQRSTUVWXYZ
zyxwvutsrqponmlkjihgfedcba

Exemple 2

Écrire des blocs d’instructions qui permettent d’afficher :

12345
2345
345
45
5

12345
2   2
3   3
4   4
54321

Solution

#include <stdio.h>
void main()
{
   int ligne, colonne;

   for (ligne = 1; ligne <= 5; ligne++){
      for (colonne = ligne; colonne <= 5; colonne++)
         printf("%d", colonne);
         printf("\n");
   }

   printf("\n");

   for (colonne = 1; colonne <= 5; colonne++)
      printf("%d", colonne);
   printf("\n");

   for (ligne = 2; ligne <= 4; ligne++)
      printf("%d%4d\n", ligne, ligne);

   for (colonne = 5; colonne >= 1; colonne--)
      printf("%d", colonne);
   printf("\n");
}

Exécution

12345
2345
345
45
5

12345
2   2
3   3
4   4
54321

Exemple 3

Écrire des blocs d’instructions qui permettent de :

  • Calculer et afficher la somme suivante : s = 5 + 6 + 7 + ... + 49

  • D’estimer la valeur de PI sachant que :

Solution

#include <stdio.h>

void main()
{
   const int BORNE1 =  5,
             BORNE2 = 49;

   const int MAX_DENO = 29999, LE_PAS = 2;

   int   somme, terme, denominateur;
   float signe, piSur4;

   /* Calcul de s = 5 + 6 + ... + 49 */

   somme = 0;
   for (terme = BORNE1; terme <= BORNE2; terme++)
      somme += terme;
   printf("\nsomme = %3d\n", somme);

   /* Estimation de PI sachant que PI/4 = 1 - 1/3 + ... - 1/29999 */
   piSur4 = 0;
   signe   = +1.0;

   for (denominateur = 1; denominateur <= MAX_DENO; denominateur += LE_PAS){
      piSur4 += signe / denominateur;
      signe = -signe;
   }

   printf("\nValeur estimée de PI = %8.6f\n", 4 * piSur4);
}

Exécution

somme = 1215
Valeur estimée de PI = 3.141533

Exemple 4

Le nombre 720 a 30 diviseurs (1, 2, 3, 4, 5, 6, 8, 9, …, 360, 720). Un autre nombre, supérieur à 720 mais inférieur à 1000, en a encore plus.

Écrire un programme qui permet de découvrir ce nombre et d’afficher ses diviseurs à raison de 5 diviseurs par ligne.

Solution

#include <stdio.h>

void main()
{
    const int MINI      =  720,
              MAXI      = 1000,
              A_BATTRE  =   30,
              PAR_LIGNE =    5;

    int nombre,
        nbDiv,
        k,
        n;

    /* examiner nombre par nombre entre 721 et 999 */
    for (nombre = MINI + 1; nombre < MAXI; nombre++){
       /* compter le nombre de diviseurs du nombre examiné */
       nbDiv = 2; /* 1 et le nombre lui-même sont 2 diviseurs */

       for (k = 2; k <= nombre / 2; k++)
          if (nombre % k == 0)
             nbDiv++;

       /* vérifier si c'est un nombre à découvrir */
       if (nbDiv > A_BATTRE){
          printf("Le nombre %d a %d diviseurs\n", nombre, nbDiv);
          printf("\nEn voici la liste:\n");
          n = 0;
          for (k = 1; k <= nombre; k++)
             if (nombre % k == 0){
                 n++;
                 printf("%4d) %5d", n, k);
                 if (n % PAR_LIGNE == 0)
                    printf("\n");
             }
       }
    }  /* fin du for */
}   /* fin du main */

Exécution

Le nombre 840 a 32 diviseurs
En voici la liste:
 1)     1   2)     2   3)     3   4)     4   5)     5
 6)     6   7)     7   8)     8   9)    10  10)    12
11)    14  12)    15  13)    20  14)    21  15)    24
16)    28  17)    30  18)    35  19)    40  20)    42
21)    56  22)    60  23)    70  24)    84  25)   105
26)   120  27)   140  28)   168  29)   210  30)   280
31)   420  32)   840

Exemple 5

Écrire un programme qui permet de :

  • Saisir et valider le nombre total de pattes de poules (à 2 pattes) et de vaches (à 4 pattes);

  • Afficher toutes les solutions possibles du nombre de poules et de vaches.

Solution

#include <stdio.h>

void main()
{
   int nbPattes, nbPoules, nbVaches, valide;

   do{
      printf("\nEntrez un nombre pair pour le nombre total de pattes : ");
      scanf("%d", &nbPattes);

      valide = nbPattes > 0 && nbPattes % 2 == 0;

      if (!valide)
         if (nbPattes <= 0)
            printf("Un nombre positif S.V.P.");
         else
            printf("Un nombre pair S.V.P.");
   } while (!valide);

   printf("\n\n");

   nbPoules = nbPattes / 2;
   for (nbVaches = 0; nbVaches <= nbPattes / 4; nbVaches++){
      printf("%2d vache(s) et %2d poule(s)\n", nbVaches, nbPoules);
      nbPoules -= 2;
    }
}

Exécution

Entrez un nombre pair pour le nombre total de pattes : –52
Un nombre positif S.V.P.
Entrez un nombre pair pour le nombre total de pattes : 21
Un nombre pair S.V.P.
Entrez un nombre pair pour le nombre total de pattes : 22
0 vache(s) et 11 poule(s)
1 vache(s) et  9 poule(s)
2 vache(s) et  7 poule(s)
3 vache(s) et  5 poule(s)
4 vache(s) et  3 poule(s)
5 vache(s) et  1 poule(s)

Exercices

Exercice 1

Écrire un bloc d’instructions permettant d’afficher les 20 consonnes en minuscules à l’écran.

Solution

char lettre ;
for (lettre = 'a'; lettre <= 'z'; lettre++)
   if (lettre != 'a' && lettre != 'e' && lettre != 'i' &&
       lettre != 'o' && lettre != 'u' && lettre != 'y')
   printf("%c", lettre);

printf("\n");

Exercice 2

Réaliser une autre solution de l’exercice 1 en remplaçant le if par un switch.

Exercice 3

Écrire un bloc d’instructions permettant de calculer et d’afficher la somme suivante :

imf imf

Solution

const int BORNE1 =   1,
          BORNE2 = 1000;
int denominateur;
float somme = 0;

for (denominateur = BORNE1; denominateur <= BORNE2; denominateur++)
   somme += 1.0 / denominateur;

printf("La somme demandée : %10.6f\n", somme);

Exercice 4

Écrire un bloc d’instructions utilisant la boucle for qui permet d’estimer la valeur de PI selon la formule suivante :

imf imf

Solution

const int LIMITE = 9999;

float piSur4 = 0.0, signe = 1.0;
int   denominateur;

for ( denominateur = 1; denominateur <= LIMITE / 2; denominateur += 2){
   piSur4 += signe / denominateur;
   signe = -signe;
}

printf("La valeur estimée de PI est %12.6f ",4 * piSur4);

On reviendra sur la boucle “for” lorsqu’on abordera la notion des tableaux un peu plus loin dans le cours.

Autres exemples

Exemple 1

/* Fichier for1.c (1er exemple de la boucle for)
 * 
 *   1) afficher 10 fois Bonsoir
 *        traitement commun : afficher Bonsoir
 *        nombre de fois connu à l'avance : 10 fois
 *        => bon candidat pour la boucle for
 * 
 *   2) calculer + afficher la somme
 *         s = 3 + 5 + 7 + ... + 51
 *        on connaît :
 *          - la valeur de départ :  3
 *          - la valeur d'arrivée : 51 
 *          - le pas entre 2 valeurs est une constante
 *            (ici le pas vaut 2)
 *        => bon candidat pour la boucle for
 *     
 *    Révision : recalculer avec do ... while, while ....
 */

 
#include <stdio.h>

void main()
{
   #define NB_FOIS 10
   #define BORNE1  3
   #define BORNE2 51
   #define LE_PAS  2

   int i,      /* pour la boucle for */
       somme,  /* pour somme = 3 + 5 + ... + 51 */
       valeur; /* somme des valeurs */

   /* afficher 10 fois Bonsoir */

   for (i = 1; i <= NB_FOIS; i++)
      printf("Bonsoir\n");

   printf("\n\nLa somme de %d + %d + ... + %d\n" , BORNE1,
                                                   BORNE1 + LE_PAS, BORNE2);

   /* calculer s = 3 + 5 + ... + 51 avec for . . .*/
   somme = 0;

   for (valeur = BORNE1; valeur <= BORNE2; valeur += LE_PAS)
      somme += valeur;

   printf("Avec la boucle for . . . . . .   %d\n", somme);

   /* calculer s = 3 + 5 + ... + 51 avec do ... while . . .*/
   somme = 0;
   valeur = BORNE1;
   do{
      somme += valeur;
      valeur += LE_PAS;
   }while (valeur <= BORNE2);

   printf("Avec la boucle do ... while ...  %d\n", somme);

   /* calculer s = 3 + 5 + ... + 51 avec while . . .*/

   somme = 0;
   valeur = BORNE1;
   while (valeur <= BORNE2){
      somme += valeur;
      valeur += LE_PAS;
   }

   printf("Avec la boucle while ..........  %d\n", somme);
}

Exécution

Bonsoir
Bonsoir
Bonsoir
Bonsoir
Bonsoir
Bonsoir
Bonsoir
Bonsoir
Bonsoir
Bonsoir


La somme de 3 + 5 + ... + 51
Avec la boucle for . . . . . .   675
Avec la boucle do ... while ...  675
Avec la boucle while ..........  675

Exemple 2

#include <stdio.h>

/* for2.c
   Dans cet exemple, on se concentre sur l'essentiel et on vous
   laisse le soin de déclarer des constantes pour les bornes,
   les pas, ici ce n'est pas l'objectif de l'exemple.
   
   But : utiliser la boucle for
 */

void main()
{

   int n, k ;
   char c ;

   /* afficher  5  7  9 11 13 15 ... 25 sur la même ligne */
   for (n = 5; n <= 25; n+= 2)
      printf("%3d", n);
   printf("\n");

   /* afficher  100 95 90 85 . . . 70  sur la même ligne */
   for (n = 100; n >= 70; n -= 5)
      printf("%3d", n);
   printf("\n");

   /* afficher  les 26 lettres MAJUSCULES sur la même ligne */
   for (c = 'A'; c <= 'Z'; c++)
      printf("%c", c);
   printf("\n");
 

   /* afficher  les 20 consonnes MAJUSCULES sur la même ligne */
   for (c = 'A'; c <= 'Z'; c++)
      switch (c){
         case 'A':
         case 'E':
         case 'I':
         case 'O':
         case 'U':
         case 'Y': break ;
         default : printf("%c", c);
      }

   printf("\n");

   /* afficher  les diviseurs de 20 */
   printf("\n\nLes diviseurs de 20 sont : ");
   for (n = 1; n <= 20; n++)
      if (20 % n == 0)
         printf("%3d", n);
      printf("\n");

   /* afficher  la table des multiplications de 1 à 10 : */
   printf("\n\nLa table des multiplications de 1 a 10 :\n");
   printf("    ");
   for (n = 1; n <= 10; n++)
      printf("%4d", n);
   printf("\n");

   for (n = 1 ; n <= 10 ; n++){
      printf("%4d", n);

      for (k = 1; k <= 10; k++)
         printf("%4d", n * k);
      printf("\n");
   }
}

Exécution

5  7  9 11 13 15 17 19 21 23 25
100 95 90 85 80 75 70
ABCDEFGHIJKLMNOPQRSTUVWXYZ
BCDFGHJKLMNPQRSTVWXZ

Les diviseurs de 20 sont :   1  2  4  5 10 20 

La table des multiplications de 1 a 10 :
       1   2   3   4   5   6   7   8   9  10
   1   1   2   3   4   5   6   7   8   9  10
   2   2   4   6   8  10  12  14  16  18  20
   3   3   6   9  12  15  18  21  24  27  30
   4   4   8  12  16  20  24  28  32  36  40
   5   5  10  15  20  25  30  35  40  45  50
   6   6  12  18  24  30  36  42  48  54  60
   7   7  14  21  28  35  42  49  56  63  70
   8   8  16  24  32  40  48  56  64  72  80
   9   9  18  27  36  45  54  63  72  81  90
  10  10  20  30  40  50  60  70  80  90 100

Exemple 3

/* Fichier for3.c (3ième exemple de la boucle for)
 *
 *   1) déterminer et afficher les diviseurs de 6
 *
 *   2) déterminer et afficher les diviseurs de 720
 *
 *    Exercices de révision : refaire avec
 *       a) do ... while
 *       b) while ....
 */
#include <stdio.h>
void main ()
{
   const int NOMBRE1 =   6,
             NOMBRE2 = 720;

   int nombre, /* le nombre est-il un diviseur de ... */
       nbDivi; /* compteur du nombre de diviseurs */

   /* compter le nombre de diviseurs de 6 */

   nbDivi = 0; /* initialiser le compteur */

   printf("Les diviseurs de %d sont :\n", NOMBRE1);

   /* on examine tous les nombres entre 1 et 6 */
   for (nombre = 1; nombre <= NOMBRE1; nombre++)
      if (NOMBRE1 % nombre == 0){   /* si nombre est un diviseur de NOMBRE1 */
         nbDivi++; /* on incrémente le compteur */
         printf("%3d) %5d\n", nbDivi, nombre);
      }

   /* affichage : */
   printf("Le nombre %d a %d diviseurs\n", NOMBRE1, nbDivi);
 

   /* compter le nombre de diviseurs de 720 */

   nbDivi = 0; /* initialiser le compteur */
   printf("\nLes diviseurs de %d sont :\n", NOMBRE2);

   /* on examine tous les nombres entre 1 et 720 */
   for (nombre = 1; nombre <= NOMBRE2; nombre++)
      if (NOMBRE2 % nombre == 0)   /* si nombre est un diviseur de NOMBRE2 */
         printf("%3d) %5d\n", ++nbDivi, nombre);

   /* affichage : */
   printf("Le nombre %d a %d diviseurs\n\n", NOMBRE2, nbDivi);
}

Exécution

Les diviseurs de 6 sont :
  1)     1
  2)     2
  3)     3
  4)     6
Le nombre 6 a 4 diviseurs

Les diviseurs de 720 sont :
  1)     1
  2)     2
  3)     3
  4)     4
  5)     5
  6)     6
  7)     8
  8)     9
  9)    10
 10)    12
 11)    15
 12)    16
 13)    18
 14)    20
 15)    24
 16)    30
 17)    36
 18)    40
 19)    45
 20)    48
 21)    60
 22)    72
 23)    80
 24)    90
 25)   120
 26)   144
 27)   180
 28)   240
 29)   360
 30)   720
Le nombre 720 a 30 diviseurs

Exemple 4

/* Fichier for4.c (4ième exemple de la boucle for)
 *   "for imbriqué" : for dans un autre for
 *     Afficher :
 *     1 2 3 4 5
 *     2 3 4 5
 *     3 4 5
 *     4 5
 *     5
 *   Simulez un bloc avec for imbriqué
 *
 *   Exercice : Écrivez un bloc avec for imbriqué pour
 *   afficher :
 *   1
 *   1 2
 *   1 2 3
 *   1 2 3 4
 *   1 2 3 4 5
 */

#include <stdio.h>

void main ()
{
   const int BORNE = 5;
   int ligne, col;    /* ligne, colonne */

   /* simuler cet extrait de code pour mieux assimiler */
   /* de la ligne 1 à la ligne 5 */
   for (ligne = 1; ligne <= BORNE; ligne++){
      /* pour colonne varie de numéro de ligne jusqu'à 5 */
      for (col = ligne; col <= BORNE; col++)
         printf("%2d", col);     /* afficher la valeur de la colonne */

      printf("\n");
   }
   printf("\n\n");
   /* À simuler pour comprendre cet extrait de code : */

   /* de la ligne 1 à la ligne 5 */
   for (ligne = 1; ligne <= BORNE; ligne++){
      for (col = 1; col <= ligne + 2; col++)
         switch (col){
             case 1 :
             case 3 : printf("%3d", col);
                      break;
             case 6 : printf("%3d", ligne+col);
                      break;
             default: printf("%3d", 2*col);
         }
      printf("\n");
   }
}

Exécution

 1 2 3 4 5
 2 3 4 5
 3 4 5
 4 5
 5


  1  4  3
  1  4  3  8
  1  4  3  8 10
  1  4  3  8 10 10
  1  4  3  8 10 11 14

Exemple 5

/* Autre application de do ... while 
   valider les (valeurs des) données
 */ 
#include <stdio.h> #include <ctype.h> 
void main() {
   const int MIN_ANC =   1,  MAX_ANC =  25;  
   char poste;      
   /* parmi : A, P, O et S analyste, programmeur,                                             
      opérateur, secrétaire */    
   
   int  anciennete; 
   /* nb. d'années d'ancienneté */    

   int  valide;
   /* Oui ou Non l'ancienneté est valide */ 

   /* Saisir et valider le poste de travail */
   do{
      printf("Entrez un caractere representant le poste de travail : "); 
      fflush(stdin); 
      /* lire et convertir le caractère lu en MAJUSCULE */ 
      poste = toupper(getchar()); 

      if (poste != 'A' && poste != 'P' && poste != 'O' && poste != 'S') 
         printf("poste invalide, retapez S.V.P.\n\n"); 
   }while (poste != 'A' && poste != 'P' && poste != 'O' && poste != 'S');  

   /* Saisir et valider l'anciennetée, entre 1 et 25 ans */ 
   do{
      printf("Entrez l'anciennete entre %d et %d : ", MIN_ANC, MAX_ANC); 
      scanf("%d", &anciennete); 
      valide = anciennete >= MIN_ANC && anciennete <= MAX_ANC; 
      if (!valide) 
         printf("L'anciennete est en dehors de l'intervalle\n\n"); 
   } while (!valide); 

   printf("\nLe poste saisi : %c, l'anciennete lue : %d\n", 
                                             poste, anciennete); 

   /* affichage utilisant le if imbriqué :  */ 
   printf("L'employe occupe un poste "); 
   if (poste == 'A') 
      printf("d'analyste "); 
   else if (poste == 'P') 
      printf("de programmeur "); 
   else if (poste == 'O') 
      printf("d'operateur "); 
   else 
      printf("de secretaire "); 

   printf("\n\nL'employe a %d annee(s) d'anciennete\n\n", anciennete); }  

Exécution

Entrez un caractere representant le poste de travail : z 
poste invalide, retapez S.V.P. 
Entrez un caractere representant le poste de travail : a
Entrez l'anciennete entre 1 et 25 : 56 
L'anciennete est en dehors de l'intervalle  
Entrez l'anciennete entre 1 et 25 : -7 
L'anciennete est en dehors de l'intervalle 
Entrez l'anciennete entre 1 et 25 : 12 
Le poste saisi : A, l'anciennetee lue : 12 
L'employe occupe un poste d'analyste 
L'employe a 12 annee(s) d'anciennetee