Counting with a while loop
A while loop can produce a sequence of numbers if you let a variable hold the current number, print it, and move it forward on every pass. This program prints the numbers from 0 through 4:
var i = 0
while (i < 5) {
println(i)
i++
}
The output is five lines:
0
1
2
3
4
Tracing it shows the pattern. Before the loop, i is 0. Each time the condition i < 5 is checked and found true, the body prints i and then adds 1. After printing 4, i becomes 5, the check 5 < 5 is false, and the loop ends. The value 5 is never printed, because the check happens before the body.
Initialization and condition
Two choices decide which numbers appear:
- The initial value is the first number printed. Starting
iat 0 prints 0 first, and starting it at 3 prints 3 first. - The condition decides the last number. With
i < 5the last printed value is 4. Withi <= 5it would be 5. The difference between<and<=is the usual source of off-by-one errors.
Tracing the loop
For the exercise below, the trace begins with counter at 3. Each pass prints the current value and then adds 1, so the printed values are 3, 4, 5 and so on. When the counter reaches 10, the condition 10 <= 10 is still true, so 10 is printed too. Only when the counter becomes 11 does the test fail. Reading a loop this way, one value at a time, is the most reliable way to find mistakes in it.
The exercise
The task is to print every number from 3 to 10, one per line. It has four steps.
- Declare the counter with
var counter = 3. The first number to print is 3, so that is where it starts. It is avarbecause the loop will change it, and avalcan't be reassigned. - Write the loop with the condition
counter <= 10. The task includes 10, so the condition must stay true whencounteris 10. With< 10the last number printed would be 9. - Print the counter with
println(counter). The function ends the line after the value, so each number is on its own line. - Increase the counter with
counter++. Without this line,counterstays 3, the condition is always true, and the loop never ends.
var counter = 3
while (counter <= 10) {
println(counter)
counter++
}
The output is the numbers 3, 4, 5, 6, 7, 8, 9 and 10, each on its own line. The loop body runs eight times, because 10 - 3 + 1 = 8. After the loop, counter holds 11.
Checking your work
Check a loop by looking at its first and last printed values. The first is the starting value, 3. The last is the largest value that still passes the condition: 10 passes 10 <= 10, while the next value, 11, fails it and ends the loop. If the output stops at 9 or runs to 11, the condition is wrong.
Gotchas
- Off by one. To include the last number, use
<=with that number, or<with the number after it. Bothcounter <= 10andcounter < 11work here. - Update before print. If
counter++comes first in the body, the first number printed is 4 and the last is 11. - Printing text instead of the value.
println("counter")prints the word, not the number. - Using
val.counter++on avalis the compile error'val' cannot be reassigned.
Key takeaways
- The initial value of the counter is the first number the loop handles.
- The condition is checked before each pass, so a number that fails it is never printed.
- Use
<=when the final number is included. - Update the counter inside the body, or the loop runs forever.