tags:

views:

241

answers:

9

let say my code look like below

for(..)
  for(..)
    for(..){
            break;  //this will break out from the most inner loop OR all 3 iterated loops?
    }
+3  A: 

From the most inner loop :)

    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;
                    }

Will produce :

0 0 0
0 1 0
1 0 0
1 1 0
Toms
+2  A: 

You should take a look here: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/branch.html

Konamiman
exactly the right documentation for the question.
pstanton
+23  A: 

Your example will break out of the innermost loop only. However, using a labeled break statement, you can do this:

outer:
  for(..)
    for(..)
      for(..){
        break outer;  //this will break out from all three loops
      }
Greg Hewgill
i dont like labels :(
ufukgun
@ufukgun: this is the only way you can get out of all loops whether you like it or not :)
Rakesh Juyal
@Raskesh you can return from a function or throw an exception to get out of a loop.
TimW
Or you can refactor your code to avoid nested for :)
romaintaz
@Rakesh or you can throw an exception and catch it at the outermost loop.
Andreas_D
But throwing an exception for flow control is not that super either,
HeDinges
labels are clearly more legible, tidy and efficient than managing booleans or throwing exceptions. if you can't tidily refactor to enclose in a method and return, breaking with a label IS the best solution.
pstanton
To be more precise: throw an exception if you have to break completly because an exceptional state occured. I thought that was clear. It's a technical solution but not suitable for all cases. For flow control: use labels (or avoid nested loops, think recursive).
Andreas_D
BTW - I have deleted my offending answer with technical alternatives to the valid and useful 'label' solution. It wasn't worth the loss of SO reputation.
Andreas_D
+9  A: 

This will only break out from the inner loop. You can also define a scope to break out from. More from the language specs:

A break statement with no label attempts to transfer control to the innermost enclosing switch, while, do, or for statement of the immediately enclosing method or initializer block; this statement, which is called the break target, then immediately completes normally.

Otto Allmendinger
+1 for looking up documentation.
Heinzi
A: 

it will breake from most inner loop,

if you want to break from all, you can hold a variable and change its value when you want to break, then control it at the beginning of each for loop

ufukgun
managing variables, although many seem to not like lables, is far messier and displays a general misunderstanding of the available constructs
pstanton
+6  A: 

Think a bit about these questions, maybe this way you'll learn more than alone from getting the answer (which has already been posted by now, I'm sure):

  • if you were alone, how would you decide? Make up a test case where it gets evident.
  • if you were to invent a language and add a break construct, how would it work? Which one would be the more useful behavior? Which one would be the one most people expected?
  • how would you solve breaking out of nested for loops in Java? In C or C++? In a language with no labels of any kind?

You'd be surprised at how much you can learn from these simple self-made exercises.

AttishOculus
+1! More thinking, less pestering other people on the internet!
Bombe
+1: more of both. :-)
Andrzej Doyle
+3  A: 

Yes, without labels it will break only the most inner loop.
Instead of using labels you can put your loops in a seperated function and return from the function.

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

    private void untilXx() {
        for()
            for()
                for()
                    if(xx)
                        return; 
    }
}
TimW
Yes, please, no breaks or even labels!
Fabian Steeg
+1  A: 

Many people here don't like labels and breaking. This technique can be compared to using a 'goto' statement, a flow control statement which allows jumping out of a block of code in a non-standard way, obliviating use of pre- and post conditions. Edsger Dijkstra published a famous article in Communications of the ACM, march 1968, 'Goto statement considered harmful' (it's a short read).

Using the same reasoning presented in the article, returning from inside an iteration as suggested by TimW is also bad practice. If one is strict, to create readable code, with predictable entry- and exit points, one should initialize the variable which will hold the return value (if any) at the beginning of the method and return only at the end of a mehod.

This poses a challenge when using an iteration to perform a lookup. To avoid using break or return one inevitably ends up with a while-loop with a regular stop condition and some boolean variable to indicate that the lookup has succeeded:

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, this works, but it seems a bit clunky to me. First of all I have to introduce a boolean to detect lookup success. Secondly I have to explicitly check targetFound after the loop to handle lookup failure.

I sometimes use this solution, which I think is more concise and readable:

lookup: {

    for(Value value : values) {

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

I think breaking (no pun intended) the rule here results in better code.

Adriaan Koster
Could you edit the first example so that both solutions use the improved for loop? This would help to compare, which solution is easier to understand (readability). Now it's an unfair competition.
Andreas_D
No I cannot. That's sort of my point. Without break or return statements (or System.exit() calls etc.) a for-loop always completes and I am assuming that nobody would accept the overhead of letting the iteration complete after the result was found. So either you work around breaks and returns by using a while-loop and an extra variable, or you accept using a break statement in combination with a for-loop and get much more concise code.
Adriaan Koster
+1  A: 

as often mentioned i don't like to break with a label eather. so while in a for loop most of the time i'm adding a boolean varible to simple exit the loop.. (only if i want to break it of cause;))

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

this is in my opinion more elegant than a break..

Dimitri