<!-- PDF page 21 -->

## Chapter 3 – Looping

### Using FOR, TO and NEXT

Suppose you want to input five numbers and add them together. One way (don't type this in unless you are feeling dutiful) is to write:

```
 10 total=0
 20 INPUT a
 30 total+=a
 40 INPUT a
 50 total+=a
 60 INPUT a
 70 total+=a
 80 INPUT a
 90 total+=a
100 INPUT a
110 total+=a
120 PRINT total
```

This method is not good programming practice. It may be just about controllable for five numbers, but you can imagine how tedious a program like this to add ten numbers would be, and to add a hundred would be just impossible.

Much better is to set up a variable to count up to **5** and then stop the program, like this (which you should type in):

```
10 total,count=0,1
20 INPUT a
30 REM count=number of times
   that a has been input so
   far
40 total += a
50 count += 1
60 IF count <= 5 THEN GO TO 20
70 PRINT total
```

Notice how easy it would be to change line 60 so that this program adds ten numbers, or even a hundred.

This sort of counting is so useful that there are two special keywords to make it easier: **FOR** and **NEXT** that are always used together. Using these, the program you have just typed in does exactly the same as:

```
10 total = 0
20 FOR count = 1 TO 5
30   INPUT a
40   ;count=number of times
   that a has been input so
   far
50   total += a
60 NEXT count
```

<!-- PDF page 22 -->

```
80 PRINT total
```

The variable named **count**, is called the *control variable* of a **FOR … NEXT** loop.

The effect of this program is that **count** runs through the values **1** (the *initial value*), **2**, **3**, **4** and **5** (the *limit*), and for each one, lines 30, 40 and 50 are executed. Then, when **count** has finished its five values, line 80 is executed.

### STEP

The control variable, does not have to increase by 1 each time; you can change this 1 to anything you like by adding a **STEP** clause in the **FOR** command. The most general form for a **FOR** command is:

**FOR** *control variable* = *initial value* **TO** *limit* **STEP** *step*

where the *initial value*, *limit* and *step* are all *numeric expressions*; things in other words that the computer can calculate as numbers – like the actual numbers themselves, or sums, or the names of numeric variables. So, if you replace line 20 in the program by:

```
20 FOR count=1 TO 5 STEP 3/2
```

then **count** will run through the values **1**, **2.5** and **4**. Notice that you don't have to restrict yourself to whole numbers, and also that the control value does not have to hit the limit exactly – it carries on looping as long as it is less than or equal to the limit. Try this program, to print out the numbers from **1** to **10** in reverse order.

```
10 FOR n=10 TO 1 STEP -1
20   PRINT n
30 NEXT n
```

We have said before that the program carries on looping as long as the control variable is less than or equal to the limit. If you work out what this would mean in this case, you will see that it gives nonsense. The normal rule has to be modified; when the step is negative, the program carries on looping as long as the control variable is greater than or equal to the limit.

You must be careful if you are running two **FOR...NEXT** loops together, one inside the other. Try this program, which prints out the numbers for a complete set of six spot dominoes.

![The listing with a brace labelled n-loop inside a larger brace labelled m-loop](/documentation/manual/rev3/figures/p022-nested-loops.png)

```
10 FOR m=0 TO 6
20   FOR n=0 TO m
30     PRINT m;":";n;" ";
40   NEXT n
50   PRINT
60 NEXT m
```

You can see that the n-loop is entirely inside the m-loop – they are properly *nested*. What must be avoided is having two **FOR … NEXT** loops that overlap without either being entirely inside the other, like this:

![The listing with overlapping braces labelled m-loop and n-loop](/documentation/manual/rev3/figures/p022-overlapping-loops.png)

```
 5 REM this program is wrong
10 FOR m=0 TO 6
20   FOR n=0 TO m
30     PRINT m;":";n;" ";
40   NEXT m
50   PRINT
60 NEXT n
```

<!-- PDF page 23 -->

Two **FOR ... NEXT** loops must either be one inside the other, or be completely separate.

Another thing to avoid is jumping into the middle of a **FOR … NEXT** loop from the outside. The control variable is only set up properly when its **FOR** statement is executed, and if you miss this out the **NEXT** statement will confuse the computer. You will probably get an error report saying **NEXT without FOR** or **Variable not found**.

There is nothing whatever to stop you using **FOR** and **NEXT** in a direct command. For example, try:

```
FOR m=0 TO 10: PRINT m: NEXT m
```

You can sometimes use this as a (somewhat artificial) way of getting round the restriction that you cannot **GO TO** anywhere inside a command – because a command has no line number. For instance:

```
FOR m=0 TO 1 STEP 0: INPUT a: PRINT a:
NEXT m
```

The step of zero here makes the command repeat itself forever.

This sort of thing is not really recommended, because if an error crops up then you have lost the command and will have to type it in again –and **CONTINUE** will not work.

For additional speed and efficiency, *NextBASIC* also allows integer variables to be used as the index in **FOR … NEXT**, eg:

```
10 FOR %i=%$c9 TO 220
20   PRINT %i
30 NEXT %i
```

Integer loops run much faster than loops using a standard floating point control variable so they're preferred, especially where speed is a concern. Remember, however, that there is only a limited amount of integer variables, so a small bit of planning is warranted before starting with your program.

### EXIT

Sometimes we need to prematurely exit from a loop, be it a **FOR...NEXT** (See previous section) or **REPEAT...REPEAT UNTIL** (See next section) one. There is a seemingly obvious solution to that; jump out of the loop with **GO TO** however this is ill advised as **GO TO** doesn't exit a loop "cleanly" and therefore should not be used. Instead, there's a specialised command however that allows for a "clean" exit and that is (the aptly named):

**EXIT** [*n*]

where *n* is an optional line number or label to jump to. **EXIT** on its own will jump to the next statement after the end of the loop. Consider this example (the actual syntax of the loop is explained in the next section):

```
100 REPEAT
110   INPUT n
120   IF n=33 THEN EXIT 150
130 REPEAT UNTIL n<0
140 PRINT "Loop ended normally"
150 PRINT "Loop ended early"
```

The loop above will terminate normally (when the condition set on line 130 is satisfied) when you enter a negative value but early if you input enter the value **33**. **EXIT** can also be used to get out of nested loops using successive **EXIT** statements on the same line within

<!-- PDF page 24 -->

the innermost loop. Note that in such cases, only the final **EXIT** statement can take the optional parameter. To illustrate, consider the following example:

```
100 FOR i=1 TO 10
110   FOR j=1 TO 10
120     PRINT i,j
130     IF j*i>80 THEN EXIT:EXIT 170
140   NEXT j
150 NEXT i
160 STOP
170 PRINT "Product exceeded 80":STOP
```

Note that when in a loop that exists within a procedure and/or subroutine, it is acceptable to use **ENDPROC** or **RETURN** as a legitimate way to exit said loop.

### REPEAT ... REPEAT UNTIL loops

*NextBASIC* has another way of looping: a set of commands (or rather a single command block) called **REPEAT … REPEAT UNTIL**. You will have noticed that **FOR … NEXT** relies on counting to control the loop however you can also use a condition to control a loop. This type of loop begins with a **REPEAT** statement to indicate the beginning of the loop and a **REPEAT UNTIL** statement at the end, which also contains the condition to exit the loop. Try this:

```
10 REPEAT
20   INPUT "Enter a number,
   or enter -1 to stop > ";n
30   PRINT n
40 REPEAT UNTIL n=-1
50 PRINT "Thank you!"
```

This program will keep accepting numbers and printing them, until you type -1 when it will politely thank you for your numbers. In a **REPEAT … REPEAT UNTIL** loop, everything between the **REPEAT** and the **REPEAT UNTIL** command will be executed (in this case, this would be lines 20 and 30), until the condition in the **REPEAT UNTIL** statement becomes *true* (in this case, that the number you have entered is **-1**). Note that because the condition is checked at the end, the block of statements will always execute at least once.\
The following, for example, would print an erroneous statement:

```
10 x=1
20 REPEAT
30   PRINT "x is ";x;" but isn't 1"
40 REPEAT UNTIL x=1
50 PRINT "x is now 1."
```

Because line 30 is executed before the condition is checked at line 40, the message **x is 1, but it isn't 1** will still be printed, which is clearly wrong. Like a **FOR … NEXT** loop, you can also nest **REPEAT** loops, if you need to. So:

```
 10 n=1
 20 REPEAT
 30   PRINT "Counting to ";n
 40   c=1
 50   REPEAT
 60     PRINT c;", ";
```

<!-- PDF page 25 -->

```
 70     c+=1
 80   REPEAT UNTIL c>n
 90   PRINT "I'll count a bit
    higher"
100   n+=1
110 REPEAT UNTIL n=10
120 PRINT "OK, I'm done now"
```

will work fine – try it and see if you can see what is happening. You can also make a **REPEAT** loop continue indefinitely, if you use a zero in the **REPEAT UNTIL** statement. Type in this program:

```
10 REPEAT
20   PRINT "Hello world!"
30 REPEAT UNTIL 0
```

It will continue printing **Hello world!** to the screen, stopping only to ask if you want to scroll (unless you press the **BREAK** key, of course). Why? Zero can be seen in *NextBASIC* as *false* when used in this way, so the **REPEAT UNTIL 0** statement will always give a *false* result; hence the loop will continue indefinitely. Obviously you can exit such a loop with **EXIT** if need be

### WHILE

The **WHILE** command, used within a **REPEAT** loop, can provide an alternative way of leaving the loop before reaching the **REPEAT UNTIL** statement. If the condition in the **WHILE** statement is *true*, the loop continues. But if it is *false*, then the remaining statements in the loop will be ignored, the loop will be exited and the program will resume with the line after the **REPEAT UNTIL** statement. Try this:

```
10 REPEAT
20   INPUT "Enter a number, or
   enter a negative number to
   stop > ";n
30   WHILE n>=0
40   PRINT n
50 REPEAT UNTIL 0
60 PRINT "Thank you!"
```

It is a different approach to the example seen earlier, this time using **WHILE** to check the number entered (and also accepting any negative number to stop). **WHILE** can also be used to exit a loop before any statements are executed, should you need to. Try:

```
10 y=0
20 REPEAT : WHILE y<22
30   PRINT AT y,0;"This is
      line ";y;"."
40   y+=1
50 REPEAT UNTIL 0
```

You will note that when **y** reaches 22, the loop will exit before printing the line number. It should also be pointed out that not only can you place a **WHILE** anywhere within the loop, but you can also place more than one **WHILE** in the same loop, if you have different conditions to check to leave the loop.

<!-- PDF page 26 -->

### Error trapping within REPEAT … REPEAT UNTIL loops

Error trapping within **REPEAT … REPEAT UNTIL** loops as well as within *subroutines* and *procedures* is localised. Refer to the last section of *Chapter 4 – Localised Error Trapping* for a complete example that covers all cases of error trapping in these programming structures.

### Exercises

1. A control variable has not just a name and a value, like an ordinary variable, but also a limit, a step, and a reference to the statement after the corresponding **FOR** statement. Persuade yourself that when the **FOR** statement is executed all this information is available (using the initial value as the first value the variable takes), and also that this information is enough for the **NEXT** statement to know by how much to increase the value, whether to jump back, and if so where to jump back to. Run the third program above and then type:

   ```
   PRINT count
   ```

   Why is the answer **6**, and not **5**? (Answer: the **NEXT** command in line 60 is executed five times, and each time **1** is added to **count**. The last time, **count** becomes **6**; and then the **NEXT** command decides not to loop back, but to carry on, **count** being past its limit.)

2. What happens if you put **STEP 2** in line 20?

3. Change the third program so that instead of automatically adding five numbers, it asks you to input how many numbers you want adding. When you run this program, what happens if you input 0, meaning that you want no numbers adding? Why might you expect this to cause problems for the computer, even though it is clear what you mean? (The computer has to make a search for the command **NEXT count**, which is not usually necessary.) In fact this has all been taken care of.

4. In line 10 of the fourth program above, change **10** to **100** and run the program. It will print the numbers from **100** to **79** on the screen, and then say **scroll?** at the bottom. This is to give you a chance to see the numbers that are about to be scrolled off the top. If you press **n**, **BREAK** or the **space bar**, the program will stop with the report **D BREAK** - **CONT repeats**. If you press any other key, then it will print another 22 lines and ask you again.

5. Delete line 30 from the fourth program. When you run the new curtailed program, it will print the first number and stop with the message **0 OK**. If you type:

   ```
   NEXT n
   ```
   The program will go once round the loop, printing out the next number.

6. Refer back to the example in the **REPEAT UNTIL** section, where the message **x is 1, but it isn't 1** was displayed incorrectly. Rewrite this using **WHILE** so that the message does not appear when x is indeed 1. Change the value of **x** in line 10 to check this works correctly.

