A tool that performs the same task multiple times is a repeat. There are three types of loops in C, and each suits different situations.
Learning Objectives
- Select
for,while, anddo-whileaccording to the situation. - Create a two-dimensional pattern using nested loops.
- Finely control the flow with
breakandcontinue. - Avoid infinite loops and off-by-one errors.
Why do we need three things?
The only difference between the three loops is when the condition is checked.
for (init; cond; step) { body } ← When initialization, inspection, and increment are performed in one line and the number of times is clear.
while (cond) { body } ← Check first, can be executed 0 times
do { body } while (cond); ← Main text first, guaranteed to run at least once
All three can be transcribed into the other two, but it is better to choose the form that best reveals your intention.
Key concepts
1) for — When the count is clear
for (int i = 0; i < 10; i++) {
/* ... */
}
The three parts (initialize ; condition ; increment) are gathered in one line so that "i is from 0 to 9" can be seen at a glance.
2) while — When there are only conditions
while (n > 0) {
sum += n % 10;
n /= 10;
}
Repeat “as long as the condition is met”. 0 times is also possible.
3) do-while — Body first, inspection last
do {
print_menu();
scanf("%d", &choice);
} while (choice != 0);
The body always runs once. Suitable for “ask at least once”, such as menu entry.
4) break / continue
break: Terminate the nearest loop immediately.continue: Skip the rest of the body and go to the next iteration (evaluating Increment/Condition).
for (int i = 1; i <= 20; i++) {
if (i % 2) continue; //Skip odd numbers
if (i == 14) break; //Ends at 14
printf("%d ", i);
}
See as example
Example 1 — ex01_for.c: Sum from 1 to N
long sum = 0;
for (int i = 1; i <= n; i++) sum += i;
Input: 10
Enter N: Sum of 1 to 10: 55
Key point: If you incorrectly write i <= n as i < n, it becomes 1+...+9=45 (off-by-one).
Example 2 — ex02_while.c: Sum of digits
while (n > 0) {
sum += n % 10;
n /= 10;
}
Input: 1234
Integer input: Sum of digits of 1234: 10
Key point: The standard pattern for digit handling is ending the digits with % and reducing the digits with /.
Example 3 — ex03_do_while.c: Menu entry (at least once)
Since the order is text → condition check, the menu is visible once even if you enter the end condition (0).
Example 4 — ex04_nested.c: Multiplication tables (nested for)
for (int i = 2; i <= 9; i++)
for (int j = 1; j <= 9; j++)
printf("%d x %d = %2d\n", i, j, i * j);
Execution result (first part)
=== 2nd stage ===
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
=== 3rd stage ===
3 x 1 = 3
...
Bottom line: When the outer loop completes one revolution, the inner loop completes all revolutions.
Example 5 — ex05_break_continue.c: Flow Control
Prints only even numbers from 1 to 20 and ends at 14.
Execution result
2 4 6 8 10 12
Key point: continue is “Skip”, break is “Escape”.
A different perspective — which loop to choose?
The number of times is predetermined → for
There are only conditions, 0 times possible → while
You must turn the text at least once → do-while
All three have equivalent transformations as follows:
/* for */ /* while */
for (int i = 0; i < n; i++) int i = 0;
body; while (i < n) {
body;
i++;
}
Common Mistakes
- off-by-one: A bug where more/less is returned as number 1 due to confusion between
i <= nandi < n. - Infinite loop: If you forget the increment, like
for (int i = 0; i < n; ), it repeats forever. - Effect of
while (n--): When it becomes 0, it is false, butn--is evaluated one more time. Check your intentions. - Re-declaration of variable within loop:
ioffor (int i = ...)disappears after the loop ends. - Nested break:
breakonly breaks out of one step. To skip step two, use a flag variable or function return.
Cleanup
- The three loop statements are different only at the time of inspection, and express intent appropriate to the situation.
- If the number of times is clear,
for, if there is only a condition,while, and if at least once,do-while. - Fine control is possible with
break/continue, but overuse reduces readability. - In nested iterations, the inner loop makes one full rotation about the outer loop.
- Write down the termination condition clearly and do not create an infinite loop.
Try it yourself
cd src
gcc -std=c11 -Wall -o ex01 ex01_for.c && echo 10 | ./ex01
gcc -std=c11 -Wall -o ex02 ex02_while.c && echo 1234 | ./ex02
gcc -std=c11 -Wall -o ex04 ex04_nested.c && ./ex04 | head -20
gcc -std=c11 -Wall -o ex05 ex05_break_continue.c && ./ex05
Application:
- Try rewriting
ex01aswhileanddo-while, respectively. - How will the output change if I change the inner loop from
ex04toj <= i?