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 ^)
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.
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.
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
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.
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:
-
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 ++))) ;
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
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.
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
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.
/ / 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.
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;
}
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.
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
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.
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;
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.
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( )
{
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.
/ / 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
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)
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.
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
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.
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
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
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.
/ / 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
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
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.
#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? “ ;
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
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.
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.
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( )
{
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.
/ / 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.
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
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;
}
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.
/ / 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.
- 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;
}
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.
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:
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.
/ / 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.
- 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.
-
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.