Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
HP Fortran 90 Programmer's Reference: HP Series 700/800 Computers > Chapter 4 Arrays

Array categories

» 

Technical documentation

» Feedback
Content starts here

 » Table of Contents

 » Glossary

 » Index

There are several different categories of array in Fortran 90. Each category is based on the shape of the array as defined by its array specifier.

Explicit-shape arrays

An explicit-shape array has explicitly declared bounds for each dimension; they are neither taken from an actual array argument ("assumed") nor otherwise specified later, prior to use ("deferred"). Each dimension of an explicit-shape array is of the form:

[lower bound:] upper bound

For a given dimension, the values of the lower bound and upper bound define the range of the array in that dimension. The bounds may be positive, negative, or zero. Normally the lower bound will be less than the upper bound; if the lower bound is the same as the upper bound then that dimension will contain only one element; if it is greater, then the dimension contains no elements, the extent of the dimension will be zero, and the array will be zero-sized. If a lower bound is not specified then it will assume the default value of 1.

More generally, the bounds of a dimension may be any specification expression. A specification expression is always a scalar and of type integer; it is either a constant expression, or one in which all variables are available at the time the subprogram is activated. Chapter 5 describes specification expressions in more detail.

There are various forms of explicit-shape array; the simplest form is represented by an array declaration in which the name of the array is not a dummy argument and all the bounds are constant expressions. This form of array may have the SAVE attribute and may be declared in any program unit.

An automatic array is an explicit-shape array that is not a dummy argument, and which has at least one nonconstant bound. Automatic arrays may be declared in a subroutine or function, but they may not have the SAVE attribute nor can they be initialized.

A dummy array is identified by the appearance of its name in a dummy argument list; its bounds may be constants or expressions. Dummy arrays may only be declared in a subroutine or function.

An adjustable array is a particular form of a dummy array; its name is specified in a dummy argument list but at least one of its bounds is a nonconstant specification expression.

Explicit-shape arrays may also be used as function results; these are described in the section “Array functions” and also in Chapter 7.

The following subroutine demonstrates how explicit-shape arrays may be declared.

SUBROUTINE sort(list1,list2,m,n)
!   examples of arrays with explicit shape
INTEGER :: m,n
INTEGER :: cnt1(2:99)
!  a rank-one array, having an explicit shape
!  represented by the vector [ 98 ]
REAL :: list1(100), list2(0:m-1,-m:n)
!  two dummy arrays with explicit shape, list1
!  is a rank-one array with an extent of 100 and
!  list2 is a rank-two array with an extent of
!  m * (m+n+1).  Note that list2 is also an
!  adjustable array
REAL :: work(100,n)
!  work is an automatic array as it does not
!  appear in the dummy argument list and its
!  bounds are not constant
INTEGER, PARAMETER :: buffsize = 0
REAL :: buffer (1: buffsize)
!  the array buffer has explicit shape, in this
!  example however it has no elements and is
!  zero-sized
...
END SUBROUTINE SORT

Assumed-shape arrays

An assumed-shape array is a dummy argument that assumes the shape of the corresponding actual argument. This should be compared with an explicit-shape dummy array in which the shape of the array is specified locally.

Each dimension of an assumed-shape array has the form:

[lower bound] :

where lower bound is a specification expression; it may be omitted and would then take the default value of 1. Note that it is the shape of the actual argument that is assumed and not its bounds and that the actual and dummy argument may have different lower (and upper) bounds for each dimension.

An assumed-shape array subscript may extend from the specified lower bound to an upper bound that is equal to the lower bound plus the extent in that dimension of the actual argument minus one.

A procedure that declares an assumed-shape dummy argument must have an explicit interface in the calling program unit; this is explained more thoroughly in Chapter 7.

The following subroutine demonstrates various forms of an assumed-shape array declaration.

SUBROUTINE initialize (a,b,c,n)
! examples of assumed-shape arrays
INTEGER :: n
INTEGER :: a(:)
! the array a is a rank-one assumed-shape array,
! it assumes (or inherits) its shape and size
! from the corresponding actual argument; its
! lower bound is 1 regardless of the lower bound
! defined for the actual argument
COMPLEX :: b(ABS(n):)
! a rank-one assumed-shape array, the lower 
! bound is ABS(n) and the upper bound will be  
! the lower bound plus the extent of the
! corresponding actual argument minus one
 
REAL, DIMENSION(:,:,:,:,:) :: c
! an assumed-shape array with 5 dimensions
! (rank=5), and all the lower bounds are 1
...
END SUBROUTINE initialize

As mentioned previously, if a procedure has an argument that is an assumed-shape array, its interface must be known to the calling program unit. For example, if subroutine initialize is an external subroutine, then it must appear in an interface block as follows:

PROGRAM main
INTEGER :: parts(0:100)
COMPLEX :: coeffs(100)
REAL    :: omega(-2:+3, -1:+3, 0:3, 1:3, 2:3)
INTERFACE
   SUBROUTINE initialize (a,b,c,n)
   INTEGER :: n
   INTEGER :: a(:)COMPLEX :: b(ABS(n):)
   REAL, DIMENSION(:,:,:,:,:) :: c
END SUBROUTINE initialize
END INTERFACE
CALL initialize & 
(parts,coeffs,omega,lbound(omega,1))
...  
END PROGRAM main

Interface blocks are described further in Chapters 7 and 10.

Deferred-shape arrays

A deferred-shape array is either an allocatable array or it is a pointer array. The array specification for a deferred-shape array is of the form:

: [ , : ] ...

It defines the rank of the array but not the bounds. The array is therefore said to have deferred-shape.

The shape of the array becomes defined either when the array is allocated or when a pointer array becomes associated with a target. Note that the form of array specifier for assumed-shape arrays and deferred-shape arrays is similar, but a deferred-shape array has either the ALLOCATABLE attribute which defines an allocatable array or it has the POINTER attribute which defines a pointer array; an assumed-shape array may have neither of these attributes.

Pointer arrays

A pointer array is an array that has the POINTER attribute and may therefore be used to point to some target object. Initially a pointer array has no shape and may not be referenced until it becomes associated either through an ALLOCATE statement or through a pointer assignment statement.

Chapter 3 describes in more detail the concept of pointers and how they may become associated, and disassociated, while Chapter 10 explains how the POINTER statement may be used to declare a pointer.

Once a pointer array has become associated it may be used in any context in which an array is allowed. Note that a pointer array is not an array of pointers; that is, its elements do not have the POINTER attribute. To create an array of pointers, define a derived type consisting of a single pointer component and declare an array of this derived type.

The following declarations illustrate different pointer array declarations:

REAL, POINTER, DIMENSION(:) :: p1
! p1 is declared as a pointer to a rank-one
! array of type real, p1 is not associated
! with any target
INTEGER, POINTER :: p2(:,:)
! p2 is a pointer to an integer array of
!rank-two,
! p2 must be associated with a target before it
! can be referenced
TYPE err_type
   INTEGER :: class
   REAL :: code
END TYPE err_type
TYPE(err_type), POINTER, DIMENSION(:,:,:) :: err
! err is a pointer to a rank-3 array of type
! err_type
 
INTEGER, POINTER :: p3(n)
! this is ILLEGAL, pointers cannot have an
! explicit shape

Allocatable arrays

An allocatable array has only its name and rank declared at compile-time, plus the ALLOCATABLE attribute. It can be allocated and deallocated as required by use of the ALLOCATE and DEALLOCATE statements. These statements give the user the ability to manage space dynamically at execution time.

The ALLOCATABLE statement and attribute, the ALLOCATE statement, and the DEALLOCATE statement are described in Chapter 10.

An allocatable array has an allocation status which is initially set to not-allocated. The array may not be referenced while it is in this state except as an argument to the ALLOCATED intrinsic inquiry function, which may be used to determine the allocation status of an allocatable array; this intrinsic function is described in Chapter 11. Once the allocatable array is allocated, its allocation status becomes allocated and the array may be used in any context in which an array may appear. If an allocatable array is deallocated then its allocation status returns to not-allocated. It is an error to either allocate an allocatable array whose status is allocated, or to deallocate an allocatable array when its status is not-allocated.

The allocation status of a local allocatable array that does not have the SAVE attribute becomes undefined if the allocation status of the array is allocated when the procedure in which it is defined exits. In HP Fortran 90 such an array will be automatically deallocated; this is a Fortran 95 feature that has been added as an extension.

Although pointer arrays provide more functionality, allocatable arrays are simpler and provide more opportunities for compiler optimization.

The following subroutine contains an example of an allocatable array declaration and uses the ALLOCATED intrinsic function to illustrate how its allocation status may change.

SUBROUTINE foo
!  demonstrate the use of an allocatable array
REAL, ALLOCATABLE, DIMENSION(:,:) :: matrix
! the array matrix is rank-2 allocatable
! array, it has no shape and no storage
 
INTEGER :: n
LOGICAL :: a1
LOGICAL :: a2
LOGICAL :: a3
a1 = ALLOCATED(matrix)
! a1 is assigned the value .FALSE.  as the
! allocation status of the array is 
! not allocated
READ *,n
ALLOCATE(matrix(n,n))
! dynamically create the array matrix; after 
! it has been allocated the array will have 
! the shape [ n, n ]
a2 = ALLOCATED(matrix)
! a2 is assigned the value .TRUE. as the
! allocatable array does exist and its
! allocation status is therefore allocated
DEALLOCATE (matrix)
a3 = ALLOCATED (matrix)
! a3 is assigned the value .FALSE. as the
! allocation status of the array is 
! not-allocated
END SUBROUTINE foo

Assumed-size arrays

An assumed-size array is an older FORTRAN 77 feature that has been modernized in Fortran 90 with the introduction of assumed-shape arrays; the use of assumed-size arrays in new code is discouraged.

An assumed-size array is a dummy argument whose size is not specified; this is in contrast to an explicit-shape dummy array where the extents of each dimension are specified, and an assumed-shape array where the extents of each dimension are assumed from the corresponding actual argument. The form of an assumed-size array specifier is the same as for an explicit-shape array except that the upper bound of the last dimension is an asterisk (*).

All dummy array arguments and their corresponding actual argument share the same initial element and are storage associated. In the case of explicit-shape and assumed-size arrays, the actual and dummy array do not have to have the same shape or even rank; however the size of the dummy array must not exceed the size of the actual argument and therefore a subscript in the last dimension of an assumed-size array may extend from the lower bound to a value that does not cause the reference to go beyond the storage associated with the actual argument.

Because the last dimension of an assumed-size array has no upper bound, the dimension has no extent and the array consequently has no shape. The name of an assumed-size array therefore cannot be used in contexts in which a shape is required, such as the name of a function result or in a whole array reference.

The following example shows how an assumed-size array may be declared.

SUBROUTINE foo(a,n)
!  an example of an assumed-size array
INTEGER :: n
REAL :: a(n,3:*)
! declares a to be a rank-two array, the array
! has no shape and its size must not be greater
! than the size of associated dummy argument;
! the bounds of the first dimension range from 1
! through to n, the lower bound of the second
! dimension starts at 3, and its upper bound is
! not specified
...
END SUBROUTINE foo
Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 1996 Hewlett-Packard Development Company, L.P.