Skip to content
Theory · Loops · lesson 1 of 8

for, while and do-while

To print the numbers 1 to 5, you can write five lines with std::cout. A thousand numbers would take a thousand lines. Instead, you write a loop, a construct that repeats an action while a condition holds:

C++
#include <iostream>

int main() {
    for (int i = 1; i <= 5; ++i) {
        std::cout << i << ' ';  // 1 2 3 4 5
    }
    std::cout << '\n';
}

How a for loop runs

The for header has three parts separated by semicolons: the initialization, the condition and the step. The initialization int i = 1 runs once, before the loop starts. Before every pass, the condition i <= 5 is checked: if it is true, the body runs, followed by the step ++i. One pass through the body is called an iteration.

When i becomes 6, the condition is false and the loop ends. The variable i is declared in the header, so it is visible only inside the loop. After the closing brace, the name i no longer exists.

Counting iterations

A loop runs as many times as there are values its counter i takes. In for (int i = 0; i < 5; ++i), those are the values 0 to 4, that is, five iterations. The < sign keeps i from reaching the bound itself.

Replace < with <=, and i reaches 5 too, which makes six iterations. A loop that runs one time too many or too few has an off-by-one error.

while and do-while

A while loop checks its condition before every iteration, like for, but it has no initialization or step. The variable is declared before the loop and changed in the body. This is how you count how many integer divisions by 2 it takes to bring 100 down to 1:

C++
int n = 100;
int steps = 0;
while (n > 1) {
    n = n / 2;
    ++steps;
}
std::cout << steps << '\n';  // 6

A do-while loop runs its body first and only then checks the condition. So its body runs at least once, even if the condition is false from the start:

C++
int n = 10;
while (n < 5) {
    std::cout << n << '\n';
    ++n;
}
do {
    std::cout << n << '\n';  // 10
    ++n;
} while (n < 5);

Common mistake

An unsigned counter in a countdown loop:

C++
for (unsigned i = 3; i >= 0; --i) {  // ✗
    std::cout << i << '\n';
}

An unsigned value is never negative, so the condition i >= 0 is always true. Subtracting one from 0 gives the largest unsigned value, and the loop prints numbers forever. GCC with the -Wextra flag warns that the comparison is always true, but Clang stays silent even with -Wextra. To count down to zero, declare the counter as int: after 0 it becomes -1, and the condition turns false.