Objectives
In this appendix you’ll:
Learn basic problem-solving techniques.
Develop algorithms through the process of top-down, stepwise refinement.
Use the if
and if
...else
selection statements to choose among alternative actions.
Use the while
repetition statement to execute statements in a program repeatedly.
Use counter-controlled repetition and sentinel-controlled repetition.
Use the compound assignment, increment and decrement operators.
Learn the essentials of counter-controlled repetition.
Use the for
and do
...while
repetition statements to execute statements in a program repeatedly.
Implement multiple selection using the switch
statement.
Use the break
and continue
statements.
Use the logical operators in conditional expressions.
C.5 if
Single-Selection Statement
C.6 if
...else
Double-Selection Statement
C.7 while
Repetition Statement
C.8 Case Study: Counter-Controlled Repetition
C.9 Case Study: Sentinel-Controlled Repetition
C.10 Case Study: Nested Control Statements
C.11 Compound Assignment Operators
C.12 Increment and Decrement Operators
C.14 Essentials of Counter-Controlled Repetition
C.16 Examples Using the for
Statement
C.17 do
...while
Repetition Statement
C.18 switch
Multiple-Selection Statement
C.19 break
and continue
Statements
Self-Review Exercises | Answers to Self-Review Exercises | Exercises
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.
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.
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.
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.”
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.
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).
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.
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" );
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" );
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.
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.
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.
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.
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).
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.
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
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
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
(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
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).
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"
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
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.
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.
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
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!"
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!
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.
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.
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.
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
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).
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).
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/
).
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
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
).
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
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.
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
.
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.
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.
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 )
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
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
).
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.
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.
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
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.
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
.
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
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 int
s 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.
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
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 case
s 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
.
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
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
.
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.
As of Java SE 7, you can use String
s 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
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.
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
.
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.
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.]
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.
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.
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
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.
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
.
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.
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.
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.
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.
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;
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;
}
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++ );
a) sequence, selection, repetition.
b) if
...else
.
c) sentinel, signal, flag or dummy.
d) strongly typed.
e) prefixed.
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.
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;
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.
a) for
, while
.
b) after.
c) switch
.
d) &&
(conditional AND).
e) false
.
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.
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
.
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?
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
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.”