CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 Ryerson University School of Computer Science CPS109 Course Notes 4 Alexander Ferworn Unrelated Facts Worth Remembering Make a “to do” list every day. Crossing things off the list is very satisfying and if items stay on the list, they become very annoying. Use metaphors to understand issues and explain them to others. Look up what metaphor means. Table of Contents 1 INTRODUCTION....................................................................................................... 1 2 IF .................................................................................................................................. 2 2.1 2.2 2.3 2.4 3 BOOLEAN EXPRESSIONS ....................................................................................... 3 BLOCKS ................................................................................................................ 4 IF-ELSE ................................................................................................................. 4 NESTING............................................................................................................... 5 SWITCH (SOMETIMES KNOWN AS “CASE”) ................................................... 7 3.1 A BIT ABOUT BREAK ............................................................................................. 7 4 CONDITIONAL OPERATOR .................................................................................. 8 5 ITERATION.............................................................................................................. 10 6 WHILE ...................................................................................................................... 10 7 DO-WHILE ............................................................................................................... 13 8 FOR ............................................................................................................................ 14 9 A BIT MORE ABOUT BREAK .............................................................................. 15 1 Introduction If nothing interferes, a Java program begins executing at the first line of code in the main() method and stops when the last line is executed. While this is useful it can be cumbersome without the ability to do things like change what will be done next based on conditions that are encountered while the program is running, or do things over and over again. 1 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 This is an easy sell for most people. Imagine being on the 10m board of a diving pool and you discover that there is no water below. If you couldn’t change your course of action you would probably have what old programmers called an ABEND or “ABnormal ENDing”. Most programming languages provide the ability to change the course of execution through a series of constructs commonly called selection constructs—allowing you to select what will be executed next. In addition they also provide a set of iteration constructs—allowing you to choose how many times something will be executed. This document discusses Java features supporting both concepts. 2 if The if statement is the first and simplest ways of changing what will be done next based on testing a condition. Definition: An if statement allows a program to choose whether or not to execute an associated statement. Syntax: The syntax for an if statement is; if(<condition>) <statement1>; [else <statement2>;] Rules: <condition> must be a boolean expression that evaluates to true or false. If the condition is true then <statement1> is executed. If the condition is false then <statement1> is skipped and <statement2> is executed if else is present. If there is no else, execution continuing after <statement1>. Only a single statement can follow the <condition> and the else (we will fix this shortly). Here is an example program illustrating how if works. // Program demoing if. A decision is made // about an input temperature. If // the temperature is below 20 // a message is output. class Temperature { final static int COLD = 20; public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); System.out.println 2 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 (“Enter the temperature outside.”); int temperature = Integer.parseInt(stdin.readLine()); if(temperature <= COLD) System.out.println (“It’s cold out there!”); System.out.println(“Bye!”); } } Don’t worry about the “IOException..” stuff for now, we will discuss this further later. As output the program could produce several results; Enter the temperature outside. 21 Bye! or Enter the temperature outside. 19 It’s cold out there! Bye! Note that only a single statement can be associated with the condition. 2.1 Boolean Expressions Definition: Anything that evaluates to true or false is a boolean expression. For example; true total == val 4 > 3 will all evaluate to one or the other. It is also possible to assign the results of a boolean expression to a boolean variable as in, … boolean ans = (total == val); … Java provides a set of relational operators each with its own precedence. The operators are shown in the table below. Operator Meaning 3 CPS109 Course Notes 4 == != < <= > >= Alexander Ferworn Updated Summer 03 equal to (note: not assignment) not equal to less than less than or equal to greater than greater than or equal to 2.2 Blocks Recall that an if statement allows only one statement after the condition. You can avoid this problem by making a block of statements. Definition: A block is a list of statements enclosed in curly brackets We have already seen blocks in the main method and a class definition. We revisit the above example below. // Program demoing if. A decision is made // about an input temperature. If // the temperature is below 20 a message is output. import java.io.*; class Temperature { final static int COLD = 20; public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); System.out.println (“Enter the temperature outside.”); int temperature = Integer.parseInt(stdin.readLine()); if(temperature <= COLD) { System.out.println (“It’s cold out there!”); System.out.println (“But this is Canada!”); } System.out.println(“Bye!”); } } 2.3 if-else The following program illustrates the use of the if-else combination as well as blocks. // Program demoing if-else. A decision is made // about input. import java.io.*; class Decision 4 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 { public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); System.out.println (“Enter the 1 or 2.”); int answer = Integer.parseInt(stdin.readLine()); if(answer == 1) { System.out.println (“You entered 1!”); System.out.println (“Ha, I knew you would”); } else { System.out.println (“You entered 2!”); System.out.println (“I thought you would enter 1 !”); } System.out.println(“Bye!”); } } Notes: The “Bye!” always gets printed There is a problem…what if they don’t enter 1 or 2? 2.4 Nesting Now, an if statement is, in particular, a statement. This means that either statement-1 or statement-2 inside an if statement can itself be an if statement. (Note: If statement-1 is an if statement, then it has to have an else part; if it does not, the computer will mistake the "else" of the main if statement for the missing "else" of statement-1. This is called the dangling else problem. You can avoid this problem by enclosing statement-1 between { and }, making it into a block.) An if statement in which the else part is itself an if statement would look like this (perhaps without the final else part): if (<boolean-expression-1>) <statement-1> else if (<boolean-expression-2>) <statement-2> else 5 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 <statement-3> You should think of this as a single statement representing a three-way branch. When the computer executes this, one and only one of the three statements, statement-1, statement-2, and statement-3, will be executed. The computer starts by evaluating boolean-expression-1. If it is true, the computer executes statement-1 and then jumps all the way to the end of the big if statement, skipping the other two statement's. If boolean-expression-1 is false, the computer skips statement-1 and executes the second, nested if statement. That is, it tests the value of boolean-expression-2 and uses it to decide between statement-2 and statement-3. Here is an example that will print out one of three different messages, depending on the value of a variable named temperature: if (temperature < 50) System.out.println("It's cold."); else if (temperature < 80) System.out.println("It's nice."); else System.out.println("It's hot."); If temperature is, the computer prints out the message "It's cold", and skips the rest -- without even evaluating the second condition. You can go on stringing together "else-if's" to make multiway branches with any number of cases: if (boolean-expression-1) statement-1 else if (boolean-expression-2) statement-2 else if (boolean-expression-3) statement-3 // (more cases) else if (boolean-expression-N) statement-N else statement-(N+1) You should just remember that only one of the statements will be executed and that the computer will stop evaluating boolean-expressions as soon as it finds one that is true. Also, remember that the final else part can be omitted and that any of the statements can be blocks, consisting of a number of 6 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 statements enclosed between { and }. (Admittedly, there is lot of syntax here; as you study and practice, you'll become comfortable with it.) 3 Switch (sometimes known as “case”) Java also provides a control structure that is specifically designed to make multiway branches of a certain type: the switch statement. A switch statement allows you to test the value of an expression and, depending on that value, to jump to some location within the switch statement. The positions you can jump to are marked with "case labels" that take the form: "case constant:". This marks the position the computer jumps to when the expression evaluates to the given constant. As the final case in a switch statement you can, optionally, use the label "default:", which provides a default jump point that is used when the value of the expression is not listed in any case label. A switch statement has the form: switch (integer-expression) { case integer-constant-1: statements-1 break; case integer-constant-2: statements-2 break; . . // (more cases) . case integer-constant-N: statements-N break; default: // optional default case statements-(N+1) } // end of switch statement 3.1 A bit about break The break statements are technically optional. The effect of a break is to make the computer jump to the end of the switch statement. If you leave out the break statement, the computer will just forge ahead after completing one case and will execute the statements associated with the next case label. This is rarely what you want, but it is legal. Note that you can leave out one of the groups of statements entirely (including the break). You then have two case labels in a row, containing two different constants. This just means that the computer will jump to the same place and perform the same action for each of the two constants. 7 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 Here is an example of a switch statement. This is not a useful example, but it should be easy for you to follow. Note, by the way, that the constants in the case labels don't have to be in any particular order, as long as they are all different: switch (N) { // assume N is an integer variable case 1: System.out.println("The number is 1."); break; case 2: case 4: case 8: System.out.println("The number is 2, 4, or 8."); System.out.println("(That's a power of 2.)"); break; case 3: case 6: case 9: System.out.println("The number is 3, 6, or 9."); System.out.println("(That's a multiple of 3.)"); break; case 5: System.out.println("The number is 5."); break; default: System.out.println("The number is 7,"); System.out.println(" or not in the range 1-9."); } The switch statement is pretty primitive as control structures go, and it's easy to make mistakes when you use it. Java takes all its control structures directly from the older programming languages C and C++. The switch statement is certainly one place where the designers of Java should have introduced some improvements. 4 Conditional Operator The conditional operator (? :) is a ternary operator. The operator selects one of two expressions for evaluation, based on the value of its first operand. In this way, the conditional operator is similar to an if statement. The conditional operator produces a pure value. Conditional expressions group from right to left. Consider the following expression: g?f:e?d:c?b:a It is equivalent to g?f:(e?d:(c?b:a)) The first operand of the conditional operator must be of type boolean, or a compile-time error occurs. If the first operand evaluates to true, the operator 8 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 evaluates the second operand (i.e., the one following the ?) and produces the pure value of that expression. Otherwise, if the first operand evaluates to false, the operator evaluates the third operand (i.e., the one following the :) and produces the pure value of that expression. Note that the conditional operator evaluates either its second operand or its third operand, but not both. The second and third operands of the conditional operator may be of any type, but they must both be of the same kind of type or a compile-time error occurs. If one operand is of an arithmetic type, the other must also be of an arithmetic type. If one operand is of type boolean, the other must also be of type boolean. If one operand is a reference type, the other must also be a reference type. Note that neither the second nor the third operand can be an expression that invokes a void method. The types of the second and third operands determine the type of pure value that the conditional operator produces. If the second and third operands are of different types, the operator may perform a type conversion on the operand that it evaluates. The operator does this to ensure that it always produces the same type of result for a given expression, regardless of the value of its first operand. If the second and third operands are both of arithmetic types, the conditional operator determines the type of value it produces as follows: If both operands are of the same type, the conditional operator produces a pure value of that type. If one operand is of type short and the other operand is of type byte, the conditional operator produces a short value. If one operand is of type short, char, or byte and the other operand is a constant expression that can be represented as a value of that type, the conditional operator produces a pure value of that type. Otherwise, if either operand is of type double, the operator produces a double value. Otherwise, if either operand is of type float, the operator produces a float value. Otherwise, if either operand is of type long, the operator produces a long value. Otherwise, if either operand is of type int, the operator produces an int value. If the second and third operands are both of type boolean, the conditional operator produces a pure boolean value. If the second and third operands are both reference types, the conditional operator determines the type of value it produces as follows: If both operands are null, the conditional operator produces the pure value null. 9 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 Otherwise, if exactly one of the operands is null, the conditional operator produces a value of the type of the other operand. Otherwise, it must be possible to cast the value of one of the operands to the type of the other operand, or a compile-time error occurs. The conditional operator produces a value of the type that would be the target of the cast. 5 Iteration Previously we have seen how to make a decision in java using the if or the switch. Often we want to make a decision about doing a task many times. In effect you hit the decision again and again and again. This repetition is called iteration or looping, where we decide to do a repetitive task based on a decision made before the task begins, or after the task has been done at least once. This is the topic of this document. The most basic loop appears as the diagram below. A test is performed before the body of a loop is executed. If the test evaluates to true then the body of the loop is executed. At the end of the body the loop returns control back to the test which is reevaluated for truth. This continues until the test turns false and the loop is exited. Test Body of Loop 6 while A while loop is used to repeat a given statement over and over. Of course, its not likely that you would want to repeat forever. That would be an infinite loop, which is generally a bad thing. (There is an old story about computer pioneer Grace Murray Hopper, who read instructions on a bottle of shampoo telling her to " lather, rinse, repeat." As the story goes, she claims that she tried to follow the directions but that she ran out of shampoo. (In case you don't get it, this is a joke about the way that computers mindlessly follow instructions.)) Definition: A while loop will repeat a statement over and over, but only so long as a specified condition remains true. A while loop can repeat zero or more times. Syntax: A while loop has the form: 10 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 while (<boolean-expression>) <statement> Since the statement can be, and usually is, a block, many while loops have the form: while (<boolean-expression>) { <statements> } When the computer comes to a while statement, it evaluates the booleanexpression, which yields either true or false as the value. If the value is false, the computer skips over the rest of the while loop and proceeds to the next command in the program. If the value of the expression is true, the computer executes the statements inside the loop. Then it returns to the beginning of the while loop and repeats the process. That is, it re-evaluates the booleanexpression, ends the loop if the value is false and continues it if the value is true. This will continue over and over until the value of the expression is false; if that never happens, then there will be an infinite loop. while boolean-expression {Body} Here is an example of a while loop that simply prints out the numbers 1, 2, 3, 4, 5: int number = 1; while ( number < 5 ) { System.out.println(number); number = number + 1; } System.out.println("Done!"); The variable number is initialized with the value 1. So the first time through the while loop, when the computer evaluates the expression "number < 5", it is asking whether 1 is less than 5, which is true. The computer therefore proceeds to execute the two statements inside the loop. The first statement prints out "1". The second statement adds 1 to number and stores the result 11 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 back into the variable number; the value of number has been changed to 2. The computer has reached the end of the loop, so it returns to the beginning and asks again whether number is less than 5. Once again this is true, so the computer executes the loop again, this time printing out 2 as the value of number and then changing the value of number to 3. It continues in this way until eventually number becomes equal to 5. At that point, the expression "number < 5" evaluates to false. So, the computer jumps past the end of the loop to the next statement and prints out the message "Done!" By the way, you should remember that you'll never see a while loop standing by itself in a real program. It will always be inside a subroutine which is itself defined inside some class. As an example of a while loop used inside a complete program, here is a little program that computes the interest on an investment over several years: public class Interest2 { /* This class implements a simple program that will compute the amount of interest that is earned on $17,000 invested at an interest rate of 0.07 for 5 years. The value of the investment at the end of each year is printed to standard output. */ public static void main(String[] args) { double principal = 17000; // the initial value of the investment double rate = 0.07; // the annual interest rate int years = 0; // counts the number of years that // have passed while (years < 5) { double interest = principal * rate; // compute this year's interest principal = principal + interest; // add it to principal years = years + 1; // count the current year. System.out.print ("The value of the invmnt after "); System.out.print(years); System.out.print(" years is $"); System.out.println(principal); } // end of while loop } // end of main() } // end of class Interest2 12 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 7 do-while A previous section introduced the while statement, in which the computer tests a condition at the beginning of the loop, to determine whether it should continue looping: The do loop is a variation of this in which the test comes at the end. It takes the form: do <statement> while ( <boolean-expression> ); or, since as usual the statement can be a block, do { <statements> } while ( <boolean-expression> ); (Note the semicolon, ';', at the end. This semicolon is part of the statement, just as the semicolon at the end of an assignment statement or declaration is part of the statement. More generally, every statement in Java ends either with a semicolon or a right brace, '}'.) Note: In a Do loop, the body of the loop is executed 1 or more times (at least once). do {Body} while boolean-expression To execute a do loop, the computer first executes the body of the loop -- that is, the statement or statements inside the loop -- and then evaluates the boolean expression. If the value of the expression is true, the computer returns to the beginning of the do loop and repeats the process; if the value is false, it ends the loop and continues with the next part of the program. The main difference between the do loop and the while loop is that the body of a do loop is executed at least once, before the boolean expression is ever evaluated. In a while loop, if the boolean expression is false when the 13 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 computer first checks it, then the body of the loop will never be executed at all. For example, consider the following pseudo code for a game-playing program. The do loop makes sense here instead of a while loop because with the do loop, you know there will be at least one game. Also, the test that is used at the end of the loop wouldn't even make sense at the beginning: do { <Play a Game> <Ask user if he wants to play another game> } while ( <the user's response is yes> ); 8 for The for loop exists to make a common type of while loop easier to write. Many while loops have the same general form: <initialization> while (<continuation-condition> ) { <statements> <update> } For example, consider int years = 0; // initialize the variable years while ( years < 5 ) { // condition for continuing loop interest = principal * rate; // do some statements principal += interest; System.out.println(principal); years++; // update the value of the variable years } This loop can be written as the following for statement: for ( int years = 0; years < 5; years++ ) { interest = principal * rate; principal += interest; System.out.println(principal); } 14 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 The initialization, continuation condition, and updating have all been combined in the first line of the for loop. This keeps everything involved in the "control" of the loop in one place, which helps makes the loop easier to read and understand. In general, a for loop takes the form: for(<initialization>;<continuation-condition>;<update>) <statement> or, using a block statement,: for(<initialization>;<continuation-condition>;<update>) { <statement> } The continuation-condition must be a boolean-valued expression. The initialization can be any expression, as can the update. Any of the three can be empty. Usually, the initialization is an assignment or a declaration, and the update is an assignment or an increment or decrement operation. The official syntax actually allows the initialization and the update to consist of several expressions, separated by commas. If you declare a variable in the initialization section, the scope of that variable is limited to the for statement; that is, it is no longer valid after the for statement is ended. Here are a few examples of for loops: // print out the alphabet on one output for ( char ch='A'; ch <= 'Z'; ch++ ) System.out.print(ch); System.out.println(); line of // count up to 10 and down from 10 at the same time for ( int i=0,j=10; i < 10; i++,j-- ) { System.out.println(i + “ “ + j); } // compute the number 1 * 2 * 3 * ... * 20 long factorial = 1; for (int num=2; num <= 20; num++) factorial *= num; System.out.println("20! = " + factorial); 9 A Bit More About Break The syntax of the while, do, and for loops allows you to make a test at either the beginning or at the end of the loop to determine whether or not to 15 CPS109 Course Notes 4 Alexander Ferworn Updated Summer 03 continue executing the loop. Sometimes, it is more natural to have the test in the middle of the loop, or to have several tests at different places in the same loop. Java provides a general method for breaking out of the middle of any loop. It's called the break statement, which takes the form break; When the computer executes a break statement, it will immediately jump out of the loop (or other control structure) that contains the break. It then continues on to whatever follows the loop in the program. Consider for example: while (true) { // looks like it will run forever! console.put("Enter a positive number: "); N = console.getlnt(); if (N > 0) // input is OK; jump out of loop break; console.putln("Your answer must be > 0."); } // continue here after break A break statement terminates the loop that immediately encloses the break statement. It is possible to have nested loops, where one loop statement is contained inside another. If you use a break statement inside a nested loop, it will only break out of that loop, not out of the loop that contains the nested loop. There is something called a "labeled break" statement that allows you to specify which loop you want to break. I won't give the details here; you can look them up if you ever need them. 16