7.10 Break and continue statements
The one-token statements continue
and break
may be used
within loops to alter control flow; continue
causes the next
iteration of the loop to run immediately, whereas break
terminates the loop and causes execution to resume after the loop.
Both control structures must appear in loops. Both break
and
continue
scope to the most deeply nested loop, but pass through
non-loop statements.
Although these control statements may seem undesirable because of their goto-like behavior, their judicious use can greatly improve readability by reducing the level of nesting or eliminating bookkeeping inside loops.
Break statements
When a break
statement is executed, the most deeply nested loop
currently being executed is ended and execution picks up with the next
statement after the loop. For example, consider the following
program:
while (1) {
if (n < 0) {
break;
}
foo(n);
n = n - 1;
}
The while~(1)
loop is a “forever” loop, because 1
is
the true value, so the test always succeeds. Within the loop, if the
value of n
is less than 0, the loop terminates, otherwise it
executes foo(n)
and then decrements n
. The statement
above does exactly the same thing as
while (n >= 0) {
foo(n);
n = n - 1;
}
This case is simply illustrative of the behavior; it is not a case
where a break
simplifies the loop.
Continue statements
The continue
statement ends the current operation of the loop
and returns to the condition at the top of the loop. Such loops are
typically used to exclude some values from calculations. For example,
we could use the following loop to sum the positive values in the
array x
,
real sum;
sum = 0;
for (n in 1:size(x)) {
if (x[n] <= 0) {
continue;
}
sum += x[n];
}
When the continue statement is executed, control jumps back to the
conditional part of the loop. With while and for loops, this causes
control to return to the conditional of the loop. With for loops,
this advances the loop variable, so the the above program will not go
into an infinite loop when faced with an x[n]
less than zero.
Thus the above program could be rewritten with deeper nesting by
reversing the conditional,
real sum;
sum = 0;
for (n in 1:size(x)) {
if (x[n] > 0) {
sum += x[n];
}
}
While the latter form may seem more readable in this simple case, the former has the main line of execution nested one level less deep. Instead, the conditional at the top finds cases to exclude and doesn’t require the same level of nesting for code that’s not excluded. When there are several such exclusion conditions, the break or continue versions tend to be much easier to read.
Breaking and continuing nested loops
If there is a loop nested within a loop, a break
or
continue
statement only breaks out of the inner loop. So
while (cond1) {
// ...
while (cond2) {
// ...
if (cond3) {
break;
}
// ...
}
// execution continues here after break
// ...
}
If the break is triggered by cond3
being true, execution will
continue after the nested loop.
As with break statements, continue statements go back to the top of
the most deeply nested loop in which the continue
appears.
Although break and continue must appear within loops, they may appear in nested statements within loops, such as within the conditionals shown above or within nested statements. The break and continue statements jump past any control structure other than while-loops and for-loops.