Module 4: Loops: the for-loop


Objectives

 

By the end of this module, for simple HelloWorld-like programs, you will be able to:

 

4.0 Audio:
 


4.0    An example

 

Consider the following program:

What we would like is a way to organize repetition.

We will do this using a version of the for-loop:

 

4.1 Exercise: Print out your own animal sound in the above fashion using a for-loop for some repetitive letter in the sound. Write your code in MyPetSound3.java.
 

Let's zoom in on the for-loop and dissect it:

  • First, there is the Java reserved word for:

  • Note: for emphasis, we have depicted only the loop, in isolation from the rest of the program.

  • Then, there is the set of conditions:

    More about this below.

  • Next, the body of the loop:

  • The body includes the opening and closing braces, and whatever lies between the two.

  • Now, let's drill down further and examine the loop conditions.

  • The first part is the initialization:

    • Think of i as something that "counts".
    • Later, we'll see that i is a variable and what we've done is declared and initalized the variable.
    • Notice how the initialization part ends with a semicolon.

  • The second part is the re-entry condition

    • Read this as "as long as the condition holds, we'll keep executing the body of the loop".
    • Here, the condition is the i must be less than 6.
    • Note: this part also ends with a semicolon.

  • The third part is the change or increment part:

    • This part usually changes the counting variable.
    • In this case, the counter variable i is increment by one.
    • Notice the use of the "increment-by-one" operator ++.

  • To summarize, when you see

    you can read this as: "for i starting at 0, ending at 5, and incrementing by 1 do ... (whatever)"

 

4.2 Video:

 


4.1    Printing the loop variable

 

Consider this example:

 

4.3 Exercise: Type, compile and execute the above program.
 

4.4 Video:

 

4.5 Exercise: In MyForLoopPrint.java, change the loop conditions so that the numbers 1 through 10 are printed. Also add a print statement after the for-loop, that prints anything.
 

Observe:

  • We are able to print out the for-loop variable i.

  • We see that the loop is executed five times.
           ⇒ Each time the variable i has increased its value.
 

Mental execution:

  • When execution first reaches the for-loop, the initialization condition is executed:

    • Say to yourself "i is set to 0".

  • Important: the initialization condition is not executed again, unless we somehow return to the statement preceding the for-loop.
    (We'll see later how this can happen.)

  • Next, we test the re-entry condition:

    • Here, you say to yourself "Is i less than 6?"
    • The answer is "yes", so we enter the loop-body and execute what's inside.

  • Execute (just once) what's inside the loop body:

    • In this case the value of i, which is now 0, gets printed out.

  • After the loop-body has executed, we apply the increment

    • Say to yourself "Now i has the value 1".

  • Next, we test the loop-entry condition:

    • Here, you say to yourself "Is i less than 6?"
    • It clearly is, so we enter the loop again.

  • Once again, we execute the loop body:

    • Because i has the value 1, this is what gets printed.

  • Once again, we apply the increment:

    • Say to yourself "Now i has the value 2".

  • Next, apply the entry condition ... and so on.

  • Finally, after the 5-th time through, i will get the value 6.

    • The re-entry condition now fails, and we exit the for-loop.

  • What "exit" means:

    • Execution continues to just after the for-loop.
    • In this program, we didn't have anything else, but we could have had:

    • In this case, you would print "MOO!" to the screen.

  • Another way to understand how it works:

  • The for-loop is one of several such strange and fascinating creatures (structures) we'll encounter in programming.
 

4.6 Video:

 


4.2    Variations

 

To explore for-loops further, we'll look at some variations of the basic for-loop:

  • First, we could have named our for-loop variable anything we like:
      	for (int count=0; count<6; count++) {
    	    printBigO ();
    	}
           
    • It's customary to use short variable names like i and j.

  • To go through a loop five times, any range of numbers will do:
      	for (int i=10; i<16; i++) {
    	    printBigO ();
    	}
           
    • Of course, this doesn't work for printing, unless we want to print values from 10 to 15.

  • Here's an example of using the <= operator:
      	for (int i=1; i<=5; i++) {
    	    printBigO ();
    	}
           
    • Treat <= as one symbol ("less than or equal to").
    • We do this because the keyboard doesn't have a symbol for .

  • Here are different ways of incrementing by 1:
      	for (int i=0; i<6 i=i+1) {
    	    printBigO ();
    	}
    
      	for (int i=0; i<6; i+=1) {    // Using the += operator.
    	    printBigO ();
    	}
           
    4.7 Exercise: Write a program to print out the odd numbers from 1 to 25. Use a single for-loop with the appropriate increment and write your code in Odd25.java.
     

  • One can count down just as easily:
      	for (int i=5; i>0; i--) {
    	    System.out.println (i);
    	}
           
      Notice the decrement-by-one operator --.
    • Observe the entry-condition is "as long as i>0".
 

4.8 Exercise: Write a program to print out the odd numbers from 25 down to 1. Write your code in Odd25Down.java.
 

4.9 Video:

 


4.3    Nested for-loops

 

We'll start by writing a program to print a little number triangle like this:

  1
  22
  333
  4444

Notice: there's repetition across a row of numbers: a potential use of for-loops!

We'll do this in stages, starting with this program:

Observe:

  • We've used System.out.print to avoid printing each number on a single line.

  • System.out.println() merely goes to the next line.
    (Or, ends the current line being printed.)
 

4.10 Exercise: Add a row for 5 (with five of them), writing your code in MyForLoopPrint2.java
 

4.11 Exercise: Just for the heck of it, could one use a for-loop to achieve the printing of 1? That is, answer the question: can a for-loop be set up so that you go into it exactly once? Write your code in MyForLoopPrint3.java
 

Next, observe that the upper-limits of the for-loops are themselves increasing:

Another way to say this:

    When the value is 2, print a row of 2's
    When the value is 3, print a row of 3's
    When the value is 4, print a row of 4's
  

Thus, we could try to do is:

    for (int j=2; j<=4; j++) {
        // Print a row of j's (j of them)
    }
  

But we already know how to print a row of j's:

    for (int j=2; j<=4; j++) {
        // Print a row of j's (j of them)
        for (int i=0; i<j; i++) {
            System.out.print (j)
        }
    }
  

The complete program:

 

4.12 Video:

 

4.13 Exercise: Change the program to print a fifth row with five 5's. Also include the row of 1's inside the loop: that is, fix the for-loop conditions so that you don't need the stand-alone println to print 1. Write your code in MyForLoopPrint4.java
 

Let's review what we learned above:

  • The outer loop variable's value is used in the inner loop:

  • Consider a single iteration of the outer-loop (e.g., when j is 3).

    • For this value of j, the inner loop executes j times.
    • Thus, when j is 3, the inner loop has 3 iterations.

  • This is an example of a nested for-loop in which the inner loop's execution depends on the value of the outer-loop variable.
 


4.4   Tracing through a program in detail

 

We'll now look at an example of how to execute a program "by hand". That is, how to trace a program's execution by painstakingly following its execution step-by-step.

At first this will appear tedious, but it is critical to firm understanding of how programs execute, and eventually to your own writing of programs.

We'll first do a longer, more narrative version here, and then show you how to submit a much shorter version for your exercises.

For our example, let's look at the program we last saw:

public class ForLoopPrint2 {

    public static void main (String[] argv)
    {
        System.out.println (1);
        for (int j=2; j<=4; j++) {
            for (int i=0; i<j; i++) {
                System.out.print (j);
            }
            System.out.println();
        }
    }

}
  
 

Here's the longer version, just for the sake of understanding. To make best use of this:

  • Open this same page in another browser, and have the program side-by-side, as you read what's below.
  • Read out aloud what you see below.
 

Ready? Let's trace through:

  • Right at the start, the first line is System.out.println(1); This prints out 1, and moves to the next line.

  • Initially j=2 at the start of the outer for-loop.

  • Since the condition j<=4 is immediately tested at entry into the loop, we see that j<=4 is satisfied when j=2.

  • This gets us into the outer loop.
    • Now we encounter the inner for-loop, where i is set to 0 (int i=0).

    • Is i<j now? At the moment i is 0, j is 2. So, since 0<2, we enter the inner loop.
    • Inside the inner loop, we execute System.out.print(j). which, because j is now 2, will print 2.
    • This is NOT println so the output will not go to the next line yet.
    • We're at the end of the inner loop, so now i increments to 1:

    • Coming back to the top of the inner for-loop, we check whether the current value of i (which is now 1) satisfies the condition i<j. Note that j is still 2 so, yes, it's satisfied.
      • Remember: the initial setting of the loop (int i=0) is never executed again after entering the loop (It could, and in this program, will be executed again if we return to the loop once we've left it).
    • So now inside the inner-loop, we print 2 again (print, not println).

    • Then, at the end of the inner for-loop, i increments to 2.
    • We're back to the entrance of the inner-loop. The condition 2<2 fails.
    • We exit the inner loop and proceed to whatever code follows the loop.

  • Now we're at System.out.println().

    This simply causes the output to go to the next line without printing any actual thing.

  • Then, it's on to the end of the outer for-loop, where j is incremented to 3.

  • Remember: the third part of the loop statement (the increment or decrement, in some cases) is done at the END of the loop, even though it's written in one line. That's just the strangeness of writing code.

  • Now we're back to checking the condition j<=4 at the top of the outer for-loop. j is 3 now.

  • Since j<=4 (that is, 3<=4), we enter the loop again.

  • Now, we see the inner loop again (AFTER exiting it earlier).
    • So, now int i=0 is executed, initializing this for-loop's variable to i=0.

    • Then, we enter and print 3 (since j is 3 at this moment).
    • i increments to 1, we enter and print 3.
    • i increments to 2, we enter and print 3.
    • i increments to 3, which fails i<j because 3<3 fails, and we exit the inner loop.
    • So, three 3's get printed.

  • Then, it's on to System.out.println().

  • Thus, the output so far is:
      1
      22
      333
      

  • Now j increments to 4 and because j<=4 is satisfied by j=4, we enter the outer-loop again.

  • Now, we see the inner loop again (AFTER exiting it the second time earlier).
    • Now int i=0 is executed, setting i=0.
    • Then, we enter and print 4 (since j is 4 at this moment).
    • i increments to 1, we print 4.
    • i increments to 2, we print 4.
    • i increments to 3, we print 4.
    • i increments to 4, which fails i<j (since j is currently 4), and we exit.

  • Next, println() occurs, which gets to the next line.

  • Now j increments to 5, which fails the j<=4 condition in the outer-loop.

  • We exit the outer-loop and proceed. This gets us to the end of the curly bracket that's the end of public static void main (String[] argv).

  • And this ends the program's execution.

  • The output is:
      1
      22
      333
      4444
      
 

Yes, that was long. But doing this a few times will help you understand how to read programs. Later, you will become good at this and will, with a quick glance at the inner-loop, say "Oh, this prints 2 twice in the first iteration of the outer."
 

Important: when you need to submit a program's traced-out execution, use a shorter version. For example, see this PDF for the above program.
 

4.14 Exercise: Consider this program:

First, trace through the values of i and j by hand and try to figure out what gets printed. Do this painstakingly for each possible value of i and j. Write your tracing in module4.pdf, using the shorter "table" format we saw in this example earlier. Then, edit, compile and execute the above program to see if you were right.
 

4.15 Exercise: Write a program to print out consecutive integers in a diagonal, as in

  1
   2
    3
     4
      5
  
Use a nested for-loop as in earlier examples to print the requisite number of spaces before printing a digit. Write your code in MyForLoopPrint5.java
 

4.16 Exercise: Write a program to print out

I'm feeling cold: b rrrrrr rrrrr rrrr rrr rr r
  
Use a regular print to print everything up to the b. Then, use a nested for-loop the r's. Don't forget the space between each grouping of r's. Write your code in MyForLoopPrint6.java
 

4.17 Video:

 


4.5    Reading and writing

 

Let's consider how to read a single for-loop, such as:

  • First, "see" the entire for-block as a whole, without looking at the details:

    Note: like the class but unlike methods, the opening brace is on the same line as the for.

  • Then, figure out how the for-loop variable is going to change:

    Say to yourself

    • "The variable is i and it starts at 0."
    • "The increment is 1."
    • "The last iteration is when i is 5."

  • Next, look for where the loop-variable is being used:

  • Now perform the mental execution, iteration by iteration.
           ⇒ It helps to write down successive values of loop variables.
 

Writing:

  • Make sure that you stick to the conventional style.

  • Again, when writing, always type matching brackets together.
 

4.18 Exercise: Consider the following program:

What does it print? Try to figure this out by mental execution first. Then, type it up, compile and execute to confirm, writing your code in MyForExercise.java.
 

4.19 Video:

 


4.6    When things go wrong

 

As code gets more complex, it gets easier to make mistakes, and harder to find them.

In each of the programs below, try to determine the error without compiling the program. Then, write up the program, compile and see what the compiler says. After that, fix the error.
 

4.20 Exercise:

Program 1:

Write your (corrected) code in MyForLoopExercise1.java
 

4.21 Exercise:

Program 2:

Write your corrected code in MyForLoopExercise2.java
 

4.22 Exercise:

Program 3:

Write your corrected code in MyForLoopExercise3.java
 

4.23 Exercise:

Program 4:

Write your corrected code in MyForLoopExercise4.java
 

4.24 Exercise:

Program 5:

Write your corrected code in MyForLoopExercise5.java
 

4.25 Exercise:

Program 6:

Write your corrected code in MyForLoopExercise6.java
 

The last one is technically not a syntax error but a logical error:

  • Logical errors compile fine, but cause a problem during execution.

  • The process of identifying and fixing logical errors is called debugging.

  • A bug is a logical error.
 

4.26 Exercise: The following program is supposed to print the triangle of numbers:

1
22
333
4444
But there are two bugs. First, try to find the problems solely by reading and mental execution. Then, type it in the file ForLoopPrintBugs.java. and see what the output really is. Report what you see in module4.pdf.

 

4.27 Exercise: The following piece of code intends to print

55555
4444
333
22
1
    
However, there are two bugs. Can you see them just by reading? Find and fix them, writing your code in ForLoopPrintDown.java. The program:
public class ForLoopPrintDown {

    public static void main (String[] argv)
    {
	for (int i=5; i>=1; i--) {
	    for (int j=1; j<i; j++); {
		System.out.print (i);
	    }
	    System.out.println ();
	}
	
    }

}
    
 


4.7    Meta

 

We will occasionally step back from the details to comment on how best to learn.

This module was a bit different, a little more challenging than modules 1-3.

What to keep in mind:

  • It is only natural to feel like you are in an alien landscape.
           ⇒ You would feel no different doing the first few modules while learning a foreign language with an entirely different script.

  • It takes a while to absorb some of the details, and that's just fine.

  • Notice that exercises 4.15 and 4.16 were significantly more challenging than others:
    • In prior exercises, you merely typed in something and tried it out, or make a small change.
    • With 4.15 and 4.16 you had to do it all from scratch.
    • Both involved problem-solving
             ⇒ Taking a problem described in words and finding a solution.

  • Problem-solving is a higher-level skill than programming.
    • It takes time to acquire this skill.
    • There is no magic formula or words to simply make "problem solving" work for you.
    • The only way is to develop this skill is to struggle with problems, and with lots of them.

  • Finally, think about this:
    • Anyone can acquire both programming and problem-solving skills with sufficient dedication. So why not you?
    • If you get past these hurdles with determination, you will leave behind all those who gave up earlier.
 

4.28 Audio:
 

On to Assignment 1


© 2017, Rahul Simha