Chapter 6

if I Could Make My Own Decisions

In This Chapter

arrow Making decisions with an if statement

arrow Looking at what else you can do

arrow Nesting if statements

arrow Confounding compound logical expressions

Making decisions is a part of the everyday world. Should I get a drink now or wait for the commercial? Should I take this highway exit to go to the bathroom or else wait for the next? Should I take another step or stop and smell the roses? If I’m hungry or I need gas, then I should stop at the convenience store? If it’s 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 must 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 Statement

The format of the if statement is straightforward:

  if (m > n)   // if m is greater than n...
{
             // ...then do this stuff
}

When encountering if, C++ first executes the logical expression contained within 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 is greater 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 the first statement after the }.

Comparison operators

Table 6-1 shows the different operators that can be used to compare values in logical expressions.

remember.eps Binary operators have the format expr1 operator expr2.

Table 6-1 The Comparison Operators

Operator

Meaning

==

equality; true if the expression on the left of the ‘==’ has the same value as the expression on the right

!=

inequality; opposite of equality

>

greater than; true if the left-hand expression is greater than the one on the right

<

less than; true if the left-hand expression is less than the one on the right

>=

greater than or equal to; true if the left-hand expression is greater than or equal to the one on the right

<=

less than or equal to; true if the left-hand expression is less than or equal to the one on the right

warning.eps Don’t confuse the equality operator (==) with the assignment operator (=). This is a common mistake for beginners.

The following BranchDemo program shows how the operators 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[])
{
    // 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
    cout << "Press Enter to continue..." << endl;
    cin.ignore(10, ' '),
    cin.get();
    return 0;
}

Program execution begins with main() as always. The program first declares two int variables cleverly named nOperand1 and nOperand2. It then prompts 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 the notification "Argument 1 is less than argument 2". The second if statement displays a message if the two operands are equal in value. The final comparison is true if nOperand1 is greater than nOperand2.

The following shows a sample run of the BranchDemo program:

  Enter argument 1:5
Enter argument 2:10
Argument 1 is less than argument 2
Press Enter to continue …

Figure 6-1 shows the flow of control graphically for this particular run.

9781118823873-fg0601.tif

Figure 6-1: The path taken by the BranchDemo program when the user enters 5 for the first argument and 10 for the second.

The way the BranchDemo program is written, all three comparisons are performed every time. This is slightly wasteful since the three conditions are mutually exclusive. For example, nOperand1 > nOperand2 can’t possibly be 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 expression after the if statement is conditional. However, it’s much too easy to make a mistake 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

You 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 anyway, no matter what 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 continues

It’s clear from the comments and the indent that the programmer really meant 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 continues

The C++ compiler can’t catch this type of mistake. It’s just safer if you always supply the braces.

remember.eps C++ treats all white space the same. It ignores the alignment of expressions on the page.

warning.eps Always use braces to enclose the statements after an if statement, even if there’s 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 is executed 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
}

The else clause must appear immediately after the close brace of the if clause. 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 "Age can’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 is not 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.

9781118823873-fg0602.tif

Figure 6-2: Flow of control through an if and else for two different values of nAge.

Nesting if Statements

The braces of an if or an else clause can contain another if statement. These are known as nested if statements. The following NestedIf program shows 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[])
{
    // enter your birth year
    int  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
    cout << "Press Enter to continue..." << endl;
    cin.ignore(10, ' '),
    cin.get();
    return 0;
}

This program starts by asking for the user’s birth year. If the birth year is later than 2000, then the program outputs the string "You were born in the 21st century".

remember.eps In mathematically accurate terms, 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 else clause 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 birth year 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 if statement 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.

In practice, the output of the program appears as follows for three possible values for birth year. First, 2002 produces the following:

  Enter your birth year: 2002
You were born in the 21st century
Press Enter to continue …

My own birth year of 1956 generates the following:

  Enter your birth year: 1956
You were born in the second half of the 20th century
Press Enter to continue …

Finally, my father’s birth year of 1932 generates the third possibility:

  Enter your birth year: 1932
You were born in the first half of the 20th century
Press Enter to continue …

I could use a nested if to avoid the unnecessary comparisons in the NestedBranchDemo 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 is greater than nOperand2, this snippet outputs the string "Argument 1 is greater than argument 2". From here, however, control jumps to the final closed brace, thereby skipping the remaining comparisons.

If nOperand1 is not greater than nOperand2, then the snippet performs a second test to differentiate the case that nOperand1 is less than nOperand2 from 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.

9781118823873-fg0603.tif

Figure 6-3: The path taken by the NestedBranchDemo program when the user enters 5 and 10 as before.

remember.eps Performing the test for equality is unnecessary: If nOperand1 is neither greater than nor less than nOperand2, then it must be equal.

Compound Conditional Expressions

The three logical operators that can be used to create what are known as compound conditional expressions are shown in Table 6-2.

Table 6-2 The Logical Operators

Operator

Meaning

&&

AND; true if the left- and right-hand expressions are true; otherwise false

||

OR; true if either the left- or right-hand expressions is true; otherwise false

!

NOT; true if the expression on the right is false; otherwise false

The programmer is asking two or more questions in a conditional compound expression, as in the following code snippet:

  // make sure that nArgument is between 0 and 5
if (0 < nArgument && nArgument < 5)

Figure 6-4 shows how three different values of nArgument are evaluated by this expression.

9781118823873-fg0604.tif

Figure 6-4: The evaluation of the compound expression 0 < n && n < 5 for three different values of n.

By the way, the snippet

  if (m < nArgument && nArgument < n)

is the normal way of coding the expression "if nArgument is between m 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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.17.18