Kodewick
Lesson 7 of 30Contents

break, continue and nested loops

Lesson 7 of 30 · Part 1 · Getting started · about 15 minutes

The loops in the last lesson dutifully went around until their condition failed. But sometimes the job is done and there's no point going on, and sometimes you want to skip this round and go straight to the next. This lesson covers break and continue, and then a loop inside another loop.

main.c
1#include <stdio.h>2 3int main(void) {4    for (int n = 51; n <= 100; n++) {5        if (n % 7 == 0) {6            printf("Found it: %d\n", n);7            break;8        }9    }10    printf("Search over\n");11    return 0;12}
Output
Found it: 56
Search over

We want the first multiple of 7 above 50. Once 56 turns up, that's enough: break ends the loop right away, and 57 to 100 are never tried.

break: stop the loop now

When break runs, the whole loop is over. The program jumps to the code after the loop, and whatever comes after break in the body doesn't run either.

break often goes with while (1). Since 1 is always true, this loop can't stop on its own: **its only way out is break**. Say you have $50 and each item costs $12. How many can you buy?

main.c
1#include <stdio.h>2 3int main(void) {4    int budget = 50;5    int spent = 0;6    int items = 0;7    while (1) {8        if (spent + 12 > budget) {9            break;10        }11        spent += 12;12        items++;13    }14    printf("Bought %d items for $%d\n", items, spent);15    return 0;16}
Output
Bought 4 items for $48

Press Step and watch the fifth round: spent + 12 is 60, more than 50, so break leaves the loop, and spent += 12; doesn't run.

Tip: Whenever you write while (1), make sure the break is sure to be reached some day, or you have an infinite loop.

continue: skip this round

continue doesn't end the loop. It skips the rest of this round and moves on to the next one. In a for loop, the i++ still runs before the next round. This prints 1 to 10, skipping the multiples of 3:

main.c
1#include <stdio.h>2 3int main(void) {4    for (int i = 1; i <= 10; i++) {5        if (i % 3 == 0) {6            continue;7        }8        printf("%d ", i);9    }10    printf("\n");11    return 0;12}
Output
1 2 4 5 7 8 10 
Guess first

How many lines does this print?

1#include <stdio.h>2 3int main(void) {4    for (int i = 1; i <= 5; i++) {5        if (i == 3) {6            continue;7        }8        if (i == 5) {9            break;10        }11        printf("%d\n", i);12    }13    return 0;14}

Take care with continue in a while loop: if i++ sits at the end of the body, continue skips it too, i never changes again, and you have an infinite loop. Change the variable before the continue, or use for instead.

A loop inside a loop

A loop body can hold another loop: a nested loop. Each time the outer loop goes around once, the inner loop runs all the way through, from start to finish:

main.c
1#include <stdio.h>2 3int main(void) {4    for (int i = 1; i <= 2; i++) {5        for (int j = 1; j <= 3; j++) {6            printf("i = %d, j = %d\n", i, j);7        }8    }9    return 0;10}
Output
i = 1, j = 1
i = 1, j = 2
i = 1, j = 3
i = 2, j = 1
i = 2, j = 2
i = 2, j = 3

Two outer rounds, three inner rounds each time: six lines. Press Step and watch j start over at 1 again and again.

A nested loop can print a multiplication table. The outer i picks the row, the inner j picks the place in that row, and j only goes up to i:

main.c
1#include <stdio.h>2 3int main(void) {4    for (int i = 1; i <= 5; i++) {5        for (int j = 1; j <= i; j++) {6            printf("%dx%d=%-4d", j, i, i * j);7        }8        printf("\n");9    }10    return 0;11}
Output
1x1=1   
1x2=2   2x2=4   
1x3=3   2x3=6   3x3=9   
1x4=4   2x4=8   3x4=12  4x4=16  
1x5=5   2x5=10  3x5=15  4x5=20  5x5=25  

Notice where printf("\n") is: outside the inner loop but inside the outer one, so there is one new line at the end of each row.

Printing a triangle

The same idea with stars instead of numbers draws a shape. Row number row gets row stars:

main.c
1#include <stdio.h>2 3int main(void) {4    int height = 4;5    for (int row = 1; row <= height; row++) {6        for (int k = 1; k <= row; k++) {7            printf("*");8        }9        printf("\n");10    }11    return 0;12}
Output
*
**
***
****

When drawing a shape, first work out how many characters each row needs and how that relates to the row number. Then write the condition of the inner loop.

break leaves one loop only

In a nested loop, break ends only the loop it is in. The outer loop carries on:

main.c
1#include <stdio.h>2 3int main(void) {4    for (int i = 1; i <= 3; i++) {5        for (int j = 1; j <= 3; j++) {6            if (j == 2) {7                break;8            }9            printf("i = %d, j = %d\n", i, j);10        }11    }12    return 0;13}
Output
i = 1, j = 1
i = 2, j = 1
i = 3, j = 1

To end both loops as soon as you find something, use a variable as a flag: when the inner loop finds it, set the flag to 1 and break; at the end of each outer round, check the flag and break too if it is 1. This finds the first pair of numbers whose product is 12:

main.c
1#include <stdio.h>2 3int main(void) {4    int found = 0;5    for (int i = 1; i <= 9; i++) {6        for (int j = 1; j <= 9; j++) {7            if (i * j == 12) {8                printf("%d x %d = 12\n", i, j);9                found = 1;10                break;11            }12        }13        if (found) {14            break;15        }16    }17    return 0;18}
Output
2 x 6 = 12

Delete the outer if (found) and run it again to see which extra lines appear.

Where a variable can be used

A variable declared inside curly braces can be used only inside those braces, and an i declared in the parentheses of a for can be used only in that loop. Use it after the loop and the program won't compile:

main.c
1#include <stdio.h>2 3int main(void) {4    for (int i = 1; i <= 3; i++) {5        int square = i * i;6        printf("%d\n", square);7    }8    printf("%d\n", i);9    return 0;10}
Output
main.c: In function 'main':
main.c:8:20: error: 'i' undeclared (first use in this function)
    8 |     printf("%d\n", i);
      |                    ^
main.c:8:20: note: each undeclared identifier is reported only once for each function it appears in

The compiler says 'i' undeclared: on line 8, i no longer exists. The same goes for square, and it is a fresh variable every round, so its value doesn't carry over from one round to the next. If you need a variable after the loop, declare it before the loop: write int i; ahead of the for, then for (i = 1; i <= 3; i++). Where a variable can be used is called its scope; lesson 9 covers it in detail.

Practice

Write the code, then press Check. A hint costs nothing; the answer is there when you need it.

Exercise 1

First square over 200

Try the numbers one by one from 1, find the first one whose square is greater than 200, print it (15), then end the loop with break.

It should print
15
exercise1.c
1#include <stdio.h>2 3int main(void) {4    for (int n = 1; n <= 100; n++) {5 6    }7    return 0;8}
Output
Press Run or Ctrl+Enter
Exercise 2

Skip the multiples of 4

Add up 1 to 20, but skip the multiples of 4, using continue. Print the result, 150.

It should print
150
exercise2.c
1#include <stdio.h>2 3int main(void) {4    int total = 0;5    for (int i = 1; i <= 20; i++) {6 7        total += i;8    }9    printf("%d\n", total);10    return 0;11}
Output
Press Run or Ctrl+Enter
Exercise 3

Upside-down triangle

Use nested loops to print an upside-down triangle: 4 * on the first row, one fewer on each row, 1 on the last.

It should print
****
***
**
*
exercise3.c
1#include <stdio.h>2 3int main(void) {4    int height = 4;5 6    return 0;7}
Output
Press Run or Ctrl+Enter

What you learned

  • break ends a loop right away; while (1) can only be left with break, so make sure it gets reached.
  • continue skips the rest of this round and goes on to the next; in a while loop, don't skip the line that changes the variable.
  • In a nested loop, the inner loop runs all the way through for each outer round; that's how the multiplication table and the triangle are printed.
  • In a nested loop, break leaves one loop only; to end both, use a flag variable.
  • A variable declared inside curly braces or in the parentheses of a for can't be used outside them.