3.2 Nested if Statements

There are times when there are more than two possible courses of action for a program to take. If there are three or more possibilities then a nested if can be used. Here is an example. It will input the score from a hockey game and then decide what the outcome of the game was. There are three possible outcomes of a hockey game. We'll do it first without nested loops and then with.

var leafs, badGuys : int

put "How many goals did the Leafs get?"
get leafs
put "How many did the other team get?"
get badGuys

if leafs > badGuys then
    put "The Leafs won!!!"
end if

if leafs < badGuys then
    put "The Leafs lost."
end if

if leafs = badGuys then
    put "It was a tie."
end if 

This version of the program is not as efficient as it could be. If the Leafs win, there is no way they can lose or tie, yet our program still checks those possibilities. No matter what happens we need to make 3 comparisons.

Here is a more efficient way of doing this by using a nested if statement:

var leafs, badGuys : int

put "How many goals did the Leafs get?"
get leafs
put "How many did the other team get?"
get badGuys

if leafs > badGuys then
    put "The Leafs won!!!"
elsif leafs < badGuys then
    put "The Leafs lost."
else
    put "It was a tie."
end if 

The first thing you should notice is the keyword elsif. That is not a typo. Many languages use the combination else if but Turing combines it into its own single keyword. Each condition in the nested if is looked at until one is true. The statement(s) following the true condition will be executed and then the if structure is exited. If none of the conditions are are true then the statement(s) after the else are executed. If there is no else then execution continues after the end if.

This version is more efficient than the first one. If the Leafs win then only one comparison is needed. The Leafs won!!! will be printed and the rest of the nested if will be skipped. If the Leafs lose then two comparisons will be needed and the else part will be skipped. If the Leafs tie then there will still only be two comparisons. The first example always needed three comparisons.

Here is another example using nested if statements:

var x, y, z : real

put "Enter a value for x"
get x
put "Enter a value for y"
get y
put "Enter a value for z"
get z

put "The largest value you entered is "..
if x >= y then % y isn't biggest
   if x >= z then % y, z aren't biggest 
      put x
   else % y, x aren't biggest
      put z
   end if
elsif y >= z then % x, z aren't biggest
   put y
else % x, y aren't biggest
   put z
end if 

The program finds the largest value that the user enters. This is not the only way to achieve that result. For instance, the code could be a little shorter if you used and to combine conditions. This program produces the same results:

var x, y, z : real

put "Enter a value for x"
get x
put "Enter a value for y"
get y
put "Enter a value for z"
get z

put "The largest value you entered is "..
if x >= y and x >= z then % x is biggest
   put x
elsif y >= z then % x isn't biggest
   put y
else % x, y aren't biggest
   put z
end if 

Exercise 3.2

  1. Simplify the following sequence so that the effect is the same but fewer comparisons are required.
    if temperature > MAX_TEMP then
       put "Porridge too hot"
    end if
    
    if temperature < MIN_TEMP then
       put "Porridge too cold"
    end if
    
    if temperature <= MAX_TEMP and temperature >= MIN_TEMP then
       put "Porridge just right - eat it all up."
    end if 
  2. Consider the following statement.
    if age > minAge then
       if income > minIncome then
          put "Accept"
       else
          put "Reject"
       end if
    end if 
    1. What will the statement print if
      age > minAge and income < minIncome?
    2. What will the statement print if
      age < minAge and income < minIncome?
  3. Using nested ifs, write a single statement that prints the smallest value contained in the variables a, b, and c.
  4. Write a statement that, if the value of the variable item is negative, adds its value to negSum, but if it is positive, adds its value to posSum. If item is zero, the statement should increase the variable zeroCount by one.
  5. Assume that the following declarations have been made.
    var year : int
    var leapYear : boolean 
    Write a fragment that will make leapYear true if year represents a leap year and false otherwise.
    A year is usually a leap year if its number is a multiple of four. It is not a leap year, however, if its number is a multiple of 100 but not a multiple of 400.