Professional Programmer's Guide to Fortran77 (7th June 2005)
Copyright © 1988 - 2005 Clive G. Page
An array is a group of memory locations given a single name. The
elements of the array all have the same data type.
In mathematics the elements of an array a would be denoted by a1, a2,
a3, and so on. In Fortran a particular array element is identified by
providing a subscript expression in parentheses after the array name:
A(1), A(2), A(3), etc. Subscripts must have integer type but they may be
specified by expressions of arbitrary complexity, including function calls.
An array element can be used in the same way as a variable in almost all
executable statements. Array elements are most often used within loops:
typically an integer loop counter selects each element of the array in
*Add array OLD to array NEW making array TOTAL
PARAMETER (NDATA = 1024)
REAL OLD(NDATA), NEW(NDATA), TOTAL(NDATA)
DO 100, I = 1,NDATA
TOTAL(I) = OLD(I) + NEW(I)
Arrays can have up to seven dimensions; the lower bound of each
dimension is one unless declared otherwise. There is no limit on the
upper bound provided it is not less than the lower bound. Arrays which
are dummy arguments of a procedure may have their dimension bounds
specified by integer variables which are arguments of the procedure; in
all other cases each dimension bound must be an integer constant
expression. This fixes the size of the array at compile-time.
Type, DIMENSION, and COMMON statements may all be used to declare
arrays, but COMMON statements have a specialised use (described in
section 12). The DIMENSION statement has a similar form to a type
statement but only declares the bounds of an array without determining
its data type. It is usually simpler and neater to use a type statement
which specifies both at once:
CHARACTER COLUMN(5)*25, TITLE*80
Note that when declaring character arrays the string length follows the
list of array bounds. The character array COLUMN has 5 elements each of
which is 25 characters long; TITLE is, of course, just a variable 80
characters long. Although a default string length can be set for an
entire type statement, it is not possible to set a default array size in
a similar way.
It is generally good practice to use named constants to specify array
bounds as this facilitates later modifications:
PARAMETER (MAXIM = 15)
These arrays all have a lower bound of one. A different lower bound can
be specified for any dimension as shown below. The lower and upper
bounds are separated by a colon:
REAL TAX(1985:1990), PAY(12,1985:1990)
LOGICAL TRIPLE(-1:1, -1:1, -1:1, -1:1)
TAX has 6 elements from TAX(1985) to TAX(1990).
PAY has 72 elements from PAY(1,1985) to PAY(12,1990).
TRIPLE has 81 elements from BIN(-1,-1.-1.-1) to BIN(1,1,1,1).
Although Fortran itself sets no limits to the sizes of arrays that can
be defined, the finite capacity of the hardware is likely to do so. In
virtual memory operating systems it is possible to use arrays larger
than physical memory: those parts of the array not in active use are
held on backing store such as a disc file.
An array element reference must always use the same number of subscripts
as the number of dimensions declared for the array. Each subscript can
be an integer expression of any complexity, but there are restrictions
on functions with side effects (see section 9.3).
An array element reference is only valid if all of the subscript
expressions are defined and if each one is in the range declared for it.
An array element can only be used in an expression if a value for it has
been defined. A DATA statement (section 12) can be used to define an
initial value for an entire array or any set of elements.
An array can be used without subscripts:
* in a specification statement such as a type, DIMENSION, or SAVE
* in a function reference or CALL statement: this transfers the
whole of the array to the associated dummy argument (which must
have a compatible array declaration);
* in the data transfer list of a READ or WRITE statement: this
causes the whole array to be input or output. This is not
permitted for an assumed size dummy argument array.
* as a unit identifier in a READ or WRITE statement: a character
array is then an internal file with one record per element.
* as a format identifier in a READ or WRITE statement: the format
specification is contained in the character array with its
elements taken in sequence.
Arrays are always stored in a contiguous set of memory locations. In the
case of multi-dimensional arrays, the order of the elements is that the
first subscript varies most rapidly, then the second subscript, and so
on. For example in the following 2-dimensional array, X(2,3) (which for
simplicity I have made one of only six elements):
The elements are stored in the following sequence:
X(1,1), X(2,1), X(1,2), X(2,2), X(1,3), X(2,3)
i.e. the sequence moves down each column first, then across to the next
row. This column order is different from that used in some other
The storage order may be important if you use large multi-dimensional
arrays and wish to carry out some operation on all the elements of the
array. It is then likely to be faster to access the array in storage
order, i.e. by columns rather than rows. This means arranging loop
indices with the last subscript indexed by the outer loop, and so on
inwards. For example:
DOUBLE PRECISION ARRAY(100,100), SUM
SUM = 0.0D0
DO 250,L = 1,100
DO 150,K = 1,100
SUM = SUM + ARRAY(K,L)
With the loops arranged this way around the memory locations are
accessed in consecutive order, which minimises the processor overhead in