Chapter 6 - Loop Structures

Often, you will find that you want to repeat a block of statements many times. True BASIC provides two loop structures that let your programs execute the same statements several times. FOR structures, often called FOR loops, repeat a block of statements a specified number of times. DO structures, or DO loops, repeat a block of statements until a certain condition is satisfied.

This chapter introduces FOR and DO loops, as well as the EXIT statements that allow you to escape from the body of a loop.

FOR Loops
A FOR structure, or FOR loop, executes a block of statements a predetermined number of times. You form a FOR
structure using a FOR statement and a NEXT statement.

The FOR statement controls the number of times the loop will be repeated by defining the index variable, its ini- tial value, its ending or limit value, and its increment. The structure uses the index variable to monitor the number of passes through the loop. After each time through the loop, True BASIC increases the index variable by the value of the increment. As soon as the index variable becomes greater than its limit value, the program goes to the statement following the NEXT statement.

Here is a simple example using the PLOT statement, which is explained in more detail in Chapter 13 “Graphics.”
! Plot the square root function
SET WINDOW 0, 10, 0, 4
FOR x = 0 to 10 step .1
PLOT x, Sqr(x); NEXT x

Here the index variable x starts with value 0 and increases in steps of 0.1 until its value reaches 10. The NEXT statement that indicates the end of the loop’s body must specify the same index variable as the FOR statement that begins the loop. For each value of x, the body of the loop (the statements between the FOR and NEXT statements) executes exactly once. The STEP clause may be omitted from the FOR statement, in which case an increment of 1 is used:
! Table of square roots
PRINT “Number”, “Square Root” FOR number = 1 to 10
PRINT number, Sqr(number) NEXT number
Note that the index variable is increased at the NEXT statement. Thus, upon completion of the loop, the index variable equals the first value that exceeds the limit value. Hence in the first example, x has a value of 10.1 upon completion of the loop, while in the second example, number is equal to 11 after the loop.

If the initial value of the index is greater than the limit value, the loop is not executed. For example:
! Sum of odd numbers to n
LET sum = 0
FOR i = 1 to n step 2
! Odd numbers only
LET sum = sum + i
! Add them up
! Answer

If a value of 0 is supplied for n, then the body of the loop is not executed at all, and an answer of 0 is printed —
which is correct!

Negative increments are also allowed, in which case the loop continues until the value of the index variable is less than the limit value. For example,
FOR x = 3.2 to 1.3 step -0.5
executes the loop with x = 3.2, 2.7, 2.2, 1.7 and exits with x = 1.2. In the case of a loop with a negative increment, the loop body will not be executed at all if the initial value is less than the limit value.
Beware of unintentionally changing the value of the index variable inside the body of the loop. Although you may do so, it can lead to unexpected results.
Occasionally, you may want to exit from a FOR loop before the index variable completes its defined sequence. True BASIC provides the EXIT FOR statement for exactly this purpose. When an EXIT FOR statement is executed, True BASIC immediately skips to the line following the NEXT statement. Upon such an exit, the index variable retains the value it had when the EXIT FOR statement was executed.

The EXIT FOR statement is typically used as part of a decision structure. For example, you may want to examine a series of values until some condition is met:
! Find smallest integer whose 5th power
! is greater than a billion
FOR n = 1 to 100
! Examine each integer
IF n^5 > 1e9 then EXIT FOR NEXT n
! First integer to satisfy condition

If you find yourself using an EXIT FOR statement that is not part of a decision structure, then you most likely don’t need the loop that contains it.

DO Loops

Often, you do not know how many times you will need to execute the body of a loop. Instead, you want to repeat the loop until a condition is met. The DO loop fulfills this need.

A DO structure, or DO loop, starts with a DO statement and ends with a LOOP statement. The following program illustrates the simplest form of the DO structure:
PRINT “Happy Birthday!”
PRINT “And many happy returns.” LOOP
The DO loop in this program will repeat forever – that is, until the user stops the program. (To stop a running program, see the “True BASIC Environment” chapter in the Introduction section.) Loops that run forever are called infinite loops.

Although infinite loops are useful sometimes, you will usually want a loop that ends once a condition is met. True BASIC provides three ways of ending a DO loop. You may attach a condition to the DO statement or to the LOOP statement, or you may use an EXIT DO statement within the loop.

You have two options for attaching a condition to the DO statement: the WHILE clause and the UNTIL clause. The WHILE clause follows the DO keyword and specifies a condition as a logical expression:
INPUT PROMPT “Initial sum, annual interest rate? “: sum, interest
LET mo_rate = interest/12

DO WHILE sum < 1000
LET sum = sum * (1 + mo_rate) LET months = months + 1

PRINT “It will take”; months; “months at”; interest; “to earn $1,000.” END

As long as the value of the logical expression is true, the body of the loop will be executed repeatedly. Before each pass through the body of the loop, True BASIC checks the value of the condition; as soon as it becomes false, the program continues with the line immediately following the LOOP statement.

The UNTIL clause is used the same way, except that the loop continues until the condition becomes true. Thus, the following two DO statements have the same effect:
DO WHILE sum < 1000
DO UNTIL sum >= 1000

You may also attach a WHILE or UNTIL clause to the LOOP statement. The behavior of the loop will differ only in when the condition is checked. With the WHILE or UNTIL on the DO statement, the condition will be checked before each pass through the loop. Thus, there is a possibility that the body may never be executed. In the above example, if the user enters an initial value greater than 1000, the program will skip the body of the loop.

On the other hand, when the WHILE or UNTIL clause is on the LOOP statement, the condition will be checked after each pass through the loop. This guarantees that the body of the loop is always executed at least once. For instance:
! Ask whether we should continue
CALL Game_Sub
! User-defined subroutine
PRINT “Shall I continue”;
! Ask question
INPUT answer$
LOOP WHILE answer$ = “yes”

Here the LOOP statement contains the WHILE clause since the loop’s body must be executed at least once before there is an answer to check.

While it is possible to specify a WHILE or UNTIL clause for both the DO and LOOP statements, this is seldom necessary. Adding clauses to the top and bottom of a loop makes the loop’s behavior difficult to understand, and you should avoid this technique in all but exceptional circumstances.

Occasionally, you may want to exit from the body of a DO loop without waiting until the next pass. To do so, use the EXIT DO statement. When an EXIT DO statement is executed, True BASIC immediately skips to the line following the next LOOP statement.

As with the EXIT FOR statement, you will typically use an EXIT DO statement as part of a decision structure, as in the following code segment:

! Ask whether we should continue
CALL Step_One
! User-defined subroutine
INPUT PROMPT “Shall I continue”: answer$
! Ask question
IF answer$ = “no” then EXIT DO
CALL Step_Two ! User-defined subroutine

You may find it convenient to use an EXIT DO statement as well as a WHILE or UNTIL clause attached to the LOOP or DO statement. One might represent the normal termination, while the other may be an exit under special conditions.

Nested Loops

As with decision structures, you may nest a loop within another loop structure, and you may nest loops within decision structures or vice versa. You may nest loops and decision structures several layers deep; in other words, a nested structure may in turn contain another nested structure. The important rule is that the nested structure must be completed before the containing structure continues.

Here’s an example of nested loops and decision structures:
! Print triangular patterns of letters
FOR row = 1 to 6
FOR triangle = 1 to 3
FOR xcount = 1 to row
IF triangle = 1 then
PRINT “a”;
ELSEIF triangle = 2 then
NEXT xcount
! Move to next column for next triangle
NEXT triangle
! Move to next row
NEXT row

This program uses three nested loops and a decision structure to produce the following output:
a b c aa bb cc aaa bbb ccc aaaa bbbb cccc
aaaaa bbbbb ccccc aaaaaa bbbbbb cccccc

To better understand the operation of these structures, it is worthwhile to study this code in detail.

The program contains three nested FOR loops and one IF structure. Notice how the indentation helps identify the nested structures. One loop governs the number of rows of text contained in each triangle. One loop controls the number of triangles. And the third loop forms the triangular shapes by varying the number of characters printed on each line. The decision structure determines which letter is used for each triangle.

The outer-most loop uses row as its index variable. As you can infer from the name of its index variable, this is the loop that controls the number of rows printed. To change the number of rows used in the printed figure, simply change the limit value of this loop. Each pass through the body of this loop is responsible for printing one row of the final image.
The body of this outer-most loop contains the middle loop and a vacuous PRINT statement that ensures that each row starts on a new line. The middle loop uses triangle as its index variable and controls how many triangles are printed — changing the limit value of this loop will change the number of triangles. Each pass through the body of this middle loop prints the current row of a single triangle.

To accomplish this, the body of the middle loop contains the third and final loop plus a PRINT statement containing nothing but a comma to force the text cursor to the next print zone. The inner-most loop uses count as its index variable and the current value of row as its limit value. Since the value of row increases by one with each pass through the outer-most loop, using it as the limit value of the inner-most loop results in the inner-most loop being executed once on the first pass through the outer-most loop, twice on the second pass, and so forth. Each pass through this loop prints one character in the current row of the current triangle.

The body of the inner-most loop contains an IF structure that determines which letter to print based upon the value of triangle. Since the value of triangle changes with each pass through the middle loop, its value is used to print a different letter for each triangle.

Nested structures give you lots of power and flexibility; however, they can also create extremely complex programs that are difficult to debug and maintain. While nested structures provide the best solution to many programming needs, it is important that you understand how such nesting works before you use it.