Module 4, Part 1: More About Loops#
In this first part of Module 4 we continue exploring how to write Java programs with loops. We introduce a new form of loop: the “for” statement. We also discuss the “continue” statement to control the execution of a loop.
For Statement#
Besides the “while” statement and
the “do-while” statement,
Java provides a third form of looping construct, called the for statement
(or “for loop”). A for loop can be a convenient alternative to a while loop
in cases where the loop has the following characteristics:
there is an initialisation statement that we want to execute only once, before starting the loop;
there is a loop condition that must evaluate to
truebefore executing the loop body (otherwise, the loop ends);there is an update statement that we want to execute just at the end of the the loop body, and just before the loop condition is evaluated again.
The for statement has the following syntax:
1for (init_statement; bool_expr; update_statement) {
2 // Statements that are executed at each loop repetition
3}
4// Other statements can follow (optionally)
The behaviour of the for loop above corresponds to the following
while loop: (NOTE: this correspondence is slightly inaccurate, as we will
discuss below — but it is good enough for now)
1{
2 init_statement;
3 while (bool_expr) {
4 // Statements that are executed at each loop repetition
5 update_statement; // Executed just at the end of the loop body
6 }
7}
8// Other statements can follow (optionally)
When represented as a flowchart, the for statement (including an optional
break statement) looks as follows — where the highlighted part (excluding
the loop condition bool_expr) is the loop body. Whenever we spot the following
pattern in a flowchart, we should consider using a for statement when writing
the corresponding Java program.
Example 27 (Summing numbers using a for loop)
Suppose we need to write a program that asks the user to provide a positive number \(n\), and then computes the sum of all numbers between 1 and \(n\). (Also suppose that we do not know the algorithm that Carl Friedrich Gauss invented when he was a child.)
We can achieve the result with the following code:
1var s = new java.util.Scanner(System.in);
2s.useLocale(java.util.Locale.ENGLISH);
3
4System.out.println("Please write a positive number:");
5var n = s.nextInt();
6
7var sum = 0; // Will be updated during the computation of the sum
8for (var i = 1; i <= n; i = i + 1) {
9 sum = sum + i;
10}
11System.out.println("The sum of all numbers from 1 to " + n + " is: " + sum);
12s.close();
The code above is equivalent to the following, which uses a while loop
instead: (for clarity, the for loop above and the equivalent while
loop below are highlighted)
1var s = new java.util.Scanner(System.in);
2s.useLocale(java.util.Locale.ENGLISH);
3
4System.out.println("Please write a positive number:");
5var n = s.nextInt();
6
7var sum = 0; // Will be updated during the computation of the sum
8{
9 var i = 1; // Initialisation statement of the 'for' loop
10 while (i <= n) { // Loop condition of the 'for' loop
11 sum = sum + i; // Body of the 'for' loop
12 i = i + 1; // Update statement of the 'for' loop
13 }
14}
15System.out.println("The sum of all numbers from 1 to " + n + " is: " + sum);
16s.close();
You can observe that the for loop is considerably shorter.
Remark 13 (Scopes)
In Example 27, in the code that uses the while loop,
notice the curly brackets {…} on lines 8 and 14: they delimit a
scope, and any variable declared inside that scope is not visible outside of
it. Consequently, the variable i declared on line 9 is usable between lines
10 and 14 — but it becomes non-existent on line 15.
You can see it for yourself: if you try to reference i outside its scope (e.g.
if you try to print its value on line 15), Java will report an error:
“Cannot find symbol: variable i”. (Try it on the Java shell!)
This corresponds to what happens in the for loop above in
Example 27: any variable declared in the initialisation
statement of the for loop is usable inside the for loop body, and does not
exist outside of it.
Tip
When writing for loops, it is quite common to increment an index variable, as
shown in Example 27. Java provides short-hand notation
for incrementing a variable: writing i++ is equivalent to writing i = i + 1.
Therefore, the for loop in Example 27 could be written
as:
1for (var i = 1; i <= n; i++) {
2 sum = sum + i;
3}
In a similar fashion, Java provides short-hand notation for decrementing a
variable: writing i-- is equivalent to writing i = i - 1. For example,
see the following program that prints a countdown:
for (var n = 10; n > 0; n--) {
System.out.println("Countdown: " + n);
}
System.out.println("Launch!");
Example 28 (Nesting loops)
The body of a for loop can contain any statement — and therefore, a for
loop can contain another for loop. This also applies to while and do-while
loops.
For instance, consider the following code snippet, which contains two nested
for loops:
the outer
forloop increments the variablei, starting from 0, until it reaches the value 3, andthe inner
forloop increments the variablej, starting from 0, until it reaches the value 2.
1for (var i = 0; i < 3; i++) {
2 System.out.println("i is now " + i);
3 for (var j = 0; j < 3; j++) {
4 System.out.println(" j is now " + j + ", while i is " + i);
5 }
6}
Try copy&pasting and executing this code snippet on the Java shell.
Observe that the inner loop is executed 3 times, i.e., once every time the body
of the outer loop is executed. The values of the variables i
and j change accordingly.
The continue Statement#
The continue statement can be used in any Java loop (while, do-while,
and for) to “skip” the rest of the current repetition of the loop body,
and possibly “continue” with the next repetition (if the loop condition is still true).
The flowcharts of while, do-while,
and for loops with a continue statement are depicted in
Fig. 14,
Fig. 15,
and Fig. 16 below.
Fig. 14 Flowchart of a while loop with a continue statement, jumping directly to
the next loop condition check.#
Fig. 15 Flowchart of a do-while loop with a continue statement, jumping directly to
the next loop condition check.#
Fig. 16 Flowchart of a for loop with a continue statement, jumping directly to the
update_statement — followed by the next loop condition check.#
Example 29 (A for loop with continue)
The following code snippet prints the numbers from 1 to 10 — and for each
number, it reports whether the number is even and/or divisible by 3. Notice that
the code snippet uses a continue statement (on line 7) to “skip” the part of
the loop body which prints “The number is divisible by 3”.
1for (var n = 1; n <= 10; n++) {
2 System.out.println("Number: " + n);
3 if ((n % 2) == 0) {
4 System.out.println(" The number is even");
5 }
6 if ((n % 3) != 0) {
7 continue; // Skip rest of the loop body, contine with next repetition
8 }
9 System.out.println(" The number is divisible by 3");
10}
Important
Observe that, in the flowchart of the for loop with continue
(Fig. 16 above), the continue statement
jumps to the execution of the update_statement, before checking the loop
condition again.
This is why the translation from for into while
loops outlined above and in
Example 27 is not entirely accurate. More precisely:
if a
forloop body does not use acontinuestatement, then the translation fromforloop intowhileloop outlined above is correct;otherwise, if a
forloop body contains acontinuestatement, and we translate theforloop into the correspondingwhileloop as outlined above, then thecontinuestatement would jump directly to the next loop condition check — without executing theupdate_statement!
(Try it yourself: translate the for loop in Example 29 into
a while loop as explained above, and observe the
different behaviour.)
Remark 14 (Using continue statements vs. program clarity)
The continue statement has drawbacks that are similar to those of the break
statement (discussed in Remark 11): it can make the loop
execution harder to understand. Therefore, the continue statement should be
only used when really needed.
Concluding Remarks#
You should now have an understanding of how to execute one or more statements repeatedly, depending on the result of a boolean expression, by using a For Statement. hem.
References and Further Readings#
You are invited to read the following section of the reference book: (Note: they sometimes mention Java features that we will address later in the course)
Section 6.4 - “The
forStatement”
Exercises#
Note
These exercises are not part of the course assessment. They are provided to help you self-test your understanding.
Exercise 24 (Does this loop terminate?)
The following code snippets contain some loops: read each one, and try to
determine whether it terminates. To check whether your guess is correct, run
the loop in the Java shell — and remember that you can interrupt the execution
of a loop by pressing Ctrl+C.
for (var i = 0; i < 10; i++) { System.out.println("i == " + i); }
for (var i = 20; i > 10; i++) { System.out.println("i == " + i); }
for (var i = 20; i < 10; i++) { System.out.println("i == " + i); }
Lab and Weekly Assessments#
During the lab you can try the exercises above or begin your work on the weekly assessments below.
Note
As an exercise, you can try solving these assessments using for loops
first, and then you could revise your solutions using while loops. For the
submissions on DTU Autolab, feel free to choose the solutions you like best.
Important
For each assessment, you can download the corresponding handout and submit your solution on DTU Autolab: https://autolab.compute.dtu.dk/courses/02312-E24.
For details on how to use Autolab and the assessment handouts, and how to submit your solutions, please read these instructions.
If you have troubles, you can get help from the teacher and TAs.
01 - Multiples#
Edit the file Multiples.java provided in the handout, and write a program
that reads from the console two inputs:
a number \(n\) (of type
int), anda number \(m\) (of type
int).
Then, the program must print all multiples of \(n\), ranging from \(n \times 0\) to \(n \times m\) (inclusive).
For instance, here is a possible execution of the program: (the highlighted lines are the user’s input)
52
4
52 * 0 = 0
52 * 1 = 52
52 * 2 = 104
52 * 3 = 156
52 * 4 = 208
When you are done, submit the modified file Multiples.java on DTU Autolab.
Warning
The automatic grading on DTU Autolab includes some additional secret checks that test your submission with more inputs. After you submit, double-check your grading result on DTU Autolab: if the secret checks fail, then your solution is not correct, and you should fix it and resubmit.
02 - Sum and Mean#
Edit the file SumMean.java provided in the handout, and write a program
that reads from the console:
first, a number \(n\) (of type
int, that you can assume to be non-negative), andthen, \(n\) values of type
double.
After reading such inputs, the program must print the sum of the given \(n\) values. Furthermore, if \(n \neq 0\), then the program must also print the mean of the given \(n\) values. Then, the program must end.
For instance, here is a possible execution of the program: (the highlighted lines are the user’s input)
4
1
2.0
3
4.0
The sum of the 4 given values is: 10.0
The mean of the 4 given values is: 2.5
When you are done, submit the modified file SumMean.java on DTU Autolab.
Hint
Your program can compute the sum of the \(n\) input values progressively, after it reads each value from the console.
Remember that, if we have a set of \(n\) input values \(x_1, \ldots, x_n\), then their mean \(\bar{x}\) is computed as:
\[ \bar{x} \;=\; \frac{1}{n}\sum_{i = 1}^n x_i \]
Warning
The automatic grading on DTU Autolab includes some additional secret checks that test your submission with more inputs. After you submit, double-check your grading result on DTU Autolab: if the secret checks fail, then your solution is not correct, and you should fix it and resubmit.
03 - String Characters Repetition#
Edit the file Ssttrriinngg.java provided in the handout, and write a program
that reads from the console two inputs:
a number of repetitions \(n\) (of type
int), anda whole line of characters (as a
String).
Then, the program prints the input string by repeating each one of its characters \(n\) times.
For example, if the input is:
3
D T U
The program must print:
DDD TTT UUU
When you are done, submit the modified file Ssttrriinngg.java on DTU Autolab.
Important
If you create a scanner s and then call s.nextInt() followed by
s.nextLine(), your program may read a number followed by an empty string:
the reason is explained e.g. in this article.
To avoid the issue, you may read the number of repetitions \(n\) by using (instead
of s.nextInt()):
var n = Integer.parseInt(s.nextLine());
Hint
You will need to use the String objects’ methods .length() and
.charAt(...), described in Some Useful String Methods.
04 - Characters#
Edit the file Characters.java provided in the handout, and write a program
that reads a whole line from the console, and then, for each character \(x\)
belonging to that line, prints:
The character 'x' is an uppercase letterif \(x\) isA…ZThe character 'x' is a lowercase letterif \(x\) isa…zThe character 'x' is a digitif \(x\) is0…9The character 'x' is a special symbolif \(x\) is one of:#!+\The character 'x' is not knownif \(x\) none of the above
The program must keep reading lines and printing the descriptions of their
characters (as explained above) until the standard input stream is closed (by
pressing Ctrl+D — or, on Windows, Ctrl+Z and then ⏎).
For example, if the line read from the console is the string Hej!, the
program must print:
The character 'H' is an uppercase letter
The character 'e' is a lowercase letter
The character 'j' is a lowercase letter
The character '!' is a special symbol
When you are done, submit the modified file Characters.java on DTU Autolab.
Hint
This program will need to loop through all characters of each input line. Consider that the program may read an empty line from the console, i.e. a
Stringobject""containing 0 characters.You will need to use the
Stringobjects’ methods.length()and.charAt(...), described in Some Useful String Methods.Remember that, in Java, we write the literal
'A'to represent the value (of typechar) of the characterA,'B'for the value of characterB, etc.You can find the numerical values of Unicode characters here:
Appendix C of the reference book, or
Observe that Java uses the numerical Unicode values to compare characters. So, for example: (try the following on the Java shell!)
the expression
'z' > 'a'producestrue, because'z'has Unicode value 122, while'a'has Unicode value 97;the expression
'D' >= 'F'producesfalse, because'D'has Unicode value 68, while'F'has Unicode value 70.
Remember that the backslash character
\must be escaped when it is written in a literalcharorString. Therefore, to represent the Unicode character\, we must write the literal character'\\'.