Decrementing The For... Next & Endless Loops
Derek Kelly
Scrolling text backward in a RUNning program can be programmed almost as easily as scrolling text forward. Scrolling text forward can be easily accomplished, as can be seen in the program in figure 1:
10 For I = 1 to 20 20 Print A$(I) 30 Get G$ 40 Next I.
The GET command in Applesoft BASIC allows a pause-until-any-key-is-hit way for a user to control the progress of a program. Here, after every string printed (A$(I), a pause is inserted. After each pause, the printing of strings will proceed in a sequential manner, incrementing the counter for ‘I’ by 1 each time. This is forward scrolling.
But what if you want to go backward? Suppose you want the previous string by a count of 1, 2, to the first printed string? Can you go backward? The answer is Yes, and it's simple to accomplish. But like the various problems associated with For... Next loops generally, if not properly constructed, e.g., with no GOTO's that branch away totally from the loop, is that For... Next loops can involve endless loops, whether such loops run forward or backward.
In any well-constructed rogram module, there should be only one point of entrance to that module, and only one real exit. Some programmers who use GOTO, and related statements, have been known to construct programs where under normal use the program will "hang" somewhere, a somewhere often caused by a GOTO or a number of GOTO's which send the program around in circles. For example, consider programs A and B below. A has one entrance and exit, B has many:
10 GOSUB 100 . . 100 For I = 1 to 230 : Print "!"; : GOSUB 5 110 GOSUB 200 : GOSUB 300 120 NEXT I 130 RETURN Program A
10 For I = 1 to 33 20 If I = Int(I/11) Then GOTO 101 30 GET G$ : If G$ = "?" Then GOTO 163 . . . 163 Print " = " : GOTO 194 101 For J = l To 3 : If I = J Then GOTO 121 : Next J 102 GOTO 30
Program B
Program A is called by a GOSUB from line 10. Program A does one set of functions in the program as a whole. When called, it does what it's supposed to, and then returns. Program B, on the other hand, GOTO's all over the place, and one can't predict that any one GOTO will even find its way back to the place that started the GOingTO process. Under normal conditions, and presupposing that the GOSUBs called by Program A are well-constructed, then we can reasonably predict that program A will not cause an endless loop, while Program B most certainly may contain an endless loop or two that will "hang" your computer.
The two short programs above affect the forward running of For... Next loops. If a user desires to decrement rather than increment a For... Next loop so as to reverse the order of a printout, and be able to review previously printed items, then other endless loop possibilities arise.
Take Program A as an example. I might want to add a pause to the program, so I add III Get G$: If G$ = "?" Then GOTO 130. This GOTO is OK because it takes place within the routine.
Now I want to add a provision to reverse the loop. Since the "NEXT I" statement increments a counter by 1 (or whatever), to reverse print, I must subtract 2 from the I counter to get the next previous record. So my program now looks like PROGRAM C:
100 For I = 1 to 230 : Print "!"; : GOSUB 5 110 GOSUB200 : GOSUB300) 111 Get G$ : If G$ = "-" Then I = 1-2 120 NEXT I 130 RETURN
Program C
As soon as Program C is RUN, you will see that it decrements to 1 then to -1 and so on. You don't want negative numbers, so another line of code will have to be added. In addition, when the counter gets to ‘-1’, the computer — at least my APPLE — hangs and prints out a steady, unstoppable — except by RESET, stream of 1's... 1.1.1.1.1.1.1.1.1.1.... This problem can be avoided by changing line 111 to read:
111 Get G$ : IF G$ = "-" Then I = I-2 : If I < = 0 Then I = 0 If I = 0 or less than zero, then the first item will be printed, as I will = 0 before the execution of the NEXT which will increment I by 1 (or more) to 1.
The simple program C, if improved to include the line 111 above, will be able to process the forward and backward scrolling in any program in which it is called.
In general, there is no formula that can guarantee that a program has no endless loops. It is always possible for some bug such as an endless loop to exist under certain conditions in any program. Since you can't be sure about the absence of bugs, you have to make do with the presence of controls to limit the possibility of harmful bugs.