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.

Aside

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  }