C. Control Statements


Objectives

In this appendix you’ll:

Image Learn basic problem-solving techniques.

Image Develop algorithms through the process of top-down, stepwise refinement.

Image Use the if and if...else selection statements to choose among alternative actions.

Image Use the while repetition statement to execute statements in a program repeatedly.

Image Use counter-controlled repetition and sentinel-controlled repetition.

Image Use the compound assignment, increment and decrement operators.

Image Learn the essentials of counter-controlled repetition.

Image Use the for and do...while repetition statements to execute statements in a program repeatedly.

Image Implement multiple selection using the switch statement.

Image Use the break and continue statements.

Image Use the logical operators in conditional expressions.


C.1 Introduction

In this appendix, we discuss the theory and principles of structured programming. The concepts presented here are crucial in building classes and manipulating objects. We introduce Java’s compound assignment, increment and decrement operators, and we discuss the portability of Java’s primitive types. We demonstrate Java’s for, do...while and switch statements. Through a series of short examples using while and for, we explore the essentials of counter-controlled repetition. We create a version of class GradeBook that uses a switch statement to count the number of A, B, C, D and F grade equivalents in a set of numeric grades entered by the user. We introduce the break and continue program-control statements. We discuss Java’s logical operators, which enable you to use more complex conditional expressions in control statements.

C.2 Algorithms

Any computing problem can be solved by executing a series of actions in a specific order. A procedure for solving a problem in terms of

1. the actions to execute and

2. the order in which these actions execute

is called an algorithm. Correctly specifying the order in which the actions execute is important.

Consider the “rise-and-shine algorithm” followed by one executive for getting out of bed and going to work: (1) Get out of bed; (2) take off pajamas; (3) take a shower; (4) get dressed; (5) eat breakfast; (6) carpool to work. This routine gets the executive to work well prepared to make critical decisions. Suppose that the same steps are performed in a slightly different order: (1) Get out of bed; (2) take off pajamas; (3) get dressed; (4) take a shower; (5) eat breakfast; (6) carpool to work. In this case, our executive shows up for work soaking wet. Specifying the order in which statements (actions) execute in a program is called program control. This appendix investigates program control using Java’s control statements.

C.3 Pseudocode

Pseudocode is an informal language that helps you develop algorithms without having to worry about the strict details of Java language syntax. The pseudocode we present is particularly useful for developing algorithms that will be converted to structured portions of Java programs. Pseudocode is similar to everyday English—it’s convenient and user friendly, but it’s not an actual computer programming language.

Pseudocode does not execute on computers. Rather, it helps you “think out” a program before attempting to write it in a programming language, such as Java. Pseudocode normally describes only statements representing the actions that occur after you convert a program from pseudocode to Java and the program is run on a computer. Such actions might include input, output or calculations.

C.4 Control Structures

Normally, statements in a program are executed one after the other in the order in which they’re written. This process is called sequential execution. Various Java statements, which we’ll soon discuss, enable you to specify that the next statement to execute is not necessarily the next one in sequence. This is called transfer of control.

During the 1960s, it became clear that the indiscriminate use of transfers of control was the root of much difficulty experienced by software development groups. The blame was pointed at the goto statement (used in most programming languages of the time), which allows you to specify a transfer of control to one of a wide range of destinations in a program. The term structured programming became almost synonymous with “goto elimination.” [Note: Java does not have a goto statement; however, the word goto is reserved by Java and should not be used as an identifier in programs.]

Research had demonstrated that programs could be written without any goto statements. The challenge of the era for programmers was to shift their styles to “goto-less programming.” Not until the 1970s did most programmers start taking structured programming seriously. The results were impressive. The key to these successes was that structured programs were clearer, easier to debug and modify, and more likely to be bug free in the first place.

Researchers demonstrated that all programs could be written in terms of only three control structures—the sequence structure, the selection structure and the repetition structure. When we introduce Java’s control structure implementations, we’ll refer to them in the terminology of the Java Language Specification as “control statements.”

Sequence Structure in Java

The sequence structure is built into Java. Unless directed otherwise, the computer executes Java statements one after the other in the order in which they’re written—that is, in sequence. Java lets you have as many actions as you want in a sequence structure. As we’ll soon see, anywhere a single action may be placed, we may place several actions in sequence.

Selection Statements in Java

Java has three types of selection statements. The if statement either performs (selects) an action, if a condition is true, or skips it, if the condition is false. The if...else statement performs an action if a condition is true and performs a different action if the condition is false. The switch statement performs one of many different actions, depending on the value of an expression.

The if statement is a single-selection statement because it selects or ignores a single action (or, as we’ll soon see, a single group of actions). The if...else statement is called a double-selection statement because it selects between two different actions (or groups of actions). The switch statement is called a multiple-selection statement because it selects among many different actions (or groups of actions).

Repetition Statements in Java

Java provides three repetition statements (also called looping statements) that enable programs to perform statements repeatedly as long as a condition (called the loop-continuation condition) remains true. The repetition statements are the while, do...while and for statements. The while and for statements perform the action (or group of actions) in their bodies zero or more times—if the loop-continuation condition is initially false, the action (or group of actions) will not execute. The do...while statement performs the action (or group of actions) in its body one or more times. The words if, else, switch, while, do and for are Java keywords.

C.5 if Single-Selection Statement

Programs use selection statements to choose among alternative courses of action. For example, suppose that the passing grade on an exam is 60. The pseudocode statement

If student’s grade is greater than or equal to 60
      Print "Passed"

determines whether the condition “student’s grade is greater than or equal to 60” is true. If so, “Passed” is printed, and the next pseudocode statement in order is “performed.” If the condition is false, the Print statement is ignored, and the next pseudocode statement in order is performed.

The preceding pseudocode If statement easily may be converted to the Java statement

if ( studentGrade >= 60 )
    System.out.println( "Passed" );

C.6 if...else Double-Selection Statement

The if single-selection statement performs an indicated action only when the condition is true; otherwise, the action is skipped. The if...else double-selection statement allows you to specify an action to perform when the condition is true and a different action when the condition is false. For example, the pseudocode statement

If student’s grade is greater than or equal to 60
      Print "Passed"
Else
      Print "Failed"

prints “Passed” if the student’s grade is greater than or equal to 60, but prints “Failed” if it’s less than 60. In either case, after printing occurs, the next pseudocode statement in sequence is “performed.”

The preceding If...Else pseudocode statement can be written in Java as

if ( grade >= 60 )
   System.out.println( "Passed" );
else
   System.out.println( "Failed" );

Conditional Operator (?:)

Java provides the conditional operator (?:) that can be used in place of an if...else statement. This is Java’s only ternary operator (operator that takes three operands). Together, the operands and the ?: symbol form a conditional expression. The first operand (to the left of the ?) is a boolean expression (i.e., a condition that evaluates to a boolean value—true or false), the second operand (between the ? and :) is the value of the conditional expression if the boolean expression is true and the third operand (to the right of the :) is the value of the conditional expression if the boolean expression evaluates to false. For example, the statement

System.out.println( studentGrade >= 60 ? "Passed" : "Failed" );

prints the value of println’s conditional-expression argument. The conditional expression in this statement evaluates to the string "Passed" if the boolean expression studentGrade >= 60 is true and to the string "Failed" if it’s false. Thus, this statement with the conditional operator performs essentially the same function as the if...else statement shown earlier in this section. The precedence of the conditional operator is low, so the entire conditional expression is normally placed in parentheses.

Nested if...else Statements

A program can test multiple cases by placing if...else statements inside other if...else statements to create nested if...else statements. For example, the following pseudocode represents a nested if...else that prints A for exam grades greater than or equal to 90, B for grades 80 to 89, C for grades 70 to 79, D for grades 60 to 69 and F for all other grades:

If student’s grade is greater than or equal to 90
       Print "A"
else
      If student’s grade is greater than or equal to 80
            Print "B"
      else
            If student’s grade is greater than or equal to 70
                  Print "C"
            else
                  If student’s grade is greater than or equal to 60
                        Print "D"
                  else
                        Print "F"

This pseudocode may be written in Java as

if ( studentGrade >= 90 )
   System.out.println( "A" );
else
   if ( studentGrade >= 80 )
      System.out.println( "B" );
   else
      if ( studentGrade >= 70 )
         System.out.println( "C" );
      else
         if ( studentGrade >= 60 )
            System.out.println( "D" );
         else
            System.out.println( "F" );

If variable studentGrade is greater than or equal to 90, the first four conditions in the nested if...else statement will be true, but only the statement in the if part of the first if...else statement will execute. After that statement executes, the else part of the “outermost” if...else statement is skipped. Many programmers prefer to write the preceding nested if...else statement as

if ( studentGrade >= 90 )
   System.out.println( "A" );
else if (studentGrade >= 80 )
   System.out.println( "B" );
else if ( studentGrade >= 70 )
   System.out.println( "C" );
else if ( studentGrade >= 60 )
   System.out.println( "D" );
else
   System.out.println( "F" );

The two forms are identical except for the spacing and indentation, which the compiler ignores. The latter form avoids deep indentation of the code to the right.

Blocks

The if statement normally expects only one statement in its body. To include several statements in the body of an if (or the body of an else for an if...else statement), enclose the statements in braces. Statements contained in a pair of braces form a block. A block can be placed anywhere in a program that a single statement can be placed. The following example includes a block in the else part of an if...else statement:

if ( grade >= 60 )
   System.out.println( "Passed" );
else
{
   System.out.println( "Failed" );
   System.out.println( "You must take this course again." );
}

In this case, if grade is less than 60, the program executes both statements in the body of the else and prints

Failed
You must take this course again.

Note the braces surrounding the two statements in the else clause. These braces are important. Without the braces, the statement

System.out.println( "You must take this course again." );

would be outside the body of the else part of the if...else statement and would execute regardless of whether the grade was less than 60.

Syntax errors (e.g., when one brace in a block is left out of the program) are caught by the compiler. A logic error (e.g., when both braces in a block are left out of the program) has its effect at execution time. A fatal logic error causes a program to fail and terminate prematurely. A nonfatal logic error allows a program to continue executing but causes it to produce incorrect results.

C.7 while Repetition Statement

As an example of Java’s while repetition statement, consider a program segment that finds the first power of 3 larger than 100. Suppose that the int variable product is initialized to 3. After the following while statement executes, product contains the result:

while ( product <= 100 )
   product = 3 * product;

When this while statement begins execution, the value of variable product is 3. Each iteration of the while statement multiplies product by 3, so product takes on the values 9, 27, 81 and 243 successively. When variable product becomes 243, the while-statement condition—product <= 100—becomes false. This terminates the repetition, so the final value of product is 243. At this point, program execution continues with the next statement after the while statement.


Image Common Programming Error C.1

Not providing in the body of a while statement an action that eventually causes the condition in the while to become false normally results in a logic error called an infinite loop (the loop never terminates).


C.8 Case Study: Counter-Controlled Repetition

To illustrate how algorithms are developed, we modify the GradeBook class of Appendix B to solve two variations of a problem that averages student grades. Consider the following problem statement:

A class of ten students took a quiz. The grades (integers in the range 0 to 100) for this quiz are available to you. Determine the class average on the quiz.

The class average is equal to the sum of the grades divided by the number of students. The algorithm for solving this problem on a computer must input each grade, keep track of the total of all grades input, perform the averaging calculation and print the result.

Pseudocode Algorithm with Counter-Controlled Repetition

Let’s use pseudocode to list the actions to execute and specify the order in which they should execute. We use counter-controlled repetition to input the grades one at a time. This technique uses a variable called a counter (or control variable) to control the number of times a set of statements will execute. In this example, repetition terminates when the counter exceeds 10. This section presents a fully developed pseudocode algorithm (Fig. C.1) and a version of class GradeBook (Fig. C.2) that implements the algorithm in a Java method. We then present an application (Fig. C.3) that demonstrates the algorithm in action.

Note the references in the algorithm of Fig. C.1 to a total and a counter. A total is a variable used to accumulate the sum of several values. A counter is a variable used to count—in this case, the grade counter indicates which of the 10 grades is about to be entered by the user. Variables used to store totals are normally initialized to zero before being used in a program.


 1  Set total to zero
 2  Set grade counter to one
 3
 4  While grade counter is less than or equal to ten
 5     Prompt the user to enter the next grade
 6     Input the next grade
 7     Add the grade into the total
 8     Add one to the grade counter
 9
10  Set the class average to the total divided by ten
11  Print the class average


Fig. C.1 | Pseudocode algorithm that uses counter-controlled repetition to solve the class-average problem.

Implementing Counter-Controlled Repetition in Class GradeBook

Class GradeBook (Fig. C.2) contains a constructor (lines 11–14) that assigns a value to the class’s instance variable courseName (declared in line 8). Lines 17–20, 23–26 and 29–34 declare methods setCourseName, getCourseName and displayMessage, respectively. Lines 37–66 declare method determineClassAverage, which implements the class-averaging algorithm described by the pseudocode in Fig. C.1.

Line 40 declares and initializes Scanner variable input, which is used to read values entered by the user. Lines 42–45 declare local variables total, gradeCounter, grade and average to be of type int. Variable grade stores the user input.


 1  // Fig. C.2: GradeBook.java
 2  // GradeBook class that solves the class-average problem using
 3  // counter-controlled repetition.
 4  import java.util.Scanner; // program uses class Scanner
 5
 6  public class GradeBook
 7  {
 8     private String courseName; // name of course this GradeBook represents
 9
10     // constructor initializes courseName
11     public GradeBook( String name )
12     {
13        courseName = name; // initializes courseName
14     } // end constructor
15
16     // method to set the course name
17     public void setCourseName( String name )
18     {
19        courseName = name; // store the course name
20     } // end method setCourseName
21
22     // method to retrieve the course name
23     public String getCourseName()
24     {
25        return courseName;
26     } // end method getCourseName
27
28     // display a welcome message to the GradeBook user
29     public void displayMessage()
30     {
31        // getCourseName gets the name of the course
32        System.out.printf( "Welcome to the grade book for %s! ",
33           getCourseName() );
34     } // end method displayMessage
35
36     // determine class average based on 10 grades entered by user
37     public void determineClassAverage()
38     {
39        // create Scanner to obtain input from command window
40        Scanner input = new Scanner( System.in );
41
42        int total; // sum of grades entered by user
43        int gradeCounter; // number of the grade to be entered next
44        int grade; // grade value entered by user
45        int average; // average of grades
46
47        // initialization phase
48        total = 0; // initialize total
49        gradeCounter = 1; // initialize loop counter
50
51        // processing phase uses counter-controlled repetition
52        while ( gradeCounter <= 10 ) // loop 10 times
53        {
54           System.out.print( "Enter grade: " ); // prompt
55           grade = input.nextInt(); // input next grade
56           total = total + grade; // add grade to total
57           gradeCounter = gradeCounter + 1; // increment counter by 1
58        } // end while
59
60        // termination phase
61        average = total / 10; // integer division yields integer result
62
63        // display total and average of grades
64        System.out.printf( " Total of all 10 grades is %d ", total );
65        System.out.printf( "Class average is %d ", average );
66     } // end method determineClassAverage
67  } // end class GradeBook


Fig. C.2 | GradeBook class that solves the class-average problem using counter-controlled repetition.

The declarations (in lines 42–45) appear in the body of method determineClassAverage. A local variable’s declaration must appear before the variable is used in that method. A local variable cannot be accessed outside the method in which it’s declared.

The assignments (in lines 48–49) initialize total to 0 and gradeCounter to 1. Line 52 indicates that the while statement should continue looping (also called iterating) as long as gradeCounter’s value is less than or equal to 10. While this condition remains true, the while statement repeatedly executes the statements between the braces that delimit its body (lines 54–57).

Line 54 displays the prompt "Enter grade: ". Line 55 reads the grade entered by the user and assigns it to variable grade. Then line 56 adds the new grade entered by the user to the total and assigns the result to total, which replaces its previous value.

Line 57 adds 1 to gradeCounter to indicate that the program has processed a grade and is ready to input the next grade from the user. Incrementing gradeCounter eventually causes it to exceed 10. Then the loop terminates, because its condition (line 52) becomes false.

When the loop terminates, line 61 performs the averaging calculation and assigns its result to the variable average. Line 64 uses System.out’s printf method to display the text "Total of all 10 grades is " followed by variable total’s value. Line 65 then uses printf to display the text "Class average is " followed by variable average’s value. After reaching line 66, method determineClassAverage returns control to the calling method (i.e., main in GradeBookTest of Fig. C.3).

Class GradeBookTest

Class GradeBookTest (Fig. C.3) creates an object of class GradeBook (Fig. C.2) and demonstrates its capabilities. Lines 10–11 of Fig. C.3 create a new GradeBook object and assign it to variable myGradeBook. The String in line 11 is passed to the GradeBook constructor (lines 11–14 of Fig. C.2). Line 13 calls myGradeBook’s displayMessage method to display a welcome message to the user. Line 14 then calls myGradeBook’s determineClassAverage method to allow the user to enter 10 grades, for which the method then calculates and prints the average—the method performs the algorithm shown in Fig. C.1.


 1  // Fig. C.3: GradeBookTest.java
 2  // Create GradeBook object and invoke its determineClassAverage method.
 3
 4  public class GradeBookTest
 5  {
 6     public static void main( String[] args )
 7     {
 8        // create GradeBook object myGradeBook and
 9        // pass course name to constructor
10        GradeBook myGradeBook = new GradeBook(
11           "CS101 Introduction to Java Programming" );
12
13        myGradeBook.displayMessage(); // display welcome message
14        myGradeBook.determineClassAverage(); // find average of 10 grades
15     } // end main
16  } // end class GradeBookTest


Welcome to the grade book for
CS101 Introduction to Java Programming!

Enter grade: 67
Enter grade: 78
Enter grade: 89
Enter grade: 67
Enter grade: 87
Enter grade: 98
Enter grade: 93
Enter grade: 85
Enter grade: 82
Enter grade: 100

Total of all 10 grades is 846
Class average is 84


Fig. C.3 | GradeBookTest class creates an object of class GradeBook (Fig. C.2) and invokes its determineClassAverage method.

Notes on Integer Division and Truncation

The averaging calculation performed by method determineClassAverage in response to the method call at line 14 in Fig. C.3 produces an integer result. The program’s output indicates that the sum of the grade values in the sample execution is 846, which, when divided by 10, should yield the floating-point number 84.6. However, the result of the calculation total / 10 (line 61 of Fig. C.2) is the integer 84, because total and 10 are both integers. Dividing two integers results in integer division—any fractional part of the calculation is lost (i.e., truncated).

C.9 Case Study: Sentinel-Controlled Repetition

Let’s generalize Section C.8’s class-average problem. Consider the following problem:

Develop a class-averaging program that processes grades for an arbitrary number of students each time it’s run.

In the previous class-average example, the problem statement specified the number of students, so the number of grades (10) was known in advance. In this example, no indication is given of how many grades the user will enter during the program’s execution. The program must process an arbitrary number of grades. How can it determine when to stop reading grades from the user? How will it know when to calculate and print the class average?

One way to solve this problem is to use a special value called a sentinel value (also called a signal value, a dummy value or a flag value) to indicate “end of data entry.” The user enters grades until all legitimate grades have been entered. The user then types the sentinel value to indicate that no more grades will be entered. Sentinel-controlled repetition is often called indefinite repetition because the number of repetitions is not known before the loop begins executing.

Clearly, a sentinel value must be chosen that cannot be confused with an acceptable input value. Grades on a quiz are nonnegative integers, so –1 is an acceptable sentinel value for this problem. Thus, a run of the class-average program might process a stream of inputs such as 95, 96, 75, 74, 89 and —1. The program would then compute and print the class average for the grades 95, 96, 75, 74 and 89; since —1 is the sentinel value, it should not enter into the averaging calculation. The complete pseudocode for the class-average problem is shown in Fig. C.4.


 1  Initialize total to zero
 2  Initialize counter to zero
 3
 4  Prompt the user to enter the first grade
 5  Input the first grade (possibly the sentinel)
 6
 7  While the user has not yet entered the sentinel
 8     Add this grade into the running total
 9     Add one to the grade counter
10     Prompt the user to enter the next grade
11     Input the next grade (possibly the sentinel)
12
13  If the counter is not equal to zero
14     Set the average to the total divided by the counter
15     Print the average
16  else
17     Print "No grades were entered"


Fig. C.4 | Class-average problem pseudocode algorithm with sentinel-controlled repetition.

Implementing Sentinel-Controlled Repetition in Class GradeBook

Figure C.5 shows the Java class GradeBook containing method determineClassAverage that implements the pseudocode algorithm of Fig. C.4. Although each grade is an integer, the averaging calculation is likely to produce a number with a decimal point—in other words, a real (i.e., floating-point) number. The type int cannot represent such a number, so this class uses type double to do so.


 1  // Fig. C.5: GradeBook.java
 2  // GradeBook class that solves the class-average problem using
 3  // sentinel-controlled repetition.
 4  import java.util.Scanner; // program uses class Scanner
 5
 6  public class GradeBook
 7  {
 8     private String courseName; // name of course this GradeBook represents
 9
10     // constructor initializes courseName
11     public GradeBook( String name )
12     {
13        courseName = name; // initializes courseName
14     } // end constructor
15
16     // method to set the course name
17     public void setCourseName( String name )
18     {
19        courseName = name; // store the course name
20     } // end method setCourseName
21
22     // method to retrieve the course name
23     public String getCourseName()
24     {
25        return courseName;
26     } // end method getCourseName
27
28     // display a welcome message to the GradeBook user
29     public void displayMessage()
30     {
31        // getCourseName gets the name of the course
32        System.out.printf( "Welcome to the grade book for %s! ",
33           getCourseName() );
34     } // end method displayMessage
35
36     // determine the average of an arbitrary number of grades
37     public void determineClassAverage()
38     {
39        // create Scanner to obtain input from command window
40        Scanner input = new Scanner( System.in );
41
42        int total; // sum of grades
43        int gradeCounter; // number of grades entered
44        int grade; // grade value
45        double average; // number with decimal point for average
46
47        // initialization phase
48        total = 0; // initialize total
49        gradeCounter = 0; // initialize loop counter
50
51        // processing phase
52        // prompt for input and read grade from user      
53        System.out.print( "Enter grade or -1 to quit: " );
54        grade = input.nextInt();                          
55
56        // loop until sentinel value read from user
57        while ( grade != -1 )
58        {
59           total = total + grade; // add grade to total
60           gradeCounter = gradeCounter + 1; // increment counter
61
62           // prompt for input and read next grade from user 
63           System.out.print( "Enter grade or -1 to quit: " );
64           grade = input.nextInt();                          
65        } // end while
66
67        // termination phase
68        // if user entered at least one grade...
69        if ( gradeCounter != 0 )
70        {
71           // calculate average of all grades entered
72           average = (double) total / gradeCounter;
73
74           // display total and average (with two digits of precision)
75           System.out.printf( " Total of the %d grades entered is %d ",
76              gradeCounter, total );
77           System.out.printf( "Class average is %.2f ", average );
78        } // end if
79        else // no grades were entered, so output appropriate message
80           System.out.println( "No grades were entered" );
81     } // end method determineClassAverage
82  } // end class GradeBook


Fig. C.5 | GradeBook class that solves the class-average problem using sentinel-controlled repetition.

In this example, we see that control statements may be stacked on top of one another (in sequence). The while statement (lines 57–65) is followed in sequence by an if...else statement (lines 69–80). Much of the code in this program is identical to that in Fig. C.2, so we concentrate on the new concepts.

Line 45 declares double variable average, which allows us to store the class average as a floating-point number. Line 49 initializes gradeCounter to 0, because no grades have been entered yet. To keep an accurate record of the number of grades entered, the program increments gradeCounter only when the user enters a valid grade.

Program Logic for Sentinel-Controlled Repetition vs. Counter-Controlled Repetition

Compare the program logic for sentinel-controlled repetition in this application with that for counter-controlled repetition in Fig. C.2. In counter-controlled repetition, each iteration of the while statement (e.g., lines 52–58 of Fig. C.2) reads a value from the user, for the specified number of iterations. In sentinel-controlled repetition, the program reads the first value (lines 53–54 of Fig. C.5) before reaching the while. This value determines whether the program’s flow of control should enter the body of the while. If the condition of the while is false, the user entered the sentinel value, so the body of the while does not execute (i.e., no grades were entered). If, on the other hand, the condition is true, the body begins execution, and the loop adds the grade value to the total (line 59). Then lines 63–64 in the loop body input the next value from the user. Next, program control reaches the closing right brace of the loop body at line 65, so execution continues with the test of the while’s condition (line 57). The condition uses the most recent grade input by the user to determine whether the loop body should execute again. The value of variable grade is always input from the user immediately before the program tests the while condition. This allows the program to determine whether the value just input is the sentinel value before the program processes that value (i.e., adds it to the total). If the sentinel value is input, the loop terminates, and the program does not add —1 to the total.

After the loop terminates, the if...else statement at lines 69–80 executes. The condition at line 69 determines whether any grades were input. If none were input, the else part (lines 79–80) of the if...else statement executes and displays the message "No grades were entered" and the method returns control to the calling method.

Explicitly and Implicitly Converting Between Primitive Types

If at least one grade was entered, line 72 of Fig. C.5 calculates the average of the grades. Recall from Fig. C.2 that integer division yields an integer result. Even though variable average is declared as a double (line 45), the calculation

average = total / gradeCounter;

loses the fractional part of the quotient before the result of the division is assigned to average. This occurs because total and gradeCounter are both integers, and integer division yields an integer result. To perform a floating-point calculation with integer values, we must temporarily treat these values as floating-point numbers for use in the calculation. Java provides the unary cast operator to accomplish this task. Line 72 uses the (double) cast operator—a unary operator—to create a temporary floating-point copy of its operand total (which appears to the right of the operator). Using a cast operator in this manner is called explicit conversion or type casting. The value stored in total is still an integer.

The calculation now consists of a floating-point value (the temporary double version of total) divided by the integer gradeCounter. Java knows how to evaluate only arithmetic expressions in which the operands' types are identical. To ensure that the operands are of the same type, Java performs an operation called promotion (or implicit conversion) on selected operands. For example, in an expression containing values of the types int and double, the int values are promoted to double values for use in the expression. In this example, the value of gradeCounter is promoted to type double, then the floating-point division is performed and the result of the calculation is assigned to average. As long as the (double) cast operator is applied to any variable in the calculation, the calculation will yield a double result.

A cast operator is formed by placing parentheses around any type’s name. The operator is a unary operator (i.e., an operator that takes only one operand). Java also supports unary versions of the plus (+) and minus () operators, so you can write expressions like -7 or +5. Cast operators associate from right to left and have the same precedence as other unary operators, such as unary + and unary -. (See the operator precedence chart in Appendix K.)

Line 77 displays the class average. In this example, we display the class average rounded to the nearest hundredth. The format specifier %.2f in printf’s format control string indicates that variable average’s value should be displayed with two digits of precision to the right of the decimal point—indicated by.2 in the format specifier. The three grades entered during the sample execution of class GradeBookTest (Fig. C.6) total 257, which yields the average 85.666666.... Method printf uses the precision in the format specifier to round the value to the specified number of digits. In this program, the average is rounded to the hundredths position and is displayed as 85.67.


 1  // Fig. C.6: GradeBookTest.java
 2  // Create GradeBook object and invoke its determineClassAverage method.
 3
 4  public class GradeBookTest
 5  {
 6     public static void main( String[] args )
 7     {
 8        // create GradeBook object myGradeBook and
 9        // pass course name to constructor
10        GradeBook myGradeBook = new GradeBook(
11           "CS101 Introduction to Java Programming" );
12
13        myGradeBook.displayMessage(); // display welcome message
14        myGradeBook.determineClassAverage(); // find average of grades
15     } // end main
16  } // end class GradeBookTest


Welcome to the grade book for
CS101 Introduction to Java Programming!

Enter grade or -1 to quit: 97
Enter grade or -1 to quit: 88
Enter grade or -1 to quit: 72
Enter grade or -1 to quit: -1

Total of the 3 grades entered is 257
Class average is 85.67


Fig. C.6 | GradeBookTest class creates an object of class GradeBook (Fig. C.5) and invokes its determineClassAverage method.

C.10 Case Study: Nested Control Statements

We’ve seen that control statements can be stacked on top of one another (in sequence). In this case study, we examine the only other structured way control statements can be connected—nesting one control statement within another.

Consider the following problem statement:

A college offers a course that prepares students for the state licensing exam for real estate brokers. Last year, ten of the students who completed this course took the exam. The college wants to know how well its students did on the exam. You’ve been asked to write a program to summarize the results. You’ve been given a list of these 10 students. Next to each name is written a 1 if the student passed the exam or a 2 if the student failed.

Your program should analyze the results of the exam as follows:

1. Input each test result (i.e., a 1 or a 2). Display the message “Enter result” on the screen each time the program requests another test result.

2. Count the number of test results of each type.

3. Display a summary of the test results, indicating the number of students who passed and the number who failed.

4. If more than eight students passed the exam, print the message “Bonus to instructor!”

The complete pseudocode appears in Fig. C.7. The Java class that implements the pseudocode algorithm and two sample executions are shown in Fig. C.8. Lines 13–16 of main declare the variables that method processExamResults of class Analysis uses to process the examination results. Several of these declarations use Java’s ability to incorporate variable initialization into declarations (passes is assigned 0, failures 0 and studentCounter 1). Looping programs may require initialization at the beginning of each repetition—normally performed by assignment statements rather than in declarations. Java requires that local variables be initialized before their values are used in an expression.


 1  Initialize passes to zero
 2  Initialize failures to zero
 3  Initialize student counter to one
 4
 5  While student counter is less than or equal to 10
 6     Prompt the user to enter the next exam result
 7     Input the next exam result
 8
 9     If the student passed
10        Add one to passes
11     Else
12        Add one to failures
13
14     Add one to student counter
15
16  Print the number of passes
17  Print the number of failures
18
19  If more than eight students passed
20    Print "Bonus to instructor!"


Fig. C.7 | Pseudocode for examination-results problem.

The while statement (lines 19–33) loops 10 times. During each iteration, the loop inputs and processes one exam result. Notice that the if...else statement (lines 26–29) for processing each result is nested in the while statement. If the result is 1, the if...else statement increments passes; otherwise, it assumes the result is 2 and increments failures. Line 32 increments studentCounter before the loop condition is tested again at line 19. After 10 values have been input, the loop terminates and line 36 displays the number of passes and failures. The if statement at lines 39–40 determines whether more than eight students passed the exam and, if so, outputs the message "Bonus to instructor!".


 1  // Fig. C.8: Analysis.java
 2  // Analysis of examination results using nested control statements.
 3  import java.util.Scanner; // class uses class Scanner
 4
 5  public class Analysis
 6  {
 7     public static void main( String[] args )
 8     {
 9        // create Scanner to obtain input from command window
10        Scanner input = new Scanner( System.in );
11
12        // initializing variables in declarations 
13        int passes = 0; // number of passes       
14        int failures = 0; // number of failures   
15        int studentCounter = 1; // student counter
16        int result; // one exam result (obtains value from user)
17
18        // process 10 students using counter-controlled loop
19        while ( studentCounter <= 10 )
20        {
21           // prompt user for input and obtain value from user
22           System.out.print( "Enter result (1 = pass, 2 = fail): " );
23           result = input.nextInt();
24
25           // if...else is nested in the while statement          
26           if ( result == 1 )          // if result 1,            
27              passes = passes + 1;     // increment passes;       
28           else                        // else result is not 1, so
29              failures = failures + 1; // increment failures      
30
31           // increment studentCounter so loop eventually terminates
32           studentCounter = studentCounter + 1;
33        } // end while
34
35        // termination phase; prepare and display results
36        System.out.printf( "Passed: %d Failed: %d ", passes, failures );
37
38        // determine whether more than 8 students passed
39        if ( passes > 8 )                               
40           System.out.println( "Bonus to instructor!" );
41     } // end main
42  } // end class Analysis


Enter result (1 = pass, 2 = fail): 1
Enter result (1 = pass, 2 = fail): 2
Enter result (1 = pass, 2 = fail): 1
Enter result (1 = pass, 2 = fail): 1
Enter result (1 = pass, 2 = fail): 1
Enter result (1 = pass, 2 = fail): 1
Enter result (1 = pass, 2 = fail): 1
Enter result (1 = pass, 2 = fail): 1
Enter result (1 = pass, 2 = fail): 1
Enter result (1 = pass, 2 = fail): 1
Passed: 9
Failed: 1
Bonus to instructor!


Fig. C.8 | Analysis of examination results using nested control statements.

During the sample execution, the condition at line 39 of method main is true—more than eight students passed the exam, so the program outputs a message to bonus the instructor.

This example contains only one class, with method main performing all the class’s work. Occasionally, when it does not make sense to try to create a reusable class to demonstrate a concept, we’ll place the program’s statements entirely within the main method of a single class.

C.11 Compound Assignment Operators

The compound assignment operators abbreviate assignment expressions. Statements like

variable = variable  operator  expression;

where operator is one of the binary operators +, -, *, / or % (or others we discuss later in the text) can be written in the form

variable  operator=  expression;

For example, you can abbreviate the statement

c = c + 3;

with the addition compound assignment operator, +=, as

c += 3;

The += operator adds the value of the expression on its right to the value of the variable on its left and stores the result in the variable on the left of the operator. Thus, the assignment expression c += 3 adds 3 to c. Figure C.9 shows the arithmetic compound assignment operators, sample expressions using the operators and explanations of what the operators do.

C.12 Increment and Decrement Operators

Java provides two unary operators (summarized in Fig. C.10) for adding 1 to or subtracting 1 from the value of a numeric variable. These are the unary increment operator, ++, and the unary decrement operator, --. A program can increment by 1 the value of a variable called c using the increment operator, ++, rather than the expression c = c + 1 or c += 1. An increment or decrement operator that’s prefixed to (placed before) a variable is referred to as the prefix increment or prefix decrement operator, respectively. An increment or decrement operator that’s postfixed to (placed after) a variable is referred to as the postfix increment or postfix decrement operator, respectively.

Image

Fig. C.9 | Arithmetic compound assignment operators.

Image

Fig. C.10 | Increment and decrement operators.

Using the prefix increment (or decrement) operator to add 1 to (or subtract 1 from) a variable is known as preincrementing (or predecrementing). This causes the variable to be incremented (decremented) by 1; then the new value of the variable is used in the expression in which it appears. Using the postfix increment (or decrement) operator to add 1 to (or subtract 1 from) a variable is known as postincrementing (or postdecrementing). This causes the current value of the variable to be used in the expression in which it appears; then the variable’s value is incremented (decremented) by 1.

Figure C.11 demonstrates the difference between the prefix increment and postfix increment versions of the ++ increment operator. The decrement operator (--) works similarly. Line 11 initializes the variable c to 5, and line 12 outputs c’s initial value. Line 13 outputs the value of the expression c++. This expression postincrements the variable c, so c’s original value (5) is output, then c’s value is incremented (to 6). Thus, line 13 outputs c’s initial value (5) again. Line 14 outputs c’s new value (6) to prove that the variable’s value was indeed incremented in line 13.


 1  // Fig. C.11: Increment.java
 2  // Prefix increment and postfix increment operators.
 3
 4  public class Increment
 5  {
 6     public static void main( String[] args )
 7     {
 8        int c;
 9
10        // demonstrate postfix increment operator
11        c = 5; // assign 5 to c
12        System.out.println( c );   // prints 5
13        System.out.println( c++ ); // prints 5 then postincrements
14        System.out.println( c );   // prints 6                    
15
16        System.out.println(); // skip a line
17
18        // demonstrate prefix increment operator
19        c = 5; // assign 5 to c
20        System.out.println( c );   // prints 5
21        System.out.println( ++c ); // preincrements then prints 6
22        System.out.println( c );   // prints 6                   
23     } // end main
24  } // end class Increment


5
5
6

5
6
6


Fig. C.11 | Preincrementing and postincrementing.

Line 19 resets c’s value to 5, and line 20 outputs c’s value. Line 21 outputs the value of the expression ++c. This expression preincrements c, so its value is incremented; then the new value (6) is output. Line 22 outputs c’s value again to show that the value of c is still 6 after line 21 executes.

When incrementing or decrementing a variable in a statement by itself, the prefix increment and postfix increment forms have the same effect, and the prefix decrement and postfix decrement forms have the same effect. It’s only when a variable appears in the context of a larger expression that preincrementing and postincrementing the variable have different effects (and similarly for predecrementing and postdecrementing).

C.13 Primitive Types

The table in Appendix L lists the eight primitive types in Java. Like its predecessor languages C and C++, Java requires all variables to have a type. For this reason, Java is referred to as a strongly typed language.

In C and C++, programmers frequently have to write separate versions of programs to support different computer platforms, because the primitive types are not guaranteed to be identical from computer to computer. For example, an int value on one machine might be represented by 16 bits (2 bytes) of memory, on a second machine by 32 bits (4 bytes) of memory, and on another machine by 64 bits (8 bytes) of memory. In Java, int values are always 32 bits (4 bytes).


Image Portability Tip C.1

The primitive types in Java are portable across all computer platforms that support Java.


Each type in Appendix L is listed with its size in bits (there are eight bits to a byte) and its range of values. Because the designers of Java want to ensure portability, they use internationally recognized standards for character formats (Unicode; for more information, visit www.unicode.org) and floating-point numbers (IEEE 754; for more information, visit grouper.ieee.org/groups/754/).

C.14 Essentials of Counter-Controlled Repetition

This section uses the while repetition statement introduced in Section C.7 to formalize the elements required to perform counter-controlled repetition, which requires

1. a control variable (or loop counter)

2. the initial value of the control variable

3. the increment (or decrement) by which the control variable is modified each time through the loop (also known as each iteration of the loop)

4. the loop-continuation condition that determines if looping should continue.

To see these elements of counter-controlled repetition, consider the application of Fig. C.12, which uses a loop to display the numbers from 1 through 10.


 1  // Fig. C.12: WhileCounter.java
 2  // Counter-controlled repetition with the while repetition statement.
 3
 4  public class WhileCounter
 5  {
 6     public static void main( String[] args )
 7     {
 8        int counter = 1; // declare and initialize control variable
 9
10        while ( counter <= 10 ) // loop-continuation condition
11        {
12           System.out.printf( "%d ", counter );
13           ++counter; // increment control variable by 1
14        } // end while
15
16        System.out.println(); // output a newline
17     } // end main
18  } // end class WhileCounter


1  2  3  4  5  6  7  8  9  10


Fig. C.12 | Counter-controlled repetition with the while repetition statement.

In Fig. C.12, the elements of counter-controlled repetition are defined in lines 8, 10 and 13. Line 8 declares the control variable (counter) as an int, reserves space for it in memory and sets its initial value to 1. Line 12 displays control variable counter’s value during each iteration of the loop. Line 13 increments the control variable by 1 for each iteration of the loop. The loop-continuation condition in the while (line 10) tests whether the value of the control variable is less than or equal to 10 (the final value for which the condition is true). The program performs the body of this while even when the control variable is 10. The loop terminates when the control variable exceeds 10 (i.e., counter becomes 11).

C.15 for Repetition Statement

Java also provides the for repetition statement, which specifies the counter-controlled-repetition details in a single line of code. Figure C.13 reimplements the application of Fig. C.12 using for.


 1  // Fig. C.13: ForCounter.java
 2  // Counter-controlled repetition with the for repetition statement.
 3
 4  public class ForCounter
 5  {
 6     public static void main( String[] args )
 7     {
 8        // for statement header includes initialization, 
 9        // loop-continuation condition and increment     
10        for ( int counter = 1; counter <= 10; ++counter )
11           System.out.printf( "%d ", counter );          
12
13        System.out.println(); // output a newline
14     } // end main
15  } // end class ForCounter


1  2  3  4  5  6  7  8  9  10


Fig. C.13 | Counter-controlled repetition with the for repetition statement.

When the for statement (lines 10–11) begins executing, the control variable counter is declared and initialized to 1. Next, the program checks the loop-continuation condition, counter <= 10, which is between the two required semicolons. Because the initial value of counter is 1, the condition initially is true. Therefore, the body statement (line 11) displays control variable counter’s value, namely 1. After executing the loop’s body, the program increments counter in the expression ++counter, which appears to the right of the second semicolon. Then the loop-continuation test is performed again to determine whether the program should continue with the next iteration of the loop. At this point, the control variable’s value is 2, so the condition is still true (the final value is not exceeded)—thus, the program performs the body statement again (i.e., the next iteration of the loop). This process continues until the numbers 1 through 10 have been displayed and the counter’s value becomes 11, causing the loop-continuation test to fail and repetition to terminate (after 10 repetitions of the loop body). Then the program performs the first statement after the for—in this case, line 13.

Figure C.13 uses (in line 10) the loop-continuation condition counter <= 10. If you incorrectly specified counter < 10 as the condition, the loop would iterate only nine times. This is a common logic error called an off-by-one error.

A Closer Look at the for Statement’s Header

Figure C.14 takes a closer look at the for statement in Fig. C.13. The for’s first line (including the keyword for and everything in parentheses after for)—line 10 in Fig. C.13—is sometimes called the for statement header. The for header “does it all”—it specifies each item needed for counter-controlled repetition with a control variable. If there’s more than one statement in the body of the for, braces are required to define the body of the loop. If the loop-continuation condition is initially false, the program does not execute the for statement’s body—execution proceeds with the statement following the for.

Image

Fig. C.14 | for statement header components.

Scope of a for Statement’s Control Variable

If the initialization expression in the for header declares the control variable (i.e., the control variable’s type is specified before the variable name, as in Fig. C.13), the control variable can be used only in that for statement—it will not exist outside it. This restricted use is known as the variable’s scope. The scope of a variable defines where it can be used in a program. For example, a local variable can be used only in the method that declares it and only from the point of declaration through the end of the method.

Expressions in a for Statement’s Header Are Optional

All three expressions in a for header are optional. If the loopContinuationCondition is omitted, Java assumes that the loop-continuation condition is always true, thus creating an infinite loop. You might omit the initialization expression if the program initializes the control variable before the loop. You might omit the increment expression if the program calculates the increment with statements in the loop’s body or if no increment is needed. The increment expression in a for acts as if it were a standalone statement at the end of the for’s body.

C.16 Examples Using the for Statement

The following examples show techniques for varying the control variable in a for statement. In each case, we write the appropriate for header. Note the change in the relational operator for loops that decrement the control variable to count downward.

a) Vary the control variable from 1 to 100 in increments of 1.

for ( int i = 1; i <= 100; ++i )

b) Vary the control variable from 100 to 1 in decrements of 1.

for ( int i = 100; i >= 1; --i )

c) Vary the control variable from 7 to 77 in increments of 7.

for ( int i = 7; i <= 77; i += 7 )

d) Vary the control variable from 20 to 2 in decrements of 2.

for ( int i = 20; i >= 2; i -= 2 )

e) Vary the control variable over the values 2, 5, 8, 11, 14, 17, 20.

for ( int i = 2; i <= 20; i += 3 )

f) Vary the control variable over the values 99, 88, 77, 66, 55, 44, 33, 22, 11, 0.

for ( int i = 99; i >= 0; i -= 11 )

Application: Compound-Interest Calculations

Let’s use the for statement to compute compound interest. Consider the following problem:

A person invests $1000 in a savings account yielding 5% interest. Assuming that all the interest is left on deposit, calculate and print the amount of money in the account at the end of each year for 10 years. Use the following formula to determine the amounts:

a = p(1 + r)n

where

p is the original amount invested (i.e., the principal)

r is the annual interest rate (e.g., use 0.05 for 5%)

n is the number of years

a is the amount on deposit at the end of the nth year.

The solution to this problem (Fig. C.15) involves a loop that performs the indicated calculation for each of the 10 years the money remains on deposit. Lines 8–10 in method main declare double variables amount, principal and rate, and initialize principal to 1000.0 and rate to 0.05. Java treats floating-point constants like 1000.0 and 0.05 as type double. Similarly, Java treats whole-number constants like 7 and -22 as type int.


 1  // Fig. C.15: Interest.java
 2  // Compound-interest calculations with for.
 3
 4  public class Interest
 5  {
 6     public static void main( String[] args )
 7     {
 8        double amount; // amount on deposit at end of each year
 9        double principal = 1000.0; // initial amount before interest
10        double rate = 0.05; // interest rate
11
12        // display headers
13        System.out.printf( "%s%20s ", "Year", "Amount on deposit" );
14
15        // calculate amount on deposit for each of ten years
16        for ( int year = 1; year <= 10; ++year )
17        {                                                      
18           // calculate new amount for specified year          
19           amount = principal * Math.pow( 1.0 + rate, year );  
20                                                               
21           // display the year and the amount                  
22           System.out.printf( "%4d%,20.2f ", year, amount ); }
23        } // end for                                           
24     } // end main
25  } // end class Interest


Year   Amount on deposit
   1            1,050.00
   2            1,102.50
   3            1,157.63
   4            1,215.51
   5            1,276.28
   6            1,340.10
   7            1,407.10
   8            1,477.46
   9            1,551.33
  10            1,628.89


Fig. C.15 | Compound-interest calculations with for.

Formatting Strings with Field Widths and Justification

Line 13 outputs two column headers. The first column displays the year and the second the amount on deposit at the end of that year. We use the format specifier %20s to output the String "Amount on Deposit". The integer 20 between the % and the conversion character s indicates that the value should be displayed in a field width of 20—that is, printf displays the value with at least 20 character positions. If the value requires fewer than 20 character positions (17 in this example), the value is right justified in the field by default. If the year value to be output were more than four character positions wide, the field width would be extended to the right to accommodate the entire value—this would push the amount field to the right, upsetting the neat columns of our tabular output. To output values left justified, simply precede the field width with the minus sign () formatting flag (e.g., %-20s).

Performing the Interest Calculations

The for statement (lines 16–23) executes its body 10 times, varying control variable year from 1 to 10 in increments of 1. This loop terminates when year becomes 11. (Variable year represents n in the problem statement.)

Classes provide methods that perform common tasks on objects. In fact, most methods must be called on a specific object. For example, to output text in Fig. C.15, line 13 calls method printf on the System.out object. Many classes also provide methods that perform common tasks and do not require objects. These are called static methods. For example, Java does not include an exponentiation operator, so the designers of Java’s Math class defined static method pow for raising a value to a power. You can call a static method by specifying the class name followed by a dot (.) and the method name, as in

ClassName.methodName( arguments )

In Appendix D, you’ll learn how to implement static methods in your own classes.

We use static method pow of class Math to perform the compound-interest calculation in Fig. C.15. Math.pow(x, y ) calculates the value of x raised to the yth power. The method receives two double arguments and returns a double value. Line 19 performs the calculation a = p(1 + r)n, where a is amount, p is principal, r is rate and n is year. Class Math is defined in package java.lang, so you do not need to import class Math to use it.

Formatting Floating-Point Numbers

After each calculation, line 22 outputs the year and the amount on deposit at the end of that year. The year is output in a field width of four characters (as specified by %4d). The amount is output as a floating-point number with the format specifier %,20.2f. The comma (,) formatting flag indicates that the floating-point value should be output with a grouping separator. The actual separator used is specific to the user’s locale (i.e., country). For example, in the United States, the number will be output using commas to separate every three digits and a decimal point to separate the fractional part of the number, as in 1,234.45. The number 20 in the format specification indicates that the value should be output right justified in a field width of 20 characters. The .2 specifies the formatted number’s precision—in this case, the number is rounded to the nearest hundredth and output with two digits to the right of the decimal point.

C.17 do...while Repetition Statement

The do...while repetition statement is similar to the while statement. In the while, the program tests the loop-continuation condition at the beginning of the loop, before executing the loop’s body; if the condition is false, the body never executes. The do...while statement tests the loop-continuation condition after executing the loop’s body; therefore, the body always executes at least once. When a do...while statement terminates, execution continues with the next statement in sequence. Figure C.16 uses a do...while (lines 10–14) to output the numbers 1–10.


 1  // Fig. C.16: DoWhileTest.java
 2  // do...while repetition statement.
 3
 4  public class DoWhileTest
 5  {
 6     public static void main( String[] args )
 7     {
 8        int counter = 1; // initialize counter
 9
10        do                                          
11        {                                           
12           System.out.printf( "%d ", counter );     
13           ++counter;                               
14        } while ( counter <= 10 ); // end do...while
15
16        System.out.println(); // outputs a newline
17     } // end main
18  } // end class DoWhileTest


1  2  3  4  5  6  7  8  9  10


Fig. C.16 | do...while repetition statement.

Line 8 declares and initializes control variable counter. Upon entering the do...while statement, line 12 outputs counter’s value and line 13 increments counter. Then the program evaluates the loop-continuation test at the bottom of the loop (line 14). If the condition is true, the loop continues from the first body statement (line 12). If the condition is false, the loop terminates and the program continues with the next statement after the loop.

C.18 switch Multiple-Selection Statement

Sections C.5C.6 discussed the if single-selection and the if...else double-selection statements. The switch multiple-selection statement performs different actions based on the possible values of a constant integral expression of type byte, short, int or char.

GradeBook Class with switch Statement to Count A, B, C, D and F Grades

Figure C.17 enhances the GradeBook case study that we began presenting in Appendix B. The new version we now present not only calculates the average of a set of numeric grades entered by the user, but uses a switch statement to determine whether each grade is the equivalent of an A, B, C, D or F and to increment the appropriate grade counter. The class also displays a summary of the number of students who received each grade. Refer to Fig. C.18 for sample inputs and outputs of the GradeBookTest application that uses class GradeBook to process a set of grades.


 1  // Fig. C.17: GradeBook.java
 2  // GradeBook class uses the switch statement to count letter grades.
 3  import java.util.Scanner; // program uses class Scanner
 4
 5  public class GradeBook
 6  {
 7     private String courseName; // name of course this GradeBook represents
 8     // int instance variables are initialized to 0 by default
 9     private int total; // sum of grades                  
10     private int gradeCounter; // number of grades entered
11     private int aCount; // count of A grades             
12     private int bCount; // count of B grades             
13     private int cCount; // count of C grades             
14     private int dCount; // count of D grades             
15     private int fCount; // count of F grades             
16
17     // constructor initializes courseName;
18     public GradeBook( String name )
19     {
20        courseName = name; // initializes courseName
21     } // end constructor
22
23     // method to set the course name
24     public void setCourseName( String name )
25     {
26        courseName = name; // store the course name
27     } // end method setCourseName
28
29     // method to retrieve the course name
30     public String getCourseName()
31     {
32        return courseName;
33     } // end method getCourseName
34
35     // display a welcome message to the GradeBook user
36     public void displayMessage()
37     {
38        // getCourseName gets the name of the course
39        System.out.printf( "Welcome to the grade book for %s! ",
40           getCourseName() );
41     } // end method displayMessage
42
43     // input arbitrary number of grades from user
44     public void inputGrades()
45     {
46        Scanner input = new Scanner( System.in );
47
48        int grade; // grade entered by user
49
50        System.out.printf( "%s %s %s %s ",
51           "Enter the integer grades in the range 0-100.",
52           "Type the end-of-file indicator to terminate input:",
53           "On UNIX/Linux/Mac OS X type <Ctrl> d then press Enter",
54           "On Windows type <Ctrl> z then press Enter" );
55
56        // loop until user enters the end-of-file indicator
57        while ( input.hasNext() )
58        {
59           grade = input.nextInt(); // read grade
60           total += grade; // add grade to total
61           ++gradeCounter; // increment number of grades
62
63           // call method to increment appropriate counter
64           incrementLetterGradeCounter( grade );
65        } // end while
66     } // end method inputGrades
67
68     // add 1 to appropriate counter for specified grade
69     private void incrementLetterGradeCounter( int grade )
70     {
71        // determine which grade was entered             
72        switch ( grade / 10 )                            
73        {                                                
74           case 9: // grade was between 90               
75           case 10: // and 100, inclusive                
76              ++aCount; // increment aCount              
77              break; // necessary to exit switch         
78                                                         
79           case 8: // grade was between 80 and 89        
80              ++bCount; // increment bCount              
81              break; // exit switch                      
82                                                         
83           case 7: // grade was between 70 and 79        
84              ++cCount; // increment cCount              
85              break; // exit switch                      
86                                                         
87           case 6: // grade was between 60 and 69        
88              ++dCount; // increment dCount              
89              break; // exit switch                      
90                                                         
91           default: // grade was less than 60            
92              ++fCount; // increment fCount              
93              break; // optional; will exit switch anyway
94        } // end switch                                  
95     } // end method incrementLetterGradeCounter
96
97     // display a report based on the grades entered by the user
98     public void displayGradeReport()
99     {
100       System.out.println( " Grade Report:" );
101
102       // if user entered at least one grade...
103       if ( gradeCounter != 0 )
104       {
105          // calculate average of all grades entered
106          double average = (double) total / gradeCounter;
107
108          // output summary of results
109          System.out.printf( "Total of the %d grades entered is %d ",
110             gradeCounter, total );
111          System.out.printf( "Class average is %.2f ", average );
112          System.out.printf( "%s %s%d %s%d %s%d %s%d %s%d ",
113             "Number of students who received each grade:",
114             "A: ", aCount,   // display number of A grades
115             "B: ", bCount,   // display number of B grades
116             "C: ", cCount,   // display number of C grades
117             "D: ", dCount,   // display number of D grades
118             "F: ", fCount ); // display number of F grades
119       } // end if
120       else // no grades were entered, so output appropriate message
121          System.out.println( "No grades were entered" );
122    } // end method displayGradeReport
123 } // end class GradeBook


Fig. C.17 | GradeBook class uses the switch statement to count letter grades.

Like earlier versions of the class, class GradeBook (Fig. C.17) declares instance variable courseName (line 7) and contains methods setCourseName (lines 24–27), getCourseName (lines 30–33) and displayMessage (lines 36–41), which set the course name, store the course name and display a welcome message to the user, respectively. The class also contains a constructor (lines 18–21) that initializes the course name.

Class GradeBook also declares instance variables total (line 9) and gradeCounter (line 10), which keep track of the sum of the grades entered by the user and the number of grades entered, respectively. Lines 11–15 declare counter variables for each grade category. Class GradeBook maintains total, gradeCounter and the five letter-grade counters as instance variables so that they can be used or modified in any of the class’s methods. The class’s constructor (lines 18–21) sets only the course name, because the remaining seven instance variables are ints and are initialized to 0 by default.

Class GradeBook contains three additional methods—inputGrades, incrementLetterGradeCounter and displayGradeReport. Method inputGrades (lines 44–66) reads an arbitrary number of integer grades from the user using sentinel-controlled repetition and updates instance variables total and gradeCounter. This method calls method incrementLetterGradeCounter (lines 69–95) to update the appropriate letter-grade counter for each grade entered. Method displayGradeReport (lines 98–122) outputs a report containing the total of all grades entered, the average of the grades and the number of students who received each letter grade. Let’s examine these methods in more detail.

Method inputGrades

Line 48 in method inputGrades declares variable grade, which will store the user’s input. Lines 50–54 prompt the user to enter integer grades and to type the end-of-file indicator to terminate the input. The end-of-file indicator is a system-dependent keystroke combination which the user enters to indicate that there’s no more data to input.

On UNIX/Linux/Mac OS X systems, end-of-file is entered by typing the sequence

<Ctrl> d

on a line by itself. This notation means to simultaneously press both the Ctrl key and the d key. On Windows systems, end-of-file can be entered by typing

<Ctrl> z

[Note: On some systems, you must press Enter after typing the end-of-file key sequence. Also, Windows typically displays the characters ^Z on the screen when the end-of-file indicator is typed, as shown in the output of Fig. C.18.]

The while statement (lines 57–65) obtains the user input. The condition at line 57 calls Scanner method hasNext to determine whether there’s more data to input. This method returns the boolean value true if there’s more data; otherwise, it returns false. The returned value is then used as the value of the condition in the while statement. Method hasNext returns false once the user types the end-of-file indicator.

Line 59 inputs a grade value from the user. Line 60 adds grade to total. Line 61 increments gradeCounter. The class’s displayGradeReport method uses these variables to compute the average of the grades. Line 64 calls the class’s incrementLetterGradeCounter method (declared in lines 69–95) to increment the appropriate letter-grade counter based on the numeric grade entered.

Method incrementLetterGradeCounter

Method incrementLetterGradeCounter contains a switch statement (lines 72–94) that determines which counter to increment. We assume that the user enters a valid grade in the range 0–100. A grade in the range 90–100 represents A, 80–89 represents B, 70–79 represents C, 60–69 represents D and 0–59 represents F. The switch statement consists of a block that contains a sequence of case labels and an optional default case. These are used in this example to determine which counter to increment based on the grade.

When the flow of control reaches the switch, the program evaluates the expression in the parentheses (grade / 10) following keyword switch. This is the switch’s controlling expression. The program compares this expression’s value (which must evaluate to an integral value of type byte, char, short or int) with each case label. The controlling expression in line 72 performs integer division, which truncates the fractional part of the result. Thus, when we divide a value from 0 to 100 by 10, the result is always a value from 0 to 10. We use several of these values in our case labels. For example, if the user enters the integer 85, the controlling expression evaluates to 8. The switch compares 8 with each case label. If a match occurs (case 8: at line 79), the program executes that case’s statements. For the integer 8, line 80 increments bCount, because a grade in the 80s is a B. The break statement (line 81) causes program control to proceed with the first statement after the switch—in this program, we reach the end of method incrementLetterGradeCounter’s body, so the method terminates and control returns to line 65 in method inputGrades (the first line after the call to incrementLetterGradeCounter). Line 65 is the end of a while loop’s body, so control flows to the while’s condition (line 57) to determine whether the loop should continue executing.

The cases in our switch explicitly test for the values 10, 9, 8, 7 and 6. Note the cases at lines 74–75 that test for the values 9 and 10 (both of which represent the grade A). Listing cases consecutively in this manner with no statements between them enables the cases to perform the same set of statements—when the controlling expression evaluates to 9 or 10, the statements in lines 76–77 will execute. The switch statement does not provide a mechanism for testing ranges of values, so every value you need to test must be listed in a separate case label. Each case can have multiple statements. The switch statement differs from other control statements in that it does not require braces around multiple statements in a case.

Without break statements, each time a match occurs in the switch, the statements for that case and subsequent cases execute until a break statement or the end of the switch is encountered. (This feature is helpful for writing a concise program that displays the iterative song “The Twelve Days of Christmas”).

If no match occurs between the controlling expression’s value and a case label, the default case (lines 91–93) executes. We use the default case in this example to process all controlling-expression values that are less than 6—that is, all failing grades. If no match occurs and the switch does not contain a default case, program control simply continues with the first statement after the switch.

GradeBookTest Class That Demonstrates Class GradeBook

Class GradeBookTest (Fig. C.18) creates a GradeBook object (lines 10–11). Line 13 invokes the object’s displayMessage method to output a welcome message to the user. Line 14 invokes the object’s inputGrades method to read a set of grades from the user and keep track of the sum of all the grades entered and the number of grades. Recall that method inputGrades also calls method incrementLetterGradeCounter to keep track of the number of students who received each letter grade. Line 15 invokes method displayGradeReport of class GradeBook, which outputs a report based on the grades entered (as in the input/output window in Fig. C.18). Line 103 of class GradeBook (Fig. C.17) determines whether the user entered at least one grade—this helps us avoid dividing by zero. If so, line 106 calculates the average of the grades. Lines 109–118 then output the total of all the grades, the class average and the number of students who received each letter grade. If no grades were entered, line 121 outputs an appropriate message. The output in Fig. C.18 shows a sample grade report based on 10 grades.


 1  // Fig. C.18: GradeBookTest.java
 2  // Create GradeBook object, input grades and display grade report.
 3
 4  public class GradeBookTest
 5  {
 6     public static void main( String[] args )
 7     {
 8        // create GradeBook object myGradeBook and
 9        // pass course name to constructor
10        GradeBook myGradeBook = new GradeBook(
11           "CS101 Introduction to Java Programming" );
12
13        myGradeBook.displayMessage(); // display welcome message
14        myGradeBook.inputGrades(); // read grades from user
15        myGradeBook.displayGradeReport(); // display report based on grades
16     } // end main
17  } // end class GradeBookTest


Welcome to the grade book for
CS101 Introduction to Java Programming!

Enter the integer grades in the range 0-100.
Type the end-of-file indicator to terminate input:
   On UNIX/Linux/Mac OS X type <Ctrl> d then press Enter
   On Windows type <Ctrl> z then press Enter
99
92
45
57
63
71
76
85
90
100
^Z

Grade Report:
Total of the 10 grades entered is 778
Class average is 77.80

Number of students who received each grade:
A: 4
B: 1
C: 2
D: 1
F: 2


Fig. C.18 | Create GradeBook object, input grades and display grade report.

Class GradeBookTest (Fig. C.18) does not directly call GradeBook method incrementLetterGradeCounter (lines 69–95 of Fig. C.17). This method is used exclusively by method inputGrades of class GradeBook to update the appropriate letter-grade counter as each new grade is entered by the user. Method incrementLetterGradeCounter exists solely to support the operations of GradeBook’s other methods, so it’s declared private.

The break statement is not required for the switch’s last case (or the optional default case, when it appears last), because execution continues with the next statement after the switch.

Notes on the Expression in Each case of a switch

When using the switch statement, remember that each case must contain a constant integral expression—that is, any combination of integer constants that evaluates to a constant integer value (e.g., —7, 0 or 221). An integer constant is simply an integer value. In addition, you can use character constants—specific characters in single quotes, such as 'A', '7' or '$'—which represent the integer values of characters and enum constants (introduced in Section D.10).

The expression in each case can also be a constant variable—a variable containing a value which does not change for the entire program. Such a variable is declared with keyword final (discussed in Appendix D). Java has a feature called enumerations, which we also present in Appendix D. Enumeration constants can also be used in case labels.

Using Strings in switch Statements (Java SE 7)

As of Java SE 7, you can use Strings in a switch statement’s controlling expression and in case labels. For example, you might want to use a city’s name to obtain the corresponding ZIP code. Assuming that city and zipCode are String variables, the following switch statement performs this task for three cities:

switch( city )
{
   case "Maynard":
      zipCode = "01754";
      break;
   case "Marlborough":
      zipCode = "01752";
      break;
   case "Framingham":
      zipCode = "01701";
      break;
} // end switch

C.19 break and continue Statements

In addition to selection and repetition statements, Java provides statements break and continue to alter the flow of control. The preceding section showed how break can be used to terminate a switch statement’s execution. This section discusses how to use break in repetition statements.

break Statement

The break statement, when executed in a while, for, do...while or switch, causes immediate exit from that statement. Execution continues with the first statement after the control statement. Common uses of the break statement are to escape early from a loop or to skip the remainder of a switch.

continue Statement

The continue statement, when executed in a while, for or do...while, skips the remaining statements in the loop body and proceeds with the next iteration of the loop. In while and do...while statements, the program evaluates the loop-continuation test immediately after the continue statement executes. In a for statement, the increment expression executes, then the program evaluates the loop-continuation test.

C.20 Logical Operators

Java’s logical operators enable you to form more complex conditions by combining simple conditions. The logical operators are && (conditional AND), || (conditional OR), & (boolean logical AND), | (boolean logical inclusive OR), ^ (boolean logical exclusive OR) and ! (logical NOT). [Note: The &, | and ^ operators are also bitwise operators when they’re applied to integral operands.]

Conditional AND (&&) Operator

Suppose we wish to ensure at some point in a program that two conditions are both true before we choose a certain path of execution. In this case, we can use the && (conditional AND) operator, as follows:

if ( gender == FEMALE && age >= 65 )
   ++seniorFemales;

This if statement contains two simple conditions. The condition gender == FEMALE compares variable gender to the constant FEMALE to determine whether a person is female. The condition age >= 65 might be evaluated to determine whether a person is a senior citizen. The if statement considers the combined condition

gender == FEMALE && age >= 65

which is true if and only if both simple conditions are true. In this case, the if statement’s body increments seniorFemales by 1. If either or both of the simple conditions are false, the program skips the increment. Some programmers find that the preceding combined condition is more readable when redundant parentheses are added, as in:

( gender == FEMALE ) && ( age >= 65 )

The table in Fig. C.19 summarizes the && operator. The table shows all four possible combinations of false and true values for expression1 and expression2. Such tables are called truth tables. Java evaluates to false or true all expressions that include relational operators, equality operators or logical operators.

Image

Fig. C.19 | && (conditional AND) operator truth table.

Conditional OR (||) Operator

Now suppose we wish to ensure that either or both of two conditions are true before we choose a certain path of execution. In this case, we use the || (conditional OR) operator, as in the following program segment:

if ( ( semesterAverage >= 90 ) || ( finalExam >= 90 ) )
   System.out.println ( "Student grade is A" );

This statement also contains two simple conditions. The condition semesterAverage >= 90 evaluates to determine whether the student deserves an A in the course because of a solid performance throughout the semester. The condition finalExam >= 90 evaluates to determine whether the student deserves an A in the course because of an outstanding performance on the final exam. The if statement then considers the combined condition

( semesterAverage >= 90 ) || ( finalExam >= 90 )

and awards the student an A if either or both of the simple conditions are true. The only time the message "Student grade is A" is not printed is when both of the simple conditions are false. Figure C.20 is a truth table for operator conditional OR (||). Operator && has a higher precedence than operator ||. Both operators associate from left to right.

Short-Circuit Evaluation of Complex Conditions

The parts of an expression containing && or || operators are evaluated only until it’s known whether the condition is true or false. Thus, evaluation of the expression

( gender == FEMALE ) && ( age >= 65 )

Image

Fig. C.20 | || (conditional OR) operator truth table.

stops immediately if gender is not equal to FEMALE (i.e., the entire expression is false) and continues if gender is equal to FEMALE (i.e., the entire expression could still be true if the condition age >= 65 is true). This feature of conditional AND and conditional OR expressions is called short-circuit evaluation.

Boolean Logical AND (&) and Boolean Logical Inclusive OR (|) Operators

The boolean logical AND (&) and boolean logical inclusive OR (|) operators are identical to the && and || operators, except that the & and | operators always evaluate both of their operands (i.e., they do not perform short-circuit evaluation). So, the expression

( gender == 1 ) & ( age >= 65 )

evaluates age >= 65 regardless of whether gender is equal to 1. This is useful if the right operand of the boolean logical AND or boolean logical inclusive OR operator has a required side effect—a modification of a variable’s value. For example, the expression

( birthday == true ) | ( ++age >= 65 )

guarantees that the condition ++age >= 65 will be evaluated. Thus, the variable age is incremented, regardless of whether the overall expression is true or false.


Image Error-Prevention Tip C.1

For clarity, avoid expressions with side effects in conditions. The side effects may seem clever, but they can make it harder to understand code and can lead to subtle logic errors.


Boolean Logical Exclusive OR (^)

A simple condition containing the boolean logical exclusive OR (^) operator is true if and only if one of its operands is true and the other is false. If both are true or both are false, the entire condition is false. Figure C.21 is a truth table for the boolean logical exclusive OR operator (^). This operator is guaranteed to evaluate both of its operands.

Image

Fig. C.21 | ^ (boolean logical exclusive OR) operator truth table.

Logical Negation (!) Operator

The ! (logical NOT, also called logical negation or logical complement) operator “reverses” the meaning of a condition. Unlike the logical operators &&, ||, &, | and ^, which are binary operators that combine two conditions, the logical negation operator is a unary operator that has only a single condition as an operand. The operator is placed before a condition to choose a path of execution if the original condition (without the logical negation operator) is false, as in the program segment

if ( ! ( grade == sentinelValue ) )
   System.out.printf( "The next grade is %d ", grade );

which executes the printf call only if grade is not equal to sentinelValue. The parentheses around the condition grade == sentinelValue are needed because the logical negation operator has a higher precedence than the equality operator.

In most cases, you can avoid using logical negation by expressing the condition differently with an appropriate relational or equality operator. For example, the previous statement may also be written as follows:

if ( grade != sentinelValue )
   System.out.printf( "The next grade is %d ", grade );

This flexibility can help you express a condition in a more convenient manner. Figure C.22 is a truth table for the logical negation operator.

Image

Fig. C.22 | ! (logical negation, or logical NOT) operator truth table.

C.21 Wrap-Up

This appendix presented basic problem solving for building classes and developing methods for these classes. We demonstrated how to construct an algorithm (i.e., an approach to solving a problem), then how to refine the algorithm through several phases of pseudocode development, resulting in Java code that can be executed as part of a method. The appendix showed how to use top-down, stepwise refinement to plan out the specific actions that a method must perform and the order in which the method must perform these actions.

Only three types of control structures—sequence, selection and repetition—are needed to develop any problem-solving algorithm. Specifically, this appendix demonstrated the if single-selection statement, the if...else double-selection statement and the while repetition statement. These are some of the building blocks used to construct solutions to many problems. We used control-statement stacking to total and compute the average of a set of student grades with counter- and sentinel-controlled repetition, and we used control-statement nesting to analyze and make decisions based on a set of exam results. We introduced Java’s compound assignment operators and its increment and decrement operators. We discussed Java’s primitive types.

We demonstrated the for, do...while and switch statements. We showed that any algorithm can be developed using combinations of the sequence structure (i.e., statements listed in the order in which they should execute), the three types of selection statements—if, if...else and switch—and the three types of repetition statements—while, do...while and for. We discussed how you can combine these building blocks to utilize proven program-construction and problem-solving techniques. We also introduced Java’s logical operators, which enable you to use more complex conditional expressions in control statements. In Appendix D, we examine methods in greater depth.

Self-Review Exercises (Sections C.1–C.13)

C.1 Fill in the blanks in each of the following statements:

a) All programs can be written in terms of three types of control structures: __________, __________ and __________.

b) The __________ statement is used to execute one action when a condition is true and another when that condition is false.

c) When it’s not known in advance how many times a set of statements will be repeated, a(n) __________ value can be used to terminate the repetition.

d) Java is a(n) __________ language; it requires all variables to have a type.

e) If the increment operator is __________ to a variable, first the variable is incremented by 1, then its new value is used in the expression.

C.2 State whether each of the following is true or false. If false, explain why.

a) A set of statements contained within a pair of parentheses is called a block.

b) A selection statement specifies that an action is to be repeated while some condition remains true.

c) A nested control statement appears in the body of another control statement.

d) Specifying the order in which statements execute in a program is called program control.

e) Instance variables of type boolean are given the value true by default.

C.3 Write Java statements to accomplish each of the following tasks:

a) Use one statement to assign the sum of x and y to z, then increment x by 1.

b) Test whether variable count is greater than 10. If it is, print "Count is greater than 10".

c) Use one statement to decrement the variable x by 1, then subtract it from variable total and store the result in variable total.

d) Calculate the remainder after q is divided by divisor, and assign the result to q. Write this statement in two different ways.

C.4 Write a Java statement to accomplish each of the following tasks:

a) Declare variables sum and x to be of type int.

b) Assign 1 to variable x.

c) Assign 0 to variable sum.

d) Add variable x to variable sum, and assign the result to variable sum.

e) Print "The sum is: ", followed by the value of variable sum.

C.5 Determine the value of the variables in the statement product *= x++; after the calculation is performed. Assume that all variables are type int and initially have the value 5.

C.6 Identify and correct the errors in each of the following sets of code:

a)

while ( c <= 5 )
{
   product *= c;
   ++c;

b)

if ( gender == 1 )
   System.out.println( "Woman" );
else;
   System.out.println( "Man" );

C.7 What is wrong with the following while statement?

while ( z >= 0 )
    sum += z;

Self-Review Exercises (Sections C.14–C.20)

C.8 Fill in the blanks in each of the following statements:

a) Typically, __________ statements are used for counter-controlled repetition and __________ statements for sentinel-controlled repetition.

b) The do...while statement tests the loop-continuation condition __________ executing the loop’s body; therefore, the body always executes at least once.

c) The __________ statement selects among multiple actions based on the possible values of an integer variable or expression.

d) The __________ operator can be used to ensure that two conditions are both true before choosing a certain path of execution.

e) If the loop-continuation condition in a for header is initially __________, the program does not execute the for statement’s body.

C.9 State whether each of the following is true or false. If false, explain why.

a) The default case is required in the switch selection statement.

b) The break statement is required in the last case of a switch selection statement.

c) The expression ( ( x > y ) && ( a < b ) ) is true if either x > y is true or a < b is true.

d) An expression containing the || operator is true if either or both of its operands are true.

e) Listing cases consecutively with no statements between them enables the cases to perform the same set of statements.

C.10 Write a Java statement or a set of Java statements to accomplish each of the following tasks:

a) Sum the odd integers between 1 and 99, using a for statement. Assume that the integer variables sum and count have been declared.

b) Calculate the value of 2.5 raised to the power of 3, using the pow method.

c) Print the integers from 1 to 20, using a while loop and the counter variable i. Assume that the variable i has been declared, but not initialized. Print only five integers per line. [Hint: Use the calculation i % 5. When the value of this expression is 0, print a newline character; otherwise, print a tab character. Assume that this code is an application. Use the System.out.println() method to output the newline character, and use the System.out.print( ' ' ) method to output the tab character.]

d) Repeat part (c), using a for statement.

C.11 Find the error in each of the following code segments, and explain how to correct it:

a)

i = 1;

while ( i <= 10 );
    ++i;
}

b)

for ( k = 0.1; k != 1.0; k += 0.1 )
   System.out.println( k );

c)

switch ( n )
{
   case 1:
     System.out.println( "The number is 1" );
   case 2:
     System.out.println( "The number is 2" );
     break;
   default:
     System.out.println( "The number is not 1 or 2" );
     break;
}

d) The following code should print the values 1 to 10:

n = 1;
while ( n < 10 )
   System.out.println( n++ );

Answers to Self-Review Exercises (Sections C.1–C.13)

C.1

a) sequence, selection, repetition.

b) if...else.

c) sentinel, signal, flag or dummy.

d) strongly typed.

e) prefixed.

C.2

a) False. A set of statements contained within a pair of braces ({ and }) is called a block.

b) False. A repetition statement specifies that an action is to be repeated while some condition remains true.

c) True.

d) True.

e) False. Instance variables of type boolean are given the value false by default.

C.3

a) z = x++ + y;

b)

if ( count > 10 )
    System.out.println( "Count is greater than 10" );

c) total -= --x;

d)

q %= divisor;
q = q % divisor;

C.4

a)

int sum;
int x;

b) x = 1;

c) sum = 0;

d) sum += x; or sum = sum + x;

e) System.out.printf( "The sum is: %d ", sum );

C.5 product = 25, x = 6

C.6 a) Error: The closing right brace of the while statement’s body is missing. Correction: Add a closing right brace after the statement ++c;.

b) Error: The semicolon after else results in a logic error. The second output statement will always be executed.

Correction: Remove the semicolon after else.

C.7 The value of the variable z is never changed in the while statement. Therefore, if the loop-continuation condition ( z >= 0 ) is true, an infinite loop is created. To prevent an infinite loop from occurring, z must be decremented so that it eventually becomes less than 0.

Answers to Self-Review Exercises (Sections C.14–C.20)

C.8

a) for, while.

b) after.

c) switch.

d) && (conditional AND).

e) false.

C.9

a) False. The default case is optional. If no default action is needed, then there’s no need for a default case.

b) False. The break statement is used to exit the switch statement. The break statement is not required for the last case in a switch statement.

c) False. Both of the relational expressions must be true for the entire expression to be true when using the && operator.

d) True.

e) True.

C.10

a)

sum = 0;
for ( count = 1; count <= 99; count += 2 )
   sum += count;

b) double result = Math.pow( 2.5, 3 );

c)

i = 1;

while ( i <= 20 )
{
   System.out.print( i );

   if ( i % 5 == 0 )
     System.out.println();
   else
     System.out.print( ' ' );

   ++i;
}

d)

for ( i = 1; i <= 20; ++i )
{
   System.out.print( i );

   if ( i % 5 == 0 )
     System.out.println();
   else
     System.out.print( ' ' );
}

C.11 a) Error: The semicolon after the while header causes an infinite loop, and there’s a missing left brace.

Correction: Replace the semicolon by a {, or remove both the ; and the }.

b) Error: Using a floating-point number to control a for statement may not work, because floating-point numbers are represented only approximately by most computers. Correction: Use an integer, and perform the proper calculation in order to get the values you desire:

for ( k = 1; k != 10; ++k )
       System.out.println( (double) k / 10 );

c) Error: The missing code is the break statement in the statements for the first case. Correction: Add a break statement at the end of the statements for the first case. This omission is not necessarily an error if you want the statement of case 2: to execute every time the case 1: statement executes.

d) Error: An improper relational operator is used in the while’s continuation condition. Correction: Use <= rather than <, or change 10 to 11.

Exercises (Sections C.1–C.13)

C.12 Explain what happens when a Java program attempts to divide one integer by another. What happens to the fractional part of the calculation? How can you avoid that outcome?

C.13 Describe the two ways in which control statements can be combined.

C.14 What type of repetition would be appropriate for calculating the sum of the first 100 positive integers? What type would be appropriate for calculating the sum of an arbitrary number of positive integers? Briefly describe how each of these tasks could be performed.

C.15 What is the difference between preincrementing and postincrementing a variable?

C.16 Identify and correct the errors in each of the following pieces of code. [Note: There may be more than one error in each piece of code.]

a)

if ( age >= 65 );
   System.out.println( "Age is greater than or equal to 65" );
else
   System.out.println( "Age is less than 65 )";

b)

int x = 1, total;
while ( x <= 10 )
{
    total += x;
    ++x;
}

c)

while ( x <= 100 )
   total += x;
   ++x;

d)

while ( y > 0 )
{
   System.out.println( y );
   ++y;

For Exercise C.17 and Exercise C.18, perform each of the following steps:

a) Read the problem statement.

b) Write a Java program.

c) Test, debug and execute the Java program.

d) Process three complete sets of data.

C.17 (Gas Mileage) Drivers are concerned with the mileage their automobiles get. One driver has kept track of several trips by recording the miles driven and gallons used for each tankful. Develop a Java application that will input the miles driven and gallons used (both as integers) for each trip. The program should calculate and display the miles per gallon obtained for each trip and print the combined miles per gallon obtained for all trips up to this point. All averaging calculations should produce floating-point results. Use class Scanner and sentinel-controlled repetition to obtain the data from the user.

C.18 (Credit Limit Calculator) Develop a Java application that determines whether any of several department-store customers has exceeded the credit limit on a charge account. For each customer, the following facts are available:

a) account number

b) balance at the beginning of the month

c) total of all items charged by the customer this month

d) total of all credits applied to the customer’s account this month

e) allowed credit limit

The program should input all these facts as integers, calculate the new balance (= beginning balance + charges — credits), display the new balance and determine whether the new balance exceeds the customer’s credit limit. For those customers whose credit limit is exceeded, the program should display the message "Credit limit exceeded".

C.19 (Find the Largest Number) The process of finding the largest value is used frequently in computer applications. For example, a program that determines the winner of a sales contest would input the number of units sold by each salesperson. The salesperson who sells the most units wins the contest. Write a pseudocode program, then a Java application that inputs a series of 10 integers and determines and prints the largest integer. Your program should use at least the following three variables:

a) counter: A counter to count to 10 (i.e., to keep track of how many numbers have been input and to determine when all 10 numbers have been processed).

b) number: The integer most recently input by the user.

c) largest: The largest number found so far.

C.20 (Tabular Output) Write a Java application that uses looping to print the following table of values:


N   10*N  100*N  1000*N

1   10    100    1000
2   20    200    2000
3   30    300    3000
4   40    400    4000
5   50    500    5000


C.21 (Multiples of 2 with an Infinite Loop) Write an application that keeps displaying in the command window the multiples of the integer 2—namely, 2, 4, 8, 16, 32, 64, and so on. Your loop should not terminate (i.e., it should create an infinite loop). What happens when you run this program?

Exercises (Sections C.14–C.20)

C.22 Describe the four basic elements of counter-controlled repetition.

C.23 (Find the Smallest Value) Write an application that finds the smallest of several integers. Assume that the first value read specifies the number of values to input from the user.

C.24 Assume that i = 1, j = 2, k = 3 and m = 2. What does each of the following statements print?

a) System.out.println( i == 1 );

b) System.out.println( j == 3 );

c) System.out.println( ( i >= 1 ) && ( j < 4 ) );

d) System.out.println( ( m <= 99 ) & ( k < m ) );

e) System.out.println( ( j >= i ) || ( k == m ) );

f) System.out.println( ( k + m < j ) | ( 3 - j >= k ) );

g) System.out.println( !( k > m ) );

C.25 (Calculating the Value of π) Calculate the value of π from the infinite series

Image

Print a table that shows the value of π approximated by computing the first 200,000 terms of this series. How many terms do you have to use before you first get a value that begins with 3.14159?

C.26 What does the following program segment do?

for ( i = 1; i <= 5; ++i )
{
   for ( j = 1; j <= 3; ++j )
   {
      for ( k = 1; k <= 4; ++k )
         System.out.print( '*' );
      System.out.println();
    } // end inner for
    System.out.println();
} // end outer for

C.27 (“The Twelve Days of Christmas” Song) Write (as concisely as possible) an application that uses repetition and one or more switch statements to print the song “The Twelve Days of Christmas.”

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.164.75