Arrays

A constant or variable is simply a symbolic name which refers to a particular memory location holding a particular type of data. An array, however, is a symbolic name which refers to a group of memory locations, all holding the same data type. Each individual memory location in an array is referenced by a subscript.

Mathematical Notation FORTRAN 77 Notation
a1, a2, …, an A(1), A(2), …, A(N)
b1,1, b1,2, …, bm,n B(1,1), B(1,2), …, B(M,N)

Array elements are referenced by the array name followed by the subscript in parentheses. In the case of multidimensional arrays, the subscripts are separated with commas.

One-Dimensional Arrays

In order to declare a one-dimensional array, two pieces of information are required: the data type and the number of elements in the array. There are two ways that this can be done. If the array holds numerical data and implicit typing is used, then the DIMENSION statement is all that is necessary.

DIMENSION array-name(array-length)

The array-name is the symbolic name used to reference the array and the array-length is the number of elements in the array. In this instance, the elements of the array have the subscripts 1, 2, 3, …, array-length. However, it is often convenient to have subscripts which have a different lower bound than one. In this case, the implicitly-typed array may be declared in this fashion:

DIMENSION array-name(lower-bound:upper-bound)

The subscripts range from lower-bound to upper-bound.

The array-length, lower-bound and upper-bound must be INTEGER constants. The array-length must be positive (although if the array-length is 1, then the array is really no different from a variable) but the lower-bound and upper-bound values may be negative, zero or positive as long as the upper-bound is greater than the lower-bound.

Example

Consider these statement which appear at the beginning of a program:

DIMENSION KOUNT(15),PERCNT(0:100)

Two arrays have been declared with a single DIMENSION statement. KOUNT is an INTEGER array of length 15. Its elements are KOUNT(1), KOUNT(2), …, KOUNT(15). PERCNT is a REAL array of length 101. Its elements are PERCNT(0), PERCNT(1), …, PERCNT(100).

If the array is to take a data type which is contrary to the implicit types, then the array can be declared in the same statement as the type declaration.

Example

Consider these declarations:

DOUBLE PRECISION LINE(-100:200)
INTEGER          DAYNO,MONNO
PARAMETER(DAYNO=31,MONNO=12)
CHARACTER*3      MONTH(MONNO)
LOGICAL          DAY(DAYNO)

The array LINE contains 301 DOUBLE PRECISION elements with subscripts ranging from -100 to 200. Two INTEGER constants are declared and then initialised in a PARAMETER statement. These constants are then used in the arrays declarations of the CHARACTER array MONTH and the LOGICAL array DAY. In the case of the CHARACTER array, each element is a three characters long. An alternative declaration of this array would be

CHARACTER        MONTH(MONNO)*3

It is also possible to use a combination of type declarations and DIMENSION statements to declare arrays but there is little to recommend it.

Example

REAL      MEASUR
DIMENSION MEASUR(-100:-1)

The symbolic name MEASUR is declared to be of type REAL and then declared to be an array of length 100 in the following DIMENSION statement. However, the same thing could be accomplished with one line.

REAL MEASUR(-100:-1)

In either case, the array elements are MEASUR(-100), MEASUR(-99), …, MEASUR(-1).

Multidimensional Arrays

FORTRAN 77 arrays may have up to seven dimensions. The elements in each dimension are of the same type so it is not possible to have an array with INTEGER values in the first dimension, REAL values in the second dimension, CHARACTER values in the third dimension, etc.

Multidimensional arrays are declared in the same way as one-dimensional arrays. The array bounds or lengths of each dimension are separated by commas.

Example

INTEGER BATTLE(31,12,1939:1945)

BATTLE is a three-dimensional array. The first dimension has length 31, the second length 12 and the third length 7. The subscripts for the first dimension range from 1 to 31, the subscripts for the second dimension range from 1 to 12 and the subscripts for the third dimension range from 1939 to 1945.

Example

The judicious use of PARAMETER statements in setting array bounds can lead to programs which are easy to understand and update. Consider this program fragment:

INTEGER   I,J,NCOL,NROW
PARAMETER(NCOL=200,NROW=400)
REAL      MATRIX(NROW,NCOL),SUM
…
SUM = 0.0
DO 20, J = 1,NCOL
DO 10, I = 1,NROW
SUM = SUM + MATRIX(I,J)
10    CONTINUE
20 CONTINUE
…

It is quite common to use the dimensions of the arrays in loops and other calculations. By using named constants instead of the actual numbers, the program is easier to understand and if at some later date it is necessary to change the dimension bounds, then this change is done in the PARAMETER statement only. It isn't necessary to hunt through the entire program looking for instances where the array bounds are used.

Storage

Arrays are stored in contiguous memory locations in the computer. Consider a one-dimensional array A(8). The elements are stored in the following manner:

 A(1) A(2) A(3) A(4) A(5) A(6) A(7) A(8)

Higher dimensional arrays are a little trickier. Consider now a two-dimensional array B(3,4):

 B(1,1) B(2,1) B(3,1) B(1,2) B(2,2) B(3,2) B(1,3) B(2,3) B(3,3) B(1,4) B(2,4) B(3,4)

Similarly, a three-dimensional array C(4,2,3) is stored like this:

 C(1,1,1) C(2,1,1) C(3,1,1) C(4,1,1) C(1,2,1) C(2,2,1) C(3,2,1) C(4,2,1) C(1,1,2) C(2,1,2) C(3,1,2) C(4,1,2) C(1,2,2) C(2,2,2) C(3,2,2) C(4,2,2) C(1,1,3) C(2,1,3) C(3,1,3) C(4,1,3) C(1,2,3) C(2,2,3) C(3,2,3) C(4,2,3)

Unlike some other programming languages, FORTRAN 77 stores arrays in column-major form. That is to say, the left-most array index varies the most rapidly, followed by the next left-most array index, etc. Thus, the last index in an array varies the most slowly. Knowledge of how FORTRAN 77 stores arrays can lead to increased efficiency (and increased speed).

Example

Consider the following REAL array:

INTEGER   I,J,NCOL,NROW
PARAMETER(NCOL=4,NROW=2)
INTEGER   B(NROW,NCOL)

The nested DO loops

DO 20, J = 1,NCOL
DO 10, I = 1,NROW
B(I,J) = I + J
10    CONTINUE
20 CONTINUE

access the array in the following order:

1. B(1,1) = 1 + 1
2. B(2,1) = 2 + 1
3. B(1,2) = 1 + 2
4. B(2,2) = 2 + 2
5. B(1,3) = 1 + 3
6. B(2,3) = 2 + 3
7. B(1,4) = 1 + 4
8. B(2,4) = 2 + 4

Note that the order in which the array is accessed is exactly the same in which it is stored. This allows the compiler to generate simpler, more efficient machine code, which will run more quickly. However, if the loops are reversed

DO 10, I = 1,NROW
DO 20, J = 1,NCOL
B(I,J) = I + J
20    CONTINUE
10 CONTINUE

then the array is accessed in this order:

1. B(1,1) = 1 + 1
2. B(1,2) = 1 + 2
3. B(1,3) = 1 + 3
4. B(1,4) = 1 + 4
5. B(2,1) = 2 + 1
6. B(2,2) = 2 + 2
7. B(2,3) = 2 + 3
8. B(2,4) = 2 + 4

Accessing an array 'out of order' slows down the program because the compiler is forced to generate less-efficient machine code. Ordering loops carefully reduces processor overheads and lookup times.

General Considerations

• The number of subscripts in any array reference must match the array declaration.
• The subscript must always remain within the bounds declared.
• The subscript must be an INTEGER expression.
• An array element is undefined until it has a value assigned to it in some manner.
• An array may be accessed by its name only (without subscripts) in a few limited circumstances:
• in a type declaration if a DIMENSION statement is used to set the array bounds;
• in a DATA statement which initialises the entire array;
• in a READ or WRITE statement which reads in or writes out the entire array;
• as an actual argument in an external function reference or subroutine call;
• as a dummy argument in an external function or subroutine.