Puis-je utiliser break pour quitter plusieurs boucles imbriquées?
Est-il possible d'utiliser la fonction break
pour quitter plusieurs boucles for
imbriquées? Si oui, comment vous y prendriez-vous faire cela? Pouvez-vous également contrôler combien de boucles la rupture sort?
17 réponses
AFAIK, C++ ne supporte pas les boucles de nommage, comme Java et d'autres langages. Vous pouvez utiliser un goto ou créer une valeur d'indicateur que vous utilisez. À la fin de chaque boucle, vérifiez la valeur du drapeau. Si c'est le cas, alors vous pouvez sortir de cette itération.
Non, ne gâchez pas avec un break
. C'est le dernier bastion de l'utilisation de goto
.
Une autre approche pour sortir d'une boucle imbriquée consiste à factoriser les deux boucles dans une fonction séparée, et return
de cette fonction lorsque vous voulez quitter.
Bien sûr, cela soulève l'autre argument de savoir si vous devriez jamais explicitement return
à partir d'une fonction autre qu'à la fin.
Juste pour ajouter une réponse explicite en utilisant lambdas:
for (int i = 0; i < n1; ++i) {
[&] {
for (int j = 0; j < n2; ++j) {
for (int k = 0; k < n3; ++k) {
return; // yay we're breaking out of 2 loops here
}
}
}();
}
Bien sûr, ce modèle a certaines limites et évidemment c++11 seulement mais je pense que c'est très utile.
Break ne quittera que la boucle la plus interne la contenant.
Vous pouvez utiliser goto pour sortir de n'importe quel nombre de boucles.
Bien sûr, goto est souvent Considérées comme Nuisibles.
Est-il approprié d'utiliser la fonction break[...]?
L'utilisation de break et goto peut rendre plus difficile la raison de l'exactitude d'un programme. Voir ici pour une discussion à ce sujet: Dijkstra n'était pas fou .
Bien que cet answear ait déjà été présenté, je pense qu'une bonne approche est de faire ce qui suit:
for(unsigned int z = 0; z < z_max; z++)
{
bool gotoMainLoop = false;
for(unsigned int y = 0; y < y_max && !gotoMainLoop; y++)
{
for(unsigned int x = 0; x < x_max && !gotoMainLoop; x++)
{
//do your stuff
if(condition)
gotoMainLoop = true;
}
}
}
Et ça?
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < 50; j++)
{
for(unsigned int k=0; k < 50; k++)
{
//Some statement
if (condition)
{
j=50;
k=50;
}
}
}
}
Une bonne façon de sortir de plusieurs boucles imbriquées est de refactoriser votre code en une fonction:
void foo()
{
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < 50; j++)
{
for(unsigned int k=0; k < 50; k++)
{
// If condition is true
return;
}
}
}
}
Un exemple de code utilisant goto
et une étiquette pour sortir d'une boucle imbriquée:
for (;;)
for (;;)
goto theEnd;
theEnd:
Goto peut être très utile pour casser des boucles imbriquées
for (i = 0; i < 1000; i++) {
for (j = 0; j < 1000; j++) {
for (k = 0; k < 1000; k++) {
for (l = 0; l < 1000; l++){
....
if (condition)
goto break_me_here;
....
}
}
}
}
break_me_here:
// Statements to be executed after code breaks at if condition
Je pense qu'un goto
est valide dans cette circonstance:
Pour simuler un break
/continue
, vous voulez:
Pause
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
goto theEnd;
}
}
}
theEnd:
Continuer
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
i++;
goto multiCont;
}
}
multiCont:
}
D'autres langages tels que PHP acceptent un paramètre pour break (c'est-à-dire break 2;) pour spécifier la quantité de niveaux de boucle imbriqués dont vous voulez sortir, C++ cependant ne le fait pas. vous devrez le résoudre en utilisant un booléen que vous avez défini sur false avant la boucle, défini sur true dans la boucle si vous voulez casser, plus un break conditionnel après la boucle imbriquée, en vérifiant si le booléen a été défini sur true et break si oui.
Je sais que c'est un ancien post . Mais je suggère une réponse un peu logique et plus simple.
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < conditionj; j++)
{
for(unsigned int k=0; k< conditionk ; k++)
{
// If condition is true
j= conditionj;
break;
}
}
}
Vous pouvez utiliser try...attraper.
try {
for(int i=0; i<10; ++i) {
for(int j=0; j<10; ++j) {
if(i*j == 42)
throw 0; // this is something like "break 2"
}
}
}
catch(int e) {} // just do nothing
// just continue with other code
Si vous devez sortir de plusieurs boucles à la fois, c'est souvent une exception de toute façon.
while (i<n) {
bool shouldBreakOuter = false;
for (int j=i + 1; j<n; ++j) {
if (someCondition) {
shouldBreakOuter = true;
}
}
if (shouldBreakOuter == true)
break;
}
Sortir d'une boucle for est un peu étrange pour moi, car la sémantique d'une boucle for indiquent généralement qu'il va lancer un certain nombre de fois. Cependant, ce n'est pas mal dans tous les cas; si vous cherchez quelque chose dans une collection et que vous voulez casser après l'avoir trouvé, c'est utile. Sortir des boucles imbriquées, cependant, n'est pas possible en C++; c'est dans d'autres langages grâce à l'utilisation d'un break étiqueté. Vous pouvez utiliser une étiquette et un goto, mais cela pourrait vous donner des brûlures d'estomac à nuit..? Semble être la meilleure option cependant.