Accès rapide :
La vidéo
L'instruction break
Sortie de deux boucles imbriquées sans étiquette
Sortie de deux boucles imbriquées avec étiquette
Travaux pratiques
L'instruction continue
Utilisation de continue avec une étiquette
Travaux pratiques
Cette vidéo vous montre comment utiliser les instructions de débranchement de boucles (continue et break) ainsi que comment utiliser les étiquettes pour pouvoir débrancher de plusieurs niveaux de boucles imbriquées.
L'instruction break
permet de stopper, sous condition, l'exécution d'une boucle. Considérons l'exemple suivant : on cherche à parcourir
toutes les valeurs comprises entre 0 et 9 avec une boucle for
, sauf que si l'on rencontre la valeur 5 alors on stoppe l'exécution de
la boucle. Voici le code correspondant.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Demo { public static void main( String [] args ) { for( int i=0; i<10; i++ ) { // On teste si on doit quitter la boucle if ( i == 5 ) break; // On affiche la valeur de la variable i System.out.println( "i == " + i ); } } |
break
, mais comme ici il n'y a qu'une ligne à exécuter,
certaines personnes préféreront s'en passer. Perso, j'aurais tendance à vous conseiller de les mettre, mais bon il faut varier les plaisirs.
Voici maintenant les résultats produits par cet exemple.
$> javac Demo.java $> java Demo i == 0 i == 1 i == 2 i == 3 i == 4 $>
Parfois, il est necessaire de sortir de deux niveaux de boucles imbriquées. Dans ce cas, une possibilité est de propager un second break
suite à l'exécution d'un premier break
. Dans l'exemple suivant, on stoppe l'execution des deux boucles quand l'indice de la ligne et
l'indique de la colonne seront tous les deux égaux à 7.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class Demo { public static void main( String [] args ) { boolean mustEnd = false; for( int line=0; line<10; line++ ) { for( int column=0; column<10; column++ ) { if ( line == 7 && column == 7 ) { mustEnd = true; break; } System.out.printf( "%dx%d ", column, line ); } System.out.println(); if ( mustEnd ) break; } } } |
Et voici les résultats produits par cet exemple.
$> javac Demo.java $> java Demo 0x0 1x0 2x0 3x0 4x0 5x0 6x0 7x0 8x0 9x0 0x1 1x1 2x1 3x1 4x1 5x1 6x1 7x1 8x1 9x1 0x2 1x2 2x2 3x2 4x2 5x2 6x2 7x2 8x2 9x2 0x3 1x3 2x3 3x3 4x3 5x3 6x3 7x3 8x3 9x3 0x4 1x4 2x4 3x4 4x4 5x4 6x4 7x4 8x4 9x4 0x5 1x5 2x5 3x5 4x5 5x5 6x5 7x5 8x5 9x5 0x6 1x6 2x6 3x6 4x6 5x6 6x6 7x6 8x6 9x6 0x7 1x7 2x7 3x7 4x7 5x7 6x7 $>
Une autre posibilité pourrait être utilisée pour arriver au même résultat. Effectivement, il est possible de débrancher directement de plusieurs
boucles en utilisant la notion d'étiquette. Une etiquette est introduite par la syntaxe suivante : un identifiant (forcément différent d'un mot clé Java)
suivi d'un caractère :
. L'étiquette utilisée par le break
devra être placée juste au dessus de la boucle de plus
haut niveau de laquelle il faudra débrancher. Voici un exemple d'utilisation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class Demo { public static void main( String [] args ) { forBreak: for( int line=0; line<10; line++ ) { for( int column=0; column<10; column++ ) { if ( line == 7 && column == 7 ) { break forBreak; } System.out.printf( "%dx%d ", column, line ); } System.out.println(); } } } |
On s'inspire du code développé lors des travaux pratiques relatifs au chapitre sur l'instruction « for each », à savoir la possibilité de gérer un labyrinthe. Le code suivant vous propose un exemple de labyrinthe à partir duquel vous pouvez démarrer l'exercice.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class Demo { public static void main( String [] args ) { // On définit le tableau : la méthode toCharArray transforme // une chaîne de caractères en un tableau de caractères. char [][] maze = { "######################################".toCharArray(), "# # # # #".toCharArray(), "###### # # ### # ########### # ### #D#".toCharArray(), "# # # #S# # # # # #####".toCharArray(), "### #### # # # # # # # # # # # # #".toCharArray(), "# # # # # # # ######### ####### #".toCharArray(), "# #### # # # # # # # #".toCharArray(), "# # # # # # # ########### # # # #".toCharArray(), "# ###### # # # # # # # # # # # # # # #".toCharArray(), "# # # # # # # # #".toCharArray(), "######################################".toCharArray() }; // TODO : trouver la pos } } |
Le but est de trouver les coordonées x et y de la sortie, identifiée par le caractère 'S'
. Dès que vous trouvez la position, vous devrez
suspendre l'execution des boucles. A vous de jouer.
Voici ma proposition de correction.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public class Demo { public static void main( String [] args ) { // On définit le tableau : la méthode toCharArray transforme // une chaîne de caractères en un tableau de caractères. char [][] maze = { "######################################".toCharArray(), "# # # # #".toCharArray(), "###### # # ### # ########### # ### #D#".toCharArray(), "# # # #S# # # # # #####".toCharArray(), "### #### # # # # # # # # # # # # #".toCharArray(), "# # # # # # # ######### ####### #".toCharArray(), "# #### # # # # # # # #".toCharArray(), "# # # # # # # ########### # # # #".toCharArray(), "# ###### # # # # # # # # # # # # # # #".toCharArray(), "# # # # # # # # #".toCharArray(), "######################################".toCharArray() }; // On recherche la position de la sortie int x=0; int y=0; forSearchBreak: for( y=0; y<maze.length; y++ ) { for( x=0; x<maze[y].length; x++ ) { if ( maze[y][x] == 'S' ) { break forSearchBreak; } } } System.out.printf( "La sortie est en %dx%d\n", x, y ); } } |
Si tout se passe bien dans votre programme, vous devriez trouver que la sortie du labyrinthe proposé est en position 12x3.
A l'instar de l'instruction break
, continue
est aussi une instruction de débranchement. Par contre, elle ne termine pas
totalement la boucle. Elle permet seulement de terminer le tour de boucle courant et de passer au tour suivant. L'exemple suivant calcule la somme
des dix premiers entiers positifs, sauf pour la valeur 5.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Demo { public static void main(String args[]){ int sum = 0; for( int i=1; i<=10; i++ ) { if ( i == 5 ) continue; sum += i; } String message = "La somme des dix premiers entiers positifs (privé de 5) est de : "; System.out.println( message + sum ); } } |
Dans l'exemple ci-dessus, l'instruction continue
est utilisée pour passer un tour durant l'exécution de la boucle for
.
Comme l'incrémentation est pris en charge par le for
, on passe bien à 6. Par contre, faites attention si vous utiliser un
continue
dans un while
: il faut garantir qu'on ne va pas exécuter une boucle infinie, car l'incrément de l'indice de boucle
est situé dans le corps de la boucle. Voici un second exemple, qui fait la même chose que l'exemple précédent, mais en utilisant le couple
while
/ continue
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class Demo { public static void main(String args[]){ int sum = 0; int i = 1; while ( i<=10 ) { if ( i == 5 ) { i++; // A ne pas oublier : testez sans ;-) continue; } sum += i; i++; } String message = "La somme des dix premiers entiers positifs (privé de 5) est de : "; System.out.println( message + sum ); } } |
Tout comme pour l'instruction break
, il est possible d'utiliser l'instruction continue
pour passer au tour suivant avec des
boucles imbriquées. Dans ce cas, il vous faudra aussi utiliser une étiquette associée à la boucle sur laquelle vous souhaitez démarrer un nouveau
tour de boucle. Encore une fois, l'étiquette doit être placée au dessus de la boucle à laquelle elle est associée.
L'exemple de code suivant définit un tableau de tableaux d'entiers. Vous devez calculer, pour chaque ligne, la somme des entiers de la ligne. Mais attention, si une valeur négative est rencontrée dans le parcours d'une ligne, on devra abandonner le calcul de la somme des valeurs de la ligne courante et passer à la suivante.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class Demo { public static void main( String [] args ) { int [][] data = { { 10, 20, 30, 40, 50 }, // 150 { 10, 20, -1, 40, 50 }, // Doit être ignorée { 100, 200, 300, 400, 500 }, // 1500 { 5, -5, 10, 11, 12 }, // Doit être ignorée { 1, 2, 3, 4, 5 } // 15 }; // TODO calculer la somme des valeurs de chaque ligne. // Mais si une ligne contient une valeur négative, on doit la passer. } } |
A vous de jouer et éviter de regarder la correction trop vite.
La correctionVoici maintenant ma correction.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class Demo { public static void main( String [] args ) { int [][] data = { { 10, 20, 30, 40, 50 }, // 150 { 10, 20, -1, 40, 50 }, // Doit être ignorée { 100, 200, 300, 400, 500 }, // 1500 { 5, -5, 10, 11, 12 }, // Doit être ignorée { 1, 2, 3, 4, 5 } // 15 }; labelForLine: for( int line=0; line<data.length; line++ ) { int sum = 0; for( int column=0; column<data[line].length; column++ ) { int value = data[line][column]; if ( value < 0 ) continue labelForLine; sum += value; } System.out.println( "Sum for line " + line + " == " + sum ); } } } |
Et voici les résultats produits par cet exemple :
$> javac Demo.java $> java Demo Sum for line 0 == 150 Sum for line 2 == 1500 Sum for line 4 == 15 $>
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :