Breaking out of Nested Loops

Coming from a variant of BASIC, C++ seems to do a lot of things the hard way. I understand some of it is to squeeze every ounce of performance out of the code that it can, but others just do not make any sense to me.

In the variant of BASIC that I learned, you were able to break out of nested loops quite easily and with only one line:
1
2
3
4
5
6
7
8
9
Do
    For Int x = 1 To 10
        Do
            Break, Break, Break
        Loop
    Next x
Loop

Print "This code would never be reached without breaking the loops"


I can't seem to find any sort of analog in C++ to do the same. I can always do it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
   for (;;)
   {
       for (;;)
       {
           for (;;)
           {
               flag = true;
               break;
           }
           if (flag==true){break;}
       }
       if (flag==true){break;}
    }


And that's how a lot of the posts I've read on the subject suggest I do it, but it seems so... crude and needless to do it that way. Not to mention far more prone to human error. Is there any better way to do it without using a GOTO?
Last edited on
Yes and no.
Generally such deeply nested loops shouldn't happen in the first place. If it does, it's usually an indicator that you didn't split up your task in small enough functions - the inner loops likely should be in separate functions and sometimes the outer loop as well (possibly a generic algorithm as they are found in the STL).
C++11 further improves the situation by introducing lambda functions that you can define and repeatedly call inside a loop when defining a "real" function seems inappropriate.

But otherwise you will have to use a flag.
Last edited on
Gotta go with @Athar on this one. For one thing (no pun intended), why are you breaking out of for loops in the first place? For loops are for when you need to process, in some way or other, each element in a container in sequence. If you want to terminate a loop early, you're probably better off with 'while' or 'do...while', and even then you should (ideally) come out of the loop as a result of the conditional that's keeping it going evaluating to false, rather than forcing a break.
I sort of know what you mean about the 'hard way', but it's that way for a reason - to try to lead you to safer and more reliable programs. If you want them, of course ;)
Last edited on
@keineahnung, I usually use it to break out of two or three nested For loops written to read multi-dimensional arrays or other data structures where I want to check each unique combination of values for a result.

Ex: If I was trying to find the value 256 in a three-dimensional array, I would use this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int num[5][5][5];

for (int x = 0; x <= 5; x++)
{
    for (int y = 0; y <= 5; y++)
    {
        for (int z = 0; z <= 5; z++)
        {
            If (num[x][y][z] == 256)
            {
                cout << "Number has been found at location: " << x << y << z;
                //break the three for loops here, it's unnecessary to check any other locations
            }
        }
    }
}

The code above doesn't actually need to break early, but it can save quite a bit of CPU time if the value is found towards the beginning of a large array. In the case above, yes all I need is to use "return", but I have encountered a few places where it would have been very difficult to compartmentalize code similar to this in a seperate function. As I get more experienced I'll probably get better at writing less-dependent code sections, but until then I run into situations like this more often than I'd like.

It's always been the easiest and most logical way for me to accomplish it, but if I found a better way that made sense I'd gladly adopt it.
Last edited on
Hi
Well you can actually pull off that Break, Break, Break trick by using a goto statement with a label:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int num[5][5][5];

for (int x = 0; x <= 5; x++)
{
    for (int y = 0; y <= 5; y++)
    {
        for (int z = 0; z <= 5; z++)
        {
            if (num[x][y][z] == 256)
            {
                cout << "Number has been found at location: " << x << y << z;
                //break the three for loops here, it's unnecessary to check any other locations
                goto finish;
            }
        }
    }
}
finish: // now you're here but still inside function 


If you're feeling very adventurous you could always look at boost::multi_array (http://www.boost.org/doc/libs/1_47_0/libs/multi_array/doc/index.html). I think you can get that to work with some of the STL algorithms but at the expense of some mind-boggling syntax (- for me anyway).
Last edited on
Or you could just, you know, not use multidimensional arrays. Or use just a single loop to iterate over it. Or use a data type that provides iterators.
@hanst99
Or you could just, you know, not use multidimensional arrays.

LOL - I think you've hit the nail on the head there ;)
I can suggest another way, which doesn't use goto or even break, though it does use dummy variables:
1
2
3
4
5
6
7
8
9
10
11
12
bool Cond1 = true, Cond2 = true, Consd3 = true;
for (;Cond1;)
{
    for (;Cond2;)
    {
        for (;Cond3;)
        {
                flag = true;
                Cond1 = Cond2 = Cond3 =false;
         }        
    }
}
Last edited on
Or you could just, you know, not use multidimensional arrays.


How else should I represent things like 2D and 3D grids?
Topic archived. No new replies allowed.