RECALL THAT THE IF STATEMENT has the form
if (comparison) true-statement else false-statement
It's a deceptively simple statement, because you can do a lot with it. Let's look at some of the possibilities.
At the beginning of the chapter, when I introduced the if statement, I showed the typical use in which the true-statement and false-statement are blocks containing multiple statements. C# allows true-statement and false-statement to be single statements, as in this example:
if ( x == 0 ) Console.WriteLine("It's a zero"); else Console.WriteLine("It's not a zero");
However, usually you need to write more than one statement in each section. In that case, you must use a block by enclosing the multiple statements in curly braces.
Now, an if statement is, in particular, a statement. This means that either the true-statement or false-statement part can itself be an if statement. For example:
if ( x == 0 ) Console.WriteLine("It's a zero"); else if ( x > 0 ) Console.WriteLine("It's positive"); else Console.WriteLine("It's negative");
To understand how this works, let's consider a specific value for x -- say, 5. The first condition ( x == 0 ) is false, so C# executes the false-statement part, which itself is an if statement. It evaluates the comparison ( x > 0 ), which is true, so the result "It's positive" would appear.
A problem arises, however, if the true-statement is an if statement that has no else part. This special case is effectively forbidden by the syntax of C#. Suppose, for example, that you type
if ( x > 0 ) if (y > 0) Console.WriteLine("First case"); else Console.WriteLine("Second case");
Now, remember that the way you've indented this doesn't mean anything at all to the computer. You might think that the else part is the second half of your "if (x > 0)" statement, but the rule that the computer follows attaches the else to "if (y > 0)", which is closer. That is, the computer reads your statement as if it were formatted:
if ( x > 0 ) if (y > 0) Console.WriteLine("First case"); else Console.WriteLine("Second case");
You can force the computer to use the other interpretation by enclosing the nested if in a block:
if ( x > 0 ) { if (y > 0) Console.WriteLine("First case"); } else Console.WriteLine("Second case");
For clarity, as well as ease of maintenance, it's usually a good idea always to use curly braces in each part of your if statement, whether they're needed or not. As an example, compare the readability of this statement to the previous two examples:
if ( x > 0 ) { if (y > 0) { Console.WriteLine("First case"); } } else { Console.WriteLine("Second case"); }
By mentally matching braces, it's much easier to tell which statements are under the control of which if conditions. Also, if you choose to add a statement to any of the sections, the curly braces are already in place -- you don't have to add them.
Much more interesting than this technicality is the case where the false-statement, the else part of the if statement, is itself an if statement. The statement would look like this (perhaps without the final else part):
if (comparison-1) { statement-1 } else { if (comparison-2) { statement-2 } else { statement-3 } }
However, since the computer doesn't care how a program is laid out on the page, this is almost always written in the format:
if (comparison-1) { statement-1 } else if (comparison-2) { statement-2 } else { statement-3 }
You should think of this as a single statement representing a three-way branch. When the computer executes this, one and only one of the three statements -- statement-1, statement-2, or statement-3 -- will be executed. The computer starts by evaluating comparison-1. If it is true, the computer executes statement-1 and then jumps all the way to the end of the outer if statement, skipping the other two statements. If comparison-1 is false, the computer skips statement-1 and executes the second, nested if statement. To do this, it tests the value of comparison-2 and uses it to decide between statement-2 and statement-3.
Here is an example that will print out one of three different messages, depending on the value of a variable named temperature:
if (temperature < 50) { Console.WriteLine("It's cold."); } else if (temperature < 80) { Console.WriteLine("It's nice."); } else { Console.WriteLine("It's hot."); }
If temperature is, say, 42, the first test is true. The computer prints out the message "It's cold", and skips the rest -- without even evaluating the second condition. For a temperature of 75, the first test is false, so the computer goes on to the second test. This test is true, so the computer prints "It's nice" and skips the rest. If the temperature is 173, both of the tests evaluate to false, so the computer says "It's hot" (unless its circuits have been fried by the heat, that is).
You can go on stringing together "else-if's" to make multi-way branches with any number of cases:
if (comparison-1) { statement-1 } else if (comparison-2) { statement-2 } else if (comparison-3) { statement-3 . . // (more cases) . } else if (comparison-N) { statement-N } else { statement-(N+1) }
The computer performs comparisons one after the other until it comes to one that is true. It executes the associated statement and skips the rest. If none of the comparisons evaluate to true, then the statement in the else part is executed. This statement is called a multi-way branch because only one of the statements will be executed. The final else part can be omitted. In that case, if all the comparisons are false, none of the statements is executed.
Finally, let's write a complete program that uses an if statement in an interesting way. I want a program that will convert measurements of length from one unit of measurement to another, such as feet to yards or inches to feet. So far, the problem is extremely under-specified. Let's say that the program will only deal with measurements in inches, feet, and yards. It would be easy to extend it later to deal with other units. The user will type in a measurement in one of these units, and will select the unit of measurement. The output will show the length in terms of each of the four units of measure. (This is easier than asking the user which units to use in the output.) An outline of the process is
Read the user's input measurement and units of measure Compute the measurement in inches, feet, and yards Display the four results
The conversion into different units of measure can be simplified by first converting the user's input into inches. From there, it can be converted into feet and yards. We still have to test the input to determine which unit of measure the user has specified:
Let measurement = Convert.ToDouble(Console.ReadLine()) Let units = Convert.ToInt32(Console.ReadLine()) if the units are inches Let inches = measurement else if the units are feet Let inches = measurement * 12 // 12 inches per foot else if the units are yards Let inches = measurement * 36 // 36 inches per yard else if the units are miles Let inches = measurement * 12 * 5280 // 5280 feet per mile else The units are illegal! Print an error message and stop processing Let feet = inches / 12.0 Let yards = inches / 36.0 Let miles = inches / (12.0 * 5280.0) Display the results
In my final program, I decided to make things more interesting by allowing the user to enter a whole sequence of measurements. The program will end only when the user inputs 0. To do this, I just have to wrap the above algorithm inside a while loop, and make sure that the loop ends when the user inputs a 0. Here's the complete program.
Example 3.4. LengthConverter.cs
/* This program will convert measurements expressed in inches, feet, or yards into each of the possible units of measure. The measurement is input by the user, followed by the unit of measure. The program will continue to read and convert measurements until the user enters an input of 0. */ using System; class LengthConverter { static void Main() { double measurement; // Numerical measurement, input by user. int units; // The unit of measure for the input, also // specified by the user. double inches, feet, yards; // Measurement expressed in // each possible unit of // measure. Console.WriteLine("Enter measurements in inches, feet, or yards."); Console.WriteLine("I will convert your input into the other units"); Console.WriteLine("of measure."); Console.WriteLine(); measurement = 1; // to get us into the loop the first time while (measurement != 0) { // Get the user's input Console.Write("Enter your measurement, or 0 to end: "); measurement = Convert.ToDouble(Console.ReadLine()); if (measurement != 0) { Console.Write("\nSelect units:\n" + "1) inches\n" + "2) feet\n" + "3) yards\n\n" + "Enter your choice (1-3): "); units = Convert.ToInt32(Console.ReadLine()); /* Convert the input measurement to inches. */ if (units == 1) { inches = measurement; } else if (units == 2) { inches = measurement * 12; } else if (units == 3) { inches = measurement * 36; } else { Console.WriteLine("Invalid unit selection."); inches = 0; } if (inches > 0) { /* Convert measurement in inches to feet, yards, and miles. */ feet = inches / 12; yards = inches / 36; /* Output measurement in terms of each unit of measure. */ Console.WriteLine(); Console.WriteLine("That's equivalent to:"); Console.WriteLine(inches + " inches"); Console.WriteLine(feet + " feet"); Console.WriteLine(yards + " yards"); Console.WriteLine(); } // if } // if } // while Console.WriteLine(); Console.WriteLine("OK! Bye for now."); } // main } // class LengthConverter