C++ For Loop - Complete Guide
Understanding the For Loop
The for
loop is a compact looping construct in C++ that repeats a statement or block for a controlled number of iterations.
It has three parts: initialization, condition, and iteration. The condition is checked before each iteration; the iteration expression runs after the loop body. Variables declared in the initialization part have scope limited to the loop.
Detailed Syntax Breakdown
#include <iostream>
using namespace std;
int main() {
for (int i = 0; i < 5; i++) {
cout << "Value: " << i << '\n';
}
}
Value: 0 Value: 1 Value: 2 Value: 3 Value: 4
Full Syntax & Variations
General form: for ( init-statement ; condition ; iteration ) statement;
Each part is optional; omitting the condition makes it true
.
// Infinite loop (use with care)
for (;;) { work(); }
// Omit initialization or iteration as needed
int i = 0;
for (; i < n; ) { /* ... */ ++i; }
// Declare multiple variables of the same type; update several with the comma operator
for (int i = 0, j = n - 1; i < j; ++i, --j) {
// process from both ends
}
Range-Based For (C++11+)
For iterating containers and arrays, prefer the range-based for loop for clarity and safety.
#include <vector>
#include <string>
#include <map>
#include <iostream>
using namespace std;
int main() {
vector<int> v{1,2,3};
// Read-only
for (int x : v) { cout << x << ' '; }
cout << '\n';
// Modify elements in place
for (int &x : v) { x *= 2; }
// Read-only strings by const reference (avoids copies)
vector<string> names{"Ann","Bob"};
for (const string &s : names) { cout << s << ' '; }
cout << '\n';
// C++17 structured bindings (maps, pairs, tuples)
map<string,int> freq{{"a",1},{"b",2}};
for (auto &[key, val] : freq) { val++; }
}
Indexing Containers Safely
When indexing standard containers, prefer std::size_t
(the type returned by size()
) to avoid signed/unsigned comparison issues.
#include <vector>
#include <cstddef>
std::vector<int> v{10,20,30};
for (std::size_t i = 0; i < v.size(); ++i) {
// safe index-based access
}
Common Patterns
Erasing While Iterating (Containers)
Erasing elements invalidates iterators for many containers. Use the erase-return pattern or erase/remove_if
.
#include <vector>
#include <algorithm>
std::vector<int> v{1,2,3,4,5,6};
// Iterator-safe erase loop
for (auto it = v.begin(); it != v.end(); ) {
if (*it % 2 == 0) it = v.erase(it); // returns next valid iterator
else ++it;
}
// Or the erase-remove idiom (removes all evens)
v.erase(std::remove_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; }), v.end());
Debugging Tips
- 🔹 Ensure the loop condition will eventually become false (avoid infinite loops).
- 🔹 Watch for off-by-one errors (
<
vs<=
). - 🔹 Initialize variables before use; keep loop state local to the loop when possible.
- 🔹 Avoid modifying the loop counter inside the body.
- 🔹 Avoid floating-point loop counters for index logic—precision can cause missed termination.
- 🔹 Prefer range-based
for
for containers/arrays when you don’t need the index.