University College of Applied SciencesProgramming 1
العربية
Lecture 10 · 100 min

For Loops

How do we write counted repetition on one line, and build tables and patterns with it?

By the end of this lecture you will be able to

  1. Write a for loop and convert it to an equivalent while
  2. Count up, down and in steps
  3. Explain the scope of the loop variable and choose between for and while
  4. Trace nested loops with the debugger and print patterns with them
  5. Check whether a number is prime and use break and continue
  6. Avoid the semicolon trap and changing the loop variable inside the loop
In this lecture
  1. for puts initialise, test and update on one line
  2. Every for loop is a while loop, neatly arranged
  3. Counting can go up, down or in any step we want
  4. A loop variable declared in for does not outlive the loop
  5. for suits a known count, while suits ending on an event
  6. A sum starts at 0, a product starts at 1
  7. A times table is one loop and one print line
  8. In a nested loop, the inner loop finishes completely for each outer iteration
  9. print stays on the line and println ends it, so together they make a grid
  10. A rectangle: the same number of stars in every row
  11. A triangle: the inner loop depends on the row number
  12. A pyramid: one loop for spaces, then one for stars, inside each row
  13. A number is prime if no divisor exists: assume so, then look for proof otherwise
  14. break ends the loop, continue skips the rest of the iteration
  15. Two common traps: a semicolon after for, and changing the loop variable inside
  16. Review questions
Part one: the anatomy of for

for puts initialise, test and update on one line

Initialise

Runs once, before everything else.

int i = 1
Test

Checked before every iteration, just as in while.

i <= 3
Update

Runs after the loop body in every iteration.

i++

Your first for loop

Predict the output, then run. Change 3 to 6 and run again. Notice that the three parts are separated by semicolons, ;.

public class FirstFor {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            System.out.println("Hello " + i);
        }
        System.out.println("Done");
    }
}
Output
Hello 1
Hello 2
Hello 3
Done

Semicolons, not commas

Fix the for line so the program prints 0, 1 and 2.

public class ForCommas {
    public static void main(String[] args) {
        for (int i = 0, i < 3, i++) {
            System.out.println(i);
        }
    }
}
Compiler message';' expected
Show the fix
public class ForCommas {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            System.out.println(i);
        }
    }
}
Output
0
1
2

Why? The three parts are separate statements, and semicolons are what separate them. On seeing a comma, the compiler assumed you were declaring another variable, so it could not make sense of what follows.

Every for loop is a while loop, neatly arranged

As a while
int i = 1;
while (i <= 3) {
    System.out.println(i);
    i++;
}
As a for
for (int i = 1; i <= 3; i++) {
    System.out.println(i);
}
  1. Initialise once
  2. Check the testIf it is false, the loop ends.
  3. Run the body
  4. Update, then go back to the test

See the order in the debugger

Press "Debug line by line", then "Next line". Because the three parts share one line, the highlight sits on the for line more than once and returns to it after each body. Watch the box i: when does it change, before the body or after it?

public class TraceFor {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            System.out.println(i);
        }
        System.out.println("Done");
    }
}
Output
1
2
3
Done

When does the i++ part of a for loop run?

Counting can go up, down or in any step we want

GoalThe lineValues
Upfor (int i = 1; i <= 5; i++)1 2 3 4 5
Downfor (int i = 5; i >= 1; i--)5 4 3 2 1
In steps of 5for (int i = 0; i <= 20; i += 5)0 5 10 15 20
Odd numbersfor (int i = 1; i < 10; i += 2)1 3 5 7 9

Three loops in one program

We use print to keep the values on one line, then an empty println() to move to the next line. Change the third loop to print the multiples of 3 up to 30.

public class Countings {
    public static void main(String[] args) {
        for (int i = 1; i <= 5; i++) {
            System.out.print(i + " ");
        }
        System.out.println();

        for (int i = 5; i >= 1; i--) {
            System.out.print(i + " ");
        }
        System.out.println();

        for (int i = 0; i <= 20; i += 5) {
            System.out.print(i + " ");
        }
        System.out.println();
    }
}
Output
1 2 3 4 5
5 4 3 2 1
0 5 10 15 20

Down in steps of 3. What does this print?

public class DownByThree {
    public static void main(String[] args) {
        for (int i = 10; i > 0; i -= 3) {
            System.out.println(i);
        }
    }
}
Show the output
Output
10
7
4
1

Why? After 1, i becomes -2, so the test i > 0 is false before printing, which is why -2 never appears.

A loop variable declared in for does not outlive the loop

The scope of a variable is the part of the program where its name is known. A variable declared on the for line is known only inside the loop, which is why each loop can declare its own i, as you saw in the Countings program.

A name that no longer exists

We want to print i after the loop ends. Fix the program so it prints 1, 2 and 3, then After: 4.

public class AfterLoop {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            System.out.println(i);
        }
        System.out.println("After: " + i);
    }
}
Compiler messagecannot find symbol
Show the fix
public class AfterLoop {
    public static void main(String[] args) {
        int i;
        for (i = 1; i <= 3; i++) {
            System.out.println(i);
        }
        System.out.println("After: " + i);
    }
}
Output
1
2
3
After: 4

Why? After the closing brace of the loop, i no longer exists. If you need its value after the loop, declare it before the loop.

The same name twice

Fix the program so it prints 5, then 0 and 1, without changing the numbers.

public class TwoNames {
    public static void main(String[] args) {
        int i = 5;
        System.out.println(i);
        for (int i = 0; i < 2; i++) {
            System.out.println(i);
        }
    }
}
Compiler messagevariable i is already defined
Show the fix
public class TwoNames {
    public static void main(String[] args) {
        int total = 5;
        System.out.println(total);
        for (int i = 0; i < 2; i++) {
            System.out.println(i);
        }
    }
}
Output
5
0
1

Why? The first i is still alive at the for line, so another variable with the same name cannot be declared inside its scope. Rename one of them.

for suits a known count, while suits ending on an event

SituationBest fitExample
The count is known before startingforPrint the 7 times table
The loop stops on an eventwhileRead until -1, or until a number reaches 0
The body must run at least oncedo-whileAsk until the answer is valid

Which loop fits adding the digits of a number the user entered?

Which loop fits reading the grades of exactly 30 students?

Part two: sums and nested loops

A sum starts at 0, a product starts at 1

Sum and product together

Trace the program and watch the boxes sum and product. Change 5 to 10 and predict which grows faster. Why did we choose long for the product?

public class SumAndProduct {
    public static void main(String[] args) {
        int sum = 0;
        long product = 1;
        for (int i = 1; i <= 5; i++) {
            sum += i;
            product *= i;
        }
        System.out.println("Sum: " + sum);
        System.out.println("Product: " + product);
    }
}
Output
Sum: 15
Product: 120

Sum of the even numbers

Read a number n, then print the sum of the even numbers from 2 to n. Print nothing else. If n is less than 2 the answer is 0.

import java.util.Scanner;

public class SumOfEvens {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        // Add the even numbers from 2 to n, then print the sum

    }
}
stdin
10
Expected output
30
Hint 1

You can start at 2 and step by 2, so you do not need an if.

Hint 2

The loop line: for (int i = 2; i <= n; i += 2).

Solution
import java.util.Scanner;

public class SumOfEvens {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        int sum = 0;
        for (int i = 2; i <= n; i += 2) {
            sum += i;
        }
        System.out.println(sum);
    }
}

A times table is one loop and one print line

Choose a number

Run the program and enter a number yourself, then change the loop to print the table downwards from 10 to 1.

import java.util.Scanner;

public class TimesTable {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Number: ");
        int n = input.nextInt();
        for (int i = 1; i <= 10; i++) {
            System.out.println(n + " x " + i + " = " + n * i);
        }
    }
}

Parentheses and joining text, from earlier lectures. What does this print?

public class TimesTrap {
    public static void main(String[] args) {
        for (int i = 1; i <= 2; i++) {
            System.out.println("Result: " + 3 + i);
            System.out.println("Result: " + (3 + i));
        }
    }
}
Show the output
Output
Result: 31
Result: 4
Result: 32
Result: 5

Why? Without parentheses "Result: " + 3 becomes text and i is stuck on. With them, 3 + i is added first. The n * i in the last program needs no parentheses, because multiplication comes before +.

The times table

Read a number n without printing a prompt, then print its times table from 1 to 10 in the form 3 x 1 = 3.

import java.util.Scanner;

public class TimesExercise {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        // Print ten lines

    }
}
stdin
3
Expected output
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
3 x 10 = 30
Hint 1

Watch the spaces: n + " x " + i + " = " + n * i.

Solution
import java.util.Scanner;

public class TimesExercise {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        for (int i = 1; i <= 10; i++) {
            System.out.println(n + " x " + i + " = " + n * i);
        }
    }
}

In a nested loop, the inner loop finishes completely for each outer iteration

Think of a clock: the minute hand goes all the way round each time the hour hand moves one step. The outer loop is the hour hand, and the inner loop is the minute hand.

Trace i and j

Press "Debug line by line", then "Next line" many times. Before each press, predict i and j. Notice that j starts again from 1 each time i changes. Then change 3 to 2 and work out the number of lines before running.

public class NestedTrace {
    public static void main(String[] args) {
        for (int i = 1; i <= 2; i++) {
            for (int j = 1; j <= 3; j++) {
                System.out.println("i=" + i + " j=" + j);
            }
            System.out.println("end of i=" + i);
        }
    }
}
Output
i=1 j=1
i=1 j=2
i=1 j=3
end of i=1
i=2 j=1
i=2 j=2
i=2 j=3
end of i=2
iValues of j in this iterationj when the inner loop endsLines printed
11 2 343 + 1
21 2 343 + 1

How many times does the line count++ run?

for (int i = 0; i < 4; i++) {
    for (int k = 0; k < 5; k++) {
        count++;
    }
}

print stays on the line and println ends it, so together they make a grid

This is the secret of all the patterns to come: the inner loop writes one line with print, the println() after it ends that line, and the outer loop repeats the lines.

The multiplication grid

We use \t to line the columns up. Trace one row only, then press Continue. Then grow the grid to 5 rows and 5 columns, and delete the println() to see what happens.

public class MultiplicationGrid {
    public static void main(String[] args) {
        for (int row = 1; row <= 3; row++) {
            for (int col = 1; col <= 4; col++) {
                System.out.print(row * col + "\t");
            }
            System.out.println();
        }
    }
}
Output
1	2	3	4
2	4	6	8
3	6	9	12

We moved the println inside the inner loop. What does this print?

public class InnerPrintln {
    public static void main(String[] args) {
        for (int row = 1; row <= 2; row++) {
            for (int col = 1; col <= 2; col++) {
                System.out.print("*");
                System.out.println();
            }
        }
    }
}
Show the output
Output
*
*
*
*

Why? println() runs after every star, so each star gets its own line: 2 × 2 = 4 lines. Where the println sits decides the shape of the output.

Part three: patterns, primes and loop control

A rectangle: the same number of stars in every row

  1. How many rows?That is how many times the outer loop turns.
  2. How many stars in row number row?That is the test of the inner loop, and it is the key question in every pattern.
  3. End each row with println()

A rectangle of stars

Predict the shape before running. Then change it to 2 rows and 7 columns, and after that change the star to #.

public class Rectangle {
    public static void main(String[] args) {
        for (int row = 1; row <= 3; row++) {
            for (int col = 1; col <= 5; col++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}
Output
*****
*****
*****

A triangle: the inner loop depends on the row number

The only difference from the rectangle is that the inner test is now col <= row instead of a fixed number: row 1 has one star, row 2 has two, and so on.

A right triangle

Trace the first two rows and watch how many times the inner loop turns. Then print row in place of the star, and after that print col: what is the difference?

public class Triangle {
    public static void main(String[] args) {
        for (int row = 1; row <= 4; row++) {
            for (int col = 1; col <= row; col++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}
Output
*
**
***
****

An upside-down triangle

Read a number n, then print an upside-down triangle: n stars in the first row, one fewer in each row, down to one star. Print nothing else.

import java.util.Scanner;

public class InvertedTriangle {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        // Print the triangle using two nested for loops

    }
}
stdin
4
Expected output
****
***
**
*
Hint 1

Make the outer loop count down: row starts at n and ends at 1.

Hint 2

The number of stars in a row still equals row.

Solution
import java.util.Scanner;

public class InvertedTriangle {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        for (int row = n; row >= 1; row--) {
            for (int col = 1; col <= row; col++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

A pyramid: one loop for spaces, then one for stars, inside each row

Row rowSpaces n - rowStars 2 * row - 1
131
223
315
407

The pyramid

Trace the first row only, then press Continue. Change n to 6. Then delete the spaces loop and explain the shape you get.

public class Pyramid {
    public static void main(String[] args) {
        int n = 4;
        for (int row = 1; row <= n; row++) {
            for (int s = 1; s <= n - row; s++) {
                System.out.print(" ");
            }
            for (int star = 1; star <= 2 * row - 1; star++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}
Output
   *
  ***
 *****
*******

A right-aligned triangle

Read n and print a right-aligned triangle: row number row has n - row spaces, then row stars. Print nothing else.

import java.util.Scanner;

public class RightAligned {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        // One outer loop, with two loops inside it

    }
}
stdin
3
Expected output
  *
 **
***
Hint 1

Copy the shape of the pyramid and change only the number of stars.

Hint 2

The test of the stars loop is star <= row.

Solution
import java.util.Scanner;

public class RightAligned {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        for (int row = 1; row <= n; row++) {
            for (int s = 1; s <= n - row; s++) {
                System.out.print(" ");
            }
            for (int star = 1; star <= row; star++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

A number is prime if no divisor exists: assume so, then look for proof otherwise

A prime number is greater than 1 and divides only by 1 and itself. The pattern is a flag variable: a boolean we assume is true, then change to false at the first evidence.

Check the number

Trace the program and watch i and prime. Then change n to 21 and trace it again: at what value of i does prime change? Do the remaining iterations help after that? We return to this question in the next section.

public class PrimeCheck {
    public static void main(String[] args) {
        int n = 7;
        boolean prime = n > 1;
        for (int i = 2; i < n; i++) {
            if (n % i == 0) {
                prime = false;
            }
        }
        System.out.println(n + " prime? " + prime);
    }
}
Output
7 prime? true

The primes up to n

Read n and print the primes from 2 to n on one line, with a space after each. You will need an outer loop over the numbers and an inner loop that checks each one.

import java.util.Scanner;

public class PrimesUpTo {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        // For each number from 2 to n, check it, then print it if it is prime

        System.out.println();
    }
}
stdin
10
Expected output
2 3 5 7
Hint 1

Declare boolean prime = true; inside the outer loop, so it goes back to true for each new number.

Hint 2

Pick another name for the inner loop, such as d: the divisor is not the number being checked.

Solution
import java.util.Scanner;

public class PrimesUpTo {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        for (int number = 2; number <= n; number++) {
            boolean prime = true;
            for (int d = 2; d < number; d++) {
                if (number % d == 0) {
                    prime = false;
                }
            }
            if (prime) {
                System.out.print(number + " ");
            }
        }
        System.out.println();
    }
}

break ends the loop, continue skips the rest of the iteration

Stop at the first evidence

This answers the question from the last section: once a divisor is found, searching further is pointless. Trace the program and notice that the loop ends at i = 3 without carrying on to 20. Delete break and trace it again to compare.

public class PrimeBreak {
    public static void main(String[] args) {
        int n = 21;
        boolean prime = n > 1;
        for (int i = 2; i < n; i++) {
            if (n % i == 0) {
                prime = false;
                System.out.println("Divisor: " + i);
                break;
            }
        }
        System.out.println(n + " prime? " + prime);
    }
}
Output
Divisor: 3
21 prime? false

continue jumps straight to the update. What does this print?

public class ContinueSkip {
    public static void main(String[] args) {
        for (int i = 1; i <= 5; i++) {
            if (i == 3) {
                continue;
            }
            System.out.print(i + " ");
        }
        System.out.println();
        for (int i = 1; i <= 5; i++) {
            if (i == 3) {
                break;
            }
            System.out.print(i + " ");
        }
        System.out.println();
    }
}
Show the output
Output
1 2 4 5
1 2

Why? continue skips printing 3 and carries on with the update. break ends the whole loop at 3, so nothing more prints.

int i = 1;
while (i <= 5) {
    if (i == 3) {
        continue;
    }
    System.out.println(i);
    i++;
}
Warning: in while, continue jumps to the test, so if the update comes after it, i never changes and the loop is infinite. Type this fragment inside main in the lab above, in place of its current lines, then press Stop.

Optional: a labelled break

A plain break leaves only the inner loop. To leave both loops at once, put a label before the outer one. Remove the name outer from the break line and compare the output. We rarely need this.

public class LabelledBreak {
    public static void main(String[] args) {
        outer:
        for (int i = 1; i <= 3; i++) {
            for (int k = 1; k <= 3; k++) {
                if (i * k == 4) {
                    break outer;
                }
                System.out.println(i + " x " + k);
            }
        }
    }
}
Output
1 x 1
1 x 2
1 x 3
2 x 1

Two common traps: a semicolon after for, and changing the loop variable inside

Look closely at the end of the for line. How many times does Hello print?

public class SemicolonTrap {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++);
        {
            System.out.println("Hello");
        }
    }
}
Show the output
Output
Hello

Why? The semicolon is the loop body: an empty statement repeated 3 times. The braces after it are not part of the loop, so Hello prints once, with no message from the compiler.

A message that looks unrelated

The message complains about i, yet i is declared right there. Where is the mistake?

public class SemicolonError {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++);
        {
            System.out.println(i);
        }
    }
}
Compiler messagecannot find symbol
Show the fix
public class SemicolonError {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            System.out.println(i);
        }
    }
}
Output
1
2
3

Why? The semicolon ended the loop, and the scope of i ended with it, leaving the print line outside the loop. So the compiler does not know i there, although the real cause is on the line before.

We also grow i inside the body. What does this print?

public class ModifyLoopVar {
    public static void main(String[] args) {
        for (int i = 0; i < 6; i++) {
            System.out.println(i);
            i++;
        }
    }
}
Show the output
Output
0
2
4

Why? i grows twice per iteration, once in the body and once in the update, so the odd numbers are skipped. Anyone reading only the for line would think the loop turns 6 times.

Review questions

How many times does the body of for (int i = 3; i < 15; i += 3) run?

Inside two nested loops, which loop does a plain break take you out of?

Which inner test makes the shape a triangle rather than a rectangle?

Trace on paper, then check with the debugger. What does this print?

public class ReviewNested {
    public static void main(String[] args) {
        int total = 0;
        for (int i = 1; i <= 3; i++) {
            for (int k = 1; k <= i; k++) {
                total += k;
            }
        }
        System.out.println(total);
    }
}
Show the output
Output
10

Why? At i = 1 we add 1, at i = 2 we add 1 + 2 and at i = 3 we add 1 + 2 + 3. The total is 1 + 3 + 6 = 10.