[c] How to break out of nested loops?

If I use a break statement, it will only break inner loop and I need to use some flag to break the outer loop. But if there are many nested loops, the code will not look good.

Is there any other way to break all of the loops? (Please don't use goto stmt.)

for(int i = 0; i < 1000; i++) {
   for(int j = 0; j < 1000; j++) {
       if(condition) {
            // both of the loops need to break and control will go to stmt2
       }
   }

}

stmt2

This question is related to c nested-loops break

The answer is


int i = 0, j= 0;

for(i;i< 1000; i++){    
    for(j; j< 1000; j++){
        if(condition){
            i = j = 1001;
            break;
        }
    }
}

Will break both the loops.


I note that the question is simply, "Is there any other way to break all of the loops?" I don't see any qualification but that it not be goto, in particular the OP didn't ask for a good way. So, how about we longjmp out of the inner loop? :-)

#include <stdio.h>
#include <setjmp.h>

int main(int argc, char* argv[]) {
  int counter = 0;
  jmp_buf look_ma_no_goto;
  if (!setjmp(look_ma_no_goto)) {
    for (int i = 0; i < 1000; i++) {
      for (int j = 0; j < 1000; j++) {
        if (i == 500 && j == 500) {
          longjmp(look_ma_no_goto, 1);
        }
        counter++;
      }
    }
  }
  printf("counter=%d\n", counter);
}

The setjmp function returns twice. The first time, it returns 0 and the program executes the nested for loops. Then when the both i and j are 500, it executes longjmp, which causes setjmp to return again with the value 1, skipping over the loop.

Not only will longjmp get you out of nested loops, it works with nested functions too!


I think goto will solve the problem

for(int i = 0; i < 1000; i++) {
    for(int j = 0; j < 1000; j++) {
        if (condition) {
            goto end;
        }
    }
}

end:
stmt2 

 

If you need the values of i and j, this should work but with less performance than others

for(i;i< 1000; i++){    
    for(j; j< 1000; j++){
        if(condition)
            break;
    }
    if(condition) //the same condition
        break;
}

bool stop = false;
for (int i = 0; (i < 1000) && !stop; i++)
{
    for (int j = 0; (j < 1000) && !stop; j++)
    {
        if (condition)
            stop = true;
    }
}

A different approach is to refactor the code from two for loops into a for loop and one manual loop. That way the break in the manual loop applies to the outer loop. I used this once in a Gauss-Jordan Elimination which required three nested loops to process.

for (int i = 0; i < 1000; i++)
{
    int j = 0;

MANUAL_LOOP:;

    if (j < 1000)
    {
       if (condition)
       {
           break;
       }

       j++;
       goto MANUAL_LOOP;
    }
}

No, don't spoil the fun with a break. This is the last remaining valid use of goto ;)

If not this then you could use flags to break out of deep nested loops.

Another approach to breaking out of a nested loop is to factor out both loops into a separate function, and return from that function when you want to exit.

Summarized - to break out of nested loops:

  1. use goto
  2. use flags
  3. factor out loops into separate function calls

Couldn't resist including xkcd here :)

enter image description here

source

Goto's are considered harmful but as many people in the comments suggest it need not be. If used judiciously it can be a great tool. Anything used in moderation is fun.


for(int i = 0; i < 1000; i++) {
   for(int j = 0; j < 1000; i++) {
       if(condition) {
            goto end;
   }
} 

end:

Caution: This answer shows a truly obscure construction.

If you are using GCC, check out this library. Like in PHP, break can accept the number of nested loops you want to exit. You can write something like this:

for(int i = 0; i < 1000; i++) {
   for(int j = 0; j < 1000; j++) {
       if(condition) {
            // break two nested enclosing loops
            break(2);
       }
   }
}

i = 0;

do
{
  for (int j = 0; j < 1000; j++) // by the way, your code uses i++ here!
  {
     if (condition)
     {
       break;
     }
  }

  ++i;

} while ((i < 1000) && !condition);

One way is to put all the nested loops into a function and return from the inner most loop incase of a need to break out of all loops.

function() 
{    
  for(int i=0; i<1000; i++)
  {
   for(int j=0; j<1000;j++)
   {
      if (condition)
        return;
   }
  }    
}

Use this wise advice from LLVM team:

"Turn Predicate Loops into Predicate Functions"

See:

http://llvm.org/docs/CodingStandards.html#turn-predicate-loops-into-predicate-functions


You'll need a boolean variable, if you want it readable:

bool broke = false;
for(int i = 0; i < 1000; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      broke = true;
      break;
    }
  }
  if (broke)
    break;
}

If you want it less readable you can join the boolean evaluation:

bool broke = false;
for(int i = 0; i < 1000 && !broke; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      broke = true;
      break;
    }
  }
}

As an ultimate way you can invalidate the initial loop:

for(int i = 0; i < size; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      i = size;
      break;
    }
  }
}

for(int i = 0; i < 1000; i++) {
    for(int j = 0; j < 1000; i++) {
       if(condition) {
          func(para1, para2...);
          return;
       }
    }
}

func(para1, para2...) {
    stmt2;
}

Examples related to c

conflicting types for 'outchar' Can't compile C program on a Mac after upgrade to Mojave Program to find largest and second largest number in array Prime numbers between 1 to 100 in C Programming Language In c, in bool, true == 1 and false == 0? How I can print to stderr in C? Visual Studio Code includePath "error: assignment to expression with array type error" when I assign a struct field (C) Compiling an application for use in highly radioactive environments How can you print multiple variables inside a string using printf?

Examples related to nested-loops

Single Line Nested For Loops How to break out of nested loops? Breaking/exit nested for in vb.net bash shell nested for loop Iterate Multi-Dimensional Array with Nested Foreach Statement How to break nested loops in JavaScript? Can I use break to exit multiple nested 'for' loops? How do I break out of nested loops in Java? Breaking out of nested loops Breaking out of a nested loop

Examples related to break

How to break a while loop from an if condition inside the while loop? illegal use of break statement; javascript How can I use break or continue within for loop in Twig template? break statement in "if else" - java Regarding Java switch statements - using return and omitting breaks in each case Is it bad practice to use break to exit a loop in Java? break/exit script Breaking out of a for loop in Java How to break out of while loop in Python? How to kill a while loop with a keystroke?