Additional C+ + Operators
C++ has several other operators you should learn besides those you learned in Chapters 9 and 10. In fact, C++ has more operators than most programming languages. Unless you become familiar with them, you might think C++ programs are cryptic and difficult to follow. C++’s heavy reliance on its operators and operator prece- dence produces the efficiency that enables your programs to run more smoothly and quickly.
This chapter teaches you the following:
-
The ?: conditional operator
-
The ++ increment operator
-
The –– decrement operator
-
The si zeof operator
-
The (, ) comma operator
-
The Bitwise Operators (&, | , and ^)
Chapter 11 ♦ Additional C++ Operators
Most the operators described in this chapter are unlike those found in any other programming language. Even if you have programmed in other languages for many years, you still will be surprised by the power of these C++ operators.
The conditional
The Conditional Operato r
The conditional operator is C++’s only ternary operator, requir-
operator is a ternary operator.
ing three operands (as opposed to the unary’s single-and the binary’s double-operand requirements). The conditional operator is used to replace i f - el se logic in some situations. The conditional operator is a two-part symbol, ?: , with a format as follows:
condi t i onal _expr essi on ? expr essi on1 : expr essi on2 ;
The condi t i onal _expr essi on is any expression in C++ that results in a True (nonzero) or False (zero) answer. If the result of condi t i onal _expr essi on is True, expr essi on1 executes. Otherwise, if the result of condi t i onal _expr essi on is False, expr essi on2 executes. Only one of the expressions following the question mark ever executes. Only a single semicolon appears at the end of expr essi on2 . The internal expressions, such as expr essi on1 , do not have a semico- lon. Figure 11.1 illustrates the conditional operator more clearly.
Figure 11.1. Format of the conditional operator.
EXAMPLE
If you require simple i f - el se logic, the conditional operator usually provides a more direct and succinct method, although you should always prefer readability over compact code.
To glimpse the conditional operator at work, consider the section of code that follows.
i f ( a > b)
{ ans = 10; } el se
{ ans = 25; }
You can easily rewrite this kind of i f - el se code by using a single conditional operator.
If the variable a is greater than the variable b*, make the variable* ans
equal to 10; otherwise, make ans equal to 25.
a > b ? ( ans = 10) : ( ans = 25) ;
Although parentheses are not required around condi t i onal _expr essi on to make it work, they usually improve read- ability. This statement’s readability is improved by using parenthe- ses, as follows:
( a > b) ? ( ans = 10) : ( ans = 25) ;
Because each C++ expression has a value—in this case, the value being assigned—this statement could be even more succinct, without loss of readability, by assigning ans the answer to the left of the conditional:
ans = ( a > b) ? ( 10) : ( 25) ;
This expression says: If a is greater than b, assign 10 to ans ; otherwise, assign 25 to ans . Almost any i f - el se statement can be rewritten as a conditional, and vice versa. You should practice converting one to the other to familiarize yourself with the condi- tional operator’s purpose.
Chapter 11 ♦ Additional C++ Operators
Examples
- Suppose
you are looking over your early C++ programs, and you notice the following section of code.
i f ( pr oduct i on > t ar get )
{ t ar get *= 1. 10; } el se
{ t ar get *= . 90; }
You should realize that such a simple i f - el se statement can be rewritten using a conditional operator, and that more efficient code results. You can therefore change it to the following single statement.
( pr oduct i on > t ar get ) ? ( t ar get *= 1. 10) : ( t ar get *= . 90) ;
- Using
a conditional operator, you can write a routine to find the minimum value between two variables. This is some- times called a minimum routine. The statement to do this is
mi ni mum = ( var 1 < var 2) ? var 1 : var 2;
If var 1 is less than var 2 , the value of var 1 is assigned to mi ni
- mum. If var 2 is less, the value of var 2 is assigned to mi ni mum. If the variables are equal, the value of var 2 is assigned to
mi ni mum, because it does not matter which is assigned.
- A maximum routine can be written just as easily:
maxi mum = ( var 1 > var 2) ? var 1 : var 2;
- Taking
the previous examples a step further, you can also test for the sign of a variable. The following conditional expression assigns –1 to the variable called si gn if t est var is less than 0; 0 to si gn if t est var is zero; and +1 to si gn if t est var is 1 or more.
si gn = ( t est var < 0) ? - 1 : ( t est var > 0) ;
It might be easy to spot why the less-than test results in a –1, but the second part of the expression can be confusing. This works well due to C++’s 1 and 0 (for True and False, respec- tively) return values from a relational test. If t est var is 0 or greater, si gn is assigned the answer ( t est var > 0) . The value
EXAMPLE
of ( t est var > 0) is 1 if True (therefore, t est var is more than 0) or 0 if t est var is equal to 0.
The preceding statement shows C++’s efficient conditional operator. It might also help you understand if you write the statement using typical i f - el se logic. Here is the same problem written with a typical i f - el se statement:
The++ operator
i f ( t est var < 0)
{ si gn = - 1; } el se
{ si gn = ( t est var > 0) ; } / / t est var can onl y be
/ / 0 or mor e her e.
The Increment an d Decrement Operator s
C++ offers two unique operators that add or subtract 1 to or
adds 1 to a variable. The–– operator subtracts 1 from a variable.
from variables. These are the increment and decrement operators: ++ and ––. Table 11.1 shows how these operators relate to other types of expressions you have seen. Notice that the ++ and –– can appear on either side of the modified variable. If the ++ or –– appears on the left, it is known as a prefix operator. If the operator appears on the right, it is a postfix operator.
Table 11.1. The ++ and –– operators.
Operator Example Description Equivalent Statements
++ |
i ++; |
postfix |
i |
= |
i |
+ 1; |
i |
+= 1; |
---|---|---|---|---|---|---|---|---|
++ |
++i ; |
prefix |
i |
= |
i |
+ 1; |
i |
+= 1; |
–– |
i ––; |
postfix |
i |
= |
i |
- 1; |
i |
- = 1; |
–– |
––i ; |
prefix |
i |
= |
i |
- 1; |
i |
- = 1; |
Any time you have to add 1 or subtract 1 from a variable, you can use these two operators. As Table 11.1 shows, if you have to increment or decrement only a single variable, these operators enable you to do so.
Chapter 11 ♦ Additional C++ Operators
Whether you use prefix or postfix does not matter—if you are incrementing or decrementing single variables on lines by them- selves. However, when you combine these two operators with other operators in a single expression, you must be aware of their differ- ences. Consider the following program section. Here, all variables are integers because the increment and decrement operators work only on integer variables.
Make a equal to 6. Increment a*, subtract 1 from it, then assign the result to *b*. *
a = 6;
b = ++a - 1;
What are the values of a and b after these two statements finish? The value of a is easy to determine: it is incremented in the second statement, so it is 7. However, b is either 5 or 6 depending on when the variable a increments. To determine when a increments, consider the following rule:
EXAMPLE
-
If a variable is incremented or decremented with a prefix
operator, the increment or decrement occurs before the variable’s value is used in the remainder of the expression.
-
If a variable is incremented or decremented with a postfix
operator, the increment or decrement occurs after the variable’s value is used in the remainder of the expression.
In the previous code, a contains a prefix increment. Therefore, its value is first incremented to 7, then 1 is subtracted from 7, and the result (6) is assigned to b. If a postfix increment is used, as in
a = 6;
b = a++ - 1;
a is 6, therefore, 5 is assigned to b because a does not increment to 7 until after its value is used in the expression. The precedence table in Appendix D, “C++ Precedence Table,” shows that prefix operators contain much higher precedence than almost every other operator, especially low-precedence postfix increments and decre- ments.
By taking advantage of this tip, you can now rewrite the previous example as follows:
a = 6;
b = a - 1; a++;
There is now no doubt as to when a is incremented: a incre- ments after b is assigned to a- 1 .
Even parentheses cannot override the postfix rule. Consider the following statement.
x = p + ((( amt ++))) ;
Chapter 11 ♦ Additional C++ Operators
There are too many unneeded parentheses here, but even the redundant parentheses are not enough to increment amt before adding its value to p. Postfix increments and decrements always occur after their variables are used in the surrounding expression.
Examples
-
As
you should with all other C++ operators, keep the prece- dence table in mind when you evaluate expressions that increment and decrement. Figures 11.2 and 11.3 show you some examples that illustrate these operators.
-
The precedence table takes on even more meaning when you see a
section of code such as that shown in Figure 11.3.
-
Considering the precedence table—and, more importantly, what you
know about C++’s relational efficiencies—what is the value of the ans in the following section of code?
i nt i =1, j =20, k=- 1, l =0, m=1, n=0, o=2, p=1;
ans = i | | j –– && k++ | | ++l && ++m | | n–– & ! o | | p––;
This, at first, seems to be extremely complicated. Neverthe- less, you can simply glance at it and determine the value of ans , as well as the ending value of the rest of the variables.
Recall that when C++ performs a relation || (or), it ignores the right side of the || if the left value is True (any nonzero value is True). Because any nonzero value is True, C++ does
EXAMPLE
not evaluate the values on the right. Therefore, C++ per- forms this expression as shown:
ans = i | | j –– && k++ | | ++l && ++m | | n–– & ! o | | p––;
|
1 ( TRUE)
Figure 11.2. C++ operators incrementing (above) and decrementing (below) by order of precedence.
Chapter 11 ♦ Additional C++ Operators
Figure 11.3. Another example of C++ operators and their precedence.
The si zeof Operato r
There is another operator in C++ that does not look like an operator at all. It looks like a built-in function, but it is called the
EXAMPLE
Thesi zeof operator returns its argument’s size in bytes.
si zeof operator. In fact, if you think of si zeof as a function call, you might not become confused because it works in a similar way. The format of si zeof follows:
si zeof dat a
or
si zeof ( dat a t ype )
The si zeof operator is unary, because it operates on a single value. This operator produces a result that represents the size, in bytes, of the dat a or dat a t ype specified. Because most data types and variables require different amounts of internal storage on different computers, the si zeof operator enables programs to maintain con- sistency on different types of computers.
The si zeof operator is sometimes called a compile-time operator. At compile time, rather than runtime, the compiler replaces each occurrence of si zeof in your program with an unsigned integer value. Because si zeof is used more in advanced C++ programming, this operator is better utilized later in the book for performing more advanced programming requirements.
If you use an array as the si zeof argument, C++ returns the number of bytes you originally reserved for that array. Data inside the array have nothing to do with its returned si zeof value—even if it’s only a character array containing a short string.
Examples
- Suppose
you want to know the size, in bytes, of floating- point variables for your computer. You can determine this by entering the keyword f l oat in parentheses—after si zeof —as shown in the following program.
Chapter 11 ♦ Additional C++ Operators
/ / Fil ename: C11SI ZE1. CPP
/ / Pr i nt s t he si ze of f l oat i ng- poi nt val ues. #i ncl ude <i ost r eam. h>
mai n( )
{
cout << “ The si ze of f l oat i ng- poi nt var i abl es on \
n” ; cout << “ t hi s comput er i s “ << si zeof ( f l oat
) << “ \ n” ; r et ur n 0;
}
This program might produce different results on different computers. You can use any valid data type as the si zeof argument. On most PCs, this program probably produces this output:
The si ze of f l oat i ng- poi nt var i abl es on t hi s comput er i s: 4
The Comma Operato r
Another C++ operator, sometimes called a sequence point, works a little differently. This is the comma operator (, ), which does not directly operate on data, but produces a left-to-right evaluation of expressions. This operator enables you to put more than one expres- sion on a single line by separating each one with a comma.
You already saw one use of the sequence point comma when you learned how to declare and initialize variables. In the following section of code, the comma separates statements. Because the comma associates from the left, the first variable, i , is declared and initial- ized before the second variable.
mai n( )
{
i nt i =10, j =25;
/ / Remai nder of t he pr ogr am f oll ows.
EXAMPLE
However, the comma is not a sequence point when it is used inside function parentheses. Then it is said to separate arguments, but it is not a sequence point. Consider the pr i ntf () that follows.
pr i ntf (“ %d %d %d” , i , i ++, ++i ) ;
Many results are possible from such a statement. The commas serve only to separate arguments of the pr i ntf () , and do not generate the left-to-right sequence that they otherwise do when they aren’t used in functions. With the statement shown here, you are not ensured of any order! The postfix i ++ might possibly be performed before the prefix ++i , even though the precedence table does not require this. Here, the order of evaluation depends on how your compiler sends these arguments to the pr i ntf () function.
Examples
- You can put more than one expression on a line, using the comma as a
sequence point. The following program does this.
/ / Fil ename: C11COM1. CPP
/ / I ll ust r at es t he sequence poi nt. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt num, sq, cube; num = 5;
/ / Cal cul at e t he squar e and cube of t he number . sq = ( num * num) , cube = ( num * num * num) ;
cout << “ The squar e of “ << num << “ i s “ << sq << “ and t he cube i s “ << cube;
r et ur n 0;
}
Chapter 11 ♦ Additional C++ Operators
This is not necessarily recommended, however, because it doesn’t add anything to the program and actually decreases its readability. In this example, the square and cube are probably better computed on two separate lines.
- The
comma enables some interesting statements. Consider the following section of code.
i = 10
j = ( i = 12, i + 8) ;
When this code finishes executing, j has the value of 20— even though this is not necessarily clear. In the first state- ment, i is assigned 10. In the second statement, the comma causes i to be assigned a value of 12, then j is assigned the value of i + 8 , or 20.
- In
the following section of code, ans is assigned the value of 12, because the assignment before the comma is per- formed first. Despite this right-to-left associativity of the assignment operator, the comma’s sequence point forces the assignment of 12 to x before x is assigned to ans.
ans = ( y = 8, x = 12) ;
When this fragment finishes, y contains 8, x contains 12, and
ans also contains 12.
Bitwise Operator s
The bitwise operators manipulate internal representations of data and not just “values in variables” as the other operators do. These bitwise operators require an understanding of Appendix A’s binary numbering system, as well as a computer’s memory. This section introduces the bitwise operators. The bitwise operators are used for advanced programming techniques and are generally used in much more complicated programs than this book covers.
Some people program in C++ for years and never learn the bitwise operators. Nevertheless, understanding them can help you improve a program’s efficiency and enable you to operate at a more advanced level than many other programming languages allow.
EXAMPLE
Bitwise operators make bit-by-bit comparisons of internal data.
Bitwise Logical Operator s
There are four bitwise logical operators, and they are shown in Table 11.2. These operators work on the binary representations of integer data. This enables systems programmers to manipulate internal bits in memory and in variables. The bitwise operators are not just for systems programmers, however. Application program- mers also can improve their programs’ efficiency in several ways.
Table 11.2. Bitwise logical operators.
Operator Meaning
& Bitwise AND
| Bitwise inclusive OR
^ Bitwise exclusive OR
~ Bitwise 1’s complement
Each of the bitwise operators makes a bit-by-bit comparison of internal data. Bitwise operators apply only to character and integer variables and constants, and not to floating-point data. Because binary numbers consist of 1s and 0s, these 1s and 0s (called bits) are compared to each other to produce the desired result for each bitwise operator.
Before you study the examples, you should understand Table
- It contains truth tables that describe the action of each bitwise
operator on an integer’s—or character’s—internal-bit patterns.
Table 11.3. Truth tables.
Bitwise AND (&)
0 | & 0 |
= |
0 |
---|---|---|---|
0 | & 1 |
= |
0 |
1 | & 0 |
= |
0 |
1 | & 1 |
= |
1 |
continues
Chapter 11 ♦ Additional C++ Operators
Table 11.3. Continued.
Bitwise inclusive OR (| )
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
Bitwise exclusive OR (^ )
0 |
^ |
0 |
= |
0 |
---|---|---|---|---|
0 |
^ |
1 |
= |
1 |
1 |
^ |
0 |
= |
1 |
1 |
^ |
1 |
= |
0 |
Bitwise 1’s complement (~)
~0 = 1
~1 = 0
In bitwise truth tables, you can replace the 1 and 0 with True and False, respectively, if it helps you to understand the result better. For the bitwise AND (&) truth table, both bits being compared by the & operator must be True for the result to be True. In other words, “True AND True results in True.”
For bitwise^ , one sideor the other— but not both—must be 1.
The | bitwise operator is sometimes called the bitwise inclusive OR operator. If one side of the | operator is 1 (True)—or if both sides are 1—the result is 1 (True).
The ^ operator is called bitwise exclusive OR. It means that either side of the ^ operator must be 1 (True) for the result to be 1 (True), but both sides cannot be 1 (True) at the same time.
EXAMPLE
The ~ operator, called bitwise 1’s complement, reverses each bit to its opposite value.
You can test and change individual bits inside variables to check for patterns of data. The following examples help to illustrate each of the four bitwise operators.
Examples
- If
you apply the bitwise & operator to numerals 9 and 14, you receive a result of 8. Figure 11.4 shows you why this is so. When the binary values of 9 (1001) and 14 (1110) are com- pared on a bitwise & basis, the resulting bit pattern is 8 (1000).
Figure 11.4. Performing bitwise & on 9 and 14.
In a C++ program, you can code this bitwise comparison as follows.
Make r esul t equal to the binary value of 9 (1001) ANDed to the binary value of 14 (1110).
r esul t = 9 & 14;
Chapter 11 ♦ Additional C++ Operators
The r esul t variable holds 8, which is the result of the bitwise &. The 9 (binary 1001) or 14 (binary 1110)—or both—also can be stored in variables with the same result.
- When you apply the bitwise | operator to the numbers 9 and 14, you
get 15. When the binary values of 9 (1001) and 14 (1110) are compared on a bitwise | basis, the resulting bit pattern is 15 (1111). r esul t ’s bits are 1 (True) in every posi- tion where a 1 appears in both numbers.
In a C++ program, you can code this bitwise comparison as follows:
r esul t = 9 | 14;
The r esul t variable holds 15, which is the result of the bitwise | . The 9 or 14 (or both) also can be stored in variables.
- The bitwise ^ applied to 9 and 14 produces 7. Bitwise ^ sets the
resulting bits to 1 if one number or the other’s bit is 1, but not if both of the matching bits are 1 at the same time.
In a C++ program, you can code this bitwise comparison as follows:
r esul t = 9 ^ 14;
The r esul t variable holds 7 (binary 0111), which is the result of the bitwise ^ . The 9 or 14 (or both) also can be stored in variables with the same result.
- The bitwise ~ simply negates each bit. It is a unary bitwise
operator because you can apply it to only a single value at any one time. The bitwise ~ applied to 9 results in 6, as shown in Figure 11.5.
Figure 11.5. Performing bitwise ~ on the number 9.
EXAMPLE
In a C++ program, you can code this bitwise operation like this:
r esul t = ~9;
The r esul t variable holds 6, which is the result of the bit- wise ~. The 9 can be stored in a variable with the same result.
- You
can take advantage of the bitwise operators to perform tests on data that you cannot do as efficiently in other ways.
For example, suppose you want to know if the user typed an odd or even number (assuming integers are being input).
You can use the modulus operator (%) to determine whether the remainder—after dividing the input value by 2—is 0
or 1. If the remainder is 0, the number is even. If the remain- der is 1, the number is odd.
The bitwise operators are more efficient than other operators because they directly compare bit patterns without using any mathematical operations.
Because a number is even if its bit pattern ends in a 0 and odd if its bit pattern ends in 1, you also can test for odd or even numbers by applying the bitwise & to the data and to a binary 1. This is more efficient than using the modulus operator. The following program informs users if their input value is odd or even using this technique.
Identify the file and include the input/output header file. This program tests for odd or even input. You need a place to put the user’s number, so declare the i nput variable as an integer.
Ask the user for the number to be tested. Put the user’s answer in
i nput . Use the bitwise operator, &, to test the number. If the bit on the extreme right in i nput is 1, tell the user that the number is odd. If the bit on the extreme right in i nput is 0, tell the user that the number is even.
/ / Fil ename: C11ODEV. CPP
/ / Uses a bi t wi se & t o det ermi ne whet her a
/ / number i s odd or even. #i ncl ude <i ost r eam. h>
mai n( )
{
Chapter 11 ♦ Additional C++ Operators
i nt i nput ; / / Will hol d user ’ s number cout << “ What number do you want me t o t est ? “ ;
ci n >> i nput;
i f ( i nput & 1) / / Tr ue i f r esul t i s 1;
/ / ot her wi se i t i s f al se ( 0)
{ cout << “ The number “ << i nput << “ i s odd\ n” ; } el se
{ cout << “ The number “ << i nput << “ i s even\
n” ; } r et ur n 0;
}
- The only difference between the bit patterns for uppercase and
lowercase characters is bit number 5 (the third bit from the left, as shown in Appendix A, “Memory Addressing, Binary, and Hexadecimal Review”). For lowercase letters, bit 5 is a 1. For uppercase letters, bit 5 is a 0. Figure 11.6 shows how A and B differ from a and b by a single bit.
Only bit 6
is different
Only bit 6
is different
Figure 11.6. Bitwise difference between two uppercase and two lower- case ASCII letters.
To convert a character to uppercase, you have to turn off (change to a 0) bit number 5. You can apply a bitwise & to the input character and 223 (which is 11011111 in binary) to turn off bit 5 and convert any input character to its uppercase equivalent. If the number is already in uppercase, this bitwise & does not change it.
The 223 (binary 11011111) is called a bit mask because it masks (just as masking tape masks areas not to be painted) bit 5 so it becomes 0, if it is not already. The following program does this to ensure that users typed uppercase characters when they were asked for their initials.
EXAMPLE
/ / Fil ename: C11UPCS1. CPP
/ / Conver t s t he i nput char act er s t o upper case
/ / i f t hey ar en’ t al r eady. #i ncl ude <i ost r eam. h>
mai n( )
{
char f i r st , mi ddl e, l ast ; / / Will hol d user ’ s i ni t i al s
i nt bi t mask=223; / / 11011111 i n bi nar y
cout << “ What i s your f i r st i ni t i al ? “ ; ci n >> f i r st;
cout << “ What i s your mi ddl e i ni t i al ? “ ; ci n >> mi ddl e;
cout << “ What i s your l ast i ni t i al ? “ ; ci n >> l ast;
/ / Ensur e t hat i ni t i al s ar e i n upper case.
f i r st = f i r st & bi t mask; / / Tur n of f bi t 5 i f
mi ddl e = mi ddl e & bi t mask; / / i t i s not al r eady
l ast = l ast & bi t mask; / / t ur ned off.
cout << “ Your i ni t i al s ar e “ << f i r st << “ “ << mi ddl e << “ “ << l ast;
r et ur n 0;
}
The following output shows what happens when two of the initials are typed with lowercase letters. The program con- verts them to uppercase before printing them again. Al- though there are other ways to convert to lowercase, none are as efficient as using the & bitwise operator.
What i s your f i r st i ni t i al ? g What i s your mi ddl e i ni t i al ? M What i s your l ast i ni t i al ? p Your i ni t i al s ar e: G M P
Chapter 11 ♦ Additional C++ Operators
Review Question s
The answers to the review questions are in Appendix B.
-
What
set of statements does the conditional operator replace?
-
Why is the conditional operator called a “ternary” operator?
-
Rewrite
the following conditional operator as an i f - el se
statement.
ans = ( a == b) ? c + 2 : c + 3;
- True or false: The following statements produce the same results.
var++;
and
var = var + 1;
-
Why
is using the increment and decrement operators more efficient than using the addition and subtraction operators?
-
What is a sequence point?
-
Can the output of the following code section be determined?
age = 20;
pr i ntf (“ You ar e now %d, and will be %d i n one year” , age, age++) ;
- What is the output of the following program section?
char name[ 20] = “ Mi ke” ;
cout << “ The si ze of name i s “ << si zeof ( name) << “ \ n” ;
- What is the result of each of the following bitwise True-False
expressions?
a. 1 ^ 0 & 1 & 1 | 0
b. 1 & 1 & 1 & 1
c. 1 ^ 1 ^ 1 ^ 1
d. ~( 1 ^ 0)
EXAMPLE
Review Exercise s
-
Write
a program that prints the numerals from 1 to 10. Use ten different cout s and only one variable called r esul t to hold the value before each cout . Use the increment operator to add 1 to r esul t before each cout .
-
Write
a program that asks users for their ages. Using a single pr i ntf () that includes a conditional operator, print on-screen the following if the input age is over 21,
You ar e not a mi nor .
or print this otherwise:
You ar e st ill a mi nor .
This pr i ntf () might be long, but it helps to illustrate how the conditional operator can work in statements where i f - el se logic does not.
-
Use
the conditional operator—and no i f - el se statements—to write the following tax-calculation routine: A family pays no tax if its annual salary is less than $5,000. It pays a 10 percent tax if the salary range begins at $5,000 and ends at $9,999. It pays a 20 percent tax if the salary range begins at $10,000 and ends at $19,999. Otherwise, the family pays a 30 percent tax.
-
Write a program that converts an uppercase letter to a lowercase
letter by applying a bitmask and one of the bit- wise logical operators. If the character is already in lower- case, do not change it.
Summary
Now you have learned almost every operator in the C++ language. As explained in this chapter, conditional, increment, and decrement are three operators that enable C++ to stand apart from many other programming languages. You must always be aware of the precedence table whenever you use these, as you must with all operators.
Chapter 11 ♦ Additional C++ Operators
The si zeof and sequence point operators act unlike most others. The si zeof is a compile operator, and it works in a manner similar to the #def i ne preprocessor directive because they are both replaced by their values at compile time. The sequence point enables you to have multiple statements on the same line—or in a single expression. Reserve the sequence point for declaring variables only because it can be unclear when it’s combined with other expressions.
This chapter concludes the discussion on C++ operators. Now that you can compute just about any result you will ever need, it is time to discover how to gain more control over your programs. The next few chapters introduce control loops that give you repetitive power in C++.
The whi l e Loop
The repetitive capabilities of computers make them good tools for processing large amounts of information. Chapters 12-15 introduce you to C++ constructs, which are the control and looping commands of programming languages. C++ constructs include powerful, but succinct and efficient, looping commands similar to those of other languages you already know.
The whil e loops enable your programs to repeat a series of statements, over and over, as long as a certain condition is always met. Computers do not get “bored” while performing the same tasks repeatedly. This is one reason why they are so important in business data processing.
This chapter teaches you the following:
-
The whil e loop
-
The concept of loops
-
The do- whil e loop
-
Differences between i f and whil e loops
-
The exi t () function
-
The br eak statement
-
Counters and totals
Chapter 12 ♦ The while Loop
After completing this chapter, you should understand the first of several methods C++ provides for repeating program sections. This chapter’s discussion of loops includes one of the most impor- tant uses for looping: creating counter and total variables.
The whi l e Statemen t
The whil e statement is one of several C++ construct statements. Each construct (from construction) is a programming language state- ment—or a series of statements—that controls looping. The whil e , like other such statements, is a looping statement that controls the execution of a series of other statements. Looping statements cause parts of a program to execute repeatedly, as long as a certain condition is being met.
The format of the whil e statement is
The body of a
whil e loop executes repeatedly as long as test expression is True.
whil e ( t est expr essi on )
{ bl ock of one or mor e C++ st at ement s ; }
The parentheses around t est expr essi on are required. As long as t est expr essi on is True (nonzero), the block of one or more C++ statements executes repeatedly until t est expr essi on becomes False (evaluates to zero). Braces are required before and after the body of the whil e loop, unless you want to execute only one statement. Each statement in the body of the whil e loop requires an ending semi- colon.
The placeholder t est expr essi on usually contains relational, and possibly logical, operators. These operators provide the True- False condition checked in t est expr essi on . If t est expr essi on is False when the program reaches the whil e loop for the first time, the body of the whil e loop does not execute at all. Regardless of whether the body of the whil e loop executes no times, one time, or many times, the statements following the whil e loop’s closing brace execute if t est expr essi on becomes False.
Because t est expressi on determines when the loop finishes, the body of the whil e loop must change the variables used in t est expr essi on . Otherwise, t est expr essi on never changes and the whil e
loop repeats forever. This is known as an infinite loop, and you should avoid it.
EXAMPLE
The Concept of Loop s
You use the loop concept in everyday life. Any time you have to repeat the same procedure, you are performing a loop—just as your computer does with the whil e statement. Suppose you are wrapping holiday gifts. The following statements represent the looping steps (in whil e format) that you follow while gift-wrapping.
while (there are still unwrapped gifts)
{ Get the next gift;
Cut the wrapping paper; Wrap the gift;
Put a bow on the gift;
Fill out a name card for the gift;
Put the wrapped gift with the others; }
Whether you have 3, 15, or 100 gifts to wrap, you use this procedure (loop) repeatedly until every gift is wrapped. For an example that is more easily computerized, suppose you want to total all the checks you wrote in the previous month. You could perform the following loop.
while (there are still checks from the last month to be totaled)
{ Add the amount of the next check to the total; }
The body of this pseudocode whil e loop has only one statement, but that single statement must be performed until you have added each one of the previous month’s checks. When this loop ends (when no more checks from the previous month remain to be totaled), you have the result.
The body of a whil e loop can contain one or more C++ state- ments, including additional whil e loops. Your programs will be
Chapter 12 ♦ The while Loop
more readable if you indent the body of a whil e loop a few spaces to the right. The following examples illustrate this.
Examples
- Some
programs presented earlier in the book require user input with ci n . If users do not enter appropriate values, these programs display an error message and ask the user to enter another value, which is an acceptable procedure.
Now that you understand the whil e loop construct, however, you should put the error message inside a loop. In this way, users see the message continually until they type proper input values, rather than once.
The following program is short, but it demonstrates a whil e loop that ensures valid keyboard input. It asks users whether they want to continue. You can incorporate this program into a larger one that requires user permission to continue. Put a prompt, such as the one presented here, at the bottom of a text screen. The text remains on-screen until the user tells the program to continue executing.
Identify the file and include the necessary header file. In this program, you want to ensure the user enters Y or N.
You have to store the user’s answer, so declare the ans variable as a character. Ask the users whether they want to continue, and get the response. If the user doesn’t type Y or N, ask the user for another response.
/ / Fil ename: C12WHI L1. CPP
/ / I nput r out i ne t o ensur e user t ypes a
/ / corr ect r esponse. Thi s r out i ne can be par t
/ / of a l ar ger pr ogr am. #i ncl ude <i ost r eam. h> mai n( )
{
char ans;
cout << “ Do you want t o cont i nue ( Y/ N) ? “ ;
ci n >> ans; / / Get user ’ s answer
EXAMPLE
whil e (( ans ! = ‘ Y’ ) && ( ans ! = ‘ N’ ))
{ cout << “ \ nYou must t ype a Y or an N\ n” ; / / War n
/ / and ask cout << “ Do you want t o cont i nue ( Y/ N) ?” ; / / agai n.
ci n >> ans;
} / / Body of whil e l oop ends her e.
r et ur n 0;
}
Notice that the two ci n functions do the same thing. You must use an initial ci n , outside the whil e loop, to provide an answer for the whil e loop to check. If users type something other than Y or N, the program prints an error message, asks for another answer, then checks the new answer. This vali- dation method is preferred over one where the reader only has one additional chance to succeed.
The whil e loop tests the test expression at the top of the loop. This is why the loop might never execute. If the test is initially False, the loop does not execute even once. The output from this program is shown as follows. The program repeats indefinitely, until the relational test is True (as soon as the user types either Y or N).
Do you want t o cont i nue ( Y/ N) ? k
You must t ype a Y or an N
Do you want t o cont i nue ( Y/ N) ? c
You must t ype a Y or an N
Do you want t o cont i nue ( Y/ N) ? s
You must t ype a Y or an N
Do you want t o cont i nue ( Y/ N) ? 5
You must t ype a Y or an N
Do you want t o cont i nue ( Y/ N) ? Y
- The following program is an example of an invalid whil e
loop. See if you can find the problem.
Chapter 12 ♦ The while Loop
/ / Fil ename: C12WHBAD. CPP
/ / Bad use of a whil e l oop. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt a=10, b=20; whil e ( a > 5)
{ cout << “ a i s “ << a << “ , and b i s “ << b << “ \ n” ; b = 20 + a; }
r et ur n 0;
}
This whil e loop is an example of an infinite loop. It is vital that at least one statement inside the whil e changes a variable in the test expression (in this example, the variable a); other- wise, the condition is always True. Because the variable a does not change inside the whil e loop, this program will never end.
- The following program asks users for a first name, then uses a whil
e loop to count the number of characters in the name. This is a string length program; it counts characters until it reaches the null zero. Remember that the length of a string equals the number of characters in the string, not including the null zero.
/ / Fil ename: C12WHI L2. CPP
/ / Count s t he number of l ett er s i n t he user ’ s f i r st name. #i ncl ude <i ost r eam. h>
mai n( )
{
char name[ 15] ; / / Will hol d user ’ s f i r st name
EXAMPLE
i nt count =0; / / Will hol d t ot al char act er s i n name
/ / Get t he user ’ s f i r st name
cout << “ What i s your f i r st name? “ ; ci n >> name;
whil e ( name[ count ] > 0) / / Loop unt il null zer o r eached.
{ count ++; } / / Add 1 t o t he count.
cout << “ Your name has “ << count << “ char act er s” ; r et ur n 0;
}
The loop continues as long as the value of the next character in the name array is greater than zero. Because the last charac- ter in the array is a null zero, the test is False on the name’s last character and the statement following the body of the loop continues.
- The previous string-length program’s whil e loop is not as efficient
as it could be. Because a whil e loop fails when its test expression is zero, there is no need for the greater-than test. By changing the test expression as the following program shows, you can improve the efficiency of the string length count.
/ / Fil ename: C12WHI L3. CPP
/ / Count s t he number of l ett er s i n t he user ’ s f i r st name. #i ncl ude <i ost r eam. h>
mai n( )
{
char name[ 15] ; / / Will hol d user ’ s f i r st name i nt count =0; / / Will hol d t ot al char act er s i n name
/ / Get t he user ’ s f i r st name
Chapter 12 ♦ The while Loop
cout << “ What i s your f i r st name? “ ; ci n >> name;
whil e ( name[ count] ) / / Loop unt il null zer o i s r eached.
{ count ++; } / / Add 1 t o t he count.
cout << “ Your name has “ << count << “ char act er s” ; r et ur n 0;
}
The body of the do- whil e loop executes at least once.
The do- whi l e Loop
The do- whil e statement controls the do- whil e loop, which is similar to the whil e loop except the relational test occurs at the end (rather than beginning) of the loop. This ensures the body of the loop executes at least once. The do- whil e tests for a positive relational test; as long as the test is True, the body of the loop continues to execute.
The format of the do- whil e is
do
{ bl ock of one or mor e C++ st at ement s ; }
whil e ( t est expr essi on )
t est expr essi on must be enclosed in parentheses, just as it must in a whil e statement.
Examples
- The
following program is just like the first one you saw with the whil e loop (C12WHIL1.CPP), except the do- whil e is used. Notice the placement of t est expr essi on . Because this expres- sion concludes the loop, user input does not have to appear before the loop and again in the body of the loop.
/ / Fil ename: C12WHI L4. CPP
/ / I nput r out i ne t o ensur e user t ypes a
/ / corr ect r esponse. Thi s r out i ne mi ght be par t
/ / of a l ar ger pr ogr am.
EXAMPLE
#i ncl ude <i ost r eam. h> mai n( )
{
char ans;
do
{ cout << “ \ nYou must t ype a Y or an N\ n” ; / / War n
/ / and ask cout << “ Do you want t o cont i nue ( Y/ N) ?” ; / / agai n.
ci n >> ans; } / / Body of whil e l oop
/ / ends her e. whil e (( ans ! = ‘ Y’ ) && ( ans ! = ‘ N’ )) ;
r et ur n 0;
}
- Suppose you are entering sales amounts into the computer to
calculate extended totals. You want the computer to print the quantity sold, part number, and extended total (quantity times the price per unit), as the following program does.
/ / Fil ename: C12I NV1. CPP
/ / Get s i nvent or y i nf ormat i on f r om user and pr i nt s
/ / an i nvent or y det ail li st i ng wi t h ext ended t ot al s. #i ncl ude <i ost r eam. h>
#i ncl ude <i omani p. h> mai n( )
{
i nt par t _no, quant i t y; f l oat cost , ext _cost;
cout << “ *** I nvent or y Comput at i on *** \ n\ n” ; / / Ti t l e
/ / Get i nvent or y i nf ormat i on. do
{ cout << “ What i s t he next par t number (- 999 t o end) ? “ ; ci n >> par t _no;
i f ( par t _no ! = - 999)
{ cout << “ How many wer e bought ? “ ; ci n >> quant i t y;
cout << “ What i s t he uni t pr i ce of t hi s i t em? “ ;
Chapter 12 ♦ The while Loop
ci n >> cost;
ext _cost = cost * quant i t y;
cout << “ \ n” << quant i t y << “ of # “ << par t _no << “ will cost “ << set pr eci si on( 2) <<
ext _cost;
cout << “ \ n\ n\ n” ; / / Pr i nt t wo bl ank li nes.
}
} whil e ( par t _no ! = - 999) ; / / Loop onl y i f par t
/ / number i s not - 999.
cout << “ End of i nvent or y comput at i on\ n” ; r et ur n 0;
}
Here is the output from this program:
*** I nvent or y Comput at i on ***
What i s t he next par t number (- 999 t o end) ? 213 How many wer e bought ? 12
What i s t he uni t pr i ce of t hi s i t em? 5. 66
12 of # 213 will cost 67. 92
What i s t he next par t number (- 999 t o end) ? 92 How many wer e bought ? 53
What i s t he uni t pr i ce of t hi s i t em? . 23
53 of # 92 will cost 12. 19
What i s t he next par t number (- 999 t o end) ? - 999 End of i nvent or y comput at i on
The do- whil e loop controls the entry of the customer sales information. Notice the “trigger” that ends the loop. If the user enters –999 for the part number, the do- whil e loop quits because no part numbered –999 exists in the inventory.
However, this program can be improved in several ways. The invoice can be printed to the printer rather than the
EXAMPLE
screen. You learn how to direct your output to a printer in Chapter 21, “Device and Character Input/ Output.” Also, the inventory total (the total amount of the entire order) can be computed. You learn how to total such data in the “Counters and Totals” section later in this chapter.
The i f Loop Versus the whi l e
Loop
Some beginning programmers confuse the i f statement with loop constructs. The whil e and do- whil e loops repeat a section of code multiple times, depending on the condition being tested. The i f statement may or may not execute a section of code; if it does, it executes that section only once.
Use an i f statement when you want to conditionally execute a section of code once, and use a whil e or do- whil e loop if you want to execute a section more than once. Figure 12.1 shows differences between the i f statement and the two whil e loops.
Figure 12.1. Differences between the i f statement and the two whil e
loops.
Chapter 12 ♦ The while Loop
Theexi t ()
The exi t ( ) Function and br eak
Statement
C++ provides the exi t () function as a way to leave a program early (before its natural finish). The format of exi t () is
exi t ( st at us ) ;
where st at us is an optional integer variable or literal. If you are familiar with your operating system’s return codes, st at us enables you to test the results of C++ programs. In DOS, st at us is sent to the operating system’s err or l evel environment variable, where it can be tested by batch files.
Many times, something happens in a program that requires the
function provides an early exit from your program.
Thebr eak statement ends the current loop.
program’s termination. It might be a major problem, such as a disk drive error. Perhaps users indicate that they want to quit the program—you can tell this by giving your users a special value to type with ci n or scanf () . You can isolate the exi t () function on a line by itself, or anywhere else that a C++ statement or function can appear. Typically, exi t () is placed in the body of an i f statement to end the program early, depending on the result of some relational test.
Always include the stdlib.h header file when you use exi t () . This file describes the operation of exi t () to your program. When- ever you use a function in a program, you should know its corre- sponding #i ncl ude header file, which is usually listed in the compiler’s reference manual.
Instead of exiting an entire program, however, you can use the
br eak statement to exit the current loop. The format of br eak is
br eak;
The br eak statement can go anywhere in a C++ program that any other statement can go, but it typically appears in the body of a whil e or do- whil e loop, used to leave the loop early. The following examples illustrate the exi t () function and the br eak statement.
EXAMPLE
Examples
- Here
is a simple program that shows you how the exi t () function works. This program looks as though it prints several messages on-screen, but it doesn’t. Because exi t () appears early in the code, this program quits immediately after mai n() ’s opening brace.
/ / C12EXI T1. CPP
/ / Qui t s ear l y due t o exi t () f unct i on. #i ncl ude <i ost r eam. h>
#i ncl ude <st dli b. h> / / Requi r ed f or exi t () . mai n( )
{
exi t ( 0) ; / / For ces pr ogr am t o end her e.
cout << “ C++ pr ogr ammi ng i s f un.\ n” ;
cout << “ I li ke l ear ni ng C++ by exampl e!\ n” ;
cout << “ C++ i s a power f ul l anguage t hat i s “ << “ not di ff i cul t t o l ear n. ” ;
r et ur n 0;
}
- The br eak statement is not intended to be as strong a pro- gram
exit as the exi t () function. Whereas exi t () ends the entire program, br eak quits only the loop that is currently active. In other words, br eak is usually placed inside a whil e or do- whil e loop to “simulate” a finished loop. The statement following the loop executes after a br eak occurs, but the program does not quit as it does with exi t () .
The following program appears to print C++ i s f un! until the user enters N to stop it. The message prints only once, how- ever, because the br eak statement forces an early exit from the loop.
/ / Fil ename: C12BRK. CPP
/ / Demonst r at es t he br eak st at ement. #i ncl ude <i ost r eam. h>
mai n( )
Chapter 12 ♦ The while Loop
{
char user _ans;
do
{ cout << “ C++ i s f un! \ n” ;
br eak; / / Causes ear l y exi t.
cout << “ Do you want t o see t he message agai n ( N/ Y) ? “ ; ci n >> user _ans;
} whil e ( user _ans == ‘ Y’ ) ;
cout << “ That ’ s all f or now\ n” ; r et ur n 0;
}
This program always produces the following output:
C++ i s f un!
That ’ s all f or now
You can tell from this program’s output that the br eak state- ment does not allow the do- whil e loop to reach its natural conclusion, but causes it to finish early. The final cout prints because only the current loop—and not the entire pro- gram—exits with the br eak statement.
- Unlike
the previous program, br eak usually appears after an i f statement. This makes it a conditional br eak , which occurs only if the relational test of the i f statement is True.
A good illustration of this is the inventory program you saw earlier (C12INV1.CPP). Even though the users enter –999 when they want to quit the program, an additional i f test is needed inside the do- whil e . The –999 ends the do- whil e loop, but the body of the do- whil e still needs an i f test, so the remaining quantity and cost prompts are not given.
If you insert a br eak after testing for the end of the user’s input, as shown in the following program, the do- whil e will not need the i f test. The br eak quits the do- whil e as soon as the user signals the end of the inventory by entering –999 as the part number.
EXAMPLE
/ / Fil ename: C12I NV2. CPP
/ / Get s i nvent or y i nf ormat i on f r om user and pr i nt s
/ / an i nvent or y det ail li st i ng wi t h ext ended t ot al s. #i ncl ude <i ost r eam. h>
#i ncl ude <i omani p. h> mai n( )
{
i nt par t _no, quant i t y; f l oat cost , ext _cost;
cout << “ *** I nvent or y Comput at i on *** \ n\ n” ; / / Ti t l e
/ / Get i nvent or y i nf ormat i on do
{ cout << “ What i s t he next par t number (- 999 t o end) ? “ ; ci n >> par t _no;
i f ( par t _no == - 999)
{ br eak; } / / Exi t t he l oop i f
/ / no mor e par t number s. cout << “ How many wer e bought ? “ ;
ci n >> quant i t y;
cout << “ What i s t he uni t pr i ce of t hi s i t em? “ ; ci n >> cost;
cout << “ \ n” << quant i t y << “ of # “ << par t _no <<
“ will cost “ << set pr eci si on( 2) << cost * quant i t y; cout << “ \ n\ n\ n” ; / / Pr i nt t wo bl ank li nes.
} whil e ( par t _no ! = - 999) ; / / Loop onl y i f par t
/ / number i s not - 999.
cout << “ End of i nvent or y comput at i on\ n” ; r et ur n 0;
}
- You can use the following program to control the two other programs.
This program illustrates how C++ can pass in- formation to DOS with exi t () . This is your first example of a menu program. Similar to a restaurant menu, a C++ menu program lists possible user choices. The users decide what they want the computer to do from the menu’s available options. The mailing list application in Appendix F, “The Mailing List Application,” uses a menu for its user options.
Chapter 12 ♦ The while Loop
This program returns either a 1 or a 2 to its operating system, depending on the user’s selection. It is then up to the oper- ating system to test the exi t value and run the proper program.
/ / Fil ename: C12EXI T2. CPP
/ / Asks user f or hi s or her sel ect i on and r et ur ns
/ / t hat sel ect i on t o t he oper at i ng syst em wi t h exi t () . #i ncl ude <i ost r eam. h>
#i ncl ude <st dli b. h> mai n( )
{
i nt ans;
do
{ cout << “ Do you want t o:\ n\ n” ;
cout << “ \t 1. Run t he wor d pr ocessor \ n\ n” ; cout << “ \t 2. Run t he dat abase pr ogr am \ n\ n” ; cout << “ What i s your sel ect i on? “ ;
ci n >> ans;
} whil e (( ans ! = 1) && ( ans ! = 2)) ; / / Ensur es user
/ / ent er s 1 or 2.
exi t ( ans) ; / / Ret ur n val ue t o oper at i ng syst em.
r et ur n 0; / / Ret ur n does not ever execut e due t o exi t () .
}
Counters and T otal s
Counting is important for many applications. You might have to know how many customers you have or how many people scored over a certain average in your class. You might want to count how many checks you wrote in the previous month with your computer- ized checkbook system.
Before you develop C++ routines to count occurrences, think of how you count in your own mind. If you were adding a total number of something, such as the stamps in your stamp collection or the
EXAMPLE
number of wedding invitations you sent out, you would probably do the following:
Start at 0, and add 1 for each item being counted. When you are finished, you should have the total number (or the total count).
This is all you do when you count with C++: Assign 0 to a variable and add 1 to it every time you process another data value. The increment operator (++) is especially useful for counting.
Examples
- To
illustrate using a counter, the following program prints “ Comput er s ar e f un! ” on-screen 10 times. You can write a program that has 10 cout statements, but that would not be efficient. It would also be too cumbersome to have 5000 cout statements, if you wanted to print that same message 5000 times.
By adding a whil e loop and a counter that stops after a certain total is reached, you can control this printing, as the following program shows.
/ / Fil ename: C12CNT1. CPP
/ / Pr ogr am t o pr i nt a message 10 t i mes. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt ct r = 0; / / Hol ds t he number of t i mes pr i nt ed.
do
{ cout << “ Comput er s ar e f un!\ n” ;
ct r ++; / / Add one t o t he count,
/ / aft er each cout.
} whil e ( ct r < 10) ; / / Pr i nt agai n i f f ewer
/ / t han 10 t i mes.
r et ur n 0;
}
Chapter 12 ♦ The while Loop
The output from this program is shown as follows. Notice that the message prints exactly 10 times.
Comput er s ar e f un! Comput er s ar e f un! Comput er s ar e f un! Comput er s ar e f un! Comput er s ar e f un! Comput er s ar e f un! Comput er s ar e f un! Comput er s ar e f un! Comput er s ar e f un! Comput er s ar e f un!
The heart of the counting process in this program is the statement that follows.
ct r++;
You learned earlier that the increment operator adds 1 to a variable. In this program, the counter variable is incremented each time the do- whil e loops. Because the only operation performed on this line is the increment of ct r , the prefix increment (++ct r ) produces the same results.
- The
previous program not only added to the counter vari- able, but also performed the loop a specific number of times. This is a common method of conditionally executing parts of a program for a fixed number of times.
The following program is a password program. A password is stored in an integer variable. The user must correctly enter the matching password in three attempts. If the user does not type the correct password in that time, the program ends. This is a common method that dial-up computers use. They enable a caller to try the password a fixed number of times, then hang up the phone if that limit is exceeded. This helps deter people from trying hundreds of different pass- words at any one sitting.
If users guess the correct password in three tries, they see the secret message.
EXAMPLE
/ / Fil ename: C12PASS1. CPP
/ / Pr ogr am t o pr ompt f or a passwor d and
/ / check i t agai nst an i nt er nal one. #i ncl ude <i ost r eam. h>
#i ncl ude <st dli b. h> mai n( )
{
i nt st or ed_pass = 11862;
i nt num_t r i es = 0; / / Count er f or passwor d att empt s. i nt user _pass;
whil e ( num_t r i es < 3) / / Loop onl y t hr ee
/ / t i mes.
{ cout << “ What i s t he passwor d ( You get 3 t r i es... ) ? “ ; ci n >> user _pass;
num_t r i es++; / / Add 1 t o count er . i f ( user _pass == st or ed_pass)
{ cout << “ You ent er ed t he corr ect passwor d.\ n” ; cout << “ The cash saf e i s behi nd t he pi ct ur e “ <<
“ of t he shi p.\ n” ;
exi t ( 0) ;
}
el se
{ cout << “ You ent er ed t he wr ong passwor d.\ n” ; i f ( num_t r i es == 3)
{ cout << “ Sorr y, you get no mor e chances” ; } el se
{ cout << “ You get “ << ( 3- num_t r i es) << “ mor e t r i es...\ n” ; }
}
} / / End of whil e l oop.
exi t ( 0) ;
r et ur n 0;
}
This program gives users three chances in case they type some mistakes. After three unsuccessful attempts, the pro- gram quits without displaying the secret message.
Chapter 12 ♦ The while Loop
- The
following program is a letter-guessing game. It includes a message telling users how many tries they made before guessing the correct letter. A counter counts the number of these tries.
/ / Fil ename: C12GUES. CPP
/ / Lett er- guessi ng game. #i ncl ude <i ost r eam. h> mai n( )
{
i nt t r i es = 0;
char comp_ans, user _guess;
/ / Save t he comput er ’ s l ett er
comp_ans = ‘ T’ ; / / Change t o a di ff er ent
/ / l ett er i f desi r ed.
cout << “ I am t hi nki ng of a l ett er ... ” ; do
{ cout << “ What i s your guess? “ ; ci n >> user _guess;
t r i es++; / / Add 1 t o t he guess- count i ng var i abl e. i f ( user _guess > comp_ans)
{ cout << “ Your guess was t oo hi gh\ n” ; cout << “ \
nTr y agai n... ” ;
}
i f ( user _guess < comp_ans)
{ cout << “ Your guess was t oo l ow\ n” ; cout << “ \
nTr y agai n... ” ;
}
} whil e ( user _guess ! = comp_ans) ; / / Qui t when a
/ / mat ch i s f ound.
/ / They got i t r i ght , l et t hem know.
cout << “ *** Congr at ul at i ons! You got i t r i ght ! \
n” ; cout << “ I t t ook you onl y “ << t r i es <<
“ t r i es t o guess. ” ;
r et ur n 0;
}
EXAMPLE
Here is the output of this program:
I am t hi nki ng of a l ett er ... What i s your guess? E Your guess was t oo l ow
Tr y agai n... What i s your guess? X Your guess was t oo hi gh
Tr y agai n... What i s your guess? H Your guess was t oo l ow
Tr y agai n... What i s your guess? O Your guess was t oo l ow
Tr y agai n... What i s your guess? U Your guess was t oo hi gh
Tr y agai n... What i s your guess? Y Your guess was t oo hi gh
Tr y agai n... What i s your guess? T
*** Congr at ul at i ons! You got i t r i ght! I t t ook you onl y 7 t r i es t o guess.
Producing Total s
Writing a routine to add values is as easy as counting. Instead of adding 1 to the counter variable, you add a value to the total variable. For instance, if you want to find the total dollar amount of checks you wrote during December, you can start at nothing (0) and add the amount of every check written in December. Instead of building a count, you are building a total.
When you want C++ to add values, just initialize a t ot al variable to zero, then add each value to the total until you have included all the values.
Chapter 12 ♦ The while Loop
Examples
- Suppose
you want to write a program that adds your grades for a class you are taking. The teacher has informed you that you earn an A if you can accumulate over 450 points.
The following program keeps asking you for values until you type –1. The –1 is a signal that you are finished entering grades and now want to see the total. This program also prints a congratulatory message if you have enough points for an A.
/ / Fil ename: C12GRAD1. CPP
/ / Adds gr ades and det ermi nes whet her you ear ned an A. #i ncl ude <i ost r eam. h>
i ncl ude <i omani p. h> mai n( )
{
f l oat t ot al _gr ade=0. 0;
f l oat gr ade; / / Hol ds i ndi vi dual gr ades.
do
{ cout << “ What i s your gr ade? (- 1 t o end) “ ; ci n >> gr ade;
i f ( gr ade >= 0. 0)
{ t ot al _gr ade += gr ade; } / / Add t o t ot al .
} whil e ( gr ade >= 0. 0) ; / / Qui t when - 1 ent er ed.
/ / Cont r ol begi ns her e i f no mor e gr ades.
cout << “ \ n\ nYou made a t ot al of “ << set pr eci si on( 1) << t ot al _gr ade << “ poi nt s\ n” ;
i f ( t ot al _gr ade >= 450. 00)
{ cout << “ ** You made an A!! ” ; }
r et ur n 0;
}
Notice that the - 1 response is not added to the total number of points. This program checks for the - 1 before adding to
t ot al _gr ade . Here is the output from this program:
EXAMPLE
What i s your gr ade? (- 1 t o end) 87. 6 What i s your gr ade? (- 1 t o end) 92. 4 What i s your gr ade? (- 1 t o end) 78. 7 What i s your gr ade? (- 1 t o end) - 1
You made a t ot al of 258. 7 poi nt s
- The following program is an extension of the grade- calculating
program. It not only totals the points, but also computes their average.
To calculate the average grade, the program must first determine how many grades were entered. This is a subtle problem because the number of grades to be entered is unknown in advance. Therefore, every time the user enters a valid grade (not –1), the program must add 1 to a counter as well as add that grade to the t ot al variable. This is a combi- nation counting and totaling routine, which is common in many programs.
/ / Fil ename: C12GRAD2. CPP
/ / Adds up gr ades, comput es aver age,
/ / and det ermi nes whet her you ear ned an A. #i ncl ude <i ost r eam. h>
#i ncl ude <i omani p. h> mai n( )
{
f l oat t ot al _gr ade=0. 0; f l oat gr ade_avg = 0. 0; f l oat gr ade;
i nt gr ade_ct r = 0;
do
{ cout << “ What i s your gr ade? (- 1 t o end) “ ; ci n >> gr ade;
i f ( gr ade >= 0. 0)
{ t ot al _gr ade += gr ade; / / Add t o t ot al .
gr ade_ct r ++; } / / Add t o count.
} whil e ( gr ade >= 0. 0) ; / / Qui t when - 1 ent er ed.
Chapter 12 ♦ The while Loop
/ / Cont r ol begi ns her e i f no mor e gr ades.
gr ade_avg = ( t ot al _gr ade / gr ade_ct r) ; / / Comput e
/ / aver age. cout << “ \ nYou made a t ot al of “ << set pr eci si on( 1) <<
t ot al _gr ade << “ poi nt s.\ n” ;
cout << “ Your aver age was “ << gr ade_avg << “ \
n” ; i f ( t ot al _gr ade >= 450. 0)
{ cout << “ ** You made an A!! ” ; } r et ur n 0;
}
Below is the output of this program. Congratulations! You are on your way to becoming a master C++ programmer.
What i s your gr ade? (- 1 t o end) 67. 8 What i s your gr ade? (- 1 t o end) 98. 7 What i s your gr ade? (- 1 t o end) 67. 8 What i s your gr ade? (- 1 t o end) 92. 4 What i s your gr ade? (- 1 t o end) - 1
You made a t ot al of 326. 68 poi nt s. Your aver age was 81. 7
Review Question s
The answers to the review questions are in Appendix B.
- What
is the difference between the whil e loop and the
do- whil e loop?
-
What is the difference between a total variable and a counter
variable?
-
Which C++ operator is most useful for counting?
-
True or false: Braces are not required around the body of
whil e and do- whil e loops.
EXAMPLE
- What
is wrong with the following code?
whil e ( sal es > 50)
cout << “ Your sal es ar e ver y good t hi s mont h.\ n” ; cout << “ You will get a bonus f or your hi gh sal es\ n” ;
-
What file must you include as a header file if you use exi t () ?
-
How
many times does this pr i ntf () print?
i nt a=0; do
{ pr i ntf (“ Car ef ul \ n”) ; a++; }
whil e ( a > 5) ;
-
How can you inform DOS of the program exit status?
-
What
is printed to the screen in the following section of code?
a = 1;
whil e ( a < 4)
{ cout << “ Thi s i s t he out er l oop\ n” ; a++;
whil e ( a <= 25)
{ br eak;
cout << “ Thi s pr i nt s 25 t i mes\ n” ; }
}
Review Exercise s
-
Write
a program with a do- whil e loop that prints the numer- als from 10 to 20 (inclusive), with a blank line between each number.
-
Write
a weather-calculator program that asks for a list of the previous 10 days’ temperatures, computes the average, and prints the results. You have to compute the total as the input occurs, then divide that total by 10 to find the average. Use a whil e loop for the 10 repetitions.
Chapter 12 ♦ The while Loop
-
Rewrite the program in Exercise 2 using a do- whil e loop.
-
Write
a program, similar to the weather calculator in Exer- cise 2, but generalize it so it computes the average of any number of days’ temperatures. (Hint: You have to count the number of temperatures to compute the final average.)
-
Write a program that produces your own ASCII table on- screen. Don’t
print the first 31 characters because they are nonprintable. Print the codes numbered 32 through 255 by storing their numbers in integer variables and printing their ASCII values using pr i ntf () and the “ %c” format code.
Summary
This chapter showed you two ways to produce a C++ loop: the whil e loop and the do- whil e loop. These two variations of whil e loops differ in where they test their t est condi t i on statements. The whil e tests at the beginning of its loop, and the do- whil e tests at the end. Therefore, the body of a do- whil e loop always executes at least once. You also learned that the exi t () function and br eak statement add flexibility to the whil e loops. The exi t () function terminates the program, and the br eak statement terminates only the current loop.
This chapter explained two of the most important applications of loops: counters and totals. Your computer can be a wonderful tool for adding and counting, due to the repetitive capabilities offered with whil e loops.
The next chapter extends your knowledge of loops by showing you how to create a determinate loop, called the f or loop. This feature is useful when you want a section of code to loop for a specified number of times.
The f or Loop
The f or loop enables you to repeat sections of your program for a specific number of times. Unlike the whil e and do- whil e loops, the f or loop is a determinate loop. This means when you write your program you can usually determine how many times the loop iterates. The
whil e and do- whil e loops repeat only until a condition is met. The f or
loop does this and more: It continues looping until a count (or countdown) is reached.
After the final f or loop count is reached, execution continues with the next statement, in sequence. This chapter focuses on the f or loop construct by introducing
-
The f or statement
-
The concept of f or loops
-
Nested f or loops
The f or loop is a helpful way of looping through a section of code when you want to count, or sum , specified amounts, but it does not replace the whil e and do- whil e loops.
Chapter 13 ♦ The for Loop
The f or Statemen t
The f or statement encloses one or more C++ statements that form the body of the loop. These statements in the loop continuously repeat for a specified number of times. You, as the programmer, control the number of loop repetitions.
The format of the f or loop is
f or ( st ar t expr essi on ; t est expr essi on ; count expr essi on )
{ Bl ock of one or mor e C++ st at ement s ; }
C++ evaluates the st ar t expr essi on before the loop begins. Typically, the st ar t expr essi on is an assignment statement (such as ct r =1; ), but it can be any legal expression you specify. C++ evaluates st ar t expr essi on only once, at the top of the loop.
Thef or loop iterates for a specified number of times.
Every time the body of the loop repeats, the count expr essi on executes, usually incrementing or decrementing a variable. The t est expr essi on evaluates to True (nonzero) or False (zero), then deter- mines whether the body of the loop repeats again.
EXAMPLE
To illustrate the concept of a for loop further, suppose you are installing 10 new shutters on your house. You must do the following steps for each shutter:
-
Move the ladder to the location of the shutter.
-
Take a shutter, hammer, and nails up the ladder.
-
Hammer the shutter to the side of the house.
-
Climb down the ladder.
You must perform each of these four steps exactly 10 times, because you have 10 shutters. After 10 times, you don’t install another shutter because the job is finished. You are looping through a procedure that has several steps (the block of the loop). These steps are the body of the loop. It is not an endless loop because there are a fixed number of shutters; you run out of shutters only after you install all 10.
For a less physical example that might be more easily comput- erized, suppose you have to fill out three tax returns for each of your teenage children. (If you have three teenage children, you probably need more than a computer to help you get through the day!) For each child, you must perform the following steps:
-
Add the total income.
-
Add the total deductions.
-
Fill out a tax return.
-
Put it in an envelope.
-
Mail it.
You then must repeat this entire procedure two more times. Notice how the sentence before these steps began: For each child. This signals an idea similar to the f or loop construct.
Chapter 13 ♦ The for Loop
Examples
- To
give you a glimpse of the f or loop’s capabilities, this example shows you two programs: one that uses a f or loop and one that does not. The first one is a counting program. Before studying its contents, look at the output. The results illustrate the f or loop concept very well.
Identify the program and include the necessary header file. You need a counter, so make ct r an integer variable.
-
Add one to the counter.
-
*If the counter is less than or equal to 10, print its value and
repeat step one.*
The program with a f or loop follows:
/ / Fil ename: C13FOR1. CPP
/ / I nt r oduces t he f or l oop. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt ct r ;
f or ( ct r =1; ct r <=10; ct r ++) / / St ar t ct r at one.
/ / I ncr ement t hr ough l oop.
{ cout << ct r << “ \ n” ; } / / Body of f or l oop.
r et ur n 0;
}
C++ |
By |
|
---|---|---|
EXAMPLE |
||
This program’s output is |
||
1 |
||
2 |
||
3 |
||
4 |
||
5 |
||
6 |
||
7 |
||
8 |
||
9 |
||
10 |
||
Here is the same program using |
a do- whil e |
loop: |
Identify the program and include the necessary header file. You need a counter, so make ct r an integer variable.
-
Add one to the counter.
-
Print the value of the counter.
-
*If
the counter is less than or equal to 10, repeat step one.*
/ / Fil ename: C13WHI 1. CPP
/ / Si mul at i ng a f or l oop wi t h a do- whil e l oop. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt ct r =1; do
{ cout << ct r << “ \ n” ; / / Body of do- whil e l oop. ct r ++; }
whil e ( ct r <= 10) ;
r et ur n 0;
}
Notice that the f or loop is a cleaner way of controlling the looping process. The f or loop does several things that re- quire extra statements in a whil e loop. With f or loops, you do not have to write extra code to initialize variables and incre- ment or decrement them. You can see at a glance (in the
Chapter 13 ♦ The for Loop
expressions in the f or statement) exactly how the loop executes, unlike the do- whil e , which forces you to look at the bottom of the loop to see how the loop stops.
- Both of the following sample programs add the numbers from 100
to 200. The first one uses a f or loop; the second one does not. The first example starts with a st ar t expr essi on bigger than 1, thus starting the loop with a bigger count
expr essi on as well.
This program has a f or loop:
/ / Fil ename: C13FOR2. CPP
/ / Demonst r at es t ot ali ng usi ng a f or l oop. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt t ot al , ct r ;
t ot al = 0; / / Hol ds a t ot al of 100 t o 200. f or ( ct r =100; ct r <=200; ct r ++) / / ct r i s 100, 101,
/ / 102,... 200
{ t ot al += ct r ; } / / Add val ue of ct r t o each i t er at i on.
cout << “ The t ot al i s “ << t ot al << “ \ n” ; r et ur n 0;
}
The same program without a f or loop follows:
/ / Fil ename: C13WHI 2. CPP
/ / A t ot ali ng pr ogr am usi ng a do- whil e l oop. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt t ot al =0; / / I ni t i ali ze t ot al
i nt num=100; / / St ar t i ng val ue
do
{ t ot al += num; / / Add t o t ot al
num++; / / I ncr ement count er
EXAMPLE
} whil e ( num <= 200) ;
cout << “ The t ot al i s “ << t ot al << “ \ n” ;; r et ur n 0;
}
Both programs produce this output:
The t ot al i s 15150
The body of the loop in both programs executes 101 times. The starting value is 101, not 1 as in the previous example. Notice that the f or loop is less complex than the do- whil e because the initialization, testing, and incrementing are performed in the single f or statement.
- The body of the f or loop can have more than one statement. The
following example requests five pairs of data values: children’s first names and their ages. It prints the teacher assigned to each child, based on the child’s age. This illus- trates a f or loop with cout functions, a ci n function, and an i f statement in its body. Because exactly five children are checked, the f or loop ensures the program ends after the fifth child.
/ / Fil ename: C13FOR3. CPP
/ / Pr ogr am t hat uses a l oop t o i nput and pr i nt
/ / t he t eacher assi gned t o each chil d. #i ncl ude <i ost r eam. h>
mai n( )
{
char chil d[ 25] ; / / Hol ds chil d’ s f i r st name i nt age; / / Hol ds chil d’ s age
i nt ct r ; / / The f or l oop count er var i abl e
f or ( ct r =1; ct r <=5; ct r ++)
{ cout << “ What i s t he next chil d’ s name? “ ;
Chapter 13 ♦ The for Loop
ci n >> chil d;
cout << “ What i s t he chil d’ s age? “ ; ci n >> age;
i f ( age <= 5)
{ cout << “ \ n” << chil d << “ has Mr s. “
<< “ Jones f or a t eacher \ n” ; } i f ( age == 6)
{ cout << “ \ n” << chil d << “ has Mi ss “
<< “ Smi t h f or a t eacher \ n” ; } i f ( age >= 7)
{ cout << “ \ n” << chil d << “ has Mr . “
<< “ Ander son f or a t eacher \ n” ; }
} / / Qui t s aft er 5 t i mes
r et ur n 0;
}
Below is the output from this program. You can improve this program even more after learning the swi t ch statement in the next chapter.
What i s t he next chil d’ s name? Joe What i s t he chil d’ s age? 5
Joe has Mr s. Jones f or a t eacher What i s t he next chil d’ s name? Larr y What i s t he chil d’ s age? 6
Larr y has Mi ss Smi t h f or a t eacher What i s t he next chil d’ s name? Juli e What i s t he chil d’ s age? 9
Juli e has Mr . Ander son f or a t eacher What i s t he next chil d’ s name? Manny What i s t he chil d’ s age? 6
Manny has Mi ss Smi t h f or a t eacher What i s t he next chil d’ s name? Lor i What i s t he chil d’ s age? 5
Lor i has Mr s. Jones f or a t eacher
EXAMPLE
- The
previous examples used an increment as the count expr essi on . You can make the f or loop increment the loop variable by any value. It does not have to increment by 1.
The following program prints the even numbers from 1 to
20. It then prints the odd numbers from 1 to 20. To do this, two is added to the counter variable (rather than one, as shown in the previous examples) each time the loop executes.
/ / Fil ename: C13EVOD. CPP
/ / Pr i nt s t he even number s f r om 1 t o 20,
/ / t hen t he odd number s f r om 1 t o 20. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt num; / / The f or l oop var i abl e
cout << “ Even number s bel ow 21\ n” ; / / Ti t l e f or ( num=2; num<=20; num+=2)
{ cout << num << “ “ ; } / / Pr i nt s ever y ot her number .
cout << “ \ nOdd number s bel ow 20\ n” ; / / A second t i t l e f or ( num=1; num<=20; num+=2)
{ cout << num << “ “ ; } / / Pr i nt s ever y ot her number .
r et ur n 0;
}
There are two loops in this program. The body of each one consists of a single pr i ntf () function. In the first half of the program, the loop variable, num, is 2 and not 1. If it were 1, the number 1 would print first, as it does in the odd number section.
The two cout statements that print the titles are not part of either loop. If they were, the program would print a title before each number. The following shows the result of running this program.
Chapter 13 ♦ The for Loop
Even number s bel ow 21
2 4 6 8 10 12 14 16 18 20
Odd number s bel ow 20
1 3 5 7 9 11 13 15 17 19
- You can decrement the loop variable as well. If you do, the value is
subtracted from the loop variable each time through the loop.
The following example is a rewrite of the counting program. It produces the reverse effect by showing a countdown.
/ / Fil ename: C13CNTD1. CPP
/ / Count down t o t he li ft off. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt ct r ;
f or ( ct r =10; ct r ! =0; ct r--)
{ cout << ct r << “ \ n” ; } / / Pr i nt ct r as i t
/ / count s down.
cout << “ *** Bl ast of f ! *** \ n” ; r et ur n 0;
}
When decrementing a loop variable, the initial value should be larger than the end value being tested. In this example, the loop variable, ct r , counts down from 10 to 1. Each time through the loop (each iteration), ct r is decremented by one. You can see how easy it is to control a loop by looking at this program’s output, as follows.
10
9
8
7
6
5
4
3
EXAMPLE
2
1
*** Bl ast Of f ! ***
- You also can make a f or loop test for something other than a
literal value. The following program combines much of what you have learned so far. It asks for student grades and computes an average. Because there might be a different number of students each semester, the program first asks the user for the number of students. Next, the program iterates until the user enters an equal number of scores. It then com- putes the average based on the total and the number of student grades entered.
/ / Fil ename: C13FOR4. CPP
/ / Comput es a gr ade aver age wi t h a f or l oop. #i ncl ude <i ost r eam. h>
#i ncl ude <i omani p. h> mai n( )
{
f l oat gr ade, avg; f l oat t ot al =0. 0;
i nt num; / / Tot al number of gr ades.
i nt l oopvar ; / / Used t o cont r ol t he f or l oop cout << “ \ n*** Gr ade Cal cul at i on *** \ n\ n” ; / / Ti t l e
Chapter 13 ♦ The for Loop
cout << “ How many st udent s ar e t her e? “ ;
ci n >> num; / / Get t ot al number t o ent er
f or ( l oopvar =1; l oopvar <=num; l oopvar ++)
{ cout << “ \ nWhat i s t he next st udent ’ s gr ade? “ ; ci n >> gr ade;
t ot al += gr ade; } / / Keep a r unni ng t ot al
avg = t ot al / num;
cout << “ \ n\ nThe aver age of t hi s cl ass i s “ << set pr eci si on( 1) << avg;
r et ur n 0;
}
Due to the f or loop, the total and the average calculations do not have to be changed if the number of students changes.
- Because
characters and integers are so closely associated in C++, you can increment character variables in a f or loop. The following program prints the letters A through Z with a simple f or loop.
/ / Fil ename: C13FOR5. CPP
/ / Pr i nt s t he al phabet wi t h a si mpl e f or l oop. #i ncl ude <i ost r eam. h>
mai n( )
{
char l ett er ;
cout << “ Her e i s t he al phabet:\ n” ;
f or ( l ett er =’ A’ ; l ett er <=’ Z’ ; l ett er ++) / / Loops A t o Z
{ cout << “ “ << l ett er ; }
r et ur n 0;
}
This program produces the following output:
Her e i s t he al phabet:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
EXAMPLE
- A f or expression can be a blank, or null expression. In the
following f or loop, all the expressions are blank:
f or ( ;; )
{ pr i ntf (“ Over and over ... ”) ; }
This f or loop iterates forever. Although you should avoid infinite loops, your program might dictate that you make a
f or loop expression blank. If you already initialized the st ar t expr essi on earlier in the program, you are wasting computer time to repeat it in the f or loop—and C++ does not require it.
The following program omits the st ar t expr essi on and the count expr essi on , leaving only the f or loop’s t est expr essi on . Most the time, you have to omit only one of them. If you use a f or loop without two of its expressions, consider replacing it with a whil e loop or a do- whil e loop.
/ / Fil ename: C13FOR6. CPP
/ / Uses onl y t he t est expr essi on i n
/ / t he f or l oop t o count by f i ves. #i ncl ude <i ost r eam. h>
mai n( )
{
i nt num=5; / / St ar t i ng val ue
cout << “ \ nCount i ng by 5s: \ n” ; / / Ti t l e f or ( ; num<=100; ) / / Cont ai ns onl y t he t est expr essi on.
{ cout << num << “ \ n” ;
num+=5; / / I ncr ement expr essi on out si de t he l oop.
} / / End of t he l oop’ s body
r et ur n 0;
}
The output from this program follows:
Count i ng by 5s: 5
10
15
Chapter 13 ♦ The for Loop
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
Use nested loops when you want to repeat a loop more than once.
Nested f or Loop s
Any C++ statement can go inside the body of a f or loop—even another f or loop! When you put a loop in a loop, you are creating a nested loop. The clock in a sporting event works like a nested loop. You might think this is stretching the analogy a little far, but it truly works. A football game counts down from 15 minutes to 0. It does this four times. The first countdown loops from 15 to 0 (for each minute). That countdown is nested in another that loops from 1 to 4 (for each of the four quarters).
If your program has to repeat a loop more than one time, it is a good candidate for a nested loop. Figure 13.1 shows two outlines of nested loops. You can think of the inside loop as looping “faster” than the outside loop. In the first example, the inside f or loop counts from 1 to 10 before the outside loop (the variable out ) can finish its first iteration. When the outside loop finally does iterate a second time, the inside loop starts over.
EXAMPLE
Ou Lo
Figure 13.1. Outlines of two nested loops.
The second nested loop outline shows two loops in an outside loop. Both of these loops execute in their entirety before the outside loop finishes its first iteration. When the outside loop starts its second iteration, the two inside loops repeat again.
Notice the order of the braces in each example. The inside loop always finishes, and therefore its ending brace must come before the outside loop’s ending brace. Indention makes this much clearer because you can align the braces of each loop.
Nested loops become important when you use them for array and table processing in Chapter 23, “Introducing Arrays.”
Chapter 13 ♦ The for Loop
Examples
- The
following program contains a loop in a loop—a nested loop. The inside loop counts and prints from 1 to 5. The outside loop counts from 1 to 3. The inside loop repeats, in its entirety, three times. In other words, this program prints the values 1 to 5 and does so three times.
/ / Fil ename: C13NEST1. CPP
/ / Pr i nt t he number s 1- 5 t hr ee t i mes.
/ / usi ng a nest ed l oop. #i ncl ude <i ost r eam. h> mai n( )
{
i nt t i mes, num; / / Out er and i nner f or l oop var i abl es
f or ( t i mes=1; t i mes<=3; t i mes++)
{
f or ( num=1; num<=5; num++)
{ cout << num; } / / I nner l oop body cout << “ \ n” ;
} / / End of out er l oop
r et ur n 0;
}
The indention follows the standard of f or loops; every statement in each loop is indented a few spaces. Because the inside loop is already indented, its body is indented another few spaces. The program’s output follows:
12345
12345
12345
- The outside loop’s counter variable changes each time through the
loop. If one of the inside loop’s control variables is the outside loop’s counter variable, you see effects such as those shown in the following program.
EXAMPLE
/ / Fil ename: C13NEST2. CPP
/ / An i nsi de l oop cont r oll ed by t he out er l oop’ s
/ / count er var i abl e. #i ncl ude <i ost r eam. h> mai n( )
{
i nt out er , i nner ;
f or ( out er =5; out er >=1; out er--)
{ f or ( i nner =1; i nner <=out er ; i nner ++)
{ cout << i nner ; } / / End of i nner l oop. cout << “ \
n” ;
}
r et ur n 0;
}
The output from this program follows. The inside loop repeats five times (as out er counts down from 5 to 1) and prints from five numbers to one number.
12345
1234
123
12
1
The following table traces the two variables through this program. Sometimes you have to “play computer” when learning a new concept such as nested loops. By executing a line at a time and writing down each variable’s contents, you create this table.
The out er variable |
The i nner variable |
|
---|---|---|
5 |
1 |
|
5 |
2 |
|
5 |
3 |
|
5 |
4 |
|
5 |
5 |
|
4 |
1 |
|
4 |
2 |
|
continues |
Chapter 13 ♦ The for Loop
The out er variable |
The i nner variable |
---|---|
4 |
3 |
4 |
4 |
3 |
1 |
3 |
2 |
3 |
3 |
2 |
1 |
2 |
2 |
1 |
1 |
4. A factorial is a mathematical number used in probability theory and statistics. A factorial of a number is the multi- plied product of every number from 1 to the number in question.
EXAMPLE
For example, the factorial of 4 is 24 because 4 ✕ 3 ✕ 2 ✕ 1 = 24.
The factorial of 6 is 720 because 6 ✕ 5 ✕ 4 ✕ 3 ✕ 2 ✕ 1 = 720. The factorial of 1 is 1 by definition.
Nested loops are good candidates for writing a factorial number-generating program. The following program asks the user for a number, then prints the factorial of that number.
/ / Fil ename: C13FACT. CPP
/ / Comput es t he f act or i al of number s t hr ough
/ / t he user ’ s number . #i ncl ude <i ost r eam. h> mai n( )
{
i nt out er , num, f act , t ot al ;
cout << “ What f act or i al do you want t o see? “ ; ci n >> num;
f or ( out er =1; out er <= num; out er ++)
{ t ot al = 1; / / I ni t i ali ze t ot al f or each f act or i al . f or ( f act =1; f act <= out er ; f act ++)
{ t ot al *= f act ; } / / Comput e each f act or i al .
}
cout << “ The f act or i al f or “ << num << “ i s “
<< t ot al ;
r et ur n 0;
}
The following shows the factorial of seven. You can run this program, entering different values when asked, and see various factorials. Be careful: factorials multiply quickly.
(A factorial of 11 won’t fit in an integer variable.)
What f act or i al do you want t o see? 7 The f act or i al f or 7 i s 5040
Chapter 13 ♦ The for Loop
Review Question s
The answers to the review questions are in Appendix B.
-
What
is a loop?
-
True or false: The body of a f or loop contains at most one
statement.
-
What is a nested loop?
-
Why
might you want to leave one or more expressions out of the f or statement’s parentheses?
-
Which loop “moves” fastest: the inner loop or the outer loop?
-
What is the output from the following program?
f or ( ct r =10; ct r >=1; ct r- =3)
{ cout << ct r << “ \ n” ; }
-
True or false: A f or loop is better to use than a whil e loop when
you know in advance exactly how many iterations a loop requires.
-
What
happens when the t est expr essi on becomes False in a
f or statement?
- True or false: The following program contains a valid nested loop.
f or ( i =1; i <=10; i ++) ;
{ f or ( j =1; j <=5; j ++)
{ cout << i << j ; }
}
- What is the output of the following section of code?
i =1;
st ar t =1; end=5; st ep=1;
EXAMPLE
f or ( ; st ar t >=end; )
{ cout << i << “ \ n” ; st ar t +=st ep;
end-- ; }
Review Exercise s
-
Write
a program that prints the numerals 1 to 15 on-screen. Use a f or loop to control the printing.
-
Write a program to print the numerals 15 to 1 on-screen. Use a f or
loop to control the printing.
-
Write
a program that uses a f or loop to print every odd number from 1 to 100.
-
Write a program that asks the user for her or his age. Use a f or
loop to print “Happy Birthday!” for every year of the user’s age.
-
Write
a program that uses a f or loop to print the ASCII characters from 32 to 255 on-screen. (Hint: Use the %c conver- sion character to print integer variables.)
-
Using the ASCII table numbers, write a program to print the
following output, using a nested f or loop. (Hint: The outside loop should loop from 1 to 5, and the inside loop’s start variable should be 65, the value of ASCII A.)
A AB ABC
ABCD ABCDE
Summary
This chapter taught you how to control loops. Instead of writing extra code around a whil e loop, you can use the f or loop to control the number of iterations at the time you define the loop. All
Chapter 13 ♦ The for Loop
f or loops contain three parts: a st ar t expr essi on , a t est expr essi on ,
and a count expr essi on .
You have now seen C++’s three loop constructs: the whil e loop, the do- whil e loop, and the f or loop. They are similar, but behave differently in how they test and initialize variables. No loop is better than the others. The programming problem should dictate which loop to use. The next chapter (Chapter 14, “Other Loop Options”) shows you more methods for controlling your loops.