Chapter 9. More on loops
In this chapter we look at two new categories of statements —
the for
loop and the break
statement. Neither
is very complex conceptually, but nonetheless they are convenient
enough in practice that you wouldn't want to miss them.
9.1. The for
loop
You may have noticed by now that our programs often have loops
incorporating some sort of counter variable, as in the following.
int <var> = <initial>;
while(<var> < <maximum>) {
// do something once
var++;
}
This happens often enough that Java provides a shortcut for the
situation in the form of a different type of loop called a for
loop. The above example could instead be written as the following.
for(int <var> = <initial>; <var> < <maximum>; <var>++) {
// do something once
}
Inside the parentheses of a for
loop are three parts separated
by semicolons.
for(<initialization>; <condition>; <update>) {
<statementsToRepeat>
}
When the Java compiler sees this, it automatically interprets it as
if the user had written the following instead.
<initialization>;
while(<condition>) {
<statementsToRepeat>
<update>;
}
In some sense, you may see the while
loop as being easier to
understand. But you should quickly be able to adapt to learning the
for
loop. Most programmers strongly prefer for
loops to
while
loops whenever a program iterates over a sequence of
numbers. This is because all the information about the numeric sequence
is contained on one line, which makes the program shorter, easier to
understand, and less liable to lead to bugs.
These aren't really exactly equivalent. A significant difference is
that if <initialization>
incorporates a variable declaration,
the declared variable's scope would be restricted to only within the
for
loop, but in the equivalent
while
loop
formulation, the variable could be accessed following the while
loop's end.
(Another difference has to do with the continue
statement, but
this statement isn't often useful, and so we'll defer discussion of it
to later.)
As an example of this in practice, suppose we wanted to modify
MovingBall
of Figure 6.3 so that the program
displays only 50 frames of the ball's movement before the program ends.
The program of Figure 9.1 manages to accomplish
this.
Notice how it introduces a for
loop to count how many
frames have been displayed thus far.
Figure 9.1: The MovingBall50
program.
1 import acm.program.*;
2 import acm.graphics.*;
3 import java.awt.*;
4
5 public class MovingBall50 extends GraphicsProgram {
6 public void run() {
7 GOval ball = new GOval(25, 25, 50, 50);
8 ball.setFilled(true);
9 ball.setFillColor(new Color(255, 0, 0));
10 add(ball);
11
12 for(int frames = 0; frames < 50; frames++) {
13 pause(40);
14 ball.move(3, 2);
15 }
16 }
17 }
The for
loop can be modified for virtually any numeric
sequence.
Suppose we want to count by fives up to 100.
for(int current = 5; current <= 100; current += 5) {
println(current);
}
Here, we've modified the <update>
clause so that the
current
variable goes up by 5 with each iteration.
Notice also that the <condition>
clause uses less-than-or-equal
rather than less-than.
Suppose we want instead to count down from 10 to 1.
In this case, we'll start our variable at 10, and we'll modify the
<update>
clause so that the variable is decremented with each
iteration rather than incremented.
for(int current = 10; current >= 1; current--) {
println(current);
}
9.2. The break
statement
The break
statement is another type of statement that
sometimes turns out to be useful. It looks quite simple.
break;
When the computer reaches a break
statement, it will immediate
exit whichever loop it is in, proceeding to the statement following the
loop's body. It's important to remember that an if
statement is
not a loop: If the break
occurs in an if
statement (as it
almost always will be), the computer will look successive levels outside
the if
statement to find the loop from which to break.
The program of Figure 9.2 illustrates
an example where one might use a break
statement.
Here, after each movement of the ball, we test to see whether the ball
has gone off the the window's edge; if the ball has gone off, the
computer executes a break
statement, which moves execution to
after the while
loop. In this program's case, the ball would
start moving backwards indefinitely.
Figure 9.2: The MovingBallBreak
program.
1 import acm.program.*;
2 import acm.graphics.*;
3 import java.awt.*;
4
5 public class MovingBallBreak extends GraphicsProgram {
6 public void run() {
7 GOval ball = new GOval(25, 25, 50, 50);
8 ball.setFilled(true);
9 ball.setFillColor(new Color(255, 0, 0));
10 add(ball);
11
12 while(true) {
13 pause(40);
14 ball.move(3, 2);
15 if(ball.getX() > getWidth() || ball.getY() > getHeight()) {
16 break;
17 }
18 }
19 while(true) {
20 pause(40);
21 ball.move(-3, -2);
22 }
23 }
24 }
(Incidentally, most programmers would argue that this program would
be better written without a break
statement. Instead, the
if
statement would go inside the while
loop's condition.
Still, this is a handy example with which to illustrate our point.)
Sometimes you'll have one loop inside another. If the computer
encounters a break
statement, it applies only to the innermost
loop. In the below example, the ball will go back and forth across the
window 10 times. Each time the computer encounters the first
break
statement, it will break out of the first while
loop
rather than the for
loop, since the while
loop is
the innermost loop containing that statement; and it would continue on
to the second while
loop. And each time the computer encounters
the second break
statement, the computer will decide whether to
repeat the for
loop for another lap.
Figure 9.3: The MovingBallLaps
program.
1 import acm.program.*;
2 import acm.graphics.*;
3 import java.awt.*;
4
5 public class MovingBallLaps extends GraphicsProgram {
6 public void run() {
7 GOval ball = new GOval(25, 25, 50, 50);
8 ball.setFilled(true);
9 ball.setFillColor(new Color(255, 0, 0));
10 add(ball);
11
12 for(int laps = 0; laps < 10; laps++) {
13 while(true) {
14 pause(40);
15 ball.move(3, 2);
16 if(ball.getX() > getWidth() || ball.getY() > getHeight()) {
17 break;
18 }
19 }
20 while(true) {
21 pause(40);
22 ball.move(-3, -2);
23 if(ball.getX() < -50 || ball.getY() < -50) {
24 break;
25 }
26 }
27 }
28 }
29 }