C Programming ยท September 25, 2026

while and do-while Loops: Indefinite Repetition in C

Module I ยท Loop Control Structure ยท Lecture 18


๐ŸŽฏ Why This Matters

The for loop is built for definite repetition โ€” you know in advance exactly how many times it needs to run. But plenty of real problems don’t work that way: keep asking a user for input until they type something valid, keep dividing a number until it reaches zero, keep drawing cards until you get a match. None of these have a fixed count decided in advance โ€” they run until a condition says stop, however many passes that takes. That’s exactly what while and do-while are built for, and this post covers both in full, with at least five worked examples for each.

๐Ÿ”ท The while Loop: Checks First

A while loop repeats its body for as long as its condition stays true โ€” checked before every single pass, including the very first one.

#include <stdio.h>

int main() {
    int i = 1;

    while (i <= 5) {
        printf("%d ", i);
        i++;
    }
    printf("\n");

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
1 2 3 4 5

This looks almost identical to a for loop with the same counter โ€” and it is, structurally. The real difference between while and for is emphasis: a for loop’s header puts initialization, condition, and update all in one place, built around counting. A while loop only has a condition โ€” initialization happens before it, and the update can happen anywhere inside the body, which is exactly what makes it flexible enough for situations where “how many times” isn’t the natural way to think about the problem.

๐Ÿ”ถ The do-while Loop: Checks Last

do-while looks almost the same, but moves the condition to the end โ€” meaning the body always runs at least once, no matter what.

#include <stdio.h>

int main() {
    int i = 1;

    do {
        printf("%d ", i);
        i++;
    } while (i <= 5);
    printf("\n");

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
1 2 3 4 5

โš ๏ธ Easy to forget:do-while needs a semicolon after its closing while(...) โ€” unlike a plain while loop, which never has one. Leaving it off is a common compile error.

๐Ÿ” The One Real Difference โ€” Made Concrete

For a condition that’s true from the start, while and do-while behave identically. The difference only shows up when the condition is already false before the loop begins.

#include <stdio.h>

int main() {
    int n = 10;

    printf("while loop: ");
    while (n < 5) {
        printf("%d ", n);
    }
    printf("(nothing printed)\n");

    printf("do-while loop: ");
    do {
        printf("%d ", n);
    } while (n < 5);
    printf("\n");

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
while loop: (nothing printed)
do-while loop: 10

This is the single most important thing to understand in this entire post: while checks before committing to run the body even once, while do-while checks after โ€” meaning it has already run the body by the time it even looks at the condition. Choosing between them almost always comes down to one question: does this need to run at least once, even if the condition starts out false?

๐Ÿง‘โ€๐ŸŽ“ Five while Loop Examples

Example 1: Sum of Digits

#include <stdio.h>

int main() {
    int n = 4527, sum = 0;

    while (n != 0) {
        sum += n % 10;
        n /= 10;
    }

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

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
Sum of digits: 18

This is a genuinely natural while problem โ€” we don’t know in advance how many digits n has, so there’s no fixed count to put in a for loop’s header. Each pass peels off the last digit with % 10 (a trick from the Data Types post) and shrinks n with integer division, stopping the moment nothing is left.

Example 2: Reversing a Number

#include <stdio.h>

int main() {
    int n = 4527, reversed = 0;

    while (n != 0) {
        int digit = n % 10;
        reversed = reversed * 10 + digit;
        n /= 10;
    }

    printf("Reversed: %d\n", reversed);

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
Reversed: 7254

Structurally identical to Example 1 โ€” same loop, same stopping condition โ€” but this time each extracted digit is built into a new number instead of summed, showing how the same “peel off digits until nothing’s left” pattern solves two different problems.

Example 3: GCD Using the Euclidean Algorithm

#include <stdio.h>

int main() {
    int a = 48, b = 18;

    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }

    printf("GCD: %d\n", a);

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
GCD: 6

One of the oldest algorithms in mathematics, and a perfect while use case โ€” the number of steps needed depends entirely on the two starting values, so there’s no way to know the iteration count ahead of time. Each pass replaces the pair (a, b) with (b, a % b) until b finally reaches zero.

Example 4: Validating User Input

#include <stdio.h>

int main() {
    int age = -1;

    printf("Enter your age: ");
    scanf("%d", &age);

    while (age < 0 || age > 120) {
        printf("Invalid. Enter age again: ");
        scanf("%d", &age);
    }

    printf("Age accepted: %d\n", age);

    return 0;
}

๐Ÿ–ฅ๏ธ Sample run:
Enter your age: -5
Invalid. Enter age again: 200
Invalid. Enter age again: 34
Age accepted: 34

This is exactly the kind of “keep going until the user gets it right” logic that has no natural upper bound โ€” the loop could run zero times (if the first input is already valid) or many times, depending entirely on the user.

Example 5: Sentinel-Controlled Sum

#include <stdio.h>

int main() {
    int num, sum = 0;

    printf("Enter numbers to sum (-1 to stop): ");
    scanf("%d", &num);

    while (num != -1) {
        sum += num;
        scanf("%d", &num);
    }

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

    return 0;
}

๐Ÿ–ฅ๏ธ Sample run:
Enter numbers to sum (-1 to stop): 10 20 30 -1
Total: 60

The special value -1 here is called a sentinel โ€” a value that doesn’t represent real data, only “stop.” This is a classic while pattern for reading an unknown-length list of values, ending whenever the user decides they’re done rather than after a fixed count.

Bonus Example 6: Power of a Number

#include <stdio.h>

int main() {
    int base = 3, exp = 4, result = 1;

    while (exp > 0) {
        result *= base;
        exp--;
    }

    printf("%d\n", result);

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
81

(3โด = 3 ร— 3 ร— 3 ร— 3 = 81.) This one could just as easily have been a for loop, since exp is known in advance โ€” included here to show that while is a valid choice even when a count exists; it’s simply the more natural fit when the count is unknown, not the only place it can be used.

๐Ÿง‘โ€๐ŸŽ“ Five do-while Loop Examples

Example 1: Menu-Driven Program (Repeat Until Exit)

#include <stdio.h>

int main() {
    int choice;

    do {
        printf("\n1. Say Hello\n2. Say Goodbye\n3. Exit\n");
        printf("Enter choice: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                printf("Hello!\n");
                break;
            case 2:
                printf("Goodbye!\n");
                break;
            case 3:
                printf("Exiting...\n");
                break;
            default:
                printf("Invalid choice\n");
        }
    } while (choice != 3);

    return 0;
}

๐Ÿ–ฅ๏ธ Sample run:
1. Say Hello … Enter choice: 1
Hello!
1. Say Hello … Enter choice: 3
Exiting…

This is the single most common real-world use of do-while: a menu must display at least once โ€” there’d be nothing to choose from otherwise โ€” which is exactly what do-while guarantees that a plain while couldn’t, since a while loop would need the menu’s first display handled as a special case outside the loop.

Example 2: Input Validation, Guaranteed to Ask Once

#include <stdio.h>

int main() {
    int marks;

    do {
        printf("Enter marks (0-100): ");
        scanf("%d", &marks);

        if (marks < 0 || marks > 100) {
            printf("Out of range, try again.\n");
        }
    } while (marks < 0 || marks > 100);

    printf("Marks recorded: %d\n", marks);

    return 0;
}

๐Ÿ–ฅ๏ธ Sample run:
Enter marks (0-100): 150
Out of range, try again.
Enter marks (0-100): 85
Marks recorded: 85

Compare this to Example 4 from the while section โ€” that version needed a separate scanf before the loop to get the first value in. This do-while version needs only one scanf, written once, because the loop itself already guarantees at least one prompt.

Example 3: Number Guessing Game

#include <stdio.h>

int main() {
    int secret = 7, guess;

    do {
        printf("Guess the number (1-10): ");
        scanf("%d", &guess);

        if (guess < secret) {
            printf("Too low!\n");
        } else if (guess > secret) {
            printf("Too high!\n");
        }
    } while (guess != secret);

    printf("Correct! The number was %d.\n", secret);

    return 0;
}

๐Ÿ–ฅ๏ธ Sample run:
Guess the number (1-10): 5
Too low!
Guess the number (1-10): 7
Correct! The number was 7.

The player must be allowed at least one guess โ€” there’s no meaningful way to “check the condition first” here, since there’s no guess to check yet on the very first pass. This is another textbook case where do-while‘s guarantee fits the problem naturally.

Example 4: Sum of Digits, the do-while Way

#include <stdio.h>

int main() {
    int n = 9, sum = 0;

    do {
        sum += n % 10;
        n /= 10;
    } while (n != 0);

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

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
Sum of digits: 9

Watch what happens with a single-digit input like 9: a while version would need to check n != 0 first (true, since n = 9), so it would work fine either way here โ€” but this highlights an important edge case worth testing whenever you’re deciding between the two: always check what your loop does with the smallest or simplest possible input, not just a typical one.

Example 5: Simple ATM PIN Retry

#include <stdio.h>

int main() {
    int pin, correctPin = 4321, attempts = 0;

    do {
        printf("Enter PIN: ");
        scanf("%d", &pin);
        attempts++;

        if (pin != correctPin) {
            printf("Incorrect PIN.\n");
        }
    } while (pin != correctPin && attempts < 3);

    if (pin == correctPin) {
        printf("Access granted.\n");
    } else {
        printf("Card blocked.\n");
    }

    return 0;
}

๐Ÿ–ฅ๏ธ Sample run:
Enter PIN: 1111
Incorrect PIN.
Enter PIN: 4321
Access granted.

Two conditions are combined with && here (from the Relational and Logical Operators post): keep retrying only while the PIN is still wrong and there are attempts left. The user always gets at least one try โ€” guaranteed by do-while โ€” but is cut off after three, whichever comes first.

๐Ÿ†š for vs. while vs. do-while: The Same Task, Three Ways

Let’s settle the differences once and for all by writing the exact same program โ€” printing 1 through 5 โ€” using all three loops, side by side.

#include <stdio.h>

int main() {
    printf("for:      ");
    for (int i = 1; i <= 5; i++) {
        printf("%d ", i);
    }
    printf("\n");

    printf("while:    ");
    int j = 1;
    while (j <= 5) {
        printf("%d ", j);
        j++;
    }
    printf("\n");

    printf("do-while: ");
    int k = 1;
    do {
        printf("%d ", k);
        k++;
    } while (k <= 5);
    printf("\n");

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
for: 1 2 3 4 5
while: 1 2 3 4 5
do-while: 1 2 3 4 5

Identical output, but look closely at where each piece lives:

  • for keeps initialization (i = 1), condition (i <= 5), and update (i++) all together in one header โ€” everything about “how many times” is visible in a single line, which is exactly why for reads best when the repetition count is the main idea.
  • while only has the condition in its header. Initialization happens before the loop, and the update (j++) is just another line inside the body โ€” nothing forces it to exist at all, which is both while‘s flexibility and its main danger (forget that line, and the loop never ends).
  • do-while has the exact same three pieces as while, just with the condition physically moved to the end โ€” which is the only thing that actually changes its behavior: the body is guaranteed to run before that condition is ever checked.

Proving the Real Difference: An Already-False Condition

#include <stdio.h>

int main() {
    int n = 0;

    printf("for loop:\n");
    for (int i = 0; i < n; i++) {
        printf("  for body ran\n");
    }

    printf("while loop:\n");
    int j = 0;
    while (j < n) {
        printf("  while body ran\n");
        j++;
    }

    printf("do-while loop:\n");
    int k = 0;
    do {
        printf("  do-while body ran\n");
        k++;
    } while (k < n);

    return 0;
}

๐Ÿ–ฅ๏ธ Output:
for loop:
while loop:
do-while loop:
  do-while body ran

With n = 0, the condition (i < 0, j < 0, k < 0) is false from the very start in all three. for and while both correctly skip their bodies entirely โ€” neither prints anything. do-while is the only one of the three that still runs its body once, printing its message despite the condition never being true even a single time. This is the complete, concrete proof of the one real behavioral difference between all three loops.

๐Ÿ“Š Choosing Between for, while, and do-while

LoopBest forRuns body at least once?
forA known, fixed number of repetitionsOnly if the condition starts true
whileAn unknown number of repetitions, condition-drivenOnly if the condition starts true
do-whileAnything that must happen at least once โ€” menus, prompts, retriesAlways, unconditionally

๐Ÿšซ Common Mistakes Beginners Make

MistakeWhy it’s dangerous
Forgetting to update the loop variable inside a while bodyThe condition never changes โ€” the loop runs forever, exactly like a for loop missing its update step
Missing the semicolon after do-while‘s closing while(...)A compile error โ€” easy to forget since a plain while loop never needs one
Using do-while when the body genuinely shouldn’t run on invalid initial dataGuarantees at least one pass even when that first pass might not make sense โ€” always ask “should this be allowed to run even once with bad input?”
Confusing which loop checks firstLeads to off-by-one-style surprises exactly like the false-condition example in this post

๐ŸŽ“ Practice Exercises

Exercise 1: Predict the Output

int x = 20;
while (x > 25) {
    printf("%d ", x);
    x++;
}
printf("done");

(Answer: prints only done โ€” the condition x > 25 is false from the start, so the loop body never runs.)

Exercise 2: Convert while to do-while

Rewrite Example 3 from the while section (GCD) as a do-while loop. Does it still give the correct answer for a = 48, b = 18? What would go wrong if b started at 0?

(Answer: the do-while version still gives GCD = 6 for this input, but if b started at 0, the do-while version would attempt a % b โ€” division by zero โ€” on its guaranteed first pass, which the while version would have correctly skipped entirely.)

Exercise 3: Build It Yourself

Write a do-while-based menu program with options to (1) check if a number is prime, (2) check if a number is a palindrome, and (3) exit โ€” looping back to the menu after each operation until the user chooses to exit.

โ“ Frequently Asked Questions

Q: Is do-while just a for loop with the check moved to the end?
Not quite โ€” a for loop is still fundamentally check-first, just like while. do-while is the only loop in C that’s genuinely check-last, which is exactly why it’s the only one of the three that can guarantee at least one execution.

Q: Can I use break and continue inside while and do-while loops?
Yes โ€” both work identically to how they’d work in a for loop, letting you exit early or skip to the next condition check. We’ll cover both properly in an upcoming post.

Q: Which loop is fastest โ€” for, while, or do-while?
There’s no meaningful performance difference between them in modern C โ€” all three compile down to essentially the same machine instructions. Choose based on which one most clearly expresses the shape of your problem, not speed.

โœ… Key Takeaways

  • while checks its condition before every pass, including the first โ€” if the condition starts false, the body never runs at all.
  • do-while checks its condition after every pass โ€” the body is guaranteed to run at least once, no matter what.
  • Both are built for indefinite repetition โ€” situations where the number of passes depends on data or user input, not a fixed count known in advance.
  • do-while is the natural fit for menus, prompts, and retry logic โ€” anything that fundamentally needs to happen at least once before it can even be evaluated.
  • Don’t forget the semicolon after do-while‘s closing while(...) โ€” and always update whatever variable your condition depends on, or the loop will never end.

๐Ÿš€ Next up: With for, while, and do-while all covered, we’ll look at break and continue โ€” the two keywords that let you exit a loop early or skip straight to its next pass, giving you finer control over exactly how a loop behaves mid-execution.