Even though the for statement can easily be rewritten using while, there are considerable advantages to using the for statement when it makes sense to do so. With a for statement, all the information you need to understand exactly which cycles will be executed is contained in the control line of the statement. For example, whenever you see the statement
for (i = 0; i< 10; i++) { ... body ...
}
in a program, you know that the statements in the body of the loop will be executed 10 times, once for each of the values of i between 0 and 9. In the equivalent while loop form
i = 0;
while (i< 10) { ... body ...
i++;
}
the increment operation at the bottom of the loop can easily get lost if the body is large.
Using for with floating-point data
Because the init, test, and step components of the for loop can be arbitrary expressions, there is no obvious reason why the loop index in a for loop has to be an integer. The fact that it is possible to count from 0 to 10 by twos using the for loop
for (i = 0; i <= 10; i += 2)...
suggests that it might also be possible to count from 1.0 to 2.9 in increments of 0.1 by declaring x as a double and then using
for (x = 1.; x <= 2.0; x += 0.1) ... This test may fail.
On some machines, this statement has the desired effect. On others, it might fail to include the last value. For example, when the for loop
for (x = 1.0; x<= 2.0; x += 0.1) {
printf(“%.1f\n, x); This loop might not include the value 2.0 }
is run on the computer system I used t oproduce this text, it generates the following output:
COMMON
Notice that the value 2.0, which you would expect to see form looking at the loop control line, is missing.
The problem here is that floating-point numbers are not exact. The value 0.1 is very close to the mathematical fraction 1/10 but is almost certainly not precisely equal to it. As 0.1 is added to the index variable x, the inaccuracy can accumulate to the point that, when x is tested against 2.0 to determine whether the loop is finished, its value may be 2.000000001 or something similar, which is not less than or equal 2.0. The condition in the for loop is therefore not satisfied, and the loop terminates after running for what seems to be one too few cycles. The best way to fix this problem is to restrict yourself to using
This for loop correctly produces the 11 values in the sequence 1.0, 1.1, 1.2, ... , 2.0.
The same warning about comparing floating-point numbers for equality applies in many other circumstances besides the for loop. Numbers that seem as if they should be exactly equal might not be, given the limitations on the accuracy of floating-point numbers stored in a particular machine.
SUMMARY
In Chapter 3, you looked at the process of programming form a holistic perspective that emphasized problem solving. Along the way, you learned about several control statements in an informal way. In this chapter, you were able to investigate how those statements work in more detail. You were also introduced to a new type of data called Boolean data. Although this data type contains only two values—TRUE and FALSE—being able to use Boolean data effectively is extremely important to successful programming and is sell worth a little extra practice.
This chapter also introduced several new operators, and at this point it is helpful to
precedence.
The important points introduced in this chapter include:
Simple statements consist of an expression followed by a semicolon.
The = used to specify assignment is an operator in C. Assignments are therefore legal expressions, which makes it possible to write embedded and multiple assignments.
Individual statements can be collected into compound statements, more commonly called blocks.
Control statements fall into two classes: conditional and iterative.
The genlib library defines a data type called bool that is used to represent Boolean data.
The type bool has only two values: TRUE and FALSE.
You can generate Boolean values using the relational operator (<, <=, >,>=,==, and !=) and combine them using the logical operators (&&, ||, and !).
The logical operators && and || are evaluated in left-to-right order in such a way that the evaluation stops as soon as the program can determine the result. This behavior is called short-circuit evaluation.
The if statement is used to express conditional execution when a section of code should be executed only in certain cases or when the program needs to choose between two alternate paths.
The switch statement is used to express conditional execution when a problem has the following structure: in case 1, do this; in case 2; do that; and so forth.
The while statement specifies repetition that occurs as long as some condition is met.
The for statement specifies repetition in which some action is needed on each cycle in order to update the value of an index variable.
REVIEW QUESTIONS
1. Is the construction 17;
a legal statement in C? Is it useful?
2. Describe the effect of the following statement, assuming that i, j, and k are declared as integer variables:
i = (j +4) * (k = 16);
3. What single statement would you write to set both x and y (which you may assume are declared to be type double) to 1.0?
4. What is meant by the term associativity? What is unusual about the associativity of assignment with respect to that of the other operators you have seen?
5. What is a block? What important fact about blocks is conveyed by the term compound statement, which is another name for the same concept?
6. What are the two classes of control statements?
7. What does it mean to say that two control statements are nested?
8. What are the two values of the data type bool?
9. What happens when a programmer tries to use the mathematical symbol for equality in a conditional expression?
10. What restriction does C place on the types of values that can be compared using the relational operators?
11. How would you write a Boolean expression to test whether the value of the integer variable n was in the range 0 to 9, inclusive?
12. Describe in English what the following conditional expression means:
(x != 4) || (x != 17)
for what values of x is this condition TRUE? 13. What does the term short-circuit evaluation mean?
14. Assuming that myFlag is declared as a Boolean variable, what is the problem with writing the following if statement?
if (myFlag == TURE) ...
15. What are the four different formats of the if statement used in this text?
16. Describe in English the general operation of the switch statement.
17. Suppose the body of a while loop contains a statement that, when executed, causes the condition for that while loop to become FALSE. Does the loop terminate immediately at that point or does it complete the current cycle?
18. Why is it important for the digitsum.c program in Figure 4-5 to specify that the integer is positive?
19. What is the loop-and-a-half problem? What two strategies are presented in the text for solving it?
20. What is the purpose of each of the three expressions that appear in the control line of a for statement?
21. What for loop control line would you use in each of the following situations:
a) Counting form 1 to 100.
b) Counting by sevens starting at 0 until the number has more than two digits.
c) Counting backward by twos form 100 to 0.
22. Why is it best to avoid using a floating-point variable as the index variable in a for loop?
PROGRAMMING EXERCISES
1. As a way to pass the time on long bus trips, young people growing up in the United States have been known to sing the following rather repetitive song:
99 bottles of beer on the wall.
99 bottles of beer.
You take one down, pass it around.
98 bottles of beer on the wall.
98 bottole of beer on the wall....
Any way, you get the idea. Write a C program to generate the lyrics to this song.
(Since you probably never actually finished singing this song, you should decide how you want it to end.) In testing your program, it would make sense to use some constant other than 99 as the initial number of bottles.
2. While we’re on the subject of silly songs, another old standby is ―This old Man,‖ for which the first verse is
This old man, he played 1.
He played knick-knack on my thumb.
With a knick-knack, paddy-whack, Give your dog a bone.
This old man came rolling home.
Each subsequent verse is the same, except for the number and the rhyming word at the end of the second line, which gets replaced as follows:
2—shoe 5—hive 8—pate 3—knee 6—sticks 9—spine 4—door 7—heaven 10—shin
Write a program to display all 10 verses of this song.
3. Write a program that reads in a positive integer N and then calculates and displays the sum of the first N odd integers. For example, if N is 4, your program should display the value 16, which is 1 + 3 +7.
4. Why is everything either at sixes or at sevens?
— Gilbert and Sullivan, H.M.S. Pinafore, 1878 Write a program that displays the integers between 1 and 100 that are divisible by either 6 or 7.
5. Repeat exercise 4, but this time have your program display only those numbers that are divisible by 6 or 7 but not both.
6. Rewrite the liftoff.c program given in Figure 4-7 so that it uses a while loop instead of a for loop.
7. Rewrite the digitsum.c program given in Figure 4-5 so that instead of adding the digits in the number, it generates the number that has the same digits in the reverse order, as illustrated by this sample run:
8. In mathematics, there is a famous sequence of numbers called the Fibonacci sequence after the thirteenth-century Italian mathematician Leonardo Fibonacci. The first two terms in this sequence are 0 and 1, and every subsequent term is the sum of the preceding two. Thus the first several numbers in the Fibonacci sequence are as follows:
F0 = 0 F1 = 1
F2 = 1 (0 + 1) F3 = 2 (1 + 1) F4 = 3 (1 + 2) F5 = 5 (2 + 3) F6 = 8 (3 + 5)
Write a program to display the values in this sequence from F0 through F15. Make sure the value line up as shown in the following sample run:
9. Modify the program in the preceding exercise so that instead of specifying the index of the final term, the program displays those terms in the Fibonacci sequence that are les than 10,000.
10. Write a program to display the following diagram on the screen. The number of rows in the figure should be a #define constant, which has the value 8 for this sample run:
This program reverses the digits in an inteer.
Enter a positive integer: 1729
The reversed number is 9271
This program lists the Fibonacci sequence.
F(1) = 0 F(2) = 1 F(2) = 1 F(3) = 2 F(4) = 3 F(5) = 5 F(6) = 8 F(7) = 13 F(8) = 21 F(9) = 34 F(10) = 55 F(11) = 89 F(12) = 144 F(13) = 233 F(14) = 377 F(15) = 610
*
**
***
****
*****
******
*******
********
11. Modify the program you wrote n exercise 10 so that it generates a different triangle.
In this triangle, each line contains two more points than the previous line does, and the point of the triangle faces upward, as follows:
*
***
*****
*******
*********
***********
*************
***************