
Computers are good at doing the same thing again, fast and without getting bored. So far every statement in your programs has run once. This section is about running one many times - a set number of times, which is the job of for.
for I := 1 to 5 do
Write(I, ' ');
1 2 3 4 5
I is an ordinary integer variable, declared under var, called the control variable. for sets it to 1 and does the statement after do; then sets it to 2 and does it again; and so on, up to 5. Inside the loop, I tells you which time round it is.
Count down with downto:
for I := 5 downto 1 do
Write(I, ' ');
5 4 3 2 1
If the start is already past the end - for I := 5 to 1 - the statement is not done at all. And when the loop is over, the control variable holds the last value it was given.
The control variable does not have to be a number. It can be a character:
for C := 'A' to 'J' do
Write(C);
ABCDEFGHIJ
It cannot be a real - Error 30: Simple type expected - because a real has no "next one" to count to.
As with if, do takes one statement, and begin and end make several into one:
for I := 1 to 10 do
begin
Write(I:2, ' x ', N, ' = ');
Writeln(I * N:3);
end;
Leave the begin and end out and only the first statement is repeated. The rest is done once, after the loop has finished.
A loop and a variable that grows each time round is how programs total things:
Sum := 0;
for I := 1 to 100 do
Sum := Sum + I;
Writeln(Sum);
prints 5050. Setting Sum to 0 first matters: a variable starts as rubbish (S8), and adding to rubbish gives rubbish.
The statement a for repeats can itself be a for:
for Row := 1 to 3 do
begin
for Col := 1 to 4 do
Write(Row * Col:4);
Writeln;
end;
1 2 3 4
2 4 6 8
3 6 9 12
For each row, the inner loop runs right through; then the Writeln ends the line. The inner loop needs its own control variable.
A compiled loop is fast. On the Einstein, for I := 1 to 30000 do ; - a loop that does nothing, thirty thousand times - takes about three quarters of a second. That is some 39,000 times round a second. With X := X + 1 inside, about 23,000.
If you have done the Xtal BASIC course, compare its figure of about 850 times round a second for its own bare loop. This is the same machine. The difference is the compiler: Turbo has turned your loop into Z80 machine code before it runs.
program Table;
var
N, I: Integer;
begin
Write('Which table? ');
Readln(N);
for I := 1 to 10 do
begin
Write(I:2, ' x ', N, ' = ');
Writeln(I * N:3);
end;
end.
Starting from
Turbo freshly started, Y, a new work file called TABLE.
What you should see
With 7:
Which table? 7
1 x 7 = 7
2 x 7 = 14
3 x 7 = 21
4 x 7 = 28
5 x 7 = 35
6 x 7 = 42
7 x 7 = 49
8 x 7 = 56
9 x 7 = 63
10 x 7 = 70
1 to 10 to 10 downto 1. What happens to the table?begin and the end; round the two lines in the loop. What is printed now, and why is there only one answer at the end?13.1 Count down from 10 to 1 on one line, then print Lift off!.
13.2 Ask for a number N and print the total of all the numbers from 1 to N. Try 100.
13.3 Print a triangle of stars, five rows, one star on the first row and five on the last.
Worked solutions are in Appendix II.
| Symptom | Cause |
|---|---|
| Only the first statement repeats; the rest happens once at the end | No begin and end round the loop's statements. |
| A loop does nothing at all | Its start is past its end - 5 to 1. Use downto to count down. |
Error 30: Simple type expected | The control variable is a real. Use an integer. |
| A total is wildly wrong | The total was not set to 0 before the loop - or it went past 32767. |
| Answers turn negative part way through | The numbers went past 32767 and wrapped round (S7). |
for V := A to B do repeats a statement with V going from A to B; downto counts down; begin and end repeat several statements. A loop runs no times if its start is past its end. Loops can go inside loops, each with its own variable. A compiled loop goes round tens of thousands of times a second.
S14, Round And Round - loops that go on until something happens, and how to stop one that never does.