Lecture 17: Arrays


Array

Imagine that we want to write a program to calculate the average of 10 numbers. With the knowledge we gained until now, we could do this by defining ten different variables, for instance
  Var a1, a2, a3, a4, a5, a6, a7, a8, a9, a10: real;
      average: real;
and in the program code:
  average := (a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) / 10;
I hope you will agree that this is very cumbersome. And, it could be even worse: imagine we want the user to select how many numbers to use in the calculation of the average:
  Var n: integer;
     |
  ReadLn(n);
  Case n of
     1: average := a1;
     2: average := (a1 + a2) / 2;
     3: average := (a1 + a2 + a3) / 3;
          |
    10: average := (a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) / 10;
  end;
For these purposes exist the arrays. An array lets us define a set of variables of the same type with an easy way of access, namely with an index. Just like in mathematics, ai is the i-th element of vector or series a, a[i] gives the i-th element of array a.
 
 An array is a set of indexed variables of the same type


Declaration of an array

To declare an array we use the following syntax:
 
 Var name: array[startindex .. endindex] of type

name is the identifier of the array, just like a name for other variables.
startindex and endindex define the limits of the indices of the array. Note that the start index is not necessarily 0, instead we can let the array start at any index we want. That is nice, because humans are more used to working with indices that start with 1 rather than 0.
type is any variable type, for instance real or integer, but it can even be another array as we will see later.

Examples:

   Var account: array[1..100] of real;
This might be used to store the information of 100 bankaccounts.

   Var prime: array[1..10] of longint;
This might be used to store the first 10 prime numbers..

   Var propinas: array[1000..2000] of boolean;
This might be used to store some boolean information of the status of the students with numbers between 1000 and 2000, for instance if they paid their tuition fees or not.


Use of an array

Inside the program we can use the elements of an array. 
 name[index]

name[index] will return the value element number index of the array name. This is then a value of the type as described in the declaration of the array. Examples of the arrays declared in the previous section:

   account[20]
is the value - of type real - of element 20 of the array with name account.

   prime[8]
is the value - of type longint - of element 8 of the array prime. The numbers on the right might represent this array, so element number 8 would be equal to 17. Of course, our program has to fill this array in some way before the array really contains the prime numbers.

   propinas[1055]
is TRUE or FALSE (type boolean). Element 1055 of the array propinas. Did student 1055 pay his tuition fees? Probably our university administration has somewhere in their computers an array with this information.

We can also use a variable for the index in addressing a single element of an array. Naturally, this variable needs to be of any integer type, because the index is something countable; index 3.4981 does not make sense. Index 3 does, it will address the third element of the array. The following code will show the entire array of 20 accounts:

  for i := 1 to 20 do
    WriteLn(account[i]);
 


Multiple arrays

Just like in mathematics, where we have vectors (tensors of 1 dimension) and matrices (tensors of 2 dimensions) we can have arrays of 1 dimension or 2 dimensions or even more. We can specify this in the following way, for instance a 'double array' (an array of two dimensions):
 
 Var name: array[startindex1 .. endindex1, startindex2 .. endindex2] of type

Technically speaking we can also do it in the way

  Var name: array[startindex1..endindex1] of array[startindex2..endindex2] of type;

which nicely shows what we are dealing with, namely an array of arrays. This is how the computer organizes our array. The first form of declaring a double array is preferred though, because it is more logical from a human point of view.

The use of a double array is similar to that of a single array. We separate the indices with a comma, or by putting them in separate square parenthesis:
 

 name[index1, index2
 name[index1][index2

 
  As an example: to write the matrix on the left we might do the following in a complete program. Note that the array consists of 9 (3x3) elements of type integer.

PROGRAM ShowMatrix;

Var matrix: array[1..3, 1..3] of integer;

begin
  matrix[1, 1] := 1;
  matrix[1, 2] := 0;
  matrix[1, 3] := 1;
  matrix[2, 1] := 2;
  matrix[2, 2] := 2;
  matrix[2, 3] := 0;
  matrix[3, 1] := 1;
  matrix[3, 2] := 0;
  matrix[3, 3] := 1;
  for i := 1 to 3 do
    begin
       for j := 1 to 3 do
         Write(matrix[i, j],' ');
      WriteLn;
    end;
end.
 


    Caution

  When we are using an array we also have to be careful not to use an index that is 'out of bounds'. This means that we always have to use an index that is inbetween the lower index and the higher index limit. If we use a too large or too low index, the results of our program canl be very odd. This is best illustrated in an example. The following program defines an array of 4 integers r[1..4] and a normal integer a. The figure on the left shows how they might be placed in memory. What will happen when our program assigns a value to r[5]? If r[5] had existed, it would have occupied the place that is now taken by a, and an assignment to r[5] would be putting a value in the box of what is now occupied by a. Most computer languages don't care and put the value for r[5] there anyway, thereby overwriting the value of a.

  PROGRAM Test;

  Var r: array[1..4] of integer;
  Var a: integer;

  begin
    a := 0;
    WriteLn('a=',a);
    r[5] := 1;
    WriteLn('a=',a);
    ReadLn;
  end.

The output of the program will probably be

  a=0
  a=1

Some programming languages will check for this at run rime. With our Turbo Pascal compiler we can select the option to verify for such an index-out-of-bounds event at run time. This is called range-checking and when the program tries to use a wrong index, a 'range-check error' will be generated. The disadvantage of doing this is that the program becomes slower and the compiled program will occupy more space in memory and on disk.



"Hurray! I know everything about arrays."

Quick Test

To test your knowledge of what you have learned in this lesson, click here for an on-line test.

Peter Stallinga. Universidade do Algarve, 11 Abril 2002