C / LOOPS AND JUMPS
break and continue without tangling control flow
Use break and continue knowing exactly where control lands in each loop form, and tell an early exit from a completed one.
What you will learn
- Predict where continue lands in for, while and do-while loops
- Use continue as a top-of-body guard so the real work stays at one indent level
- Distinguish a break exit from a normal exit by testing the index or a flag
- Recognise that break inside a switch inside a loop ends only the switch
Understanding break and continue without tangling control flow
break ends the innermost enclosing loop or switch statement; continue abandons the rest of the current iteration but leaves the loop running. Both are jumps, yet their targets are fixed by the surrounding braces, so you can find the landing point by reading outward from the statement itself. That is why they stay readable: there is exactly one destination, and it is either the statement after the loop or the start of the next iteration.
The trap is that "start of the next iteration" means different things in different loops. In a for loop, continue runs the third clause first, so an i++ written in the header still happens. In a while loop, continue goes straight to the controlling expression, so an i++ sitting at the bottom of the body is skipped and the loop spins forever on the same value. In a do-while, continue jumps to the condition at the bottom, which is evaluated normally, so the loop can still finish.
Two habits keep these statements from turning a loop into a puzzle. Write continue as a guard at the very top of the body: reject the cases you do not care about, then state the real work once, at a single indentation level, instead of scattering continues among statements whose reachability the reader has to reconstruct. And because break silently discards the remaining iterations, leave a record of why the loop stopped, either by comparing the index against the bound or by setting a flag, and test that record immediately after the closing brace.
<stdio.h>
int main(void)
{
int data[] = {4, -1, 7, 0, 9, -3, 2};
int n = (int)(sizeof data / sizeof data[0]);
int sum = 0;
int i;
for (i = 0; i < n; i++) {
if (data[i] < 0)
continue; /* skip this one; i++ still runs */
if (data[i] == 0)
break; /* 0 is the sentinel: stop reading */
sum += data[i];
}
if (i == n)
printf("ran to the end, sum = %d\n", sum);
else
printf("stopped at index %d, sum = %d\n", i, sum);
return 0;
}
continue and break jump to a point fixed by the innermost enclosing loop or switch, and that point is not the same in a for loop as in a while loop.
Worked examples
continue in a while loop, without hanging
Shows how to place the index advance so that continue cannot skip it.
<stdio.h>
int main(void)
{
int i = 0;
int odds = 0;
while (i < 10) {
int v = i; /* value for this iteration */
i++; /* advance first, so continue can never skip it */
if (v % 2 == 0)
continue;
odds += v;
printf("kept %d\n", v);
}
printf("i = %d, odds = %d\n", i, odds);
return 0;
}
Example explained
Line 1A while loop has no third clause, so continue jumps directly to the test i < 10.
Line 2i++ is placed above the continue, which is the only way to guarantee it runs on every iteration.
Line 3v holds the value belonging to this iteration, since i has already moved on.
Line 4The final i = 10 shows the loop ended through its condition rather than by getting stuck.
break inside a switch inside a loop
Demonstrates that a switch swallows break, so ending the loop needs something else.
<stdio.h>
int main(void)
{
const char *cmd = "arbq";
int done = 0;
int i;
for (i = 0; cmd[i] != '\0' && !done; i++) {
switch (cmd[i]) {
case 'a':
printf("add\n");
break; /* leaves the switch, not the for */
case 'r':
printf("remove\n");
break;
case 'q':
done = 1; /* the loop condition is what stops us */
break;
default:
printf("unknown '%c'\n", cmd[i]);
break;
}
}
printf("processed %d chars\n", i);
return 0;
}
Example explained
Line 1Each break here terminates the switch statement; the for loop then continues as normal.
Line 2case 'q' sets done, and the loop's own condition !done is what ends the iteration sequence.
Line 3i++ runs after the 'q' iteration, so i reaches 4 and counts 'q' as processed.
Line 4Without the done flag there is no structured way to leave the loop from inside the switch.
Important notes
continue is valid only inside a loop; break is valid inside a loop or a switch. Neither escapes more than one enclosing statement, so leaving two nested loops needs a flag or a return.
Because continue discards the rest of the body, end-of-iteration work such as a log line or a counter update is discarded too. Put that work in the for header's third clause or after the loop.
Common mistakes
Incrementing at the bottom of a while body with a continue above it: the counter never changes and the program hangs on the same element.
Expecting break inside a switch to end the surrounding loop: the switch ends instead, the next iteration starts, and a "quit" case appears to do nothing.
Declaring the counter in the for header and then testing it after the loop to see whether break fired: the name is out of scope there, so the code fails to compile or silently reads an unrelated outer variable.
Try it yourself
Change, predict, then run
Rewrite the main example as a while loop that still skips negatives and stops at the first 0, positioning the index advance so continue cannot skip it. Confirm it still reports index 3 and sum 11.
Open the C workspaceCheck your understanding
Given int i = 0; while (i < 5) { if (i == 2) continue; printf("%d ", i); i++; } what happens?
- It prints "0 1 " and then hangs, retesting i < 5 with i stuck at 2
- It prints "0 1 3 4 ", because continue in a while loop still performs the i++ at the bottom of the body
- It prints "0 1 " and then leaves the loop, because continue with nothing left to execute behaves like break
- It fails to compile, because continue must be the last statement in a loop body
Show answer
continue transfers control straight to the controlling expression i < 5, so the i++ written below it never runs when i is 2; i stays 2 and the condition stays true forever. The second option describes for-loop behaviour: only a for header's third clause is guaranteed to run on continue, and a while loop has no such clause.