2009-11-24 6 views

Répondre

28

Votre exemple ne sortira que de la boucle la plus interne. Cependant, en utilisant une instruction labeled break, vous pouvez le faire:

outer: 
    for(..) 
    for(..) 
     for(..){ 
     break outer; //this will break out from all three loops 
     } 
+6

Je n'aime pas les étiquettes :( – ufukgun

+4

@ufukgun: c'est la seule façon de sortir de toutes les boucles que cela vous plaise ou non :) –

+1

@Raskesh vous pouvez revenir d'une fonction ou lancer une exception pour sortir d'une boucle . – TimW

3

De la boucle la plus intérieure :)

int i,j,k; 
    for(i = 0; i < 2; i++) 
      for(j = 0; j < 2; j++) 
        for(k = 0; k < 2; k++) 
        { 
          printf("%d %d %d\n", i, j, k); 
          break; 
        } 

va émettre:

0 0 0 
0 1 0 
1 0 0 
1 1 0 
11

Cela ne sortir de la boucle intérieure. Vous pouvez également définir une portée à partir de laquelle. Plus de la language specs:

Une instruction break sans étiquette tente de transférer le contrôle au plus profond enfermant l'interrupteur, alors que, faire, ou déclaration de la méthode englobante immédiatement ou bloc initialiseur; cette instruction, qui est appelée la cible de pause , puis immédiatement se termine normalement.

+1

+1 pour rechercher de la documentation. – Heinzi

-2

il breake de la plupart boucle interne,

si vous voulez rompre tout, vous pouvez tenir une variable et changer sa valeur lorsque vous voulez briser, puis contrôler au début de chacun pour boucle

+1

gérer des variables, bien que beaucoup semblent ne pas aimer les lables, est beaucoup plus en désordre et affiche un malentendu général des constructions disponibles – pstanton

7

Pensez un peu à ces questions, peut-être cette façon, vous en apprendrez plus que tout seul d'obtenir la réponse (qui a déjà été écrit maintenant, je suis sûr):

  • si vous étiez seul, comment décideriez-vous? Faites un test élémentaire là où cela devient évident.
  • Si vous deviez inventer un langage et ajouter une construction de rupture, comment cela fonctionnerait-il? Lequel serait le comportement le plus utile? Lequel serait le plus attendu?
  • comment résoudreiez-vous la rupture des boucles for imbriquées dans Java? En C ou C++? Dans une langue sans étiquettes d'aucune sorte?

Vous seriez surpris de voir tout ce que vous pouvez apprendre de ces simples exercices faits par vous-même.

+0

+1! Plus de réflexion, moins de harcèlement d'autres personnes sur internet! – Bombe

+0

+1: plus des deux. :-) –

3

Oui, sans étiquettes, il ne casse que la boucle la plus interne. Au lieu d'utiliser des étiquettes, vous pouvez placer vos boucles dans une fonction séparée et revenir à la fonction.

class Loop { 
    public void loopForXx() { 
     untilXx(); 
    } 

    private void untilXx() { 
     for() 
      for() 
       for() 
        if(xx) 
         return; 
    } 
} 
+1

Oui, s'il vous plaît, pas de pauses ou même des étiquettes! –

0

Beaucoup de gens ici n'aiment pas les étiquettes et la casse. Cette technique peut être comparée à l'utilisation d'une instruction 'goto', une instruction de contrôle de flux qui permet de sauter d'un bloc de code d'une manière non standard, en ignorant l'utilisation des conditions pré et post. Edsger Dijkstra a publié un article célèbre dans Communications de l'ACM, mars 1968, 'Déclaration de Goto considérée comme nuisible' (c'est une courte lecture).En utilisant le même raisonnement présenté dans l'article, revenir de l'intérieur d'une itération comme suggéré par TimW est également une mauvaise pratique. Si l'on est strict, pour créer du code lisible, avec des points d'entrée et de sortie prévisibles, on devrait initialiser la variable qui contiendra la valeur de retour (le cas échéant) au début de la méthode et retourner seulement à la fin d'un mehod.

Cela pose un défi lors de l'utilisation d'une itération pour effectuer une recherche. Pour éviter d'utiliser pause ou retour on finit inévitablement par une boucle while avec une condition d'arrêt régulier et une variable booléenne pour indiquer que la recherche a réussi:

boolean targetFound = false; 
int i = 0; 
while (i < values.size() && ! targetFound) { 

    if (values.get(i).equals(targetValue)) { 
     targetFound = true; 
    } 
} 
if (!targetFound) { 
    // handle lookup failure 
} 

Ok, cela fonctionne, mais il semble un peu maladroit pour moi. Tout d'abord, je dois introduire un booléen pour détecter le succès de la recherche. Deuxièmement, je dois vérifier explicitement targetFound après la boucle pour gérer l'échec de la recherche.

J'utilise parfois cette solution, qui je pense est plus concis et facile à lire:

lookup: { 

    for(Value value : values) { 

     if (value.equals(targetValue)) { 
      break lookup; 
     } 
    } 
    // handle lookup failure here 
} 

Je pense casser (sans jeu de mots) la règle résulte ici un meilleur code.

+0

Pourriez-vous éditer le premier exemple afin que les deux solutions utilisent la boucle améliorée pour? Cela aiderait à comparer, quelle solution est plus facile à comprendre (lisibilité). Maintenant, c'est une concurrence déloyale. –

+0

Non, je ne peux pas. C'est en quelque sorte mon point. Sans les instructions break ou return (ou les appels System.exit() etc.), une boucle for termine toujours et je suppose que personne n'accepterait la surcharge de laisser l'itération terminée après que le résultat ait été trouvé. Donc soit vous travaillez autour des pauses et des retours en utilisant une boucle while et une variable supplémentaire, soit vous acceptez d'utiliser une instruction break en combinaison avec une boucle for et obtenez un code beaucoup plus concis. –

1

comme souvent mentionné je n'aime pas rompre avec une étiquette. Ainsi, alors que dans une boucle la plupart du temps je suis l'ajout d'un varible booléenne sortie simple, la boucle .. (seulement si je veux briser la cause;))

boolean exit = false; 
for (int i = 0; i < 10 && !exit; i++) { 
    for (int j = 0; j < 10 && !exit; j++) { 
     exit = true; 
    } 
} 

c'est à mon avis plus élégant que d'une pause ..