c-foundations Lesson 8 18 min read

How Do Loops Let Me Repeat Code?

for, while, do-while — plus the input validation pattern you'll use everywhere

Reading: C Text: Ch. 5 §1–7 (pp. 257–337)

After this lesson, you will be able to:

  • Write for, while, and do-while loops and select the appropriate type
  • Use do-while for the input validation pattern (read, check, re-prompt)
  • Use break to exit a loop early and continue to skip to the next iteration
  • Identify the empty-body bug caused by a semicolon after for (...) or while (...)
  • Identify off-by-one errors caused by using <= vs. < in loop conditions

The Input Validation Problem

Your program asks for a positive number. The user types -5. You need to ask again. They type 0. Ask again. They type abc. Ask again. They finally type 7. Accept it.

This “ask, validate, repeat” pattern shows up in every interactive C program. And it naturally leads to the do-while loop — one of C’s three loop types.


Three Loops, Three Use Cases

The for Loop

Use for when you know how many times to loop:

for (int i = 0; i < 5; i++)
{
    printf("Iteration %d\n", i);
}

Same syntax as Java. The three parts: initialize, condition, update.

The while Loop

Use while when you don’t know how many iterations but check the condition first:

int sum = 0;
int value;

printf("Enter numbers (0 to stop): ");
scanf("%d", &value);

while (value != 0)
{
    sum += value;
    scanf("%d", &value);
}

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

The do-while Loop

Use do-while when the body must run at least once:

int choice;

do
{
    printf("Enter a positive number: ");
    scanf("%d", &choice);

    if (choice <= 0)
    {
        printf("Invalid! Must be positive.\n");
    }
} while (choice <= 0);

printf("You entered: %d\n", choice);

Key Insight: do-while is the natural choice for input validation: “get input, check if valid, if not ask again.” The loop body runs at least once (you need to read input before you can check it). This is the pattern you’ll use in every lab with user input.

Check Your Understanding
You need to read a number from the user and keep asking until they enter a valid positive integer. Which loop is the best fit?
A for — because you know you'll ask at most 10 times
B do-while — you must read input at least once before you can validate it
C while — check the value before reading input
D Any loop works equally well — it's just a style preference
Answer: B. Input validation follows the "read-then-check" pattern: you must execute the body (read input) before you can check the condition (is it valid?). do-while guarantees the body runs at least once. A while loop would check the condition first, but you haven't read anything yet — the variable would contain garbage.

Choosing the Right Loop

Situation Best Loop Why
Known number of iterations for Counter is built in
Check condition before first run while May not run at all
Must run at least once do-while Checks after body
Input validation do-while Read-then-check pattern

break and continue

break exits the loop immediately. continue skips to the next iteration:

for (int i = 0; i < 100; i++)
{
    if (i % 2 == 0)
    {
        continue;        // Skip even numbers
    }
    if (i > 10)
    {
        break;           // Stop after 10
    }
    printf("%d ", i);    // Prints: 1 3 5 7 9
}

From Java: for, while, do-while, break, and continue work identically in C and Java. If you’ve used them in CSCD 210, you already know them. The only difference is C’s truthiness rule — any non-zero value is true in the loop condition.

Common Loop Mistakes

The semicolon trap:

for (int i = 0; i < 10; i++);    // <-- semicolon makes body empty!
{
    printf("%d\n", i);             // Runs once, AFTER the loop
}

Common Pitfall: for (i = 0; i < n; i++); — that semicolon makes the loop body empty! The printf in braces runs once after the loop finishes, not 10 times. Remove the semicolon.

Check Your Understanding
What does this code print?
for (int i = 0; i < 5; i++); { printf("%d ", i); }
A 0 1 2 3 4
B 0 1 2 3 4 5
C 5
D It won't compile — i is out of scope in the printf
Answer: D. The semicolon after for (...) makes the loop body empty. The braced block is separate from the loop. Since i was declared inside the for statement (int i = 0), it's out of scope after the semicolon ends the loop. If i were declared before the loop, the answer would be 5 — the loop runs 5 times doing nothing, then printf prints i's final value once.

Infinite loop from forgetting the update:

int i = 0;
while (i < 10)
{
    printf("%d\n", i);
    // Forgot i++! Infinite loop
}

Off-by-one errors:

// Prints 0..9 (10 times) — correct
for (int i = 0; i < 10; i++)

// Prints 0..10 (11 times) — probably wrong
for (int i = 0; i <= 10; i++)

Putting It Together: Average Calculator

#include <stdio.h>

int main(void)
{
    int count;
    double sum = 0.0;
    double value;

    do
    {
        printf("How many numbers? ");
        scanf("%d", &count);
        if (count <= 0)
        {
            printf("Must be positive!\n");
        }
    } while (count <= 0);

    for (int i = 0; i < count; i++)
    {
        printf("Enter number %d: ", i + 1);
        scanf("%lf", &value);
        sum += value;
    }

    printf("Average: %.2f\n", sum / count);

    return 0;
}

This program uses do-while for input validation and for for the counting loop — the two most common patterns combined.

Why does this matter?

Loops plus scanf are the core of every interactive program you’ll write this quarter. The do-while validation pattern and the for counting pattern appear in every lab from here on. Get comfortable with both — they’re not going away.

Check Your Understanding
In the average calculator above, what would happen if you used sum / count instead of sum / count where sum is a double and count is an int? And what if both were int?
A With double sum, it's floating-point division. With both as int, the decimal part is truncated
B Both produce integer division — you always need an explicit cast
C Both produce the same result — C always uses floating-point division
D It depends on the printf format specifier, not the variable types
Answer: A. When one operand is double, C promotes the other to double and performs floating-point division. When both are int, C performs integer division and truncates the result. printf's format specifier only controls how the result is displayed, not how the division is computed. If both are int, cast one: (double)sum / count.
Quick Check: When should you use do-while instead of while?

When the loop body must run at least once. The classic case is input validation: you need to read input before you can check if it’s valid, so the body (reading) must happen before the condition (checking).

Quick Check: What's wrong with for (i = 0; i < n; i++);?

The semicolon after the closing parenthesis creates an empty loop body. The loop runs n times doing nothing, then whatever code follows runs once. Remove the semicolon.

Quick Check: How do you exit a loop early without finishing all iterations?

Use break. It immediately exits the innermost loop containing it. continue is different — it skips to the next iteration without exiting the loop.


Loops Are Your Workhorse

Between for (counted), while (conditional), and do-while (at-least-once), you can express any repetition pattern. The input validation do-while pattern in particular will appear in nearly every lab.

Next: functions and recursion. You’ll learn to break your code into reusable pieces, understand pass-by-value (and why you can’t swap two variables without pointers), and see how recursion uses the call stack.

Big Picture: With decisions and loops, you now have all the control flow tools C offers. Every algorithm — sorting, searching, parsing, processing — is built from these primitives. The for loop will drive your array processing, the while loop will read files line by line, and the do-while loop will validate every piece of user input. Functions (next lesson) let you organize these patterns into reusable pieces.