3.3 - for
Boucle for … :
Syntaxe
for (<expr. 1 initialisation>; <expr. condition de boucle>; <expr. de boucle>)
instruction
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 :
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 :
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