Lesson Two - Using Arrays

Using Arrays

Computers are more often than not used to keep track of lists of things. These could be lists of customers, lists of stock #'s, or lists of fonts. A list of things doesn't even have to look like a list. For an example of this, take a look at your favorite video games. If you've ever played PacMan or Doom, the monsters are managed in one kind of list or another (but you never see the list). Arrays are what BASIC (and most other programming languages) uses to keep lists.

To see why we need arrays, let's look at what programming for lists looks like without arrays. Suppose we want to keep track of a list of 10 names. Using only the techniques we've covered so far it would look like this:

'NOARRAY.BAS
'List handling without arrays

if yourName\$ = "" then print "No name entered." : goto [quit]
if name1\$ = "" then name1\$ = yourName\$ : goto [nameAdded]
if name2\$ = "" then name2\$ = yourName\$ : goto [nameAdded]
if name3\$ = "" then name3\$ = yourName\$ : goto [nameAdded]
if name4\$ = "" then name4\$ = yourName\$ : goto [nameAdded]
if name5\$ = "" then name5\$ = yourName\$ : goto [nameAdded]
if name6\$ = "" then name6\$ = yourName\$ : goto [nameAdded]
if name7\$ = "" then name7\$ = yourName\$ : goto [nameAdded]
if name8\$ = "" then name8\$ = yourName\$ : goto [nameAdded]
if name9\$ = "" then name9\$ = yourName\$ : goto [nameAdded]
if name10\$ = "" then name10\$ = yourName\$ : goto [nameAdded]

'There weren't any available slots, inform user
print "All ten name slots are already used!"
goto [quit]

print yourName\$; " has been added to the list."

[quit]
end

In this example when we enter a name, the computer will look at up to ten variables in turn. If it finds a variable that is an empty string, it will set the value of that variable to be equal to yourName\$. Then it will GOTO [nameAdded] and display a notice that the name has been added. If this were part of a larger program, we would execute this code whenever we wanted to add a name, and the name would be inserted into the next available slot.

This technique is manageable only for very small lists. Imagine how many lines of code we would need to track hundreds or thousands of names in this way! Arrays provide a special way to make a single line of BASIC code refer to any one variable out of a list of thousands.

Here is our name list example rewritten using a BASIC array. If it seems unclear to you, try running the debugger on it.

'ARRAYS.BAS
'List handling with arrays

dim names\$(10) 'set up our array to contain 10 items

if yourName\$ = "" then print "No name entered." : goto [quit]

index = 0
[insertLoop]
'check to see if index points to an unused item in the array
if names\$(index) = "" then names\$(index) = yourName\$ : goto [nameAdded]
index = index + 1 'add 1 to index
if index < 10 then [insertLoop] 'loop back until we have counted to 10

'There weren't any available slots, inform user
print "All ten name slots already used!"
goto [quit]

print yourName\$; " has been added to the list."

[quit]
end

You'll immediately notice the dim names\$(10) statement at the start of this example. This tells BASIC to create an array called names\$ with space for 10 items. Because the name of the array ends with a \$ character, this is an array of strings. An array named without a \$ character would contain numeric values. The first item in an array is referred to by the value 0, and so an array of 10 items starts with item 0 and ends with item 9 (most BASICs work like this, but Run BASIC will actually number the array from 0 to 10, giving you eleven items).

The real work is done in this part of the code:

index = 0
[insertLoop]
'check to see if index points to an unused item in the array
if names\$(index) = "" then names\$(index) = yourName\$ : goto [nameAdded]
index = index + 1 'add 1 to index
if index < 10 then [insertLoop] 'loop back until we have counted to 10

Here we are using a simple loop to control a search for an empty slot in our array names\$. Take a look at this line:

if names\$(index) = "" then names\$(index) = yourName\$ : goto [nameAdded]

The if names\$(index) = "" part of the line uses the value of index to point to a selected string in the array. When index is 0, we are looking at the first item in the array. When the code loops back and index is 1, it will be looking at the second item in the array, and so on.

In the same line of code, the names\$(index) = yourName\$ part is used to set the item selected by index. The total effect of the line is to set the selected item in the array to to be yourName\$ if that selected array item is an empty string. When this happens it also exits the loop with GOTO [nameAdded].

This is more involved than the technique used in NOARRAY.BAS, but it has the advantage of size. Even if we need to manage 1000 items, we only need to change our code like this (most of the code is left out):

dim names\$(1000)
.
.
[insertLoop]
.
.
if index < 1000 then [insertLoop] 'loop back until we have counted to 1000

If we extend NOARRAY.BAS to manage 1000 names, the resulting program would have one line for each name slot we needed to keep. Our program would be more than 1000 lines long!

Index Out of Bounds

Try running the following mini program.

'done wrong
dim names\$(10)
print names\$(15)

You will get an error message saying 'index out of bounds'. This means that you tried to print the contents of an array item that doesn't exist. If you dimension the array to make it large enough, it will work.

'done right
dim names\$(20)
print names\$(15)

A similar error will occur if you try to set the item of an array using an index that is too large.

'done wrong again
dim names\$(10)
names\$(15) = "John Doe"

Playing the numbers

Numeric arrays work very much like their relative the string array (featured above in ARRAYS.BAS). To demonstrate how numeric arrays work, examine this program that asks for some numbers, adds them up, and calculates the average value.

'AVERAGE.BAS
'Accept some numbers from the user, then total and average them
dim numbers(20)
print "AVERAGE.BAS"
print

'loop up to 20 times, getting numbers
print "Enter up to 20 non-zero values."
print "A zero or blank entry ends the series."

[entryLoop] 'loop around until a zero entry or until index = 20
'get the user's entry
print "Entry "; index + 1;
input entry

if entry = 0 then [endSeries] 'quit if entry is zero or blank

index = index + 1 'add one to index
numbers(index) = entry 'set the specified array item to be entry

total = total + entry 'add entry to the total

if index = 20 then [endSeries] 'if 20 values were entered, exit loop

goto [entryLoop] 'go back and get another entry

[endSeries] 'entries are finished
'Set entryCount to index
entryCount = index
if entryCount = 0 then print "No Entries." : goto [quit]

print "Entries completed."
print
print "Here are the "; entryCount; " entries:"
print "-----------------------------"

'This loop displays each entered value in turn.
'Notice that we re-use the index variable. It
'can be confusing to use a new variable for each
'new loop.
index = 0
[displayLoop]
index = index + 1
print "Entry "; index; " is "; numbers(index)
if index < entryCount then [displayLoop]

'Now display the total and average value
print
print "The total is "; total
print "The average is "; total / entryCount

[quit]
end

******************************
Challenge exercises
******************************

1) Add code to ARRAYS.BAS after [quit] to display all the names entered.

2) There's no reason we can't have more than one array in a BASIC program. For an example of this, look at the program file FF12.BAS. Altogether, it uses no fewer than 18 arrays. Some of them are string arrays and some are of the numeric type. Modify the AVERAGE.BAS program so it asks for a name and age for up to 20 people. The names should be managed in a string array (remember ARRAYS.BAS?) that you'll add to the program. When the list of entries is displayed, each name is to be displayed with its age. Then the total and average age will be displayed after this. Call the program AGES.BAS.