CS 1440 Lab 2
Cover sheetPrevious ActivityNext Activity

Activity 2-7: Nested (multiple) if-else statements

Activity Procedure

Often it is necessary to classify a number as belonging to one of several disjoint sets. For example, a program may ask the user for his income, classify it by range, and use an appropriate tax rate for that "bracket". We'll explore alternative approaches.

Let's review a little mathematics interval notation. A number x is in the closed interval [a,b] if x >a and x < b. Parentheses indicate an open interval: the set (a,b) does not include the end points a and b. Half-open intervals are described with mixed notation: e.g. (a, b] includes b but not a. Finally, intervals can be infinite: (- , b] is the set of numbers less than or equal to b.

Suppose we want to read a (double) number from the user, then print "Low" if the number is less than 1, "One" if the number is in the interval [1,2), "Two" if it is in the interval [2,3), and "High" otherwise. Here's a rather painful way using just if statements:

#include <iostream.h>
int main()
{
        double x;
        cout << "Enter number: ";
        cin >> x;
        if(x<1)cout << "Low" << endl;
        if(x>=1 && x<2)cout << "One" << endl;
        if(x>=2 && x<3)cout << "Two" << endl;
        if(x>=3)cout << "High" << endl;
        return 0;
}

The reason this is painful is that we are classifying a number as belonging to one of 4 disjoint sets. When we check to see if x is less than one in the first if statement, it seems unnecessary to then check if it is greater than or equal to one in the next line. If you were playing "20 questions", and the answer to your question "is it bigger than a breadbox?" was "No", would you then ask "is it smaller than or equal to a breadbox?"?

The if..else statement can be used to quickly and cleanly find which of several disjoint sets an element belongs to. Here's a rewrite of the last program:

#include <iostream.h>
int main()
{
        double x;
        cout << "Enter number: ";
        cin >> x;
        if(x<1){
                cout << "Low" << endl;
        }
        else{
                if(x<2)cout << "One" << endl;
                else{
                        if(x<3)cout << "Two" << endl;
                        else cout << "High" << endl;
                }
        }
        return 0;
}

There actually are no compound statements in this program, and using a more readable indentation style we may write this as:

#include <iostream.h>
int main()
{
        double x;
        cout << "Enter number: ";
        cin >> x;
        if(x<1) cout << "Low" << endl;
        else if(x<2)cout << "One" << endl;
        else if(x<3)cout << "Two" << endl;
        else cout << "High" << endl;
        return 0;
}

It's important to understand that the last two versions are exactly the same as far as the compiler is concerned -- we have only modified white space and eliminated grouping symbols that weren't grouping anything. The executable code -- what you get after compilation -- will be byte-for-byte identical. The second style is preferred because it's more readable. Using the first style, as additional options are added the program creeps to the right.

The second style works fine with compound statements as well:

if(condition 1){
        statement 1;
        statement 2;
        ...
}else if(condition 2){
        statement 1;
        statement 2;
        ...
...
}else if(condition n){
        statement 1;
        statement 2;
        ...
}else{
        statements if none of the previous conditions apply;
}

Note that this sequence of if..else statements is used only when the conditions are disjoint. Suppose we offer a $5 discount to patrons over 65, and a $3 discount for patrons under 6 feet tall:

double discount;
discount=0;
if(age>65)discount=discount+5;
if(height<6)discount=discount+3;

A patron could get both discounts if he's short and old!

Suppose we want to classify a taxpayer's tax rate based on income: less than $10,000 puts him in the 15% bracket, at least $10,000 but less than $20,000 puts him in the 20% bracket, and at least $20,000 results in the 30% bracket. Does the following program called taxes.C do what we want?

#include <iostream.h>
int main()
{
        double income;
        cout << "Enter income: ";
        cin >> income;
        if(income<10000) cout << "15% rate\n";
        if(income>=10000 && income<20000) cout << "20% rate\n";
        else cout << "30% rate\n";
        return 0;
}

You may be able to spot a flaw in the program just by looking at it. But a pretty good way of chasing down potential problems is to run the program with data representing typical brackets, and also boundary cases. Copy the program into a file called taxes.C and run the program 5 times, using each of the following incomes:

5000, 10000, 15000, 20000, 25000

Does this help you locate the error? Fix the problem and run the program again with the same 5 data values.