and smell the roses? If I am hungry or I need gas, then I should stop at the
convenience store. If it is a weekend and I feel like it, then I can sleep in. See
what I mean?
An assistant, even a stupid one, has to be able to make at least rudimentary
decisions. Consider the Tire Changing Language in Chapter 1. Even there, the
program had to be able to test for the presence of a lug nut to avoid waving a
wrench around uselessly in space over an empty bolt, thereby wasting everyone’s time.
All computer languages provide some type of decision-making capability. In
C++, this is handled primarily by the if statement.The if StatementThe format of the if statement is straightforward:if (m > n) // if m is greater than n...{
// ...then do this stuff
}
70 Part II: Writing a Program: Decisions, DecisionsWhen encountering if, C++ first executes the logical expression containedwithin the parentheses. In this case, the program evaluates the conditional
expression “is m greater than n.” If the expression is true, that is, if m truly isgreater than n, then control passes to the first statement after the { and continues from there. If the logical expression is not true, control passes to thefirst statement after the }.Comparison operatorsTable 6-1 shows the different operators that can be used to compare valuesin logical expressions.
Binary operators have the format expr1 operator expr2.Table 6-1 The Comparison OperatorsOperator Meaning== equality; true if the left-hand argument has the same value as theexpression on the right!= inequality; opposite of equality> greater than; true if the left-hand argument is greater than the right< less than; true if the left-hand argument is less than the right>= greater than or equal to; true if the left argument is greater than orequal to the right<= less than or equal to; true if the left argument is less than or equal tothe rightDon’t confuse the equality operator (==) with the assignment operator (=).This is a common mistake for beginners.
The following BranchDemo program shows how the operators shown in
Table 6-1 are used:// BranchDemo - demonstrate the if statement#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int nNumberofArgs, char* pszArgs[])
Chapter 6: if I Could Make My Own Decisions 71{// enter operand1 and operand2
int nOperand1;
int nOperand2;
cout << “Enter argument 1:”;
cin >> nOperand1;
cout << “Enter argument 2:”;
cin >> nOperand2;
// now print the results
if (nOperand1 > nOperand2)
{
cout << “Argument 1 is greater than argument 2”
<< endl;
}
if (nOperand1 < nOperand2)
{
cout << “Argument 1 is less than argument 2”
<< endl;
}
if (nOperand1 == nOperand2)
{
cout << “Argument 1 is equal to argument 2”
<< endl;
}
// wait until user is ready before terminating program
// to allow the user to see the program results
system(“PAUSE”);
return 0;
}Program execution begins with main() as always. The program first declarestwo int variables cleverly named nOperand1 and nOperand2. It thenprompts the user to “Enter argument 1”, which it reads into nOperand1.The process is repeated for nOperand2.The program then executes a sequence of three comparisons. It first checks
whether nOperand1 is less than nOperand2. If so, the program outputs thenotification “Argument 1 is less than argument 2”. The second ifstatement displays a message if the two operands are equal in value. Thefinal comparison is true if nOperand1 is greater than nOperand2.The following shows a sample run of the BranchDemo program:Enter argument 1:5Enter argument 2:10Argument 1 is less than argument 2Press any key to continue . . .
72 Part II: Writing a Program: Decisions, DecisionsFigure 6-1 shows the flow of control graphically for this particular run.Figure 6-1:The path
taken by the
BranchDemo
program
when the
user enters
5 for the first
argument
and 10 for
the second.// enter operand1 and operand2int nOperand1;
int nOperand2;
cout << "Enter argument 1:";
cin >> nOperand1;
cout << "Enter argument 2:";
cin >> nOperand2;
// now print the results
if (nOperand1 > nOperand2)
{
cout << "Argument 1 is greater than argument 2"cout << end1;}
if (nOperand1 < nOperand2)
{
cout << "Argument 1 is less than argument 2"cout << end1;}
if (nOperand1 == nOperand2)
{
cout << "Argument 1 is equal to argument 2"cout << end1;}Entered 5
Entered 10
5 > 10 is false
5 < 10 is true
5 == 10 is falseThe way the BranchDemo program is written, all three comparisons are performed every time. This is slightly wasteful since the three conditions aremutually exclusive. For example, nOperand1 > nOperand2 can’t possiblybe true if nOperand1 < nOperand2 has already been found to be true.Later in this chapter, I show you how to avoid this waste.Say “No” to “No braces”Actually the braces are optional. Without braces, only the first expressionafter the if statement is conditional. However, it is much too easy to make amistake this way, as demonstrated in the following snippet:// Can’t have a negative age. If age is less than zero...if (nAge < 0)
cout << “Age can’t be negative; using 0” << endl;
nAge = 0;
// program continues
Chapter 6: if I Could Make My Own Decisions 73You may think that if nAge is less than 0, this program snippet outputs a message and resets nAge to zero. In fact, the program sets nAge to zero no matterwhat its original value. The preceding snippet is equivalent to the following:// Can’t have a negative age. If age is less than zero...if (nAge < 0)
{
cout << “Age can’t be negative; using 0” << endl;
}
nAge = 0;
// program continuesIt’s clear from the comments and the indent that the programmer reallymeant the following:// Can’t have a negative age. If age is less than zero...if (nAge < 0)
{
cout << “Age can’t be negative; using 0” << endl;
nAge = 0;
}
// program continuesThe C++ compiler can’t catch this type of mistake. It’s safer just to alwayssupply the braces.
C++ treats all white space the same. It ignores the alignment of expressions on
the page.
Always use braces to enclose the statements after an if statement, even ifthere is only one. You’ll generate a lot fewer errors that way.What else Is There?C++ allows the program to specify a clause after the keyword else that isexecuted if the conditional expression is false, as in the following example:if (m > n) // if m is greater than n...{
// ...then do this stuff;...
}
else // ...otherwise,...
{
// ...do this stuff
}
74 Part II: Writing a Program: Decisions, DecisionsThe else clause must appear immediately after the close brace of the ifclause. In use, the else appears as shown in the following snippet:if (nAge < 0){
cout << “Age can’t be negative; using 0.” << endl;
nAge = 0;
}
else
{
cout << “Age of “ << nAge << “ entered” << endl;
}In this case, if nAge is less than zero, the program outputs the message “Agecan’t be negative; using 0.” and then sets nAge to 0. This corresponds to the flow of control shown in the first image in Figure 6-2. If nAge isnot less than zero, the program outputs the message “Age of x entered”,where x is the value of nAge. This is shown in the second image in Figure 6-2.Figure 6-2:Flow of control through
an if andelse for
two different values
of nAge.if (nAge < 0){
cout << "Age can’t be negative; using 0."
<< end1;
nAge = 0;
}
else
{
cout << "Age of " << nAge
<< " entered" << end1;
}For nAge = –1if (nAge < 0){
cout << "Age can’t be negative; using 0."
<< end1;
nAge = 0;
}
else
{
cout << "Age of " << nAge
<< " entered" << end1;
}For nAge = 26
Chapter 6: if I Could Make My Own Decisions 75
Nesting if StatementsThe braces of an if or an else clause can contain another if statement.These are known as nested if statements. The following NestedIf programshows an example of a nested if statement in use.// NestedIf - demonstrate a nested if statement//
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int nNumberofArgs, char* pszArgs[])
{Logical expressions: Do they have any value?At the beginning of this chapter, I called the comparison symbols < and > operators, and I describedstatements containing these operators as expressions. But expressions have a value and a type.What is the value and type of an expression like m > n? In C++, the type of this expression is bool(named in honor of George Boole, the inventor of Logic Calculus). Expressions of type bool canhave only one of two values: true or else false. Thus, you can write the following:bool bComparison = m > n;For historical reasons, there is a conversion between the numerical types like int and char andbool: A value of 0 is considered the same as false. Any non-zero value is considered the sameas true.Thus, the if statementif (cCharacter){
// execute this code if cCharacter is not NULL
}is the same asif (cCharacter != ‘\0’){
// execute this code if cCharacter is not NULL
}Assigning a true/false value to a character may seem a bit obtuse, but you’ll see in Chapter 16 thatit has a very useful application.
76 Part II: Writing a Program: Decisions, Decisions// enter your birth yearint nYear;
cout << “Enter your birth year: “;
cin >> nYear;
// Make determination of century
if (nYear > 2000)
{
cout << “You were born in the 21st century”
<< endl;
}
else
{
cout << “You were born in “;
if (nYear < 1950)
{
cout << “the first half”;
}
else
{
cout << “the second half”;
}
cout << “ of the 20th century”
<< endl;
}
// wait until user is ready before terminating program
// to allow the user to see the program results
system(“PAUSE”);
return 0;
}This program starts by asking the user for his birth year. If the birth year isgreater than 2000, then the program outputs the string “You were born inthe 21st century”.The year 2000 belongs to the 20th century, not the 21st.
If the birth year is not greater than 2000, then the program enters the elseclause of the outer if statement. This clause starts by outputting the string“You were born in” before comparing the birth year to 1950. If the birthyear is less than 1950, then the program adds the first “the first half”.If the birth year is not less than 1950, then the else clause of the inner ifstatement is executed, which tacks on the phrase “the second half”.Finally, the program adds the concluding phrase “of the 20th century”to whatever has been output so far.Chapter 6: if I Could Make My Own Decisions 77In practice, the output of the program appears as follows for three possiblevalues for birth year. First, 2002 produces the following:Enter your birth year: 2002You were born in the 21st centuryPress any key to continue . . .My own birth year of 1956 generates the following:Enter your birth year: 1956You were born in the second half of the 20th century
Press any key to continue . . .Finally, my father’s birth year of 1932 generates the third possibility:Enter your birth year: 1932You were born in the first half of the 20th century
Press any key to continue . . .I could use a nested if to avoid the unnecessary comparisons in theNestedBranchDemo program:if (nOperand1 > nOperand2){
cout << “Argument 1 is greater than argument 2”
<< endl;
}
else
{
if (nOperand1 < nOperand2)
{
cout << “Argument 1 is less than argument 2”
<< endl;
}
else
{
cout << “Argument 1 is equal to argument 2”
<< endl;
}
}This version performs the first comparison just as before. If nOperand1 isgreater than nOperand2, this snippet outputs the string “Argument 1 isgreater than argument 2”. From here, however, control jumps to thefinal closed brace, thereby skipping the remaining comparisons.
78 Part II: Writing a Program: Decisions, DecisionsIf nOperand1 is not greater than nOperand2, then the snippet performs asecond test to differentiate the case that nOperand1 is less than nOperand2from the case that they are equal in value.Figure 6-3 shows graphically the flow of control for the NestedBranchDemo
program for the same input of 5 and 10 described earlier in the chapter.Figure 6-3:The path
taken by the
NestedBranchDemo
program
when the
user enters
5 and 10
as before.// enter operand1 and operand2int nOperand1;
int nOperand2;
cout << "Enter argument 1:";
cin >> nOperand1;
cout << "Enter argument 2:";
cin >> nOperand2;
// now print the results
if (nOperand1 > nOperand2)
{
cout << "Argument 1 is greater than argument 2"
<< end1;
}
else
{
if a(nOperand1 < nOperand2){ | 5 < 10 is true |
else
{
cout << "Argument 1 is equal to argument 2"cout << end1;}
}Entered 5
Entered 10
5 > 10 is falsePerforming the test for equality is unnecessary: If nOperand1 is neithergreater than nor less than nOperand2, then it must be equal.Compound Conditional ExpressionsThe three logical operators that can be used to create what are known ascompound conditional expressions are shown in Table 6-2.Chapter 6: if I Could Make My Own Decisions 79Table 6-2 The Logical OperatorsOperator Meaning&& AND; true if the left- and right-hand arguments are true; otherwise, false|| OR; true if either the left- or right-hand arguments is true; otherwise, false
! NOT; true if the argument on the right is false; otherwise, falseThe programmer is asking two or more questions in a conditional compoundexpression, as in the following code snippet:// make sure that nArgument is between 0 and 5if (0 < nArgument && nArgument < 5)Figure 6-4 shows how three different values of nArgument are evaluated bythis expression.Figure 6-4:The evaluation of the
compound
expression0 < n&& n <
5 for three
different
values of n.
0 < nArgument && nArgument < 5
where nArgument = –1
0 < –1 && –1 < 5
false && true
false
where nArgument = 7
0 < 7 && 7 < 5
true&&false
false
where nArgument = 2
0 <2 && 2 < 5
true && true
trueBy the way, the snippetif (m < nArgument && nArgument < n)is the normal way of coding the expression “if nArgument is betweenm and n, exclusive”. This type of test does not include the end points —that is, this test will fail if nArgument is equal to m or n. Use the <= comparison operator if you want to include the end points.80 Part II: Writing a Program: Decisions, DecisionsShort circuit evaluationLook carefully at a compound expression involving a logical AND likeif (expr1 && expr2)If expr1 is false, then the overall result of the compound expression is false, irrespective ofthe value of expr2. In fact, C++ doesn’t even evaluate expr2 if expr1 is false — false &&anything is false. This is known as short circuit evaluation because it short circuits aroundexecuting unnecessary code in order to save time.
The situation is exactly the opposite for the logical OR:if (expr1 || expr2)If expr1 is true, then the overall expression is true, irrespective of the value of expr2.Short circuit evaluation is a good thing since the resulting programs execute more quickly;
however, it can lead to unexpected results in a few cases. Consider the following admittedly contrived case:if (m <= nArgument && nArgument++ <= n)The intent is to test whether nArgument falls into the range [m, n] and to incrementnArgument as part of the test. However, short circuit evaluation means that the second testdoesn’t get executed if m <= nArgument is not true. If the second test is never evaluated,then nArgument doesn’t get incremented.Remember: If you didn’t follow that, just remember the following: Don’t put an expression that hasa side effect like incrementing a variable in a conditional.
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
(adsbygoogle = window.adsbygoogle || []).push({
google_ad_client: "ca-pub-3147778191066425",
enable_page_level_ads: true
});
</script>
No comments:
Post a Comment