for
StatementThe syntactic form of the for
statement is:
for (init-statement condition; expression)
statement
The for
and the part inside the parentheses is often referred to as the for
header.
init-statement must be a declaration statement, an expression statement, or a null statement. Each of these statements ends with a semicolon, so the syntactic form can also be thought of as
for (initializer; condition; expression)
statement
In general, init-statement is used to initialize or assign a starting value that is modified over the course of the loop. condition serves as the loop control. As long as condition evaluates as true
, statement is executed. If the first evaluation of condition yields false
, statement is not executed. expression usually modifies the variable(s) initialized in init-statement and tested in condition. expression is evaluated after each iteration of the loop. As usual, statement can be either a single or a compound statement.
for
LoopGiven the following for
loop from § 3.2.3 (p. 94):
// process characters in s until we run out of characters or we hit a whitespace
for (decltype(s.size()) index = 0;
index != s.size() && !isspace(s[index]); ++index)
s[index] = toupper(s[index]); // capitalize the current character
the order of evaluation is as follows:
1. init-statement is executed once at the start of the loop. In this example, index
is defined and initialized to zero.
2. Next, condition is evaluated. If index
is not equal to s.size()
and the character at s[index]
is not whitespace, the for
body is executed. Otherwise, the loop terminates. If the condition is false
on the first iteration, then the for
body is not executed at all.
3. If the condition is true
, the for
body executes. In this case, the for
body makes the character at s[index]
uppercase.
4. Finally, expression is evaluated. In this example, index
is incremented by 1.
These four steps represent the first iteration of the for
loop. Step 1 is executed only once on entry to the loop. Steps 2, 3, and 4 are repeated until the condition evaluates as false
—that is, when we encounter a whitespace character in s
, or index
is greater than s.size()
.
It is worth remembering that the visibility of any object defined within the for
header is limited to the body of the for
loop. Thus, in this example, index
is inaccessible after the for
completes.
for
HeaderAs in any other declaration, init-statement can define several objects. However, init-statement may be only a single declaration statement. Therefore, all the variables must have the same base type (§ 2.3, p. 50). As one example, we might write a loop to duplicate the elements of a vector
on the end as follows:
// remember the size of v and stop when we get to the original last element
for (decltype(v.size()) i = 0, sz = v.size(); i != sz; ++i)
v.push_back(v[i]);
In this loop we define both the index, i
, and the loop control, sz
, in init-statement.
for
HeaderA for
header can omit any (or all) of init-statement, condition, or expression.
We can use a null statement for init-statement when an initialization is unnecessary. For example, we might rewrite the loop that looked for the first negative number in a vector
so that it uses a for
:
auto beg = v.begin();
for ( /* null */; beg != v.end() && *beg >= 0; ++beg)
; // no work to do
Note that the semicolon is necessary to indicate the absence of init-statement—more precisely, the semicolon represents a null init-statement. In this loop, the for
body is also empty because all the work of the loop is done inside the for
condition and expression. The condition decides when it’s time to stop looking and the expression increments the iterator.
Omitting condition is equivalent to writing true
as the condition. Because the condition always evaluates as true
, the for
body must contain a statement that exits the loop. Otherwise the loop will execute indefinitely:
for (int i = 0; /* no condition */ ; ++i) {
// process i; code inside the loop must stop the iteration!
}
We can also omit expression from the for
header. In such loops, either the condition or the body must do something to advance the iteration. As an example, we’ll rewrite the while
loop that read input into a vector
of int
s:
vector<int> v;
for (int i; cin >> i; /* no expression */ )
v.push_back(i);
In this loop there is no need for an expression because the condition changes the value of i
. The condition tests the input stream so that the loop ends when we’ve read all the input or encounter an input error.