Back To Basics - Part 6

In part six of his series on Basic programming, Mark Moxon looks at more control statements, and decides that arrays are more useful than they seem

This month I'm going to look at the final control statement as promised: the FOR-NEXT construction. However, before getting stuck into this particular delight, I'm going to talk about a new type of variable - arrays.

They allow sets of data to be stored together under one variable name, in a similar way to a card database allows a number of items of data to be stored on one card. The easiest way to imagine a simple array is if I show you an example. Arrays are defined using the DIM command, as in the following line:

DIM array$(10)

This line defines an array of eleven string variables (because of the dollar sign). These can be referred to using the names array$(0), array$(1) and so on, up to array$(10). These array variables act just like normal variables, so you can assign them with commands like:

array$(3)="Hello"

and you can print them with lines like:

PRINT array$(6)

However, the real power of arrays is that you can use other variable names inside the brackets. So, assuming we have defined a variable called index%, we can refer to the string array$(index%). Have a look at Listing 1: here we define an array using the DIM command (line 5) and assign values to the four elements in that array in lines 6 to 9. Now the user inputs a number from 0 to 3, and print out the contents of the array.

Listing 1

REM >Listing1
:
ON ERROR REPORT:PRINT " at line ";ERL/10:END
MODE 0
DIM array$(3)
array$(0)="Zero"
array$(1)="One"
array$(2)="Two"
array$(3)="Three"
REPEAT
  INPUT "Input number (0-3):"index%
  PRINT array$(index%)
UNTIL FALSE
END

In this case, the array Contains English versions of the numbers, showing how you can easily write a program to convert numbers from digits to English. For example, if the user enters the number 2, the program prints array$(2), which contains "Two".

There is an added flexibility to arrays which can prove invaluable when writing programs which deal with stored data. Arrays can be defined to be two-dimensional, which means you can include two numbers inside the brackets. Now don't worry, there's nothing confusing about two-dimensional arrays, it just means that you can refer to the elements of an array in a different way.

For example, take the array definition:

DIM array(5,25)

This contains numerical elements which can be referred to using two numbers, such as array(3,7) and array(1,20). The rule is that the numbers you put inside the brackets when referring to elements of the array cannot be more than the corresponding numbers when you defined it, so the numbers in the above definition can be between 0 and 5 (for the first number) and 0 and 25 (for the second. At this stage people normally worry a bit and wonder what on earth the value of all this is, and why anyone should want to define a set of variables which you still have to treat like any other variable. Well, the real power comes in the ability to use variable names inside the brackets when referring to array variables, but before I can show you how really flexible this is, I have to explain the last of our control structures, as promised last month.

For-next loops

The FOR-NEXT construct is an easy one to understand. Basically a FOR-NEXT loop is executed a specific number of times, unlike a WHILE-ENDWHILE or REPEAT-UNTIL loop which may be executed an unpredictable number of times. In its simplest form a FOR-NEXT loop takes the following form:

FOR var=start TO end
...
NEXT var

The statements inbetween the FOR and NEXT lines are executed again and again: the first time they are executed, the variable var has value start; the next time var has value start+1; next time it's start+2; and so on, until var has value end. So a loop starting:

FOR var=1 TO 10

would execute ten times, with var=1 for the first time, var=2 for the second and so on, up to the last time when var=10.

For an example of a FOR-NEXT loop in operation, try out Listing 2. This asks for a number from the user, which is put into the variable num%. A loop is then executed, incrementing the variable loop% from 1 to the value of num%, printing out a line "Loop number ..." each time. So, for example, if you enter 5 at the prompt, you'll get five lines printed out, numbered 1 to 5.

Listing 2

REM >Listing2
:
ON ERROR REPORT:PRINT " at line ";ERL/10:END
MODE 0
INPUT "Give me a number ";num%
FOR loop%=1 TO num%
  PRINT "Loop number ";loop%
NEXT loop%
END

Address database

All this explanation has now, at last, bought us to our practical program for the month. It's a (very primitive) address database, capable of storing up to 25 names and addresses, and searching through the names for occurrences of strings you choose to enter. Not bad for just 30 lines of code, don't you think?

Listing 3

REM >Listing3
:
ON ERROR REPORT:PRINT " at line ";ERL/10:END
MODE 0
DIM name$(24),addr$(24,3)
REPEAT
  INPUT "Option (A)dd, (S)earch ";opt$
  CASE opt$ OF
    WHEN "A"
      temp%=0
      WHILE name$(temp%<>"" AND temp%<>25:temp%+=1:ENDWHILE
      IF temp%<>25 THEN
        INPUT "Name ";name$(temp%)
        INPUT "Address 1 ";addr$(temp%,0)
        INPUT "Address 2 ";addr$(temp%,1)
        INPUT "Address 3 ";addr$(temp%,2)
      ELSE
        PRINT "Records full"
      ENDIF
    WHEN "S"
      INPUT "Search name ",search$
      FOR loop%=0 TO 24
        IF INSTR(name$(loop%),search$)<>0 THEN
          PRINT "Match found"
          PRINT "Name: ";name$(loop%)
          PRINT "Address: ";addr$(loop%,0);",";addr$(loop%,1);",";addr$(loop%,2);","
        ENDIF
      NEXT loop%
  ENDCASE
UNTIL FALSE

To use the program, enter A or S (captials, please) to enter a new address, or search for a name respectively. To enter an address, simply enter the name, followed by RETURN, followed by three address lines (each ended by RETURN). If you get a 'Records full' error you have entered 25 names: that's the limit as set in line 5; change the number 24s in line 5 to increase the limit.

To search for entries containing a certain string in the name field, choose the S option. Now type in your search string, and any matches will be shown. Note that a search string of "Jul" would match "Julie" and "Julian", but not "John" (unsurprisingly).

That's all there is to Listing 3, but you can see how this can easily be extended into a complete address database, with record deletion and searching on other fields in the database. Just to hammer home how arrays and FOR-NEXT loops work, here's a breakdown of Listing 3.

Line 5: Two arrays are defined, one called name$ with 25 entries (0 to 24), and one called addr$ with 25 by 3 entries (0 to 24, 0 to 3).

Line 6: Start an endless REPEAT loop.

Line 7: Get the option into the variable opt$.

Line 8: Start a CASE construct depending on the option.

Line 9: If the user wants to add a record (opt$ is "A") ...

Lines 10-11: Set the variable temp% to point to the first entry in the array which is empty. We do this by setting temp% to 0, and looking through the array until we find an empty name$(temp%), or we reach the end of the array (in which case temp% will be 25).

Line 12: If there is an empty entry in the address database, then ...

Lines 13-16: Get the user to input the name and address of the entry. Note that temp% is the number of the blank entry in the array, so we enter name(temp%), addr$(temp%,0) and so on.

Lines 17-18: If we get here, there are no blank entries, so print an error message

Line 19: Terminate IF construct started in line 12.

Line 20: If the user wants to search for a record (opt$ is "S") ...

Line 21: Get the search string into search$.

Line 22: Start a FOR-NEXT loop. This loop will enable us to search through each of the entries in turn, so we want to look at entries 0 through 24. This can be done using a FOR-NEXT loop, starting the variable loop% at 0 and incrementing it through to 24.

Line 23: This line looks at the current name we are searching through, and checks to see if the name contains the .search string. The INSTR command returns a value greater than zero if name$(loop%) contains the string search$ - in other words if we have a match. If we do have a match, then ...

Lines 24-27: Print "Match found" followed by the entry.

Line 28: Loop back to line 22 to search through the next record, until we reach the last: when loop% is 24.

Line 29: End the CASE.

Line 30: Loop back to the prompt for Add or Search.

That's all we have space for this month. Next time we progress into the land of procedures and functions.


Source: Acorn User 138 - January 1994
Publication: Acorn User
Contributor: Mark Moxon