C language: does break statement break out of all loops?

Status
Not open for further replies.

grizedale

Advanced Member level 3
Joined
Jun 13, 2011
Messages
838
Helped
17
Reputation
34
Reaction score
17
Trophy points
1,298
Activity points
8,804
Supposing i have a break statement inside a for loop, which lies inside a while loop.

Does the break statement, if executed, make control jump out of both loops, or just out of the for loop?

eg

while(1);
{

for (i=0;i<10;i++) {

c = c+1;
if (c = 10) {break;}
}
d = d+1;
}
 

Does the break statement, if executed, make control jump out of both loops, or just out of the for loop?

Just the loop containing the break statement.

The break command can be used with any of the three loop forms as well as the switch statement. It causes program execution to skip the rest of the loop or switch containing the break statement and resume execution with the next command following the loop or switch program execution has immediately exited.

However, be aware, in your example, an if control structure is not a loop, therefore the program execution will resume after the for loop.

Code:
while(1);
{

     for (i=0;i<10;i++) {

        c = c+1;

        if (c = 10) {break;}
     }

     [COLOR="#FF0000"]d = d+1;[/COLOR]  // Program execution resumes here after encountering the break statement
}

Jump statements: The break statement


BigDog
 
There are many other ways to get the effect of breaking out of multiple loops. For example, let's say you are looking for a value in a 2D int array:

One option is to check your condition in all loops:
Code:
int haystack[10][20]; /* an array full of values. */
int needle; /* the value to search for. */

int i, j = 0;
for (i = 0; i < 10 && haystack[i][j] != needle; ++ i)
  for (j = 0; j < 20 && haystack[i][j] != needle; ++ j)
    ;

if (i == 10)
  printf("not found.\n");
else
  printf("found %d at [%d][%d]\n", needle, i, j);

That may not be appropriate depending on the nature of the condition, and also the dimensions of the array need to be specified twice (in the for loop conditions and also in the not-found check) which can increase the chance of making a mistake, especially in more complex code. But it works.

Another option is to set a termination flag (you said C so we'll use int, since C doesn't have bool):

Code:
int haystack[10][20]; /* an array full of values. */
int needle; /* the value to search for. */

int i, j, found = 0; /* found set to 1 if found. */
for (i = 0; i < 10 && !found; ++ i)
  for (j = 0; j < 20 && !found; ++ j)
    if (haystack[i][j] == needle)
      found = 1;

if (found)
  printf("found %d at [%d][%d]\n", needle, i, j);
else
  printf("not found.\n");

Another variation on that theme is to use your results as the flag:

Code:
int haystack[10][20]; /* an array full of values. */
int needle; /* the value to search for. */

int found_i = -1, found_j; /* found_i is both result and flag (-1 = not found). */
for (int i = 0; i < 10 && found_i == -1; ++ i)
  for (int j = 0; j < 20 && found_i == -1; ++ j)
    if (haystack[i][j] == needle) {
      found_i = i;
      found_j = j;
    }

if (found_i != -1)
  printf("found %d at [%d][%d]\n", needle, found_i, found_j);
else
  printf("not found.\n");

Note that in all above cases a "break" statement in the loop is extraneous, however if you have other code inside the loop after the condition that you don't want to execute, break would be appropriate, e.g. based on the second example above:

Code:
int haystack[10][20]; /* an array full of values. */
int needle; /* the value to search for. */

int i, j, found = 0; /* found set to 1 if found. */
for (i = 0; i < 10 && !found; ++ i) {
  for (j = 0; j < 20 && !found; ++ j) {
    if (haystack[i][j] == needle) {
      found = 1;
      break;
    }
    /* following code not executed if condition above was true */
    assert(!found);
    printf("i checked haystack[%d][%d] but didn't find it. :(\n", i, j);
  }
}

if (found)
  printf("found %d at [%d][%d]\n", needle, i, j);
else
  printf("not found.\n");

Of course, an "else" would accomplish the same thing in the above example. As you can see, there are many ways to skin this cat.

You could also encapsulate what you're doing in a function and use return, e.g.:

Code:
/* param: haystack - a 10x20 array to search in
 * param: needle - value to search for
 * param: found_i, found_j - if found, set to location, otherwise unmodified. do not pass null.
 * return: 1 if found, 0 if not. */
int search (const int haystack[10][20], int needle, int *found_i, int *found_j) {

  for (int i = 0; i < 10; ++ i)
    for (int j = 0; j < 20; ++ j)
      if (haystack[i][j] == needle) {
        *found_i = i;
        *found_j = j;
        return 1;
      }

  return 0; /* not found */

}

(Note: Personally I find code is easier to maintain when functions have only a single return point but in the above simple example there is no harm done.)

You could also use goto statements, which have a bad reputation, but the bad reputation is because they can easily enable a novice developer to write very confusing code, not because they are inherently problematic, e.g.:

Code:
int haystack[10][20]; /* an array full of values. */
int needle; /* the value to search for. */

int found_i = -1, found_j;
for (int i = 0; i < 10; ++ i)
  for (int j = 0; j < 20; ++ j)
    if (haystack[i][j] == needle) {
      found_i = i;
      found_j = j;
      goto search_complete;
    }
search_complete:

if (found_i != -1)
  printf("found %d at [%d][%d]\n", needle, found_i, found_j);
else
  printf("not found.\n");

It does not matter how you do it but find a way that is both simple and clear given your specific code.

J
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…