break and continue
Chapter Thirty
Syllabus topic 1, "Control Flow: Statements and Blocks, If-Else, Else-If, Switch, Loops- While and For Loops Do-while, Break and Continue, Goto and Labels"
Pages 141 to 145 of 222
In one line
break leaves the innermost loop or switch at once, and continue abandons the rest of the current pass and goes on to the next one.
break
#include <stdio.h>
int main(void)
{
int a[] = {4, 17, 8, 23, 42, 9};
int n = 6;
int target = 23;
int found_at = -1;
for (int i = 0; i < n; i++) {
printf("looking at a[%d] = %d\n", i, a[i]);
if (a[i] == target) {
found_at = i;
break; /* stop: there is nothing left to learn */
}
}
if (found_at >= 0) {
printf("%d is at index %d\n", target, found_at);
} else {
printf("%d is not in the array\n", target);
}
return 0;
}looking at a[0] = 4
looking at a[1] = 17
looking at a[2] = 8
looking at a[3] = 23
23 is at index 3The loop examined four elements and stopped. It did not look at 42 or 9, because the question was answered. That is the honest use of break: a search, where continuing would be work with no purpose.
found_at starting at -1 is the idiom that goes with it. After the loop, -1 means "not found" and anything else is the position. Chapter 36 uses the same pattern.
continue
#include <stdio.h>
int main(void)
{
int a[] = {4, -17, 8, -23, 42, 0, 9};
int n = 7;
int sum = 0, counted = 0;
for (int i = 0; i < n; i++) {
if (a[i] <= 0) {
continue; /* skip this one, go on to the next */
}
sum = sum + a[i];
counted++;
}
printf("the %d positive value(s) sum to %d\n", counted, sum);
return 0;
}the 4 positive value(s) sum to 63continue did not end the loop; it ended the pass. It is a way of saying "this one does not interest us" at the top of a body, which keeps the rest of the body from being wrapped in an if.
The same loop written without continue:
for (int i = 0; i < n; i++) {
if (a[i] > 0) {
sum = sum + a[i];
counted++;
}
}For two lines, that version is clearer. continue earns its place when the body is long, or when there are several separate reasons to skip.
The difference between continue in a for and in a while
This is the one to get right, and it is where continue causes a hung program.
In a for loop, continue jumps to the step clause, so the counter still advances.
In a while loop, continue jumps straight to the condition, so anything in the body that was going to advance the counter is skipped.
break and continue
#include <stdio.h>
int main(void)
{
printf("for loop, continue skips to the step: ");
for (int i = 1; i <= 6; i++) {
if (i % 2 == 0) {
continue;
}
printf("%d ", i);
}
printf("\n");
printf("while loop, written correctly: ");
int i = 0;
while (i < 6) {
i++; /* advance FIRST */
if (i % 2 == 0) {
continue;
}
printf("%d ", i);
}
printf("\n");
return 0;
}for loop, continue skips to the step: 1 3 5
while loop, written correctly: 1 3 5The for loop is safe because i++ is in the header and continue runs it. The while loop was made safe by advancing i before the continue can be reached.
Written the other way round it never ends:
int i = 0;
while (i < 6) {
if (i % 2 == 0) {
continue; /* jumps to the condition; i never changes */
}
printf("%d ", i);
i++;
}i starts at 0, which is even, so continue runs, the condition is tested, i is still 0, and so on for ever. The rule: in a while loop, make the progress happen before any continue can skip it.
break in a switch inside a loop
Chapter 29 said a break in a case does not leave the loop. Here is the proof.
#include <stdio.h>
int main(void)
{
printf("with break in the case:\n");
for (int i = 1; i <= 4; i++) {
switch (i) {
case 3:
printf(" i is 3, and break here leaves the SWITCH\n");
break;
default:
printf(" i is %d\n", i);
break;
}
}
printf("\nto leave the loop, use a flag:\n");
int done = 0;
for (int i = 1; i <= 4 && !done; i++) {
switch (i) {
case 3:
printf(" i is 3, setting done\n");
done = 1;
break;
default:
printf(" i is %d\n", i);
break;
}
}
printf("\n");
return 0;
}with break in the case:
i is 1
i is 2
i is 3, and break here leaves the SWITCH
i is 4
to leave the loop, use a flag:
i is 1
i is 2
i is 3, setting doneThe first loop ran all four passes. The break in case 3 ended the switch for that pass and the loop carried on, which is almost never what a student writing that code intends.
Three ways out of a loop from inside a switch:
- A flag, tested in the loop's condition, as above.
return, if the loop is the last thing the function does.goto, which chapter 31 covers and which is the honest choice for leaving several nested levels at once.
break and continue
break in nested loops
break leaves one level. In a nested loop it leaves the inner loop only.
#include <stdio.h>
int main(void)
{
printf("break leaves only the inner loop:\n");
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (j == 2) {
break;
}
printf(" i=%d j=%d\n", i, j);
}
}
printf("\nleaving both, with a flag:\n");
int stop = 0;
for (int i = 1; i <= 3 && !stop; i++) {
for (int j = 1; j <= 3; j++) {
if (i == 2 && j == 2) {
stop = 1;
break;
}
printf(" i=%d j=%d\n", i, j);
}
}
return 0;
}break leaves only the inner loop:
i=1 j=1
i=2 j=1
i=3 j=1
leaving both, with a flag:
i=1 j=1
i=1 j=2
i=1 j=3
i=2 j=1The first nest printed j=1 three times: the inner break fired on every outer pass and the outer loop kept going.
Where break and continue are not allowed
continuein aswitchthat is not inside a loop is an error. There is no pass to continue.breakoutside any loop orswitchis an error.breakin aswitchinside a loop applies to theswitch.continuein the same place applies to the loop, because aswitchhas no passes. That asymmetry is worth a mark: the two keywords do not both stop at theswitch.
#include <stdio.h>
int main(void)
{
for (int i = 1; i <= 4; i++) {
switch (i) {
case 2:
continue; /* skips to the loop's next pass */
default:
break; /* leaves the switch only */
}
printf("reached the end of pass %d\n", i);
}
return 0;
}reached the end of pass 1
reached the end of pass 3
reached the end of pass 4Pass 2 printed nothing: continue skipped the rest of the loop body, printf included. The other three passes reached the printf, because their break left only the switch.
What this does NOT mean
break does not leave a function. return does.
break does not leave more than one level. Use a flag, a return or a goto.
continue does not restart the loop from the beginning. It moves to the next pass: the step clause in a for, or the condition in a while.
continue in a while does not run anything at the bottom of the body. That is how a while loop with a continue hangs.
break in a case does not leave the enclosing loop. It leaves the switch.
Neither is bad practice. break in a search and continue as a guard at the top of a body are both clearer than the alternatives. What is unclear is several of them scattered through a long body.
break and continue
Quick revision
breakleaves the innermost enclosing loop orswitch.continueends the current pass and goes on to the next.- In a
for,continueruns the step clause. In awhile, it goes straight to the condition. - In a
while, advance the counter before anycontinuecan skip it, or the loop never ends. breakin acaseleaves theswitch, not the loop.continuein acasedoes affect the loop.breakleaves one level of nesting. Use a flag, areturnor agotofor more.breaknever leaves a function;returndoes.- The search idiom:
found_at = -1before the loop, set andbreakon a match.
Test yourself
1. What does break do inside a switch that is inside a for loop?
It ends the switch for that pass. The loop continues with its next pass.
2. Why does this loop never end?
int i = 0;
while (i < 5) {
if (i == 0) continue;
printf("%d ", i);
i++;
}continue jumps to the condition, so i++ at the bottom of the body is never reached while i is 0. i stays 0 for ever. Advance i before the continue.
3. How many lines does this print?
for (int i = 1; i <= 3; i++)
for (int j = 1; j <= 3; j++) {
if (j == 2) break;
printf("%d %d\n", i, j);
}Three. The inner break fires on each outer pass after printing j=1, and the outer loop runs three times.
4. How do you leave both loops of a nest at once?
Set a flag tested by the outer loop's condition, return from the function, or goto a label after the outer loop.
5. What is the difference between break and continue in one line?
break ends the loop; continue ends only the current pass.
6. Is continue allowed in a switch?
Only if the switch is inside a loop, and it then applies to the loop, not the switch. Outside a loop it is an error.
What can be asked on this, and how to answer it
"Explain break and continue with examples." Define both in one line each, give a search using break and a skip using continue, and then the two things that earn the extra marks: continue runs the step clause in a for but not the bottom of a while body, and break in a case leaves the switch rather than the loop.
"What is the difference between break and continue?" break ends the innermost loop or switch immediately. continue abandons the rest of the current pass and proceeds to the next. Add that break also works in a switch while continue in a switch refers to an enclosing loop.
break and continue
"How do you exit from a nested loop?" break leaves only one level. Use a flag in the outer condition, a return if the loop is the last thing in the function, or a goto to a label after the loops. Say which you would choose and why.
"Trace the output" of a loop with break or continue in it. Write the pass number and the variable's value in a small table and mark where control jumped. That table is the answer; the printed lines fall out of it.
The rest of this subject
These notes are cut from the University's printed syllabus. Open the syllabus itself for the same subject.