Skip to content
Laviyx Learn

Try

C++ course menu

C++ for Loops in Depth: Counting, Range-Based for, Nested Loops and Patterns

Go deeper with C++ for loops: counting up and down, custom steps, several loop variables, range-based for with auto and references, structured bindings, nested loops and patterns, and choosing int vs size_t for indexes.

Beginner12 min readUpdated
On this page

The Loops lesson introduced the for loop. This lesson covers the variations you will use every day, and the patterns that come up again and again in exercises and interviews.

Counting in different ways#

The three parts of a for loop can do more than count up by one:

C++
#include <iostream>

int main() {
    for (int i = 10; i > 0; i -= 3) {   // count down in steps of 3
        std::cout << i << ' ';
    }
    std::cout << '\n';

    for (int i = 1; i <= 100; i *= 2) {  // powers of two
        std::cout << i << ' ';
    }
    std::cout << '\n';
}
Output
10 7 4 1
1 2 4 8 16 32 64

Several loop variables#

The initialization and update parts can handle more than one variable, separated by commas. A common use is walking from both ends towards the middle:

C++
#include <iostream>
#include <string>

int main() {
    std::string word = "level";
    bool palindrome = true;

    for (int left = 0, right = word.size() - 1; left < right; ++left, --right) {
        if (word[left] != word[right]) {
            palindrome = false;
        }
    }
    std::cout << word << (palindrome ? " is" : " is not") << " a palindrome\n";
}
Output
level is a palindrome

Range-based for in detail#

The range-based for visits every element of a container:

C++
#include <iostream>
#include <vector>

int main() {
    std::vector<int> prices = {120, 45, 300};

    for (int p : prices) {          // p is a copy
        std::cout << p << ' ';
    }
    std::cout << '\n';

    for (int& p : prices) {         // p refers to the real element
        p += 10;
    }

    for (const auto& p : prices) {  // read-only, no copies
        std::cout << p << ' ';
    }
    std::cout << '\n';
}
Output
120 45 300
130 55 310

Three forms to remember:

FormUse when
for (auto x : items)Elements are small (numbers, char) and you only read them
for (const auto& x : items)Reading larger elements, such as strings or objects, without copying
for (auto& x : items)Changing the elements in place

Looping over a map with structured bindings#

When each element is a pair, such as in a std::map, structured bindings (C++17) unpack it into two names:

C++
#include <iostream>
#include <map>
#include <string>

int main() {
    std::map<std::string, int> stock = {{"pens", 40}, {"books", 12}, {"bags", 5}};

    for (const auto& [item, count] : stock) {
        std::cout << item << ": " << count << '\n';
    }
}
Output
bags: 5
books: 12
pens: 40

A std::map keeps its keys sorted, which is why bags comes first. See map.

Index loops and size_t#

When you need the position, loop with an index. A container's size() is an unsigned type (std::size_t), so comparing it with an int triggers a signed/unsigned warning. Use std::size_t for the index:

C++
#include <iostream>
#include <vector>

int main() {
    std::vector<int> scores = {72, 88, 95};

    for (std::size_t i = 0; i < scores.size(); ++i) {
        std::cout << "#" << i + 1 << ": " << scores[i] << '\n';
    }
}
Output
#1: 72
#2: 88
#3: 95

Nested loops#

A loop inside a loop runs the inner loop completely for every step of the outer loop:

C++
#include <iostream>

int main() {
    for (int row = 1; row <= 3; ++row) {
        for (int col = 1; col <= 4; ++col) {
            std::cout << row * col << '\t';
        }
        std::cout << '\n';
    }
}
Output
1	2	3	4
2	4	6	8
3	6	9	12

The inner body runs 3 × 4 = 12 times. Nested loops multiply quickly: two loops of 1000 steps each run the inner body a million times.

Printing patterns#

Pattern problems are classic practice for nested loops. The inner loop's limit depends on the outer variable:

C++
#include <iostream>

int main() {
    int height = 4;
    for (int row = 1; row <= height; ++row) {
        for (int i = 0; i < height - row; ++i) std::cout << ' ';
        for (int i = 0; i < 2 * row - 1; ++i) std::cout << '*';
        std::cout << '\n';
    }
}
Output
   *
  ***
 *****
*******

Row r has height - r spaces, then 2r - 1 stars.

Common loop patterns#

C++
#include <iostream>
#include <vector>

int main() {
    std::vector<int> values = {14, 3, 27, 8, 19};

    int sum = 0;
    int largest = values[0];
    int even_count = 0;

    for (int v : values) {
        sum += v;
        if (v > largest) largest = v;
        if (v % 2 == 0) ++even_count;
    }

    std::cout << "Sum: " << sum << '\n';
    std::cout << "Largest: " << largest << '\n';
    std::cout << "Even numbers: " << even_count << '\n';
}
Output
Sum: 71
Largest: 27
Even numbers: 2

Accumulate (sum), track the best so far (largest), and count matches: these three patterns solve a large share of loop problems. The standard library also has ready-made versions (std::accumulate, std::max_element, std::count_if) covered in Algorithms.

Common mistakes#

Practice#

Practice exercise

Print this right-angled number triangle using nested loops:

Text
1
1 2
1 2 3
1 2 3 4
Show solution
C++
#include <iostream>

int main() {
    for (int row = 1; row <= 4; ++row) {
        for (int n = 1; n <= row; ++n) {
            std::cout << n;
            if (n < row) std::cout << ' ';
        }
        std::cout << '\n';
    }
}
Output
1
1 2
1 2 3
1 2 3 4

Practice exercise

Given std::vector<int> marks = {56, 91, 78, 34, 88};, use a range-based for to print the average (as a decimal) and how many marks are 75 or above.

Show solution
C++
#include <iostream>
#include <vector>

int main() {
    std::vector<int> marks = {56, 91, 78, 34, 88};

    int total = 0;
    int high = 0;
    for (int m : marks) {
        total += m;
        if (m >= 75) ++high;
    }

    double average = static_cast<double>(total) / marks.size();
    std::cout << "Average: " << average << '\n';
    std::cout << "75 or above: " << high << '\n';
}
Output
Average: 69.4
75 or above: 3

Key takeaway#

Finished this lesson?