Le langage C - boucles

Boucles de type do...while

On a souvent besoin de répéter un bout de programme tant qu'une condition est vraie (par exemple tant que la précision d'un calcul est insuffisante). Le C propose les deux structures suivantes pour cela:

while (condition) { /* structure 1: condition à l'entrée du code */
  instructions à répéter;
}

do { /* structure 2: condition à la sortie du code */
  instructions à répéter;
} while (condition);

Le bloc entre les accolades {} est répété dans les deux cas tant que la conditions est vraie. Dans le cas de la première structure, la condition est évaluée en tout premier, il est donc possible (si la condition est fausse dès le départ) que les instructions ne soient pas exécutés du tout. Avec la deuxième structure on sait en revanche que les instructions seront exécutées au moins une fois, puisque la condition est évaluée à la fin de chaque répétition.

Parfois on aimerait faire évaluer la condition ni au début, ni à la fin de la boucle, mais quelque part au milieu (voir l'exemple qui suit). L'astuce consiste alors à créer une boucle infinie (condition toujours vraie) et à utiliser l'instruction break, qui fait sortir immédiatement de la boucle:

while (1) { /* structure 3: condition dans la boucle */
  instructions...;
  if (condition) break;
  instructions...;
}

Boucles de type for ( ; ; ) ...

Il arrive fréquemment qu'on veuille exécuter une suite d'instructions un nombre connu de fois (par exemple pour évaluer une fonction en N points). On utilise alors la construction for ( ; ; ) ..., dont la syntaxe générale est:

for (initialisation du compteur ; condition testée à chaque pas ; modification du compteur) {
  bloc d'instructions exécuté à chaque pas de la boucle ;
}

Elle est strictement équivalente à

initialisation du compteur ;
while (condition testée à chaque pas) {
  bloc d'instructions exécuté à chaque pas de la boucle ;
  modification du compteur ;
}

mais elle est en général plus lisible (si on ne met que le stricte nécessaire à l'intérieur des parenthèses, notamment une condition simple: > , < , ==, ...). Par exemple, pour calculer la somme des 100 premiers entiers :

int main(void) {
  int i, somme;
  somme = 0; /* on initialise la somme a 0 */
  for (i=1 ; i<=100 ; i=i+1) { /* boucle, i varie de 1 a 100, par pas de 1 */
    somme = somme + i ; /* on ajoute la valeur actuelle de i a la somme */
  }
  printf ("%d\n", somme) ; /* le résultat est écrit a l'écran */
  return 0;
}

/!\ Attention /!\

Dans cet exemple la boucle est exécutée 100 fois (le compteur vaut successivement 1,2,3,...,100), et la valeur du compteur i à la sortie de la boucle est 101 (la boucle est quittée quand la condition devient fausse, ce qui arrive pour la première fois pour cette valeur).

Comme pour les conditions, on décale les blocs à exécuter pour plus de clarté; voir le chapître entrées/sorties pour le printf.

Comme pour les boucles while, on peut utiliser break pour sortir de la boucle. On pourrait par exemple réécrire notre exemple précédent sous la forme :

i = 1 ;
for ( ; ; ) { /* boucle infinie */
  somme = somme + i ;
  if (i == 100) break ; /* condition d'arrêt */
  i = i + 1 ;
}

Écritures courantes

Le paragraphe précédent illustre la liberté que le C donne au programmeur pour l'écriture de boucles: une même boucle peut être écrite de nombreuses manières équivalentes. Profitez en pour penser avant tout à la clarté de l'organisation de votre code. Il s'est en particulier cristallisé un certain nombre d'"expressions figées" très usitées et particulièrement claires. Adoptez-les dès le début, elles diminueront la probabilité de faire une erreur (toute construction exotique sautera aux yeux et fera réfléchir).

incréments

Dans une boucle, on effectue souvent une incrémentation simple d'une variable :

i = i + 1 ;

Le C permet une écriture plus compacte de ce type d'expression grâce aux opérateurs de type += :

notation longue notation courte équivalente
i = i + 5 ; i += 5 ;
i = i - 9 ; i -= 9 ;
i = i / 7 ; i /= 7 ;
i = i * 2 ; i *= 2 ;

Enfin, dans le cas des opération + et -, et si la modification est d'une unité (incrément ou décrément), il y a deux opérateurs spéciaux ++ et -- :

i++ ; // augmente la valeur de i d'une unité
i-- ; // diminue la valeur de i d'une unité

le piège de l'ordre d'évaluation

Faites attention en mélangeant ces opérateurs abrégés avec d'autres opérations:

int i,j ;
i = 2;
          /* i vaut 2 */
j = i++;
          /* i vaut 3 et j vaut 2 */
i = 2;
          /* i vaut 2 */
j = ++i;
          /* i et j valent 3 */

Dans le cas des opérateurs i++ ou i--, la variable est bien modifiée d'une unité, mais uniquement après avoir utilisé son ancienne valeur pour le reste de l'expression (on parle de "post-(in/de)crémentation"). À l'inverse, les opérateurs ++i ou --i modifient la variable avant que sa valeur soit considéré pour le reste de l'expression ("pré-(in/de)crémentation").

boucles for

Une boucle pour répéter 100 fois une suite d'instructions s'écrit
int i, n = 100;
for (i=0 ; i<n; i++) {
  instructions;
}

Exemples

Affichez, compilez et exécutez les programmes suivants :

prog4.c : boucle 'for'

prog5.c : boucle 'for' : opérateur +=

prog6.c : boucle 'for' : opérateur ++

Auteur(s) : Anciens, A. Daerr. Dernière modification : Mon Feb 20 06:51:45 2006. [validate XHTML]