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.
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.
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.
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.
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)
.
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.
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.
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.
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).
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:
B(1,1) = 1 + 1
B(2,1) = 2 + 1
B(1,2) = 1 + 2
B(2,2) = 2 + 2
B(1,3) = 1 + 3
B(2,3) = 2 + 3
B(1,4) = 1 + 4
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:
B(1,1) = 1 + 1
B(1,2) = 1 + 2
B(1,3) = 1 + 3
B(1,4) = 1 + 4
B(2,1) = 2 + 1
B(2,2) = 2 + 2
B(2,3) = 2 + 3
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.
INTEGER
expression.DIMENSION
statement is used to
set the array bounds;DATA
statement which initialises the entire array;READ
or WRITE
statement which reads in
or writes out the entire array;