The preceding sections have primarily been concerned with
describing the concepts of arrays in Fortran 90, the various
categories of arrays, and the different ways that they may be referenced.
An important feature of Fortran 90 is also the ability
to use arrays as operands in expressions; for example, in traditional
Fortran an expression of the form:
is restricted to scalars, but in Fortran 90 the variables
a and b
may equally be arrays. Operations involving arrays are performed
elementally — that is, an equivalent scalar operation is
performed on each element of the arrays.
Array
operations generally require the arrays involved to be conformable
—that is, they must have the same rank (number of dimensions),
same shape, and the extents of corresponding dimensions must be
the same. Assumed-size arrays therefore may not be used in an array
operation, although a section of such an array is allowed. Note
that conformability does not require the lower and upper bounds
of corresponding dimensions to be the same.
The Fortran 90 array semantics specifies that array
operations are conceptually performed in parallel — that
is, the result of such an operation must be as if the operation
were performed on each element independently and in any order. The
practical effect of this is that, because an assignment statement
may have the same array on both the left and right-hand sides, the
right-hand side is fully evaluated before any assignment takes place.
This means that in some cases the compiler may create temporary
space to hold intermediate results of the computation.
A scalar may appear in an array expression. The effect is
as if the scalar were evaluated and then broadcast to form a conformable
array of elements, each having the value of the scalar. Thus a scalar
used in an array context is regarded as conformable with the array
or arrays involved.
Zero-sized arrays may also be used in an array expression,
but while they have no elements they do have a shape and must therefore
follow the rule of conformable arrays. Note that scalars are conformable
with any array and may therefore be used in an operation involving
a zero-sized array.
The following example contains valid and invalid examples
of array operations.
! a is an assumed-shape array with rank-one |
! b is a pointer to a rank-two array |
! c is an assumed-size array |
REAL, ALLOCATABLE :: d(:) |
! d is an allocatable array, its shape can |
! only be defined in an ALLOCATE statement |
! creates the array d with the same size as a; |
! in this example a and d are conformable as |
! they have the same shape |
! copies the array a into d |
! sets each element of the array associated |
! with b to 0.0; the effect is as if the scalar |
! were broadcast into a temporary array, with |
! the same shape as b,that is then assigned |
! corresponding elements of a and d are added |
! together and then stored back into the |
! corresponding array element of d |
! conceptually the operand SQRT(d) is evaluated |
! into an intermediate array with the same shape |
! as d; each element of the intermediate array |
! will be added to the corresponding element of |
! a and stored into the corresponding element of |
! examples of invalid uses of arrays |
! illegal - c is an assumed-size array and so |
! has no shape; an assumed-size array may not be |
! used as a whole array operand (except in an |
! illegal - the arrays a and b do not have the |
! same shape and are therefore not conformable |
! illegal - in this example d has already been |
! deallocated and may not be referenced |