Computers excel at performing repetitive operations with blazing speed and absolute precision. Whether you are summing a million numbers, parsing rows of telemetry data, rendering frames in a game loop, or searching through a database, you need a mechanism to execute code repeatedly.
In C++, iteration is accomplished through loops.
What You’ll Learn
- Why iteration is essential for clean software architecture
- The four loop constructs in C++:
for,while,do-while, and modern range-basedfor - The precise three-part lifecycle of a traditional
forloop - When to choose a pre-test loop (
while) vs. a post-test loop (do-while) - Controlling execution flow with
breakandcontinue - How to write intentional infinite loops safely
- Working with nested loops for multi-dimensional data
- Comprehensive loop comparison reference table
- Diagnosing classic pitfalls: off-by-one errors and floating-point counter drift
1. The Standard for Loop
The traditional for loop is ideal when you know in advance how many times an operation should repeat (such as iterating over a fixed count or an indexed sequence).
Syntax
for (initialization; condition; update) {
// Loop body
}
Execution Lifecycle
- Initialization: Executes exactly once before the first iteration begins. Typically declares and initializes a loop counter.
- Condition: Evaluated before every iteration. If
true, the loop body executes. Iffalse, the loop terminates. - Loop Body: The statements inside
{ ... }run. - Update: Executes immediately after the loop body on every iteration. Usually increments or decrements the counter. Then flow returns to Step 2.
Practical Example: Counting and Accumulation
#include <iostream>
using namespace std;
int main() {
int sum = 0;
// Sum numbers from 1 to 10
for (int i = 1; i <= 10; ++i) {
sum += i;
}
cout << "Sum of integers 1 through 10 is: " << sum << '\n';
return 0;
}
Output
Sum of integers 1 through 10 is: 55
2. The while Loop
The while loop is a pre-test loop. It checks its condition before entering the loop body. If the condition is false initially, the loop body never executes.
Syntax
while (condition) {
// Loop body (must modify state so condition eventually becomes false!)
}
The while loop is best suited for scenarios where the number of iterations depends on runtime events, user actions, or external state rather than a predetermined index count.
Practical Example: Interactive Number Guessing Game
#include <iostream>
using namespace std;
int main() {
const int secretCode = 7;
int guess = 0;
cout << "Guess the secret digit between 1 and 9:\n";
while (guess != secretCode) {
cout << "Enter your guess: ";
cin >> guess;
if (guess != secretCode) {
cout << "Incorrect! Try again.\n";
}
}
cout << "Congratulations! You found the secret code.\n";
return 0;
}
3. The do-while Loop
The do-while loop is a post-test loop. Unlike for and while, its condition is checked after the loop body executes.
As a result, a do-while loop is guaranteed to execute at least once, regardless of the initial condition.
Syntax
do {
// Loop body (runs at least once)
} while (condition); // Notice the required trailing semicolon!
do-while is especially valuable for menu selection and user validation where you must prompt the user at least once before checking if their response was valid.
Practical Example: Input Validation Loop
#include <iostream>
using namespace std;
int main() {
int choice = 0;
do {
cout << "\n=== System Control Menu ===\n";
cout << "1. Run Diagnostics\n";
cout << "2. View Error Logs\n";
cout << "3. Exit System\n";
cout << "Select an option (1-3): ";
cin >> choice;
} while (choice < 1 || choice > 3);
cout << "You selected valid option #" << choice << '\n';
return 0;
}
4. Modern C++: Range-Based for Loops
Introduced in C++11 and refined in C++17/20, the range-based for loop provides a clean, safe, and expressive syntax for iterating through all elements of an array, vector, or standard container without manual index counters:
Syntax
Practical Example
#include <iostream>
#include <vector>
using namespace std;
int main() {
int numbers[] = {12, 45, 68, 91, 33};
cout << "Iterating over array elements:\n";
// Read-only iteration using const reference (avoids copying elements)
for (const auto& num : numbers) {
cout << num << " ";
}
cout << '\n';
return 0;
}
Why Prefer Range-Based for?
- Eliminates Off-by-One Errors: You cannot accidentally exceed array boundaries or access an out-of-bounds index.
- Cleaner Syntax: No clutter with
int i = 0; i < size; ++i. - Safe by Default: Pairing
const auto& itemprevents expensive accidental object copies during iteration.
Controlling Loop Flow: break and continue
C++ provides two jump statements to alter loop flow dynamically.
1. The break Statement
Immediately terminates the enclosing loop, transferring control to the first statement following the loop:
#include <iostream>
using namespace std;
int main() {
// Searching for a target value
int values[] = {10, 25, 42, 88, 99};
int target = 42;
bool found = false;
for (int val : values) {
if (val == target) {
found = true;
break; // Stop searching immediately! No need to inspect remaining items
}
}
cout << "Target found: " << boolalpha << found << '\n';
return 0;
}
2. The continue Statement
Skips the remainder of the current iteration’s body and jumps straight to the loop’s update step:
#include <iostream>
using namespace std;
int main() {
// Print all odd numbers between 1 and 10
for (int i = 1; i <= 10; ++i) {
if (i % 2 == 0) {
continue; // Skip even numbers!
}
cout << i << " ";
}
cout << '\n'; // Prints: 1 3 5 7 9
return 0;
}
Intentional Infinite Loops
An infinite loop runs indefinitely unless explicitly terminated via break, return, or program exit. In event-driven programming, server daemons, and video game mainloops, intentional infinite loops are standard:
while (true) {
auto event = pollUserEvent();
if (event.isQuitRequest()) {
break; // Graceful exit
}
renderFrame();
}
Nested Loops
A loop placed inside the body of another loop is called a nested loop. For each single iteration of the outer loop, the inner loop executes its entire lifecycle from beginning to end:
Practical Example: Multiplication Table Matrix
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << "--- 5x5 Multiplication Grid ---\n\n";
for (int row = 1; row <= 5; ++row) {
for (int col = 1; col <= 5; ++col) {
cout << setw(4) << (row * col);
}
cout << '\n'; // End row
}
return 0;
}
Output
--- 5x5 Multiplication Grid ---
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
Loop Comparison Reference Table
| Loop Type | Condition Evaluation | Guaranteed Executions | Best Used For |
|---|---|---|---|
for | Pre-test (before body) | 0 | Known number of iterations, index counters |
while | Pre-test (before body) | 0 | Unknown count, event-driven loops, streams |
do-while | Post-test (after body) | At least 1 | User menus, input validation prompts |
Range-based for | Managed internally | 0 | Iterating through entire arrays, vectors, containers |
Common Beginner Mistakes
1. The Off-by-One Error
Using <= instead of < when indexing zero-based collections:
int arr[5] = {10, 20, 30, 40, 50};
// BUG: i goes up to 5, but valid indices are 0 to 4!
for (int i = 0; i <= 5; ++i) {
cout << arr[i]; // Memory corruption on i = 5!
}
2. Accidental Infinite Loops via Missing Updates
int i = 0;
while (i < 10) {
cout << i << '\n';
// BUG: Forgot ++i! i remains 0 forever!
}
3. Using Floating-Point Loop Counters
// BUG: Due to binary floating-point rounding inaccuracies, 0.1 cannot be represented exactly!
for (double d = 0.0; d != 1.0; d += 0.1) {
// May never hit exactly 1.0, looping forever!
}
// Fix: Use integer counters or relational inequalities (d < 1.0)
Best Practices
- Prefer range-based
forloops: When reading or modifying all elements of a collection, usefor (auto& x : col)orfor (const auto& x : col). - Keep loop bodies focused: If a loop body exceeds 30–40 lines, extract the logic into a dedicated helper function.
- Declare loop counters in the initialization clause: Write
for (int i = 0; ...)soiis scoped strictly to the loop and destroyed afterward. - Use prefix increment (
++i): Prefix avoids unnecessary copy creation for complex iterators.
Summary
- Iteration allows running a block of statements repeatedly without duplicating code.
foris best for counting and index-driven iteration.whilechecks its condition upfront and is best for dynamic conditions.do-whileguarantees at least one execution before testing the condition.- Modern range-based
forloops provide safe, elegant iteration over arrays and collections. breakexits a loop entirely;continueskips to the next iteration.
Continue Learning C++
- Previous Article: Conditional Statements in C++: if, else if, else, and switch
- Next Article: Functions in C++: Declaration, Scope, Overloading, and Parameters
- Explore Topic Hub: C++ Programming & Systems Engineering