Ready to practice?
Sign up to access interactive coding exercises and track your progress.
Repetition with While Loops
Repeat code execution with while loops and control when loops should terminate.
The need for repetition
Consider a game that awards 10 XP at the end of each level. If a player completes 5 levels, you need to add 10 XP five times. Without loops, you'd write:
playerXP += 10;
playerXP += 10;
playerXP += 10;
playerXP += 10;
playerXP += 10;
This works, but what if the player completes 100 levels? Or what if the number of levels varies based on player input? You can't write code for every possibility.
Loops solve this by executing code repeatedly. Instead of duplicating statements, you describe what to repeat and when to stop.
The while loop
The while statement is the simplest loop in C++:
while (condition)
statement;
The condition is checked before each iteration. If true, the statement executes and control returns to check the condition again. If false, the loop ends and execution continues after it.
Here's the XP example with a loop:
#include <iostream>
int main()
{
int playerXP{ 0 };
int levelsCompleted{ 5 };
int level{ 1 };
while (level <= levelsCompleted)
{
playerXP += 10;
std::cout << "Level " << level << " complete. XP: " << playerXP << '\n';
++level;
}
std::cout << "Total XP earned: " << playerXP << '\n';
return 0;
}
Output:
Level 1 complete. XP: 10
Level 2 complete. XP: 20
Level 3 complete. XP: 30
Level 4 complete. XP: 40
Level 5 complete. XP: 50
Total XP earned: 50
Change levelsCompleted to 100 and the loop handles it - no code changes needed.
Tracing loop execution
Understanding loops requires tracing through iterations. Let's trace a simpler example:
int health{ 3 };
while (health > 0)
{
std::cout << "Health: " << health << '\n';
--health;
}
std::cout << "Game over\n";
| Iteration | health at start | Condition | Output |
|---|---|---|---|
| 1 | 3 | 3 > 0 = true | "Health: 3" |
| 2 | 2 | 2 > 0 = true | "Health: 2" |
| 3 | 1 | 1 > 0 = true | "Health: 1" |
| - | 0 | 0 > 0 = false | loop ends |
After the loop, "Game over" prints.
Loops that never execute
If the condition is false initially, the loop body is skipped entirely:
int attempts{ 0 };
while (attempts > 0)
{
std::cout << "Trying...\n";
--attempts;
}
std::cout << "Done\n";
Since 0 > 0 is false, this prints only "Done".
This behavior is useful - you don't need special handling for empty cases:
int itemsToProcess{ getUserInput() }; // might be 0
while (itemsToProcess > 0)
{
processItem();
--itemsToProcess;
}
// Works correctly even if user entered 0
Infinite loops
If the condition never becomes false, the loop runs forever:
int fuel{ 100 };
while (fuel > 0) // condition never changes!
{
std::cout << "Flying...\n";
// forgot to decrease fuel
}
Without --fuel;, fuel stays 100 and 100 > 0 is always true. The program prints "Flying..." until you force-quit it.
Intentional infinite loops
Sometimes you want an infinite loop. Use while (true):
#include <iostream>
int main()
{
int balance{ 1000 };
while (true)
{
std::cout << "Balance: $" << balance << '\n';
std::cout << "Withdraw amount (0 to exit): ";
int amount{};
std::cin >> amount;
if (amount == 0)
break; // exit the loop
if (amount > balance)
{
std::cout << "Insufficient funds\n";
continue; // skip to next iteration
}
balance -= amount;
}
std::cout << "Thank you for banking with us.\n";
return 0;
}
This ATM simulation runs until the user enters 0. The break statement exits the loop, and continue skips to the next iteration. We'll cover these in detail in a later lesson.
Use `while (true)` for intentional infinite loops. It clearly signals that the loop is meant to run indefinitely until explicitly exited.
The semicolon trap
A semicolon after the while condition creates a subtle bug:
int timer{ 5 };
while (timer > 0); // semicolon creates an empty loop body!
{
std::cout << timer << "...\n";
--timer;
}
This is actually:
int timer{ 5 };
while (timer > 0)
; // empty statement - does nothing, forever
{
// this block is not part of the loop
std::cout << timer << "...\n";
--timer;
}
Since timer never changes inside the loop, 5 > 0 is always true and the program hangs.
Never put a semicolon directly after a while condition unless you're intentionally creating a single-statement loop body.
Why loop variables should be signed
Consider counting down with an unsigned variable:
unsigned int missiles{ 3 };
while (missiles >= 0) // always true for unsigned!
{
std::cout << "Missiles: " << missiles << '\n';
--missiles;
}
This looks reasonable but loops forever. After printing 3, 2, 1, 0, decrementing the unsigned value 0 wraps to 4294967295. Since unsigned values can never be negative, missiles >= 0 is always true.
Use signed integers for loop variables. Unsigned types can cause subtle infinite loops when decrementing.
Doing something periodically
Use the remainder operator to take action every Nth iteration:
#include <iostream>
int main()
{
int second{ 0 };
while (second <= 30)
{
std::cout << second << "s ";
if (second % 5 == 0)
std::cout << "[checkpoint] ";
if (second % 10 == 0)
std::cout << '\n';
++second;
}
return 0;
}
Output:
0s [checkpoint]
1s 2s 3s 4s 5s [checkpoint] 6s 7s 8s 9s 10s [checkpoint]
11s 12s 13s 14s 15s [checkpoint] 16s 17s 18s 19s 20s [checkpoint]
21s 22s 23s 24s 25s [checkpoint] 26s 27s 28s 29s 30s [checkpoint]
Checkpoints appear at 0, 5, 10, 15, 20, 25, 30 (every 5 seconds). Newlines appear at 0, 10, 20, 30 (every 10 seconds).
Nested loops
Loops can contain other loops. The inner loop runs completely for each iteration of the outer loop.
#include <iostream>
int main()
{
int rows{ 4 };
int cols{ 6 };
int y{ 0 };
while (y < rows)
{
int x{ 0 };
while (x < cols)
{
std::cout << '*';
++x;
}
std::cout << '\n';
++y;
}
return 0;
}
Output:
******
******
******
******
For each row (y = 0, 1, 2, 3), the inner loop prints 6 asterisks (x = 0, 1, 2, 3, 4, 5), then we print a newline and move to the next row.
Here's a more interesting pattern:
#include <iostream>
int main()
{
int size{ 5 };
int row{ 1 };
while (row <= size)
{
int star{ 1 };
while (star <= row)
{
std::cout << '*';
++star;
}
std::cout << '\n';
++row;
}
return 0;
}
Output:
*
**
***
****
*****
The inner loop's limit (row) changes with each outer iteration, creating the triangle pattern.
Summary
- Loops execute code repeatedly until a condition becomes false
- While loops check the condition before each iteration - if initially false, the body never executes
- Infinite loops occur when the condition never becomes false - intentional ones use
while (true) - The semicolon trap: a semicolon after
while (condition)creates an empty loop body - Signed loop variables prevent wrap-around bugs that cause infinite loops with unsigned types
- The remainder operator (
%) enables periodic actions every Nth iteration - Nested loops place one loop inside another - the inner loop completes fully for each outer iteration
While loops provide fundamental repetition capabilities. The for loop (next lesson) offers more convenient syntax for counting patterns.
Repetition with While Loops - Quiz
Test your understanding of the lesson.
Practice Exercises
Introduction to Loops
Practice using while loops for repetition.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!