UKOnline

Instruction répétitive

Les instructions répétitives, également appelées instructions itératives ou boucles, permettent de répéter un certain nombre de fois une instruction ou un bloc de code. Il y a quatre types de boucle en Java : l'instruction while, l'instruction do, l'instruction for et l'instruction for-each. Cette section expose les trois premiers types; les boucles for-each étant traitée au chapitre 8.

Instruction while

L'instruction while permet de répéter une instruction ou un bloc de code tant qu'une condition est vraie. La condition est une expression booléenne, comme pour l'instruction if-else.

Commençons avec un exemple dont le but est d'afficher à l'écran tous les nombres entiers compris entre 1 et 5. Une fois tous ces nombres affiché, le programme affiche Done et se termine. Voici le corps de la méthode main :

L'exécution de ce programme affiche donc à la console :

1
2
3
4
5
Done

Pourriez-vous dire ce que le programme aurait affiché si on avait inversé les deux instructions du bloc while et d'abord fait compteur++ avant de faire System.out.println (compteur); ?

Comme le montre la figure 11, une instruction while est donc formée avec le mot réservé while suivi d'une condition entre parenthèses et d'une instruction. Cette instruction est appelée corps de la boucle.

While instruction syntax
Syntaxe de l'instruction while.

L'exécution d'une boucle while commence par l'évaluation de la condition. Si la valeur de celle-ci est false, la boucle est terminée et le programme continue son exécution. Si la valeur de la condition est true, le corps de la boucle est exécuté, et la condition est ensuite à nouveau évaluée et on recommence. Le corps de la boucle est donc exécuté tant que la condition est vérifiée. La figure 12 illustre l'exécution d'une boucle while. L'exécution d'une boucle est une succession d'itérations; une itération correspondant à une exécution du corps de la boucle.

While instruction flowchart
Instruction while.

Boucle infinie

Lorsqu'on utilise des boucles, il faut faire très attention aux boucles infinies. Comme le nom le suggère, il s'agit de boucles dont le corps est exécuté un nombre infini de fois. La condition est toujours vérifiée et la boucle ne s'arrête donc jamais de s'exécuter. Une boucle infinie dans un programme consiste la plupart du temps en une erreur logique (la plupart du temps car parfois de telles boucles sont voulues, notamment dans des applications de contrôle qui doivent fonctionner en permanence).

L'exemple suivant est une boucle infinie. En effet, la valeur de la variable compteur sera toujours plus petite ou égale à 0 puisqu'elle est initialisée à zéro et ne fait que diminuer :

Les boucles infinies sont en général assez difficiles à détecter, mais sont sources de problème. Si une telle boucle se présente dans vos programmes, la plupart du temps votre processeur va tourner à 100%. Il faut ensuite retrouver quelle boucle ne s'arrête pas.

Il existe des méthodes formelles qui permettent de prouver qu'une boucle se termine toujours, mais nous n'allons pas nous attarder là-dessus dans ce chapitre. Pour qu'une boucle se termine, il faut se convaincre que la condition finira tôt ou tard par valoir false. Pour ça, il faut que dans tous les chemins pouvant être empruntés lors de l'exécution du corps de la boucle, les variables impliquées dans la condition voient leurs valeurs changer, de sorte que la condition finisse par ne plus être vérifiée.

Dans l'exemple qu'on vient de voir, on se rend bien compte que la valeur de la variable compteur ne fait que diminuer et sera toujours plus petite ou égale à zéro. La plus simple boucle infinie que l'on puisse construire est tout simplement :

Notez qu'on aurait pu remplacer le bloc d'instruction vide ( {} ) par l'instruction vide ( ;).

Boucle imbriquée

Tout comme pour les instructions if-else, on peut imbriquer les instructions while. La figure 13 montre un programme qui affiche les tables de multiplications de 2, 3 et 4. Il y a une première boucle dont le but est de faire varier une variable n de 2 à 4. La seconde boucle permet de calculer tous les produits de n par 1, 2, ..., 10.

Programme qui affiche des tables de multiplication.

L'exécution du programme affiche à l'écran :

Table de 2 : 2 4 6 8 10 12 14 16 18 20 
Table de 3 : 3 6 9 12 15 18 21 24 27 30 
Table de 4 : 4 8 12 16 20 24 28 32 36 40 

Instruction do

L'instruction do est similaire à l'instruction while sauf pour ce qui est de l'ordre dans lequel les choses sont exécutées : le corps de la boucle est d'abord exécuté, puis la condition est évaluée. Si sa valeur est false, le programme continue; sinon, le corps de la boucle est à nouveau exécuté, etc... Ceci implique donc que le corps de la boucle sera exécuté au moins une fois dans tous les cas. La figure 14 illustre la syntaxe de cette instruction. Faites bien attention qu'il faut un point-virgule ( ; ) après la condition.

Do instruction syntax
Syntaxe de l'instruction do.

Comme le montre la figure 15, on voit donc bien que le corps de la boucle est exécuté au moins une fois. La condition est vérifiée après chaque itération et pas avant comme pour les boucles while.

Notez qu'il est toujours possible de transformer une boucle construite avec l'instruction do en une boucle while. Néanmoins, il est parfois plus clair et lisible d'utiliser l'instruction do, notamment pour mettre en avant le fait que le corps de la boucle sera exécuté au moins une fois.

Do instruction flowchart
Instruction do.

Voici comment on pourrait faire pour afficher les nombres entiers compris entre 1 et 5 avec l'instruction do :

Instruction for

Les deux instructions qu'on vient de voir sont intéressantes si vous ne savez pas de manière explicite combien de fois vous voulez que le corps de la boucle soit exécuté. Si on veut exécuter une instruction ou un bloc de code un nombre précis et connu de fois, on va préférer utiliser l'instruction for. Commençons avec le même exemple que précédemment, c'est-à-dire le programme qui affiche les nombres entiers de 1 à 5, mais faisons le avec l'instruction for :

Comme le montre la figure 16, l'instruction for commence par le mot réservé for suivi de trois éléments séparés par des points-virgules, le tout mis entre parenthèses, suivi du le corps de la boucle. Les trois éléments de la boucle for sont respectivement appelés l'initialisation, la condition et la mise à jour; elles sont toutes optionnelles.

For instruction syntax
Syntaxe de l'instruction for.

Si vous ne spécifiez pas de partie condition, c'est comme-ci vous aviez mis true comme condition. Voyons maintenant comme se déroule l'exécution d'une boucle for avec la figure 17. La partie initialisation est exécutée une seule fois, au début. Ensuite, la condition est évaluée : si sa valeur est false, la boucle s'arrête et le programme continue. Par contre, si la condition est vérifiée, le corps de la boucle est exécuté suivi par la partie mise à jour. Enfin, la condition est à nouveau évaluée et on boucle.

For instruction flowchart
Instruction for.

Dans la partie initialisation, on peut soit déclarer et initialiser une nouvelle variable, soit juste affecter une valeur à une variable déjà existante. Dans la partie mise à jour, on retrouve une instruction.

La figure 18 montre un exemple de boucle for infinie qui affiche à la console 1, 2, 3, 4, 5,... Dans ce cas-ci, le compilateur Java peut même détecter la boucle infinie et génèrera une erreur de compilation signalant que certaines instructions ne seront jamais atteinte :

InfiniteForLoop.java:10: unreachable statement
      System.out.println ("Ceci ne sera JAMAIS affiché");
      ^
1 error
Boucle infinie et code non atteignable.

Il n'y a que très peu de cas dans lesquels le compilateur peut détecter les boucles infinies. Il ne faut donc surtout pas compter sur lui pour vous aider et plutôt se montrer prudent et bien analyser vos boucles.

Équivalence des boucles for et while

Vous voyez que l'instruction for ressemble fort à l'instruction while. En fait, on peut toujours transformer une instruction for en une instruction while. Il suffit de commencer avec l'initialisation, ensuite vient l'instruction while avec la même condition que le for. Enfin, le corps du while est constitué avec le corps du for suivi par la partie mise à jour.

L'instruction for est beaucoup plus compacte et lisible que la while. Lorsqu'on voit par exemple for (int i = 1; i <= 5; i++), on lit « Pour i allant de 1 à 5 » et on sait donc qu'il y aura exactement cinq itérations. De plus, la portée de la variable déclarée dans la partie initialisation se limite au corps de la boucle et aux parties condition et mise à jour.

Plusieurs instructions

Enfin, sachez que l'on peut déclarer et initialiser plusieurs variables du même type dans la partie initialisation d'une boucle for et que l'on peut également avoir plusieurs instructions dans la partie mise à jour en les séparant par une virgule. Voici un exemple qui utilise deux variables i et j et affichant en même temps les entiers de 0 à 4 et de 0 à -4 :

L'exécution de ce programme affiche à l'écran :

0 / 0
1 / -1
2 / -2
3 / -3
4 / -4