wiki:InsiaProgCSyntaxe3

Sommaire

Syntaxe - Boucles et tests

Comme nous l'avons vu en introduction, les instructions des blocs sont exécutés de manières séquentielles, et ce sont les articulations entre les blocs qui permettent de contrôler le flux d'exécution du programme. On pourra ainsi répéter un bloc, choisir un bloc ou un autre en fonction d'une condition, etc. Ce mode d'écriture est appelé programmation structurée, et il est employé de manière quasi universelle aujourd'hui.

1. Boucles

for (...) {}

Il s'agit de la boucle la plus versatile. Elle est surtout connue pour son rôle de simple boucle avec compteur, mais elle être utilisée de manière bien plus large. Exemple classique:

int i;
for (i = 1; i <= 10; i++) {
  printf("i vaut %d\n", i);
}

Ce programme affiche naturellement les entiers de 1 à 10. La syntaxe générale est la suivante:

for (initialisation; test de boucle; instruction de fin de boucle) {
  code de boucle
}

La boucle s'exécute comme suit:

  • L'instruction initialisation est exécutée une seule fois et une seule, dès le démarrage de la boucle. En général on initialise un compteur à cet endroit.
  • Avant chaque tour de boucle, le test de boucle est évalué: s'il est vrai, alors le tour de boucle est exécuté, sinon on sort immédiatement de la boucle. Il est donc en particulier possible de réaliser une boucle qui n'effectue aucun tour.
  • L' instruction de fin de boucle est exécutée quand un tour de boucle s'est déroulé jusqu'au bout (voir break plus loin).
  • Enfin, le code de boucle est normalement exécuté à chaque fois que le test de boucle a été vérifié.

Si nous décomposons la boucle dans le premier exemple, nous observons la séquence suivante:

  • la variable i est initialisée à 1
  • le test i <= 10 est évalué, il est alors vrai: on continue
  • le code de boucle est exécuté (avec i=1 donc)
  • une fois le code de boucle terminé, le code de fin de boucle est exécuté, cad. que i est incrémenté de 1: i vaut désormais 2
  • le test i <= 10 est évalué, il est alors vrai: on continue
  • ...
  • code de fin de boucle, i est incrémenté: il vaut alors 11
  • le test i <= 10 est évalué, il est faux: on quitte immédiatement la boucle

Note: en sortie de boucle, la variable i contient donc la première valeur qui a fait échouer le test de boucle (et non nécessairement le nombre de tours effectués !).

Note: il est possible d'omettre les instructions et tests de boucle (le test est alors toujours vrai). Par exemple pour effectuer une boucle infinie, on peut faire:

for (;;) {
  printf("Vers l'infini et au-delà !\n");
}

while (...) {}

Il s'agit de la boucle la plus simple: une condition de boucle, et un code de boucle. Par exemple, pour paraphraser l'exemple de boucle du début:

int i = 1;
while (i <= 10) {
  printf("i vaut %d\n", i);
  i++;
}

Comme la boucle for, la condition de boucle étant évaluée avant le code de boucle, il est possible qu'aucun tour de boucle ne soit effectué.

do {} while (...);

Cette variante du while peut s'avérer très utile dans certains algorithmes. La seule différence réside dans l'évaluation du test de boucle qui a lieu en fin de boucle. Si l'on veut toujours compter de 1 à 10, nous écrirons alors:

int i = 1;
do {
  printf("i vaut %d\n", i);
  i++;
} while (i <= 11);

2. Tests

if (...) {} else {}

Il s'agit du test de branchement le plus simple: en fonction d'une condition, on peut choisir d'exécuter un bloc ou non:

int i = 0;
if (i < 42) {
  printf("Effectivement, i est plus petit que 42\n");
}

On peut également fournir un bloc qui est exécuté si la condition n'est pas vérifiée:

if (i % 2) {
  printf("i est un nombre impair");
} else {
  printf("i est un nombre pair");
}

switch (...) { case: ...; }

Dans le cas où le choix n'est pas binaire, on peut brancher vers plusieurs issues possibles à partir d'une valeur précise. Cette construction ne fonctionne qu'avec les valeurs entières et assimilées (char, enum):

void choix_qcm(int reponse) {
  switch (reponse) {
    case 1: printf("Bonne réponse!"); break;
    case 2: printf("Mauvaise réponse!"); break;
    case 3: printf("Réponse acceptable, 1/2 point"); break;
    default: print("Reponse inconnue");
  }
}

La syntaxe est un peu surprenante: ce n'est pas un bloc qui suit les case valeur:, mais une suite d'instructions. Si le mot-clé break (voir plus bas) n'est pas utilisé en fin de cas, le cas suivant est évalué. Ceci permet d'effectuer les évaluations en cascade (pas de "break"), ou exclusives ("break" sur chaque cas).

3. Contrôles spéciaux

break

Il est possible à tout moment de sortir du bloc en cours: l'exécution continue alors à la première instruction suivant le bloc. Si en particulier le bloc est un code de boucle, alors la boucle se termine immédiatement. Exemple:

int i = 0;
for (;;) {
  if (i > 10) break;
  printf("i vaut %d\", i);
  i++;
}
printf("on continue le programme ici...");

continue

Ce mot-clé ne peut être utilisé que dans un code de boucle: il force le passage immédiat au tour de boucle suivant, tout en passant bien par le test de boucle s'il y en a un (for et while...):

while (fgets(buffer, 4096, stdin)) {
  if (buffer[0] == '#') continue;
  ...
}
Last modified 14 years ago Last modified on Oct 30, 2006, 2:45:34 PM