C SC 160 Chapter 5: Selection Statements
major resource: An Introduction to Object-Oriented Programming with Java, fourth
edition,
Wu, McGraw Hill, 2006
[ previous | schedule | next ]
secondary resource: Programming and Problem Solving with Java, Slack, Brooks/Cole, 2000
if (condition) { // does this if the condition is true }
if (condition) { // does this if the condition is true } else { // does this if the condition is false }
IF condition is Boolean expression
Example: Illustration of both equals() and compareTo(), using String class:
public class StringDemo { public static void main(String[] args) { String str1 = "high"; String str2 = "low"; String message; if (str1.equals(str2)) { message = "the same"; } else { message = "different"; } System.out.println("The two strings are "+message); if (!str1.equals(str2)) { int order = str1.compareTo(str2); if (order < 0) { message = "second"; } else { message = "first"; } System.out.println("The "+message+" string is greater"); } } }
|
|
|
|
|
Here are two situations in which short-circuit evaluation can affect
the operation of a program
1. Boolean expression contains operators having side effects
2. Boolean expression contains operands which could cause run-time
errors.
Short circuit and side effects
Use when one selection depends on another. Control flow can become confusing, and it may be advantageous to draw a chart diagramming the decision logic.
Example: calculating wind chill. There is a temperature threshold above which wind chill calculations do not make sense. If the temperature is below this threshold, then there is a wind speed threshold below which wind chill calculations do not make sense. The logic is thus:
if (temperature < TEMP_THRESHOLD) {
if (windSpeed > WIND_THRESHOLD) {
windChillTemp = <whatever the
formula is>;
} else {
windChillTemp = temperature;
}
} else {
windChillTemp = temperature;
}
Are there other ways of writing this? Here are three others:
windChillTemp = temperature;
if (temperature < TEMP_THRESHOLD) {
if (windSpeed > WIND_THRESHOLD) {
windChillTemp = <whatever the
formula is>;
}
}
windChillTemp = temperature;
if (temperature < TEMP_THRESHOLD && windSpeed > WIND_THRESHOLD)
{
windChillTemp = <whatever the
formula is>;
}
if (temperature < TEMP_THRESHOLD && windSpeed > WIND_THRESHOLD)
{
windChillTemp = <whatever the
formula is>;
} else {
windChillTemp = temperature;
}
Consider this nested-if example:
d = 0;
if (a > b) {
if (b > c) {
d = 1;
}
} else {
d = 2;
}
There appears to be no need to use brackets, since neither of the IFs uses compound statements. Removing brackets results in:
d = 0;
if (a > b)
if (b > c)
d = 1;
else
d = 2;
Suppose a=4, b=2, and c=5. What value is given to d in the first (bracketed) version? What value is given to d in the second (non-bracketed) version?
The $64,000 question is, "Which IF does the ELSE belong to????"
If you guessed "The inner one, (b > c)" you would be correct! The compiler's rule is: absent brackets, ELSE always matches the nearest unfinished IF. Regardless of what you may wish to infer from visually inspecting the indentation. The compiler ignores indentation.
In this case, brackets are required to match the ELSE to the first IF instead of the second.
The lesson, once again, is to use brackets. 'Nuff sed.
Sometimes, multiway decisions need to be made. The classic example is transforming a numerical score into a grade.
if (average >= 90.0) {
grade = 'A';
} else {
if (average >= 80.0) {
grade = 'B';
} else {
if (average >= 70.0) {
grade = 'C';
} else {
if (average >=
60.0) {
grade = 'D';
} else {
grade = 'F';
}
}
}
}
There are many situations in which such deeply-nested logic makes sense. (note that this particular calculation can be carried out using sequential IFs but exercise caution when doing such a thing).
This code was properly indented, but had the logic been a few levels deeper, indentation would result in code creeping further and further to the right side of the page.
This can be rewritten using a technique called "IF ladder" which selectively removes brackets and rearranges some white space. Here is the same code rewritten as an IF ladder:
if (average >= 90.0) {
grade = 'A';
} else if (average >= 80.0) {
grade = 'B';
} else if (average >= 70.0) {
grade = 'C';
} else if (average >= 60.0) {
grade = 'D';
} else {
grade = 'F';
}
It is easier to follow the logic visually.
It is also easier to see that the last ELSE represents a "catch-all" condition. You may wish to use this final ELSE to catch error conditions such as out-of-range values that fall through the cracks.
Java has a construct known as the SWITCH statement that can be used as an alternative to an IF ladder under the following restriction: all of the IF conditions can be expressed as the same variable or expression being equal to a small discrete number of integer or character constants.
This cannot be applied to the previous example because grades are represented by a continuous range of floating point values.
Best demonstrated by example.
Example: in the old (pre-GUI) days, menus were often presented
as numbered lists with the user prompted to enter the number corresponding to
the desired selection. Here is a generic example for software that controls
laboratory testing equipment.
1. view test parameters
2. modify test parameters
3. run a test
4. print test results
5. quit the program
Which option (1-5)? __
The corresponding code, using an IF ladder, is:
int option;
boolean invalidOption = true;
while (invalidOption) {
System.out.println("1. view test parameters");
System.out.println("2. modify test parameters");
System.out.println("3. run a test");
System.out.println("4. print test results");
System.out.println("5. quit the program");
option = Keyboard.readInt("Which option (1-5)? ");
invalidOption = false;
if (option == 1) {
test.viewParameters();
} else if (option == 2) {
test.modifyParameters();
} else if (option == 3) {
test.run();
} else if (option == 4) {
test.printResults();
} else if (option == 5) {
finished = true;
} else {
System.out.print("Invalid Option.
");
System.out.println(" Please
Re-enter.");
invalidOption = true;
}
}
Notice that all the IF conditions meet the SWITCH restrictions, so the IF ladder can be rewritten using SWITCH.
switch (option) {
case 1:
test.viewParameters();
break;
case 2:
test.modifyParameters();
break;
case 3:
test.run();
break;
case 4:
test.printResults();
break;
case 5:
finished = true;
break;
default:
System.out.print("Invalid
Option. ");
System.out.println("
Please Re-enter.");
invalidOption
= true;
break;
}
Notice some of the differences: