5.11 The for Construct
5.11.1 The for Statement in C
The pseudocode construct for h = 1 to 5 do
print "I must not sleep in class"
endfor
is implemented in C as follows:
for (h = 1; h <= 5; h++)
printf("I must not sleep in class\n");
assuming that h is declared as int. However, it is more common to declare h in the for statement itself, like this:
for (int h = 1; h <= 5; h++)
printf("I must not sleep in class\n");
In this case, though, note that the scope of h extends only to the body of the for (see next).
■Caution the ability to declare the loop variable in the for statement was not allowed in early versions of C.
if you are using an older compiler, you will get an error. in that case, just declare the loop variable before the for statement.
In C, the body of the for must be a single statement or a block. In the example, it is the single printf statement. If it were a block, we would write it in the following form:
for (int h = 1; h <= 5; h++) { <statement1>
<statement2>
etc.
}
When we declare the loop variable (h in the example) in the for statement, h is “known” (can be used) within the block only. If we attempt to use h after the block, we will get an “undeclared variable” error message.
Program P5.10 illustrates how the for statement is used to print the following five times:
I must not sleep in class
As you could probably figure out, if you want to print 100 lines, say, all you have to do is change 5 to 100 in the for statement.
Program P5.10
#include int main() { int h;
for (h = 1; h <= 5; h++)
printf("I must not sleep in class\n");
}
The general form of the for statement in C is for (<expr1>; <expr2>; <expr3>)
<statement>
The word for, the brackets, and the semicolons are required. You must supply <expr1>,
<expr2>, <expr3>, and <statement>.
In detail, the for statement consists of
• The word for
• A left bracket, (
• <expr1>, called the initialization step; this is the first step performed when the for is executed.
• A semicolon, ;
• <expr2>, the condition which controls whether or not <statement> is executed.
• A semicolon, ;
• <expr3>, called the reinitialization step
• A right bracket, )
• <statement>, called the body of the loop. This can be a simple statement or a block.
When a for statement is encountered, it is executed as follows:
1. <expr1> is evaluated.
2. <expr2> is evaluated. If it is false, execution continues with the statement, if any, after <statement>. If it is true, <statement> is executed, followed by <expr3>, and this step (2) is repeated.
This can be expressed more concisely as follows:
<expr1>;
while (<expr2>) { <statement>;
<expr3>;
}
Consider the following:
for (h = 1; h <= 5; h++)
printf("I must not sleep in class\n");
• h = 1 is <expr1>
• h <= 5 is <expr2>
• h++ is <expr3>
• <statement> is printf(...);
This code is executed as follows:
1. h is set to 1
2. The test h <= 5 is performed. It is true, so the body of the loop is executed (one line is printed). The reinitialization step h++ is then performed, so h is now 2.
3. The test h <= 5 is again performed. It is true, so the body of the loop is executed (a second line is printed); h++ is performed, so h is now 3.
4. The test h <= 5 is again performed. It is true, so the body of the loop is executed (a third line is printed); h++ is performed, so h is now 4.
5. The test h <= 5 is again performed. It is true, so the body of the loop is executed (a fourth line is printed); h++ is performed, so h is now 5.
6. The test h <= 5 is again performed. It is true, so the body of the loop is executed (a fifth line is printed); h++ is performed, so h is now 6.
7. The test h <= 5 is again performed. It is now false, so execution of the for loop ends and the program continues with the statement, if any, after printf(...).
On exit from the for loop, the value of h (6, in this case) is available and may be used by the programmer, if required. Note, however, that if h was declared in the for statement, it would be unavailable outside the loop.
If we need a loop to count backwards (from 5 down to 1, say), we can write for (int h = 5; h >= 1; h--)
The loop body is executed with h taking on the values 5, 4, 3, 2, and 1.
We can also count upwards (or downwards) in steps other than 1. For example, the statement for (int h = 10; h <= 20; h += 3)
will execute the body with h taking on the values 10, 13, 16 and 19. And the statement for (int h = 100; h >= 50; h -= 10)
will execute the body with h taking on the values 100, 90, 80, 70, 60, and 50.
In general, we can use whatever expressions we need to get the effect that we want.
In Program P5.10, h takes on the values 1, 2, 3, 4, and 5 inside the loop. We have not used h in the body but it is available, if needed. We show a simple use in Program P5.11 in which we number the lines by printing the value of h.
Program P5.11
#include <stdio.h>
int main() {
for (int h = 1; h <= 5; h++)
printf("%d. I must not sleep in class\n", h);
}
When run, this program will print the following:
1. I must not sleep in class 2. I must not sleep in class 3. I must not sleep in class 4. I must not sleep in class 5. I must not sleep in class
The initial and final values in the for statement do not have to be constants; they can be variables or expressions. For example, consider this:
for (h = 1; h <= n; h++) ...
How many times would the body of this loop be executed? We cannot say unless we know the value of n when this statement is encountered. If n has the value 7, then the body would be executed 7 times.
This means that before the computer gets to the for statement, n must have been assigned some value and it is this value which determines how many times the loop is executed. If a value has not been assigned to n, the for statement would not make sense and the program will crash (or, at best, give some nonsensical output).
To illustrate, we can modify Program P5.11 to ask the user how many lines she wants to print.
The number entered is then used to control how many times the loop is executed and, hence, how many lines are printed.
The changes are shown in Program P5.12.
Program P5.12
#include <stdio.h>
int main() { int n;
printf("How many lines to print? ");
scanf("%d", &n);
printf("\n"); //print a blank line for (int h = 1; h <= n; h++)
printf("%d. I must not sleep in class\n", h);
}
A sample run is shown below. We will show shortly how to neaten the output.
How many lines to print? 12 1. I must not sleep in class 2. I must not sleep in class 3. I must not sleep in class 4. I must not sleep in class 5. I must not sleep in class 6. I must not sleep in class 7. I must not sleep in class 8. I must not sleep in class 9. I must not sleep in class 10. I must not sleep in class 11. I must not sleep in class 12. I must not sleep in class
Note that we do not (and cannot) know beforehand what number the user will type. However, that is not a problem. We simply store the number in a variable (n is used) and use n as the “final value” in the for statement. Thus, the number the user types will determine how many times the body is executed.
Now the user can change the number of lines printed simply by entering the desired value in response to the prompt. No change is needed in the program. Program P5.12 is much more flexible than P5.11.