The C Path — learn C, visually

🌱 C Basics

while & do-while: repeat until told otherwise

⏱ 13 min · free interactive lesson · quizzes, visualizations & a real compiler

▶ Open the interactive lesson — free, no signup
Why you're learning this

Behind nearly every frozen app — the spinner that never stops spinning — is a loop that lost its way out. Loops are how a program does something a million times without complaining, and this lesson teaches you to build ones that always know when to quit, plus the variant every "enter a valid number" prompt is secretly built on.

Computers don't get bored — and loops are how you exploit that. The while loop is the simplest: check a condition; if true, run the body; go back and check again. Repeat until the condition turns false.

countdown.c
#include <stdio.h>

int main(void) {
    int n = 3;
    while (n > 0) {
        printf("%d\n", n);
        n--;
    }
    printf("Liftoff!\n");
    return 0;
}
terminal
$ gcc countdown.c -o countdown && ./countdown
3
2
1
Liftoff!

The shape of every while loop, as a diagram — note the edge that makes it a loop:

This spot has an interactive flow widget — open the interactive lesson to play with it.

Three ingredients make a healthy loop: initialize something before it (n = 3), test it in the condition (n > 0), and update it in the body (n--). Forget the update and you've built an infinite loop — the condition never changes, and your program spins forever (Ctrl+C to rescue your terminal).

Step through the countdown and watch the check-run-update rhythm:

This spot has an interactive trace widget — open the interactive lesson to play with it.

🧠 Checkpoint: What does int n = 0; while (n > 0) { printf("hi"); n--; } print?

  • "hi" once
  • Nothing — the body never runs
  • "hi" forever
  • Compile error
Show answer

Nothing — the body never runs — while tests first: 0 > 0 is false on the very first check, so the body runs zero times. (A do-while version WOULD print "hi" once — and then run forever as n goes negative… twice the trap!)

Zero iterations is a feature

while tests before every run of the body — including the first. If the condition starts false, the body runs zero times. That's usually exactly right: "process items while any remain" should do nothing when there are none.

do-while: test at the bottom

Sometimes the body must run at least once before you can sensibly test — like asking a user for input and validating it. That's do … while, C's only loop that checks at the end (mind the required semicolon after the condition!):

dowhile.c
#include <stdio.h>

int main(void) {
    int tries = 0;
    int guess;

    do {
        guess = 30 + tries * 6;      /* stand-in for user input */
        tries++;
        printf("try %d: guessing %d\n", tries, guess);
    } while (guess != 42);

    printf("got it in %d tries\n", tries);
    return 0;
}
terminal
$ gcc dowhile.c -o dowhile && ./dowhile
try 1: guessing 30
try 2: guessing 36
try 3: guessing 42
got it in 3 tries

🧠 Checkpoint: The key difference between while and do-while is…

  • do-while is faster
  • do-while runs the body at least once — it tests at the bottom
  • while can’t contain if statements
  • do-while can’t be infinite
Show answer

do-while runs the body at least once — it tests at the bottom — Same loop, different first move: while checks before the first iteration (0+ runs); do-while checks after (1+ runs). Use do-while when the body itself produces the thing you test — like reading input.

Sentinel loops: "read until a special value"

A classic while pattern: keep consuming input until a sentinel value says stop. Here the sentinel is 0 (real programs use scanf's own return value; return values are next lesson's territory):

sentinel.c
#include <stdio.h>

int main(void) {
    int scores[] = { 8, 12, 30, 0, 99 };  /* 0 = sentinel: stop */
    int i = 0, total = 0;

    while (scores[i] != 0) {
        total += scores[i];
        i++;
    }
    printf("total before sentinel: %d\n", total);
    return 0;
}
terminal
$ gcc sentinel.c -o sentinel && ./sentinel
total before sentinel: 50
# the 99 after the sentinel is never touched
💡

Deliberate infinite loops are respectable C: while (1) { … } is the standard skeleton for servers, embedded firmware, and game loops — anything that should run "forever" and exits via break or never. It's not a bug when it's on purpose.

This spot has an interactive editor widget — open the interactive lesson to play with it.

🧠 Checkpoint: Which loop is guaranteed infinite?

  • while (n != 0) n -= 2; starting at n = 7
  • while (0) { }
  • while (n > 0) n--; starting at n = 1000000
  • do { } while (0);
Show answer

while (n != 0) n -= 2; starting at n = 7 — From 7, subtracting 2 gives 5, 3, 1, −1, −3… it steps right over 0 and never equals it (until signed overflow, which is UB). Prefer n > 0 over n != 0 — robust conditions survive imperfect inputs. Option B never runs; D runs exactly once.

Most loops share that init-test-update trio so often that C packs all three into one line — say hello to for.

▶ Practice this lesson interactively (with live gcc)