RISCOS.com

www.riscos.com Technical Support:
BBC BASIC Reference Manual

 


Control statements


Normally, lines in a BASIC program are executed in sequence, one after the other. However, the language includes two types of structure which alter this sequence:

  • Conditional structures allow statements to be executed only if certain conditions are met.
  • Loop structures allow statements to be executed repeatedly, either for a fixed number of times, or until a certain condition is met.

In all cases, the code is easier to read if it is clear which statements are in the loop and which are conditional on certain factors. This clarity can be achieved by use of the LISTO command before listing the programs, to indent the conditional and loop structures in the listing. All programs included in this chapter are listed as if the command:

LISTO 3

had been typed beforehand; this gives a space after the line number and indents structures.

IF... THEN... ELSE

The IF (single line) statement may be used to enable the computer to make a choice about whether or not to execute a statement or group of statements. It has the form

IF condition [THEN] statements [ELSE statements]

A condition is an expression that gives a number. It is said to be TRUE if the number if not zero, or FALSE if the number is zero. Usually the relational operators described below are used in conditional expressions.

The statements after the THEN keyword (which is optional, as indicated by the square brackets) are only executed if the condition is TRUE. If it is FALSE, the statements are skipped. However, if there is an ELSE, then the statements following that are executed if the condition is FALSE.

For example:

10 PRINT "What is 2 * 4"
20 INPUT ans%
30 IF ans% = 8 THEN PRINT "Well done" ELSE PRINT "Wrong" 

Line 30 contains a conditional expression. In the example shown the expression is TRUE (i.e. has a non-zero value) when ans% is equal to 8, and is FALSE (i.e. has a zero value) otherwise. Note that in an IF statement, either the THEN part or the ELSE part (if present) is executed, never both.

Any non-zero number is treated as TRUE in an IF statement, however, the comparison operators described in the following section return a particular value meaning TRUE: -1. They return 0 for FALSE, of course. In addition, there are two functions called FALSE and TRUE which return 0 and -1 respectively.

Operators

Two kinds of operators may be used in expressions:

  • relational operators
  • logical operators (on TRUE and FALSE values).
Relational operators

Relational operators can be used to evaluate numbers or strings:

Numbers

In the following, A and B can be integers or floating point numbers.

Operator Meaning
A = B TRUE when A is equal to B
A < B TRUE when A is less than B
A > B TRUE when A is greater than B
A <= B TRUE when A is less than or equal to B
A >= B TRUE when A is greater than or equal to B
A <> B TRUE when A is not equal to B
Strings
Operator Meaning
A$ = B$ TRUE when A$ and B$ are the same
A$ <> B$ TRUE when A$ and B$ are different
A$ < B$ String comparisons; see below:
A$ > B$
A$ <= B$
A$ >= B$
String comparison

Corresponding characters of each string are examined until either they are different, or the end of a string is reached. If the strings are the same length, and the corresponding characters are the same, the strings are said to be equal; otherwise, the shorter string is 'less than' the longer one.

In the case where the two corresponding characters differ, the relationship between the strings is the same as that between the ASCII codes of the mismatched characters. For example, "HI" < "Hi" yields TRUE, because the ASCII code of upper case I is less than that of lower case i. Similarly, "SIX" > "FIFTEEN" is TRUE because "SIX" starts with S, and the ASCII value of S is larger than that of F.

Logical operators (on TRUE and FALSE values)
Operator Meaning
NOT A TRUE when A is FALSE
A AND B TRUE if both A and B are TRUE
A OR B TRUE if either A or B or both are TRUE
A EOR B TRUE if either A or B but not both are TRUE

IF... THEN... ELSE... ENDIF

A block structured IF... THEN... [ELSE ...] ENDIF statement is available. It executes a series of statements, which may be split over several lines, conditionally on the result of the IF expression.

 10 n% = RND(10)
 20 m% = RND(10)
 30 PRINT "What is ";n% " * "m%;
 40 INPUT ans%
 50 IF ans% = n%*m% THEN
 60   PRINT "Well done"
 70 ELSE
 80   PRINT "Wrong"
 90   PRINT n%;" * ";m% " = ";n%*m%
100 ENDIF

The ENDIF on line 90 terminates the statement. It indicates that execution of the following statements is not dependent on the outcome of the conditional expression on line 50, so these statements are executed as normal. Without the ENDIF the computer has no way of knowing whether or not the statements on line 100 belongs to the ELSE part.

There are certain rules which must be obeyed when using IF... THEN... [ELSE...] ENDIF constructions:

  • The first line must take the form:
    IF condition THEN
    with THEN being the last item on the line.
  • The ELSE part need not be present, but if it is, the ELSE must be the first thing on a line (excluding spaces).
  • The ENDIF statement must be the first thing on a line (excluding spaces).
  • IF... THEN ... [ELSE ...] ENDIF statements may be nested: one may occur inside another. For example:
     10 DIM A%(10)
     20 count% = 0
     30 PRINT "Give me an integer between 0 and 9 ";
     40 INPUT number%
     50 IF number% >= 0 AND number% <= 9 THEN
     60   IF A%(number%) = 0 THEN
     70     PRINT "Thank you"
     80     A%(number%) = 1 : count% = count% + 1
     90   ELSE
    100     PRINT "You've already had that number"
    110   ENDIF
    120 ELSE
    130   PRINT number% " is not between 0 and 9 !"
    140 ENDIF
    150 IF count% < 10 GOTO 30

FOR... NEXT

The FOR and NEXT statements are used to specify the number of times a block of a program is executed. These statements are placed so that they surround the block to be repeated:

10 FOR N% = 1 TO 6
20   PRINT N%
30 NEXT N%

Type RUN and the following is produced:

	1
	2
	3
	4
	5
	6

The variable N% is called the control variable. It is used to control the number of times the block of code is executed. The control variable can be started at any number you choose, and you may alter the step size; the amount by which it changes each time round the loop.

10 FOR N% = -5 TO 5 STEP 2
20   PRINT N%
30 NEXT N%

This program produces:

	-5
	-3
	-1
	1
	3
	5

The step size can be negative so that the control variable is decreased each time. It does not have to be an integer value. You can also use a decimal step size, although this is not generally advisable. The reason is that numbers such as 0.1 are not exactly representable in the internal format used by the computer. This means that when the step is added to the looping variable several times, small errors may accumulate. You can see this by typing the following program:

10 FOR i=0 TO 100 STEP 0.1
20   PRINT i
30 NEXT i

The looping variable i doesn't reach exactly 100.

FOR ... NEXT loops may be nested. For example,

10 FOR N = 3.0 TO -1.0 STEP -2.0
20   FOR M = 2.5 TO 2.9 STEP 0.2
30     PRINT N,M
40   NEXT M
50 NEXT N

produces:

	3	2.5
	3	2.7
	3	2.9
	1	2.5
	1	2.7
	1	2.9
	-1	2.5
	-1	2.7
	-1	2.9

You do not need to specify the control variable to which NEXT refers. The following program produces the same results as the one above:

10 FOR N = 3.0 TO -1.0 STEP -2.0
20   FOR M = 2.5 TO 2.9 STEP 0.2
30     PRINT N,M
40   NEXT
50 NEXT

The program will now run slightly faster because the computer assumes that NEXT applies to the most recent FOR.

If you put variable names after NEXT you should not mix them up as shown below:

10 FOR N = 3.0 TO -1.0 STEP -2.0
20   FOR M = 2.5 TO 2.9 STEP 0.2
30     PRINT N,M
40 NEXT N
50   NEXT M

The output produced by this example is:

       3.0       2.5
       1.0       2.5
      -1.0       2.5
Not in a FOR loop at line 50

Loops must be nested totally within each other: they must not cross. In the above example, the N and M loops are incorrectly nested. BASIC tries to run the program, but when line 50 is reached, it gives an error message indicating that it cannot match the FOR statements with the NEXT statements.

Note: The reason the error wasn't given sooner, i.e. as soon as the mismatched NEXT was met, was that it is actually legal, though not advisable, to close more than one loop with a single NEXT. When BASIC meets a NEXT var statement, it terminates all open FOR loops until it meets one which started FOR var. Thus the NEXT N in the example above closed the FOR M loop before performing the NEXT N.

A FOR loop is ended when the control variable is:

  • greater than the terminating value (value in the FOR statement) when a positive step size is used.
  • less than the terminating value (value in the FOR statement) when a negative step size is used.

The loop is performed in the following sequence:

Assign the initial value to the control variable.
  1. Execute the block of code.
  2. Add the step to the control variable.
  3. Test against terminating value, and if it is to be performed again, go back to step 2.

The initial and terminating values and the step size are calculated only once, at the start of the loop.

One of the consequences of the way in which the loop is performed is that the block of code is always executed at least once. Thus,

10 FOR N = 6 TO 0
20   PRINT N
30 NEXT

produces:

         6

FOR ... NEXT loops are very versatile, since the initial and terminating values and the step size can be assigned any arithmetic expression containing variables or functions. For example:

10 REM Draw a sine curve
20 MODE 0 : MOVE 0,512
30 PRINT "Please give me a step size (eg 0.1) "
40 INPUT step
50 FOR angle = -2*PI TO 2*PI STEP step
60   DRAW 100*angle, 100*SIN(angle)+512
70 NEXT
80 END

REPEAT... UNTIL

The REPEAT ... UNTIL loop repeats a block of code until a given condition is fulfilled. For example:

10 REM Input a number in a given range
20 REPEAT
30   PRINT "Please give me a number between 0 and 9 "
40   INPUT N
50 UNTIL N >= 0 AND N <= 9
60 PRINT "Thank You"

If the result of the conditional expression following the UNTIL is TRUE, then the loop is ended and the statement following the UNTIL is executed. If, however, the result of the expression is FALSE, the block of code after the REPEAT is executed again and the conditional expression is re-evaluated.

REPEAT ... UNTIL LOOPS MAY BE NESTED IN THE SAME WAY AS FOR ... NEXT loops. They are also similar to FOR loops in that the body of the loop is always executed once, since no test is performed until the end of the loop is reached.

 10 REM Repeat questions until answered right first time
 20 REPEAT
 30   tries% = 0
 40   REPEAT
 50     PRINT "What is 20 * 23 + 14 * 11 ";
 60     INPUT ans%
 70     tries% += 1
 80   UNTIL ans% = 20 * 23 + 14 * 11
 90   REPEAT
100     PRINT "What is 12 + 23 * 14 + 6 / 3 ";
110     INPUT ans%
120     tries% += 1
130   UNTIL ans% = 12 + 23 * 14 + 6 / 3
140 UNTIL tries% = 2;

WHILE... ENDWHILE

The WHILE ... ENDWHILE loop repeats a block of code while a given condition holds true. For example:

10 X = 0
20 WHILE X < 100
30   PRINT X
40   X += RND(5)
50 ENDWHILE

The WHILE ... ENDWHILE LOOP HAS A CONDITIONAL EXPRESSION AT THE START OF IT. IF THIS EXPRESSION RETURNS TRUE_ THE BLOCK OF STATEMENTS FOLLOWING THE WHILE_ DOWN TO THE MATCHING ENDWHILE STATEMENT_ IS EXECUTED. THIS IS REPEATED UNTIL THE EXPRESSION RETURNS FALSE_ IN WHICH CASE EXECUTION JUMPS TO THE STATEMENT FOLLOWING THE MATCHING ENDWHILE. WE SAY 'MATCHING' ENDWHILE BECAUSE WHILE LOOPS MAY BE NESTED. THIS MEANS THAT WHEN BASIC IS LOOKING FOR AN ENDWHILE TO TERMINATE A LOOP_ IT MIGHT SKIP NESTED WHILE ... ENDWHILE loops.

Here is an example of nested WHILE loops:

10 A%=256
20 WHILE A%<>0
30   B%=1
40   WHILE B%<8
50     PRINT A%,B%
60     B%=B%*2
70   ENDWHILE
80   A%=A% DIV 2
90 ENDWHILE

WHILE ... ENDWHILE IS SIMILAR TO REPEAT ... UNTIL EXCEPT THAT THE CONDITIONAL EXPRESSION IS EVALUATED AT THE BEGINNING OF THE LOOP (SO THE BODY OF THE LOOP MAY NEVER BE EXECUTED IF THE CONDITION IS INITIALLY FALSE) AND THE LOOP REPEATS IF THE RESULT IS TRUE. THE FOLLOWING PROGRAM DEMONSTRATES THE FACT THAT REPEAT ... UNTIL LOOPS ARE ALWAYS EXECUTED AT LEAST ONCE_ WHEREAS THE WHILE ... ENDWHILE loops need not be executed at all.

10 REPEAT
20   PRINT "Repeat"
30 UNTIL TRUE
40
50 WHILE FALSE
60   PRINT "While"
70 ENDWHILE
80
90 PRINT "All done"

This program produces the following output:

Repeat
All done

CASE... OF... WHEN... OTHERWISE... ENDCASE

The IF ... THEN ... ELSE ... ENDIF CONSTRUCT IS USEFUL IF YOU WISH TO MAKE A CHOICE BETWEEN TWO ALTERNATIVES. THE CASE statement can be used when there are many alternatives to be acted upon in different ways.

The following program is a keyboard-controlled sketch pad. The statements after the WHENs alter the values of X% and Y%, and then DRAW a line.

 10 REM Draw a line depending on the L,R,U,D keys
 20 MODE 0
 30 MOVE 640,512
 40 X% = 640: Y% = 512
 50 REPEAT
 60   CASE GET$ OF
 70     WHEN "L","l": X% -= 40: DRAW X%,Y% :REM go left
 80     WHEN "R","r": X% += 40: DRAW X%,Y% :REM go right
 90     WHEN "D","d": Y% -= 40: DRAW X%,Y% :REM go down
100     WHEN "U","u": Y% += 40: DRAW X%,Y% :REM go up
110   ENDCASE
120 UNTIL FALSE : REM go on forever ...

This program reads in the character of the next key pressed and checks it against each of the strings following the WHEN statements. If it matches one of these values, the statements following it are executed. Execution continues until another WHEN or the ENDCASE is reached. When this happens, control passes to the statement after the ENDCASE.

If you press a key which is not recognised by any of the four WHEN statements, the program goes round again and waits for another key to be pressed. You can include another line to warn you that you pressed the wrong key. For example:

105   OTHERWISE VDU 7 : REM Make a short noise

The OTHERWISE statement is used if none of the WHENs finds a matching key. The VDU 7 makes a short bell sound to warn you that you have pressed the wrong key.

The following rules apply to CASE statements:

  • CASE must be followed by an expression, and then OF. This statement must be at the end of the line.
  • Each WHEN must start at the beginning of a line. It may be followed by one or more values, separated by commas.
  • The statements dependent on a WHEN may follow it on the same line after a colon :, or be spread over several lines following it.
  • The OTHERWISE part is optional. If present it must be at the beginning of a line. The statements following OTHERWISE may be spread over several lines.
  • An ENDCASE statement must be present. Like WHEN and OTHERWISE, it must be the first non-space item on a line.

Whenever the result of the expression matches one of the values listed after a WHEN, all the statements following this WHEN down to the next WHEN, OTHERWISE or ENDCASE are executed. BASIC then skips to the statement following the ENDCASE. This means that if the result matches a value in more than one WHEN, only the statements following the first one are executed: the others are ignored. Since OTHERWISE matches any value, having WHEN statements following an OTHERWISE is pointless since they can never be reached.

The following gives another example of using the CASE statement:

   10 REM Guess a number
   20 X% = RND(100)
   30 Still_guessing% = TRUE
   40 tries% = 0
   50 WHILE Still_guessing%
   60   INPUT "What is your guess ",guess%
   70   CASE guess% OF
   80     WHEN X%
   90     PRINT "Well done, you've guessed it after ";tries% " attempts"
  100     Still_guessing% = FALSE
  110     WHEN X%-1,X%+1
  120     PRINT "Very close"
  130     tries% += 1
  140     OTHERWISE
  150     IF guess%<X% THEN PRINT "Too low" ELSE PRINT "Too high"
  160     tries% += 1
  170   ENDCASE
  180 ENDWHILE

Like all the other BASIC structures, CASE statements may be nested.

GOTO

The GOTO instruction may be used to specify a line number from which the computer is to continue executing the program. For example:

10 PRINT "Hello"
20 GOTO 10

Whenever the computer executes line 20 it is sent back to line 10 once again. Left on its own, this program never ends. To stop it, press Esc.

GOTO instructions send the control of the program either forwards or backwards. The specified line number may be given as an expression. For example:

 10 start% = 100
 20 GOTO (start%+10)
 30 PRINT "This line should not be executed"
100 REM start of the action
110 PRINT "Hello"
120 END

Using a variable, however, as the destination for a GOTO is not recommended because while RENUMBER changes the line numbers, it does not alter GOTO destinations that are given as anything other than a simple number. If you must use an expression, it is best to put in inside brackets, since BASIC may get confused if the expression starts with a number.

If you wish to make your programs easy to read, especially for other people, use as few GOTOs as possible. They make a program very difficult to follow. It is far better to use one of the loop constructs like REPEAT ... UNTIL which have been described above.

GOSUB... RETURN

GOSUB stands for 'go to subroutine' and is another variation of GOTO. Instead of continuing indefinitely from the line number which is jumped to, the lines are executed until a RETURN statement is reached. Control then passes back to the instruction which comes after the GOSUB. For example,

 10 GOSUB 100
 20 PRINT "This is printed after the first GOSUB returns"
 30 GOSUB 100
 40 PRINT "This is printed after the second GOSUB returns"
 50 END
100 PRINT "This is printed in the GOSUB"
110 RETURN

produces:

This is printed in the GOSUB
This is printed after the first GOSUB returns
This is printed in the GOSUB
This is printed after the second GOSUB returns

Like GOTO, GOSUB should be used sparingly, if at all. It is provided in this version of BASIC for compatibility with weaker dialects of the language. Better methods of providing blocks of code, which once executed then return control back to the point from which they were called are described in the Procedures and functions chapter.

ON... GOTO/GOSUB

The ON ... GOTO statement is used to choose one of a number of different lines depending on the value of a given expression. For example:

 10 PRINT "Input a number between 1 and 4"
 20 INPUT N%
 30 ON N% GOTO 60, 100, 80, 120
 60 PRINT "Your number is 1"
 70 GOTO 999
 80 PRINT "Your number is 3"
 90 GOTO 999
100 PRINT "Your number is 2"
110 GOTO 999
120 PRINT "Your number is 4"
999 END

The computer checks the value of N% which is input, then jumps to the N%th line number in the list. If N% is 3, the computer starts executing at line 80 and so on. If N% is less than 1 or greater than 4, the error message

ON range at line 30

is displayed.

ELSE can be used to catch all other values. It is followed by a statement which is executed if the value of the expression after ON has no corresponding line number. For example, line 30 above could be replaced by:

  30 ON N% GOTO 60,100,80,120 ELSE PRINT "Number out of range"
  40 GOTO 999

Now, when the program is run, if N% is not between 1 and 4 the message Number out of range is displayed and the program ends normally.

ON ... GOSUB acts in exactly the same way:

 10 PRINT "Input a number between 1 and 4"
 20 INPUT N%
 30 ON N% GOSUB 60, 100, 80, 120
 40 END
 60 PRINT "Your number is 1"
 70 RETURN
 80 PRINT "Your number is 3"
 90 RETURN
100 PRINT "Your number is 2"
110 RETURN
120 PRINT "Your number is 4"
130 RETURN

There is also an ON ... PROC STATEMENT WHICH IS DESCRIBED IN THE Procedures and Functions chapter. Note, however, that when writing new programs, it is better to use the more versatile CASE structures rather than the ON ... GOTO/GOSUB/PROC constructs. Again, this old-fashioned construct is provided mainly for backwards compatibility with less powerful versions of BASIC.

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015