For Loops
A for loop repeats a block of code a specified number of times. C++ provides two for loop forms: the traditional for loop (giving precise control over an index) and the range-based for loop (C++11, iterating over any container without index arithmetic).
Traditional For Loop
cpp
#include <iostream>
using namespace std;
int main() {
// Syntax: for (init; condition; update)
for (int i = 0; i < 5; i++) {
cout << i << " ";
}
cout << "\n";
// Output: 0 1 2 3 4
// Count down
for (int i = 5; i > 0; i--) {
cout << i << " ";
}
cout << "\n";
// Output: 5 4 3 2 1
// Step by 2
for (int i = 0; i <= 10; i += 2) {
cout << i << " ";
}
cout << "\n";
// Output: 0 2 4 6 8 10
return 0;
}The three parts of the for header are all optional:
- Init: executed once before the loop starts
- Condition: checked before each iteration; loop exits when false
- Update: executed after each iteration body
Range-Based For Loop (C++11)
cpp
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
// Iterating over an array
int numbers[] = {10, 20, 30, 40, 50};
for (int n : numbers) {
cout << n << " ";
}
cout << "\n";
// Output: 10 20 30 40 50
// Iterating over a vector
vector<string> fruits = {"apple", "banana", "cherry"};
for (const string& fruit : fruits) { // const& avoids copying
cout << fruit << "\n";
}
// Using auto (type deduced automatically)
for (const auto& fruit : fruits) {
cout << fruit.size() << " ";
}
cout << "\n";
// Output: 5 6 6
// Modifying elements (by reference)
vector<int> v = {1, 2, 3, 4, 5};
for (auto& elem : v) {
elem *= 2;
}
// v = {2, 4, 6, 8, 10}
return 0;
}Note: Use const auto& when you only need to read elements — it avoids copying and works with any container type.
Nested For Loops
cpp
#include <iostream>
using namespace std;
int main() {
// Multiplication table
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
cout << i * j;
if (j < 5) cout << "\t";
}
cout << "\n";
}
// Output:
// 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
// Triangle pattern
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
cout << "* ";
}
cout << "\n";
}
// *
// * *
// * * *
// * * * *
// * * * * *
return 0;
}break and continue
cpp
#include <iostream>
using namespace std;
int main() {
// break — exits the loop entirely
for (int i = 0; i < 10; i++) {
if (i == 5) break;
cout << i << " ";
}
cout << "\n";
// Output: 0 1 2 3 4
// continue — skips to the next iteration
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) continue;
cout << i << " ";
}
cout << "\n";
// Output: 1 3 5 7 9
// break in nested loops — only breaks the innermost loop
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) break; // Breaks inner loop only
cout << "(" << i << "," << j << ") ";
}
}
cout << "\n";
// Output: (0,0) (1,0) (2,0)
return 0;
}Breaking Out of Nested Loops
C++ does not have labelled break (unlike Java). Use a flag variable or goto:
cpp
#include <iostream>
using namespace std;
int main() {
bool found = false;
int targetRow = -1, targetCol = -1;
int matrix[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int target = 7;
// Method 1: Flag variable
for (int i = 0; i < 3 && !found; i++) {
for (int j = 0; j < 4; j++) {
if (matrix[i][j] == target) {
targetRow = i;
targetCol = j;
found = true;
break; // Breaks inner; outer checks !found
}
}
}
if (found) cout << "Found " << target << " at [" << targetRow << "][" << targetCol << "]\n";
// Found 7 at [1][2]
// Method 2: goto (acceptable for breaking nested loops)
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
if (matrix[i][j] == target) {
cout << "Found again at [" << i << "][" << j << "]\n";
goto done;
}
}
}
done:;
return 0;
}Loop with Index and Element (Enumerate Pattern)
cpp
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
vector<string> items = {"alpha", "beta", "gamma", "delta"};
// Traditional — when you need the index
for (size_t i = 0; i < items.size(); i++) {
cout << i << ": " << items[i] << "\n";
}
// 0: alpha
// 1: beta
// 2: gamma
// 3: delta
// Alternatively, using integer-based range
for (int i = 0; auto& item : items) { // C++20 init in range-for
cout << i++ << ": " << item << "\n";
}
return 0;
}Infinite Loop with for
cpp
// An infinite loop — break must exit it
for (;;) {
cout << "Press q to quit: ";
char ch;
cin >> ch;
if (ch == 'q') break;
cout << "You pressed: " << ch << "\n";
}Loop Optimisation Tips
cpp
#include <vector>
using namespace std;
int main() {
vector<int> v(1000000, 1);
// BAD: calls v.size() (and implicit conversion) every iteration
for (int i = 0; i < v.size(); i++) { }
// BETTER: cache size, use size_t to match container type
for (size_t i = 0, n = v.size(); i < n; i++) { }
// BEST for simply iterating: range-based for
for (const auto& elem : v) { }
// Prefer pre-increment (++i) over post-increment (i++) in loops
// Post-increment creates a temporary copy — irrelevant for int but matters for iterators
for (auto it = v.begin(); it != v.end(); ++it) { }
return 0;
}Practical Example: Sorting with Bubble Sort
cpp
#include <iostream>
#include <vector>
using namespace std;
void bubbleSort(vector<int>& arr) {
int n = arr.size();
for (int pass = 0; pass < n - 1; pass++) {
bool swapped = false;
for (int j = 0; j < n - 1 - pass; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
swapped = true;
}
}
// Early exit if no swaps in this pass — already sorted
if (!swapped) break;
}
}
void printArray(const vector<int>& arr) {
for (const auto& val : arr) {
cout << val << " ";
}
cout << "\n";
}
int main() {
vector<int> data = {64, 25, 12, 22, 11};
cout << "Before: ";
printArray(data);
// Before: 64 25 12 22 11
bubbleSort(data);
cout << "After: ";
printArray(data);
// After: 11 12 22 25 64
// Matrix operations with nested loops
const int ROWS = 3, COLS = 3;
int matrix[ROWS][COLS] = {{1,2,3},{4,5,6},{7,8,9}};
cout << "Transpose:\n";
for (int j = 0; j < COLS; j++) {
for (int i = 0; i < ROWS; i++) {
cout << matrix[i][j] << " ";
}
cout << "\n";
}
// 1 4 7
// 2 5 8
// 3 6 9
return 0;
}Summary
- Traditional
for:for (init; condition; update)— use when you need an index or precise iteration control - Range-based
for:for (const auto& elem : container)— use for all standard container iteration in modern C++ - Use
const auto&to read without copying; useauto&to modify elements breakexits the innermost loop;continueskips to the next iteration- Breaking out of nested loops requires a flag variable, a function with
return, orgoto - Prefer pre-increment
++iin loops — never slower and sometimes faster for complex types - Cache
v.size()outside the loop if calling in a tight inner loop to avoid repeated method calls
Next, we'll cover while and do-while loops — repeating code until a condition changes, without a fixed count.