Loops — for, while, do-while, Range-Based for, break, continue
In this tutorial, you will learn about Loops. We cover key concepts, practical examples, and best practices to help you master this topic.
C++ offers four loop constructs — for, while, do-while, and range-based for — each suited to different iteration patterns and all supporting break and continue for fine-grained control.
What You'll Learn
You will understand when to use each loop type, master the range-based for loop introduced in C++11 (with C++20 extensions), control loop flow with break and continue, avoid infinite loops and off-by-one errors, and see how loops interact with containers and iterators.
Why It Matters
Loops are the fundamental mechanism for processing sequences of data. Every non-trivial program iterates over collections, processes input streams, or repeats operations until a condition is met. Choosing the right loop type and understanding its semantics separates clean, correct code from buggy, hard-to-maintain code.
Learning Path
graph LR
A["07: Control Flow"] --> B["08: Loops"]
B --> C["09: Arrays & C-Strings"]
C --> D["10: Functions"]
style A fill:#4a90d9,stroke:#2c5f8a,color:#fff
style B fill:#4a90d9,stroke:#2c5f8a,color:#fff
style C fill:#4a90d9,stroke:#2c5f8a,color:#fff
style D fill:#4a90d9,stroke:#2c5f8a,color:#fff
The for Loop
The classic for loop has three parts: initialization, condition, and increment.
#include <iostream>
int main() {
for (int i = 0; i < 5; ++i) {
std::cout << i << " ";
}
std::cout << "\n";
// Output: 0 1 2 3 4
// Multiple variables
for (int i = 0, j = 10; i < j; ++i, --j) {
std::cout << i << "-" << j << " ";
}
std::cout << "\n";
// Output: 0-10 1-9 2-8 3-7 4-6
// Omitted sections
int k = 0;
for (; k < 3; ) {
std::cout << k++ << " ";
}
std::cout << "\n";
// Output: 0 1 2
// Infinite loop (use Ctrl+C to stop)
// for (;;) { std::cout << "forever "; }
}
The three sections of for are optional. A missing condition defaults to true. You can declare multiple variables of the same type in the initialization section.
The while Loop
A while loop checks the condition before each iteration. It runs zero or more times.
#include <iostream>
int main() {
int i = 0;
while (i < 5) {
std::cout << i << " ";
++i;
}
std::cout << "\n";
// Output: 0 1 2 3 4
// Sentinel-controlled loop
int sum = 0;
int value;
std::cout << "Enter numbers (negative to stop): ";
while (std::cin >> value && value >= 0) {
sum += value;
}
std::cout << "Sum: " << sum << "\n";
// Boolean flag
bool found = false;
int numbers[] = {3, 7, 1, 9, 4};
int idx = 0;
while (!found && idx < 5) {
if (numbers[idx] == 9) found = true;
else ++idx;
}
std::cout << "9 found at index " << idx << "\n";
}
The do-while Loop
A do-while loop checks the condition after each iteration. It always executes at least once.
#include <iostream>
int main() {
int i = 0;
do {
std::cout << i << " ";
++i;
} while (i < 5);
std::cout << "\n";
// Output: 0 1 2 3 4
// Guaranteed at least one execution
int x = 10;
do {
std::cout << "runs once\n";
} while (x < 5);
// Output: runs once
// Menu-driven program pattern
char choice;
do {
std::cout << "Menu: (q)uit, (h)ello: ";
std::cin >> choice;
if (choice == 'h') std::cout << "Hello!\n";
} while (choice != 'q');
}
The do-while is ideal for menus and input validation where you need to show the prompt at least once.
Range-Based for Loop (C++11)
The range-based for loop iterates over every element in a container or array.
#include <iostream>
#include <vector>
int main() {
int arr[] = {10, 20, 30, 40, 50};
for (int x : arr) {
std::cout << x << " ";
}
std::cout << "\n";
// Output: 10 20 30 40 50
std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
for (const std::string& name : names) {
std::cout << name << " ";
}
std::cout << "\n";
// Output: Alice Bob Charlie
// Modify elements with reference
for (int& x : arr) {
x *= 2;
}
for (int x : arr) {
std::cout << x << " ";
}
std::cout << "\n";
// Output: 20 40 60 80 100
// C++20: range-based for with initializer
for (std::vector<int> vec = {1, 2, 3}; int v : vec) {
std::cout << v << " ";
}
std::cout << "\n";
}
Always use const auto& for read-only iteration of non-trivial types, auto& to modify elements, and auto for cheap-to-copy types (int, char, bool, pointers).
break and continue
#include <iostream>
int main() {
// break: exit the loop immediately
for (int i = 0; i < 10; ++i) {
if (i == 5) break;
std::cout << i << " ";
}
std::cout << "\n";
// Output: 0 1 2 3 4
// continue: skip to next iteration
for (int i = 0; i < 10; ++i) {
if (i % 2 == 0) continue;
std::cout << i << " ";
}
std::cout << "\n";
// Output: 1 3 5 7 9
// Nested loop with break (breaks only the inner loop)
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (j == 1) break;
std::cout << i << "," << j << " ";
}
}
std::cout << "\n";
// Output: 0,0 1,0 2,0
}
break exits the innermost enclosing loop. continue skips the rest of the current iteration and evaluates the loop condition again.
Loop Comparison
| Loop | When the Condition is Checked | Minimum Executions | Best Use Case |
|---|---|---|---|
for |
Before each iteration | 0 | Known number of iterations, counter-controlled |
while |
Before each iteration | 0 | Condition-controlled, unknown iterations |
do-while |
After each iteration | 1 | Menu-driven, input validation |
| Range-for | N/A (uses iterators) | 0 | Iterating over containers/arrays |
Common Mistakes
Mistake 1: Off-by-One Errors
int arr[5];
for (int i = 0; i <= 5; ++i) arr[i] = i; // writes to arr[5], out of bounds
Use strict less-than (<) for zero-based indexing.
Mistake 2: Infinite Loops
for (int i = 0; i < 10; ++j) { ... } // i never increments
Double-check that your loop variable actually changes toward the exit condition.
Mistake 3: Modifying Container During Range-For
std::vector<int> v = {1, 2, 3};
for (int x : v) {
v.push_back(x); // invalidates iterators, undefined behavior
}
Do not add or remove elements from a container while iterating with range-for.
Mistake 4: continue in While Skips Increment
int i = 0;
while (i < 10) {
if (i % 2 == 0) continue; // skips ++i, infinite loop!
++i;
}
In a while loop, continue jumps to the condition check, skipping any increment below it. Use for loops to avoid this pattern.
Mistake 5: Forgetting Semicolon After do-while
do {
std::cout << "hello\n";
} while (false) // Error: missing semicolon
Mistake 6: Using = Instead of == in Condition
while (int i = 10) { ... } // assigns 10, always true
Practice Questions
- What is the difference between
whileanddo-while? - Write a range-based for loop that doubles every element in an
std::vector<int>. - What does
breakdo inside a nested loop? - Write a loop that prints the first 10 Fibonacci numbers.
- Convert this
whileloop to aforloop:int i = 0; while (i < 10) { cout << i; ++i; }
Challenge
Write a program that reads integers from std::cin until a negative number is entered, stores them in a std::vector<int>, then prints only the even numbers using a range-based for loop with continue.
FAQ
Mini Project
Write a prime number generator:
#include <iostream>
#include <vector>
bool isPrime(int n) {
if (n < 2) return false;
for (int d = 2; d * d <= n; ++d) {
if (n % d == 0) return false;
}
return true;
}
int main() {
std::vector<int> primes;
for (int i = 2; i <= 100; ++i) {
if (isPrime(i)) {
primes.push_back(i);
}
}
std::cout << "Primes up to 100:\n";
for (int p : primes) {
std::cout << p << " ";
}
std::cout << "\nCount: " << primes.size() << "\n";
}
Expected output:
Primes up to 100:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Count: 25
What's Next
Loops let you Process sequences of data efficiently. The next lesson covers C-style arrays and C-strings, including array decay, pointer arithmetic, and the std::array fixed-size container.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro