|LOOPING THE LOOP|
|Because loops are so useful some special statements have been devised to make it easy to use them.
Program for printing J:
10 FOR J= 1 TO 152 (use SHIFT 4 for TO)
20 PRINT "$";
60 NEXT J
In chapter 9 it took 5 lines of program to get the same result using IF and GO TO statements. Note the ; after the PRINT statement. This tells the computer to print each J immediately after its predecessor. Try running this program. It's a pity that one can't have a dollar bill for each $ sign printed.
In BASIC these loops are normally called FOR loops. They are also widely known as DO loops (because other languages, such as FORTRAN, use DO instead of FOR).
There is nothing to stop us from putting a loop inside another loop - or putting several loops in:
Add the following lines to the program
30 FOR I = 1 TO 3
40 PRINT “£”
50 NEXT I
The Flowchart for this program is
You can jump out of a loop at any time. If you do this the loop control variable, will remain at whatever value if had got to when you jumped out. In our case the loop control variables were J for the major loop and I for the minor loop.
Try jumping out of the major loop at J = 100 add:
15 IF J = 100 THEN GO TO 1000
Run this. You'll see that you get fewer $'s and £'s. Get into command mode.
Now type PRINT J NEWLINE
The computer responds with 100
This shows two things
1. J was 100 when the program jumped out of the loop and stopped.
2. You can use PRINT to find out what state the control variables (or other variable) were in when the program stopped. This is especially useful when you are debugging programs.
If the loop is completed successfully for all values of J up to 152 (in this case) the control variable will be left at 153. This is because the NEXT J statement not only tests the value of but also increments J by 1. Some BASIC'S allow you to increment the control variable by other amounts, but this isn't possible on the ZX-80 (It's not a very useful feature anyway.)
All this is quite straightforward.
defines what variable you want to use, what value it should start at and at what value of control variable you want to leave the loop.
NEXT J reminds the computer that it is in a loop and tells it what variable it should be testing and (in fact) where it should jump back to if the loop isn't finished.
You can start at any value you like - try starting at J = 100.
The computer will go round the loop M - N + 1 times.
DON'T EVER jump into a loop unless you have just jumped out of it — if you do the computer will skip the FOR statement and will get very confused because it won't know what the control variable is, what it should start at and what it should finish at. It will do the best it can but it will probably stop when it gets to the NEXT statement. The error message will be of the form
1/LINE No. where 1 means "no FOR statement to match this NEXT statement",
or 2/LINE No. where 2 means "variable name not found".
You can try this by adding to the program:
5 GO TO 20
and running, and then adding
4 LET J = 4
and running (you must say RUN, not GO TO 4).
This will jump the ZX-80 into the major loop and it will stop when it gets to statement 60 (NEXT J) giving the error message 2/60 or 1/60.
In chapter 6 there was a program to divide one number by another to give a quotient to 3 decimal places.
Here is a program to give any number of decimal places. Statement 10 is a remark. The computer disregards REM statements when it executes programs. It's often useful to put comments and remarks into programs so that you can remind yourself what the program does when you look at it, often months later!
10 REM HIGH PRECISION DIVISION
20 PRINT "HOW MANY DECIMAL PLACES?"
30 INPUT D
40 PRINT "DIVIDEND?"
50 INPUT R
60 PRINT "DIVISOR?"
70 INPUT Y
80 LET Z = R/Y
90 LET R=R-Z*Y
100 PRINT "QUOTIENT IS "; Z; ";.”;
110 FOR J=1 TO D (110 to 150 evaluate
120 LET Z = 10* R/Y successive decimal
130 LET R=10*R-Z*Y places until the program
140 PRINT Z; has produced D
150 NEXT J decimal places)
Try running this, first of all with dividend = 1, divisor =3, D = 100 (say).
Note line 110
110 FOR J = 1 TO D
The starting and finishing values can be variables. This means that you can control the starting value and finishing value of the loop variable as you wish. The starting and finishing values can also be expressions of the form D/2, (D+1)*5 or indeed any other arithmetic expression.
110 FOR J = D*10 TO D*200 would be quite legal. However, the name of the control variable must be a single letter.
If you decide to use several FOR loops, one inside the other, be very careful in the way you go about it
is definitely not all right and could cause major problems. Another good reason for using flowcharts!.
One final point: because the control variable is effectively tested and incremented by the NEXT statement the main part of the loop will always be executed at least once regardless of the value of the control variable even if you have jumped into the loop.
A subroutine is a sub-program which may be used once or many times by the program (or main program).
10 FOR J= 1 TO 10
20 GO SUB 1000 (GO SUB is on key V)
30 NEXT J
40 PRINT "END"
900 GO TO 1200
1000 PRINT "SUBROUTINE EXECUTED"
1100 RETURN (RETURN is on key B)
Statement 20 tells the computer to GO TO the subroutine at line 1000.
Statement 1100 tells the computer that the subroutine is finished and that it should return to the main program. The computer then jumps to the line immediately following the GO SUB statement and executes that (in this case: NEXT J).
An example of the use of subroutines is given below: The Chinese Ring Puzzle.
As you will see, one subroutine can call another, or even call itself (this is called recursion).
THE CHINESE RINGS PUZZLE
This is a program which will say what moves are required to remove N rings from the T-shaped loop.
The mechanics of this wire puzzle are not important — roughly speaking "one" manipulates, the rings until they all come off the loop.
For an arbitrary number of rings the rules are as follows:
1. Each ring can be either on the loop or off it.
2. Only one ring may be moved (from on to off or vice versa) at a time.
3. The first ring may be moved at any time.
4. The ith ring (i>1) may be moved if and only if:
(a) All the rings numbered i-2 or lower are off.
(b) Ring i-1 is on.
... the rings higher up the loop (number >i) may be in any state, so:
To remove the first i rings:
1. Remove the first i-2 rings
2. Remove the ith ring
3. Replace the first i-2 rings
4. Remove the first i-1 rings
To replace the first i rings:
1. Replace the first i-1 rings
2. Remove the first i-2 rings
3. Replace the ith ring
4. Replace the first 1-2 rings
CHINESE RINGS (Recursive procedure)
10 INPUT N
20 GO SUB 100
100 IF N<1 THEN RETURN
120 LET N=N-2
130 GO SUB 100
140 PRINT N+2; "OFF",
150 GO SUB 500
160 LET N=N+1
170 GO SUB 100
180 LET N=N+1
500 IF N<1 THEN RETURN
520 LET N = N-1
530 GO SUB 500
540 LET N = N-1
550 GO SUB 100
560 PRINT N+2; "ON",
570 GOSUB5 500
575 LET N = N+2
Your output for the case N = 4 should look like:
2 OFF 1 OFF 4 OFF 1 ON
2 ON 1 OFF 3 OFF 1 ON
2 OFF 1 OFF
The GO SUB statement can be used in conjunction with a variable, e.g.
10 GO SUB G whereupon the computer will jump to the subroutine at line whose number is the value of G (if there is such a line).
As before, an expression can also be used.
In general it is not a very good idea to use variables or expressions in this way because the program may alter the variable in a way you hadn't foreseen and thus cause problems.