Phase 1 · C FoundationsModule 5~38 min read

Loops

Repeat work safely with while, do-while, and for loops, then control iteration with break and continue.

What you'll learn

Loops express repetition without duplicating code. The syntax is compact; the real skill is proving that each loop starts correctly, stays within its boundary, makes progress, and eventually stops.

By the end, you'll be able to:

  • Choose between while, do-while, and for
  • Write counter-controlled, sentinel-controlled, and validation loops
  • Use break and continue without hiding the loop's logic
  • Reason precisely about inclusive and exclusive boundaries
The four responsibilities of a terminating loop
1

Initialize

Create the loop state

2

Test

Continue only if true

3

Work

Execute the body

4

Update

Move toward termination

while loops

A while loop tests before every iteration. Use it when repetition depends on a condition and you do not necessarily know the number of iterations in advance.

countdown.c
#include <stdio.h>

int main(void) {
    int countdown = 3;          // initialize

    while (countdown > 0) {     // test
        printf("%d...\n", countdown);
        countdown--;            // update
    }

    printf("Launch!\n");
    return 0;
}

A sentinel is a special value that ends input. Here, zero stops the loop, while a failed conversion also prevents the body from using invalid data:

sentinel.c
#include <stdio.h>

int main(void) {
    int value = 0;
    int sum = 0;

    printf("Enter values; 0 stops: ");
    while (scanf("%d", &value) == 1 && value != 0) {
        sum += value;
    }

    printf("Sum: %d\n", sum);
    return 0;
}

Watch out

If invalid text causes scanf to fail, that text remains unread. Real interactive loops should consume the bad line or use the fgets-then-parse pattern shown later in this lesson.

do-while loops

A do-while loop tests after its body, so the body always runs at least once. This fits menus and prompts that must be displayed before a response can be checked.

menu.c
#include <stdio.h>

int main(void) {
    int choice;

    do {
        printf("1. Play\n2. Quit\nChoice: ");
        choice = 2; // imagine this came from validated input
    } while (choice != 1 && choice != 2);

    printf("Selected %d\n", choice);
    return 0;
}

Note

The trailing semicolon in do { ... } while (condition); is required. It belongs to the syntax of the do-while statement.

for loops

A for loop keeps initialization, condition, and update together. Use it when a loop has a clear counter or traversal variable.

sum.c
#include <stdio.h>

int main(void) {
    int sum = 0;

    for (int number = 1; number <= 5; number++) {
        sum += number;
        printf("%d%s", number, number < 5 ? " + " : " = ");
    }

    printf("%d\n", sum);
    return 0;
}

Tip

Declaring the counter in the for initializer limits its scope to the loop, reducing accidental reuse later.

break & continue

break exits the nearest loop immediately. continue skips the rest of the current iteration and proceeds with the next test or update.

loop_control.c
#include <stdio.h>

int main(void) {
    for (int number = 1; number <= 20; number++) {
        if (number % 2 != 0) {
            continue;                    // skip odd numbers
        }
        if (number > 10) {
            break;                       // stop the loop
        }
        printf("%d ", number);
    }
    putchar('\n');
    return 0;
}

Note

These statements are useful for clear early exits and filters. If a loop needs many breaks and continues, consider extracting part of its logic into a function.

Nested loops

A loop may contain another loop. For every outer iteration, the inner loop completes all of its iterations. This is natural for tables, grids, matrices, and pairs of values.

grid.c
#include <stdio.h>

int main(void) {
    for (int row = 1; row <= 3; row++) {
        for (int column = 1; column <= 4; column++) {
            printf("(%d,%d) ", row, column);
        }
        putchar('\n');
    }
    return 0;
}

Key idea

Three rows multiplied by four columns produce twelve body executions. Multiply the iteration counts to estimate work in rectangular nested loops.

Useful loop patterns

  • Count: increment when an item matches a condition
  • Accumulate: add each value into a running total
  • Search: stop when the target is found
  • Filter: continue past values that should be ignored
  • Validate: repeat until parsing and range checks both succeed
validation_loop.c
#include <stdio.h>

int main(void) {
    char line[80];
    int age;

    for (;;) {
        printf("Age (1..120): ");

        if (fgets(line, sizeof line, stdin) == NULL) {
            fprintf(stderr, "Input ended.\n");
            return 1;
        }
        if (sscanf(line, "%d", &age) == 1 && age >= 1 && age <= 120) {
            break;
        }
        printf("Please enter a valid age.\n");
    }

    printf("Accepted: %d\n", age);
    return 0;
}

Off-by-one errors

An off-by-one error runs once too many or once too few. For a count of five zero-based positions, valid values are 0 through 4, so the condition is index < count.

boundaries.c
#include <stdio.h>

int main(void) {
    const int count = 5;

    // Exactly five iterations: 0, 1, 2, 3, 4
    for (int index = 0; index < count; index++) {
        printf("%d ", index);
    }
    putchar('\n');
    return 0;
}

Watch out

C does not check array bounds. The difference between index < count andindex <= count will become a memory-safety issue when arrays arrive in the next phase.

Recap & quick check

Key takeaways

  • while tests before the body; do-while guarantees at least one execution.
  • for keeps counter initialization, condition, and update in one visible place.
  • break exits the nearest loop, while continue skips to its next iteration.
  • Nested-loop work is determined by the combined iteration counts.
  • Reason about the first valid value, last valid value, and stopping boundary to prevent off-by-one errors.

Quick check

1. Which loop always executes its body at least once?

2. What does continue do?

3. How many iterations does for (int i = 0; i < 5; i++) perform?

4. What makes a loop's termination easiest to reason about?

You can now express controlled repetition. Next up: Module 6 — Functions, Scope & Program Structure, where repeated logic becomes reusable design.