450 likes | 624 Views
Chapter 4 Statement Forms. Statement types. Simple statements e xpression; p rintln (“The total is “ + total + “.”); (method call) 2. Compound statements { s tatement1; ... s tatementn ; }. Control statements Conditional statements: if, switch Iterative statements: for, while
E N D
Statement types • Simple statements expression; println(“The total is “ + total + “.”); (method call) 2. Compound statements { statement1; ... statementn; }
Control statements Conditional statements: if, switch Iterative statements: for, while Example: Add more than 2 integers Three startegies Duplicating the code in Add2Integers; Repeating the input cycle a predetermined number of times; Repeating the input cycle until the user enters a special sentinel value;
public class Add4Integers extends ConsoleProgram { public void run() { println(“This program adds four integers.”); int n1 = readInt(“ ? “); int n2 = readInt(“ ? “); int n3 = readInt(“ ? “); int n4 = readInt(“ ? “); int total = n1 + n2 + n3 + n4; println(“The total is “ + total + “.”); } } • Difficult to generalize • Cumbersome to add 100 values
The repeat-N-times idiom for (int i = 0; i < N; i++) { statements to be repeated } • header line: for (int i = 0; i < N; i++) • body: statements to be repeated
/* * file: AddNIntegers.java * ------------------------------ * This program adds a predefined number of integers * and them prints the total. To change the number of * integers, change the definition of N_VALUES */ Import acm.program.*;
public class AddNIntegers extends ConsoleProgram { public void run() { println(“This program adds “ + N_VALUES + “integers.”); int total = 0; for (i = 0; i < N_VALUES; i++) { int value = readInt(“ ? “); total += value; } println(“The total is “ + total + “.”); } /* specifies the number of values */ private static final int N_VALUES = 4; }
Tracing the program public void run() { println(“This program adds “ + N_VALUES + “integers.”); int total = 0; for (i = 0; i < N_VALUES; i++) { int value = readInt(“ ? “); total += value; } println(“The total is “ + total + “.”); } N_VALUES (4) total (0) i (0) value ( )
The repeat-until-sentinel Read numbers until the user signals the end of input data. Sentinel: A special value, not a legitimate data value, signals the end of input data. Examples • Add a list of integers sentinel: 0 • Average grades Sentinel: -1
Repeat-until sentinel idiom while (true) { prompt user and read in a value if (value == sentinel) break; rest of the loop body }
A sample output This program adds a list of integers. Enter values, one per line, using 0 to signal the end of the list. ? 1 ? 2 ? 3 ? 0 This total is 6.
/* * File: AddIntegerList.java * -------------------------------- * This program reads integers one per line until the * user enters a special sentinel value to signal the * end of the input. At that point, the program prints * the sum of the numbers entered so far. */ import acm.program.*;
public class AddIntegerList extends ConsoleProgram { public void run() { println(“This program adds a list of integers.”); println(“Enter values, one per line,”); println(“using “ + SENTINEL + “ to signal the end of the list.”); int total = 0; while (true) { int value = readInt(“ ? “); if (value == SENTINEL) break; total += value; } println(“The total is “ + total + “.”); } /* Specifies the value of the sentinel */ private static final int SENTINEL = 0; }
Tracing the program int total = 0; while (true) { int value = readInt(“ ? “); if (value == SENTINEL) break; total += value; } println(“The total is “ + total + “.”); } SENTINEL (0) total (0) value ( )
Average grade Changes • new variable: int count • new variable: double average • SETINEL = -1 • comments
public class AverageGrade extends ConsoleProgram { public void run() { println(“This program calculates average grades.”); println(“Enter grades, one per line,”); println(“using “ + SENTINEL + “ to signal the end of the list.”); int total = 0; int count = 0; while (true) { int value = readInt(“ ? “); if (value == SENTINEL) break; total += value; count++; } double average = (double) total / count; println(“The average is “ + average + “.”); } /* Specifies the value of the sentinel */ private static final int SENTINEL = -1; }
Zeros are not counted int total = 0; int count = 0; while (true) { int value = readInt(“ ? “); if (value == SENTINEL) break; if (value > 0) { total += value; count++; } } double average = (double) total / count; println(“The average is “ + average + “.”);
What if count = 0? int total = 0; int count = 0; while (true) { int value = readInt(“ ? “); if (value == SENTINEL) break; if (value > 0) { total += value; count++; } } if (count == 0) { println(“No grades entered.”); } else { /* count > 0 */ double average = (double) total / count; println(“The average is “ + average + “.”); }
Example: IsLeapYear.java /* * File: IsLeapYear.java * -------------------------- * * This program reads in a year and determines whether it is a * leap year. A year is a leap year if it is divisible by four, unless * it is divisible by 100. Years divisible by 100 are leap years only * if divisible by 400. */ Import acm.program.*;
public class IsLeapYear extends ConsoleProgram { public void run() { println(“This program checks for leap years.”); int year = readInt(“Enter year: “); boolean isLeapYear = (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0); if (isLeapYear) { println(year + “ is a leap year.”); } else { println(year + “ is not a leap year.”); } } }
Four forms of if statements Single-line if (condition) statement Multiline if (condition) { statements; } if-else if (condition){ statement1 }else{ statement2 }
Cascading if (condition1) { statements1 } else if (condition2) { statements2 ... } else { statements }
Example: Sign of x If x > 0, sign(x) = 1; if x < 0, sign(x) = -1; if x == 0, sign(x) = 0. Using a table
The ? : operator condition ?expressionT : expressionF equivalent to if (condition) { expressionT } else { expressionF }
Examples • Max = (x >y)? x : y; • println(nItems + “item” + ((nItems == 1) ? “” : “s”) + “ found.”);
The switch statement switch (e) { case c1: statements1 break; case c2: statements2 break; ... more case clauses ... default: statements break; } Useful when program must choose among several cases.
Good programming practice • Although a break is not necessary for each case, it is advised to include a break at the end of each case. • Although a default clause is optional, it is advised to include a default clause unless you are absolutely sure that you have covered all the cases (using a table).
Example public void run() { println(“This program shows the number of days in a month.”); int month = readInt(“Enter numeric month (Jan = 1): “); switch (month) { case 2: println(“28 days (29 in leap years)”); break; case 4: case 6: case: 9 case 11: println(“30 days”); break; case 1: case 3: case 5: case 7: case 8: case 10: case 12: println(“31 days”); break; default: println(“Illegal month number”); break; } } Tracing the program.
The while statement while (condition) { statements } • The conditional test is performed only at the beginning of a loop cycle. If the condition happens to become false at some point in the middle of the loop, the program doesn’t notice the fact until it has executed a complete cycle. At that point, the program evaluates the test condition again. If it is still false, the loop terminates. • If you must quit loop inside a cycle, use break. See later.
Example: DigitSum Pseudo code: public void run() { println(“This program sums the digits in an integer.”); int n = readInt(“Enter a positive integer: “); int dsum = 0; for each digit in the number, add that digit to dsum; println(“The sum of the digits is “ + dsum + “.”); }
Find digits in an integer 1729 % 10 = 9 1729 / 10 = 172 ... 1 % 10 = 1 1 / 10 = 0 /* for each digit in the number, add that digit to dsum */ while (n > 0) { dsum += n % 10; n /= 10; }
public void run() { println(“This program sums the digits in an integer.”); int n = readInt(“Enter a positive integer: “); intdsum = 0; while (n > 0) { dsum += (n % 10); n = n /10; } println(“The sum of the digits is “ + dsum + “.”); } Trace the program.
Loop terminationg • When you use a while loop in a program, it is important to make sure the loop eventually terminates. while (n >= 0) { dsum += n % 10; n /= 10; } Infinite loop! • Find out the command sequence on your computer which stops an infinite loop.
The loop-and-half patterns while (true) { prompt user and read in a value if (value == sentinel) break; process the data value } or the sentinel-based loop Prompt user and read in a value while (value != sentinel) { process the data value prompt user and read in a value }
Two drawbacks of the sentinel-based loop: • The order of the operations in the loop in unnatural, hard to follow. (Process the data value, then read in a new value.) • Duplication of code presents a serious maintenance problem. Subsequent edits to one copy might not be made in the other.
The for statement for (init; test; step) { statements } Example: countdown Int START = 10; for (int t = START; t >= 0; t--) { println(t); } println(“Liftoff!”);
The expressions init, test, and step are each optional, but semicolons must appear. • If init is missing, no initialization is performed; • If test is missing, it is assumed to be true; • If step is missing, no action occurs between loop cycles. for ( ; ;) is equivalent to while (true)
Effect of each of the following for statements for (int i = 0; i < N; i++) for (int i = 1; i <= 10; i++) for (int n = 99; i >= 1; n -= 2) for (int x = 1; x <= 1024; x *= 2)
Simple graphic animation Moving a square diagonally. /* File: AnimatedSquare.java * ------------------------------------ * This program animates a square so that it moves from the * upper left corner of the window to the lower right corner. */ import acm.graphics.*; import acm.program.*;
public class AnimatedSquare extends GraphicsProgram { public void run() { GRect square = new Grect(0,0,SQUARE_SIZE, SQUARE_SIZE); square.setFilled(true); add(square); double dx = (double) (getWidth() – SQUARE_SIZE) / N_STEPS; double dy = (double) (getHeight() – SQUARE_SIZE) / N_STEPS; for (inti = 0; i < N_STEPS; i++) { square.move(dx, dy); pause(PAUSE_TIME); } /* private constants */ private static final int N_STEPS = 1000; private static final int PAUSE_TIME = 20; private static final int SQUARE_SIZE = 50; }
for vs while for (init; test; step) { statements } is equivalent to Init; while (test) { statements step; } Prefer for over while, when you have choice.
Nested for statements 2D applications. Example: Checkerboard /* * File: Checkerboard.java * -------------------------------- * This program draws a checkerboard. The dimensions of * checkerboard are specified by the constants N_ROWS and * N_COLIMNS, and the size of the square is chosen so that the * checkerboard fills the available vertical space. */ import acm.graphics.*; import acm.program.*;
public class Checkerboard extends GraphicsProgram { public void run() { double sqSize = (double) getHeight() / N_ROWS; for (inti = 0; i < N_ROWS; i++) { for (int j = 0; j < N_COLUMNS; j++) { double x = j * sqSize; double y = i * sqSize; GRect sq = new GRect(x, y, sqSize, sqSize); sq.setFilled(((i + j) % 2) != 0); add(sq); } /* for j */ } /* for i */ /* private constants */ private static final int N_ROWS = 8; private static final int N_COLUMNS = 8; }
Using for with floating-point data double h = 0.1; for (double x = 1.0; x <= 2.0; x += h) { println(x); } Output: 1.0 1.1 1.2000000000000002 ... 1.9000000000000008
Why? Decimal 0.1 cannot be exactly represented in binary. During the assignment h = 0.1, decimal 0.1 is rounded to it closest double floating-point, which is slightly larger than 0.1. Caution: more rounding errors occur during addition. for (double x = 0.0; x <= 0.5; x += h) { println(x); } The final value of x is 0.5 exact.