Full file at
Chapter 3
Flow of Control
Key Terms
parentheses, p. 95
if-else, p. 95
if-elsewith multiple statements, p. 96
compound statements, p. 96
indenting, p. 98
multiway if-else, p. 98
switch statement, p. 101
controlling expression, p. 102
case labels, p. 102
break, p. 102
default, p. 102
conditional operator, p. 106
Boolean expression, p. 107
lexicographical ordering, p. 110
compareTo, p. 110
compareToIgnoreCase, p. 111
means “and”, p. 113
|| means “or”, p. 113
truth tables, p. 115
Boolean variables in assignments, p. 116
short-circuit evaluation, p. 118
lazy evaluation, p. 118
complete evaluation, p. 118
precedence rules, p. 119
associativity rules, p. 119
higher precedence, p. 119
binding, p. 122
side effects, p. 123
while and do-while compared, p. 126
executing the body zero times, p. 128
algorithm, p. 128
pseudocode, p. 128
sentinel values, p. 131
for statement, p. 132
empty statement, p. 137
infinite loop, p. 138
nested loop, p. 139
break statement, p. 142
continue statement, p. 142
label, p. 142
off-by-one error, p. 144
incremental development, p. 150
cod review, p. 150
pair programming, p. 150
assertion, p. 151
assert, p. 151
assertion check, p. 152
Brief Outline
3.1Branching Mechanism
If-else statements
Omitting the else
Compound Statements
Nested Statements
Multiway if-else Statement
The switch Statement
The Conditional Operator
3.2Boolean Expressions
Simple Boolean Expressions
Lexicographic and Alphabetic Order
Building Boolean Expressions
Evaluating Boolean Expressions
Short-Circuit and Complete Evaluation
Precedence and Associativity Rules
3.3Loops
While statement and do-while statement
Algorithms and Pseudocode
The for Statement
The Comma in for Statements
Nested Loops
The break and continue Statements
The exit Statement
3.4 Debugging
Loop Bugs
Tracing Variables
General Debugging Techniques
Preventive Coding
Assertion Checks
Teaching Suggestions
This chapter discusses flow of control using both selection and iteration. The if-statement and loops are introduced both in this chapter. With both topics in one chapter, it is conceivable that this chapter will take longer for students to work through than many of the others in the text.
Branching, or selection, is introduced using the if-statement, the if-else statement, and the switch statement. Multiple paths and therefore, nested if-else statements are introduced. As the last form of selection available, the conditional operator is introduced at the end of the chapter. The coverage of the conditional operator is optional and can be omitted.
The section on Boolean expressions follows the introduction of selection. However, some instructors might choose to put the second section before the first so that more complicated conditions on if-statements can be introduced right away.
The third section on looping introduces all three looping constructs available inside Java. Loops can pose many challenges for students as illustrated by the Pitfall sections in the chapter.
Having all of these tools available to them, students can write some fairly complex programs at the end of this chapter. However, what usually begins to happen is that students will write code that has errors. Finding these errors can be tedious and time-consuming. The last section on tracing loops, common loop bugs, and debugging is included as a way to help students begin to understand how to track down their errors in code. An option that would be useful to them if it is available would be to introduce and discuss the use of your computing environment’s debugger at this time.
Key Points
If-else statement & Multiway if-else Statement. Thereare many ways to give the program a sense of choice or branching. First, we can use an if-statement by itself without an else. This allows us the option to do something or skip over it. We can also use an if-else statement, which allows us to take one path or another. Lastly, we can use combinations of these to have more than two choices for execution. As the number of paths increase, so does the complexity of code for the students. Students should be able to follow as well as write these more complicated branching code segments.
The switch Statement. The switch also allows for branching, but it has limitations as to what the condition for branching can be. Also, the syntax contains more keywords and is more structured than the if-else. Discussion of the break statement is needed here as the switch will not function properly without the correct use of break between the cases.
The Methods equals and equalsIgnoreCase. Since the equality operator cannot be used on objects, we have the equals method. On Strings, we also have the equalsIgnoreCase method when we are concerned with the content of the String, not necessarily that all of the same words are capitalized within the String. The equalsIgnoreCase can be important especially when taking user input. If you ask the user to input a certain letter as a choice, some of them might instinctively make that letter capital. If you are not ignoring case, equals may return false even if the user has pressed the correct key.
The “and” Operator &. In the section on Boolean Expressions, we introduce the Boolean operators & and ||. It is important for students to realize when the & operator returns true and when it returns false.
The “or” Operator. The introduction of the || operator once again compels students to understand when it will return true and when it will return false in their programs.
The Boolean Values are true and false. In Java, the values for the boolean data type are constants that are defined within the system. Therefore, they must always be written in all lower case as true or false.
true and false are not Numbers. This point coincides with the last one because in some other languages, true and false can be represented as the numbers 1 and 0. However, in Java this is not the case and trying to use a number where the system expects a boolean value will cause a compiler error. You also can not typecast a number to a boolean or a boolean to a number.
Rules for Evaluating Expressions. The precedence and associativity rules for evaluating expressions are given in charts within this chapter. Understanding how to evaluate a boolean expression is as important as how to evaluate the arithmetic expressions in Chapter 1.
Syntax for while and do-while Statements. The while and do-while loops are the indefinite loops supported by Java. They also illustrate the differences between an entry-test and an exit-test loop.
The for Statement. The for loop is a definite loop or counting loop that is also an entry-test loop. The syntax for the for loop is different from the other two loops and has a loop counter built right into the construct. However, in Java, we can have more than one statement inside the parts of the for-loop separated by commas and we can also leave parts empty, which can create many different results when using a for-loop.
Assertion Checking. The assert statement can help you ensure that a particular condition is true at a given time in a program. You can use this feature to make sure that a variable is positive at a given point in the program, for example. You need to turn on assertion checking to make Java execute the assert statements in the program. If at any time, an assertion fails, the program will exit with an error.
Tips
Placing of Braces. The book introduces its way of placing braces for an if-statement. There are other options, which are presented. Style will vary on what an instructor/programmer wants. There is no correct way to place your braces. However, having braces or not definitely makes a difference in the code.
Naming boolean Variables. It is helpful to name boolean variables with names that will indicate what they are holding the values for. Names like isFull, isEmpty, etc will help distinguish what it is that you are holding the value for and make the code that is written easier for others to read and understand.
End of Input Character. This tip is optional and discusses how the user can indicate the end of input to the program. This involves the introduction of control characters in the system and uses the ConsoleIn classes in the example. Therefore, instructors that did not cover ConsoleIn will not be able to cover this point to its entirety, but could discuss how the program will know when the user is done entering input to the program.
Repeat N Times Loops. The easiest way to repeat something a definitive number of times is to use the for-loop. The loop counter does not have to be referenced in the loop body, so it can simply just keep track of how many times the loop has been executed.
Pitfalls
Forgetting a break in a Switch Statement. This is an important pitfall because of the fact that the compiler will not tell you that you have forgotten it. Simply, the program will not execute correctly. Therefore, it is important to show what will happen if the break statements are not properly inserted in the switch statement.
Using = Place of ==. Now that we have introduced the notion of equality, one element that is of confusion is that the double equals sign is what actually tests for equality, while the single equals is assignment. This is different than in mathematics and can be confusing for students. In some instances, the confusion of the two may not even cause a compiler error, but once again the program will not run correctly.
Using == with Strings. Since Strings are objects, the equality operator does not always give the correct result and should not be used to check for two Strings that contain the same character sequence. The equals method is introduced as the way to achieve the correct answer always to this problem.
Strings of Inequalities. Unlike in mathematics, where x < 10 < y is understood, Java will not be able to understand the previous statement. Therefore, it needs to be broken up into two parts, x < 10 & 10 < y. Students who fail to do this will usually receive a compiler error.
Extra Semicolon in a for Statement. The extra semicolon at the end of the for loop will not cause a compiler error, but will cause the loop to execute the proper amount of times with an empty loop body. This can also arise with the while loop. However, the do-while needs the semicolon at the end of its condition to work properly.
Infinite Loops. It is quite possible and quite common to accidentally write a loop that never ends because the condition on the loop will never become false. These infinite loops will generally cause errors to be generated when the program is run and can be difficult to spot. It is helpful in these cases to use the technique of tracing variables to find the problem.
Examples
State Income Tax. In this example we see how to use multiway if-else statements with the example of computing how much state income tax one owes. Depending on your level of income, the program gives the amount of tax that should be paid. This problem’s solution is given in the text in Display 3.1.
Averaging a List of Scores. The second example in this chapter looks at a program that will average a list of scores inputted by the user. This example brings together the input/output from last chapter and the looping that was introduced in this chapter. The code is once again presented in Display 3.8.
Programming Projects Answers
1.
/**
* Question1.java
*
* This program uses the Babylonian algorithm, and keeps looping
* until the current guess is within 1% of the previous guess value
* to estimate the square root of a number n.
*
* Created: Sat Mar 05, 2005
*
* @author Kenrick Mock
* @version 1
*/
import java.util.Scanner;
public class Question1
{
public static void main(String[] args)
{
// Variable declarations
Scanner scan = new Scanner(System.in);
double guess, previousGuess;
int n;
double r;
System.out.println("This program estimate square roots.");
System.out.println("Enter an integer to estimate the square root of: ");
n = scan.nextInt();
// Initial guess
guess = (double) n/2;
previousGuess = n;
// Keep looping as long as (oldguess - guess) / old guess is > 0.01.
// The ratio should always be positive since we approach the
// square root starting at n/2 and work our way down to the actual square root.
while (((previousGuess-guess)/previousGuess) > 0.01)
{
r = (double) n / guess;
previousGuess = guess;
guess = (guess+r)/2;
System.out.println("Current guess: " + guess);
}
System.out.printf("\nThe estimated square root of %d is %6.2f\n", n , guess);
}
} // Question1
2.
/**
* Question2.java
*
* This program simulates 10,000 games of craps.
* It counts the number of wins and losses and outputs the probability
* of winning.
*
* Created: Sat Mar 05, 2005
*
* @author Kenrick Mock
* @version 1
*/
public class Question2
{
private static final int NUM_GAMES = 10000;
/**
* This is the main method. It loops 10,000 times, each simulate
* a game of craps. Math.random() is used to get a random number,
* and we simulate rolling two dice (Math.random() * 6 + 1 simulates
* a single die).
*/
public static void main(String[] args)
{
// Variable declarations
int numWins = 0;
int numLosses = 0;
int i;
int roll;
int point;
// Play 10,000 games
for (i=0; i<NUM_GAMES; i++)
{
// Simulate rolling the two dice, with values from 1-6
roll = (int) (Math.random() * 6) + (int) (Math.random() * 6) + 2;
// Check for initial win or loss
if ((roll == 7) || (roll == 11))
{
numWins++;
}
else if ((roll==2) || (roll==3) || (roll==12))
{
numLosses++;
}
else
{
// Continue rolling until we get the point or 7
point = roll;
do
{
roll = (int) (Math.random() * 6) + (int) (Math.random() * 6) + 2;
if (roll==7)
{
numLosses++;
}
else if (roll==point)
{
numWins++;
}
} while ((point != roll) & (roll != 7));
}
}
// Output probability of winning
System.out.println("In the simulation, we won " + numWins +
" times and lost " + numLosses + " times, " +
" for a probability of " +
(double) (numWins) / (numWins+numLosses));
}
} // Question2
3.
/**
* Question3.java
*
* This program estimates the height of a child using
* the formula: H(male) = (H(mother)*13/12 + H(father))/2
* H(female) = (H(father)*12/13 + H(mother))/2
*
* All heights are in inches. A function takes as input
* parameters the heights in inches and outputs the height in inches.
* Conversions are made by allowing the user to input the height
* in feet and inches.
*
* Created: Sat Mar 05, 2005
*
* @author Kenrick Mock
* @version 1
*/
import java.util.Scanner;
public class Question3
{
/**
* This is the main method. It loops repeatedly until the
* user stops by not entering "Y" to continue using a do-while loop.
* Input is accomplished through the Scanner class.
*/
public static void main(String[] args)
{
// Variable declarations
int gender;// 0=male, 1=female
int mom_feet, mom_inches;
int dad_feet, dad_inches;
int child_total_inches;
String doAgain;// Set to "Y" if user wants to try again
Scanner scan = new Scanner(System.in);
do
{
System.out.println("Enter the gender of your future child. " +
"Use 1 for female, 0 for male.");
gender = scan.nextInt();
System.out.println("Enter the height in feet then the height " +
"in inches of the mom.");
mom_feet = scan.nextInt();
mom_inches = scan.nextInt();
System.out.println("Enter the height in feet then the height " +
"in inches of the dad.");
dad_feet = scan.nextInt();
dad_inches = scan.nextInt();
// Convert input to all inches and get the estimate for the child
int mother_height = (mom_feet*12)+mom_inches;
int father_height = (dad_feet*12)+dad_inches;
if (gender==0)
{
// Male child formula
child_total_inches = ((mother_height * 13 / 12)
+ father_height)/2;
}
else
{
// Female child formula
child_total_inches = ((father_height * 12 / 13)
+ mother_height)/2;
}
// Output the estimated height
System.out.println("Your future child is estimated to grow to " +
child_total_inches / 12 + " feet and " +
child_total_inches % 12 + " inches.");
System.out.println();
System.out.println("Enter 'Y' to run again, anything else to exit.");
scan.nextLine();// Skip newline remaining from nextInt
doAgain = scan.nextLine();
}
while (doAgain.equals("Y"));
}
} // Question3
4.
/**
* Question4.java
*
*
* Created: Sun Nov 09 16:00:30 2003
* Modified: Sat Mar 05 2005, Kenrick Mock
*
* @author AdrienneDecker
* @version 2
*/
import java.util.Scanner;
import java.text.NumberFormat;
public class Question4
{
public static void main (String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter the cost of the item " +
"in the present as a decimal with"
+ " no dollar sign:");
double price = keyboard.nextDouble();
System.out.println("Enter the number of years from now"
+ " you will be purchasing the item:");
int years = keyboard.nextInt();
System.out.println("Enter the rate of inflation as "
+ "a decimal number.\nFor " +
"example, enter 5.6 for 5.6%");
double inflation = keyboard.nextDouble() / 100;
double newPrice = price;
for ( int i = 0; i < years; i++ )
{
newPrice = newPrice + (newPrice * inflation);
} // end of for ()
NumberFormat moneyFormater = NumberFormat.getCurrencyInstance();
System.out.println("in " + years + " years, your item that costs "
+ moneyFormater.format(price) + " now, will cost "
+ moneyFormater.format(newPrice));
} // end of main ()
}// Question4
5.
/**
* Question5.java
*
* Created: Sun Nov 09 16:14:44 2003
* Modified: Sat Mar 05 2005, Kenrick Mock
*
* @author Adrienne Decker
* @version 2
*/
import java.text.NumberFormat;
public class Question5
{
public static final int STEREO_COST = 1000;
public static final double YEARLY_INTEREST = 0.18;
public static final double MONTHLY_INTEREST = 0.015;
public static final int MONTHLY_PAYMENT = 50;
public static void main(String[] args)
{
NumberFormat moneyFormater = NumberFormat.getCurrencyInstance();
int monthNumber = 1;
double amountRemaining = STEREO_COST;
double interestAccrued = 0;
double diff = 0;
double totalInterestPaid = 0;
while ( amountRemaining > 0.0)
{
//System.out.println("For month number " + monthNumber);
/*System.out.println("You will pay "