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
true
before 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.
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.
(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!");
(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
for
loop increments the variablei
, starting from 0, until it reaches the value 3, andthe inner
for
loop 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.
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
for
loop body does not use acontinue
statement, then the translation fromfor
loop intowhile
loop outlined above is correct;otherwise, if a
for
loop body contains acontinue
statement, and we translate thefor
loop into the correspondingwhile
loop as outlined above, then thecontinue
statement 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.)
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
for
Statement”
Exercises#
Note
These exercises are not part of the course assessment. They are provided to help you self-test your understanding.
(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 letter
if \(x\) isA
…Z
The character 'x' is a lowercase letter
if \(x\) isa
…z
The character 'x' is a digit
if \(x\) is0
…9
The character 'x' is a special symbol
if \(x\) is one of:#
!
+
\
The character 'x' is not known
if \(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
String
object""
containing 0 characters.You will need to use the
String
objects’ 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 literalchar
orString
. Therefore, to represent the Unicode character\
, we must write the literal character'\\'
.