Previous Table of Contents Next


3.4.7. break and continue

Frequently, it is necessary to modify the behavior of a loop slightly. Under certain conditions, it may be necessary to break out of a loop early, before its normal termination condition is met. Under certain conditions, it may be necessary to jump immediately to the next iteration through a loop, without completing the current one. The break and continue statements provide these capabilities. (In effect, both break and continue are constrained forms of goto, but they are favored in structured programming precisely because they are constrained.)

We have seen the break statement already, in the context of the switch statement. The break statement causes an immediate exit from the nearest enclosing loop or switch statement. For example, to read up to 10 lines of text from the file pointer fp using the fgets function, we might write this loop:

char lines[10][80];
int i;
for(i = 0; i < 10; i++)
       { if(fgets(lines[i], 80, fp) == NULL)
               break;
        }

If fgets returns a null pointer, signifying end-of-file, we use the break statement to exit the loop early, because it will be impossible to read all 10 lines. (See section 3.10.1 for more information on file pointers and fgets.)

The continue statement causes an immediate jump back to the head of a loop. The loop’s test expression is immediately executed, and if still true, another trip through the loop is taken. In a for loop, the increment expression is also executed, just as if execution had reached the end of the loop body normally.

Continuing the previous example, if the 10 lines of text are to be processed in some way, except for those that begin with a # character (which are to be treated, as is common in many data file formats, as comments), we might rewrite the loop like this:

for(i = 0; i < 10; i++)
       {
       if(fgets(lines[i], 80, fp) == NULL)
               break;
       if(lines[i][0] == ‘#’)
               continue;
       …other processing…
        }

If a line begins with #, the other processing is not performed. (Exactly 10 lines are read in any case, however, because continue does imply execution of the for loop’s increment expression. To read 10 noncomment lines, possibly reading more than 10 lines total, would require a different loop.)

We can summarize the operation of the break and continue statements with these three skeletal loops (after Kernighan and Ritchie):

while(expr)           for(e1; e2; e3)            do
      {                       {                        {
      body ;                  body ;                   body ;
cont: ;               cont:   ;                  cont: ;
      }                       }                        }
                                                       while(expr);
brk:                  brk:                       brk:

In each case, a continue statement implies a jump to the label cont, and a break statement implies a jump to the label brk. (This example brings out the one discrepancy in the comparison, made in section 3.4.5, between a for loop and the apparently equivalent while loop. In the pair of examples in section 3.4.5, a continue statement would cause expr3 to be skipped in the while loop, but it is always executed in the for loop.)

The break and continue statements work only on the innermost containing loop or (in the case of break) switch statement. When one loop is nested inside another, there is no way to specify that a break or continue within the inner loop should break or continue the outer one. When a switch statement is nested inside a loop, a break statement inside the switch terminates one case of the switch, but a continue statement continues the loop. (Neither the break nor continue statements have any effect on an enclosing or intervening if statement, however.)

Stylistically, break and continue statements are preferred when their use simplifies the normal processing case(s) within a loop. A continue statement could, in principle, always be replaced by inverting the test and placing the remainder of the loop body (which would have been skipped by a continue) into an if statement, at the cost of an extra level of indentation. A break statement could, in principle, always be replaced by adding extra tests and boolean control variables, at the cost of those extra tests and variables.

It is also possible to terminate a loop abnormally by using a goto statement (see the next section) or by returning from the containing function. For example, the body of a function that searches an array for a particular value, returning the index of the value or -1 if it cannot be found, might be written like this:

for(i = 0; i < arraysize; i++)
       { if(array[i] == value)
                 return i;       /* found */
       }
return -1;                       /* loop completed, so not found */


Previous Table of Contents Next