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 Compiler for HP-UX: HP Fortran Programmer's Reference > Chapter 3 Arrays

Array declarations

» 

Technical documentation

Complete book in PDF
» Feedback
Content starts here

 » Table of Contents

 » Glossary

 » Index

An array is a data object with the dimension attribute. Its rank—and possibly the extents—are defined by an array specification. The array specification is enclosed in parentheses and can be attached either to the DIMENSION attribute, as in:

INTEGER, DIMENSION(17) :: a, b

or to the array name, as in:

REAL :: y(3,25)

If the array specification is attached both to the DIMENSION attribute and to the array name in the same declaration statement, the specification attached to the name takes precedence. In the following example:

INTEGER, DIMENSION(4,7) :: a, b, c(15)

a and b are declared as two-dimensional arrays, but c is declared as a one-dimensional array.

An array specification can declare an array as one of the following:

  • Explicit-shape array

  • Assumed-shape array

  • Deferred-shape array

  • Assumed-size array

The following sections describe these types and the form of the array specification for each type. For information about initializing arrays with the array constructor, see “Array constructors”.

Explicit-shape arrays

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

[lower-bound :] upper-bound

where lower-bound and upper-bound are specification expressions and may be positive, negative, or zero. The default for lower-bound is 1.

For a given dimension, the values of lower-bound and upper-bound define the range of the array in that dimension. Usually, lower-bound is less than upper-bound; if lower-bound is the same as upper-bound, then the dimension contains only one element; if it is greater, then the dimension contains no elements, the extent of the dimension is zero, and the array is zero-sized.

The simplest form is represented by an array declaration in which the name of the array is not a dummy argument and all bounds are constant expressions, as in the following example:

INTEGER :: a(100,4,5)

This form of array may have the SAVE attribute and may be declared in any program unit.

Other forms of the explicit-shape array include:

  • An automatic array: An array that is declared in a subprogram but is not a dummy argument and has at least one nonconstant bound. Automatic arrays may be declared in a subroutine or function, but may not have the SAVE attribute nor be initialized.

    Character strings can also be declared as automatic data objects; see “Character strings as automatic data objects”.

  • A dummy array: An array that is identified by its appearance 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: A particular form of a dummy array. Its name is specified in a dummy argument list, and at least one of its bounds is a nonconstant specification expression.

Explicit-shape arrays may also be used as function results, as described in “Array-valued functions” and in “Array dummy argument”.

The following code segment illustrates different forms of explicit-shape arrays:

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; list2 is a rank-two array with an
! extent of m * (m+n+1). list2 is also an adjustable array.

REAL :: work(100,n)
! work is an automatic array; it does not appear in the dummy
! argument list and at least one of its bounds is not constant

INTEGER, PARAMETER :: buffsize = 0
REAL :: buffer (1: buffsize)
! buffer has explicit shape, but 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. It must not have the POINTER attribute. Each dimension of an assumed-shape array has the form:

[lower-bound] :

where lower-bound is a specification expression. The default for lower-bound is 1.

The actual argument and the corresponding dummy argument may have different bounds for each dimension. An assumed-shape array subscript may extend from the specified lower-bound to an upper bound that is equal to lower-bound plus the extent in that dimension of the actual argument minus one.

The following code segment illustrates different declarations of assumed-shape arrays.

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 takes 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; the lower bound for
! each dimension is 1
.
.
.
END SUBROUTINE initialize

If a procedure has an argument that is an assumed-shape array, its interface must be explicit within the calling program unit. A procedure’s interface is explicit if it is an internal procedure within the caller procedure or if the interface is declared in an interface block within the caller.

For example, to call the external subroutine initialize in the previous example, its interface must appear in an interface block, as in the following:

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

SUBROUTINE initialize (a,b,c,n)
INTEGER :: n
INTEGER :: a(:)
COMPLEX :: b(ABS(n):)
REAL, DIMENSION(:,:,:,:,:) :: c
.
.
.
END SUBROUTINE initialize

For more information about:

Deferred-shape arrays

A deferred-shape array has either the POINTER attribute or the ALLOCATABLE attribute. Its shape is not specified until the array is pointer assigned or allocated. Although a deferred-shape array can have the same form as an assumed-shape array, the two are different. The assumed-shape array is a dummy argument and must not have the POINTER attribute.

The array specification for a deferred-shape array has the form:

: [ , : ] ...

The specification for a deferred-shape array defines its rank but not the bounds. The bounds are defined either when the array is allocated or when an array pointer becomes associated with a target.

Array pointers and allocatable arrays are described in the following sections.

Array pointers

An array pointer is a deferred-shape array with the POINTER attribute. Its bounds and shape are defined only when the array is associated with a target in a pointer assignment statement or in an ALLOCATE statement. An array pointer must not be referenced until it is associated.

Following are example declarations of array pointers:

! p1 is declared as a pointer to a rank-one
! array of type real; p1 is not associated with any target
REAL, POINTER, DIMENSION(:) :: p1

! p2 is a pointer to an integer array of rank-two;
! it must be associated with a target before it can be referenced
INTEGER, POINTER :: p2(:,:)

! err is a pointer to a rank-3 array of type err_type
TYPE err_type
INTEGER :: class
REAL :: code
END TYPE err_type
TYPE(err_type), POINTER, DIMENSION(:,:,:) :: err

! The next statement is ILLEGAL: pointers cannot have an
! explicit shape.
INTEGER, POINTER :: p3(n)

For information about associating an array pointer with a target, see “Pointers”. For information about the POINTER attribute and ALLOCATE statement, see Chapter 10, “HP Fortran Statements.”

Allocatable arrays

An allocatable array is a deferred-shape array with the ALLOCATABLE attribute. Its bounds and shape are defined when it is allocated with the ALLOCATE statement. Once allocated, the allocatable array may be used in any context in which any other array may appear. An allocatable array can also be deallocated with the DEALLOCATE statement.

An allocatable array has an allocation status that can be tested with the ALLOCATED intrinsic inquiry function. Its status is unallocated when the array is first declared and after it is deallocated in a DEALLOCATE statement. After the execution of the ALLOCATE statement, its status is allocated. An allocatable array with the unallocated status may not be referenced except as an argument to the ALLOCATED intrinsic or in an ALLOCATE statement. If it has the allocated status, it may not be referenced in the ALLOCATE statement. It is an error to allocate an allocatable array that is already allocated, or to deallocate an allocatable array either before it is allocated or after it is deallocated.

In HP Fortran, an allocatable array that is unallocated, is local to a procedure, and does not have the SAVE attribute. It is automatically deallocated when the procedure exits.

The following example, alloc_array.f90, calls a subroutine that allocates and deallocates an allocatable array and uses the ALLOCATED intrinsic function to test its allocation status:

Example 3-1 alloc_array.f90

PROGRAM main
! driver program for calling a subroutine that allocates and
! deallocates an allocatable array
CALL test_alloc_array
END PROGRAM main

SUBROUTINE test_alloc_array
! demonstrate how to allocate and deallocate an allocatable array

! the array matrix is rank-2 allocatable array, with no
! shape or storage
REAL, ALLOCATABLE, DIMENSION(:,:) :: matrix

INTEGER :: n
LOGICAL :: sts

! sts is assigned the value .FALSE. as the array is not yet
! allocated
sts = ALLOCATED(matrix)
PRINT *, 'Initial status of matrix: ', sts

PRINT *, 'Enter an integer (rank of array to be allocated):'
READ *,n

! dynamically create the array matrix; after allocation, array
! will have the shape [ n, n ]
ALLOCATE(matrix(n,n))


! test allocation by assigning to array
matrix(n,n) = 9.1
PRINT *, 'matrix(',n,',',n,') = ', matrix(n,n)
! sts is assigned the value .TRUE. as the allocatable array
! does exist and its allocation status is therefore allocated
sts = ALLOCATED(matrix)
PRINT *, 'Status of matrix after ALLOCATE: ', sts

DEALLOCATE (matrix)

! sts is assigned the value .FALSE. as the
! allocation status of a deallocated array
sts = ALLOCATED (matrix)
PRINT *, 'Status of matrix after DEALLOCATE: ', sts
END SUBROUTINE test_alloc_array

Here are the command lines to compile and execute the program, along with the output from a sample run:

$ f90 alloc_array.f90
$ a.out
Initial status of matrix: F
Enter an integer (rank of array to be allocated):
4
matrix( 4 , 4 ) = 9.1
Status of matrix after ALLOCATE: T
Status of matrix after DEALLOCATE: F

For information about the ALLOCATABLE, ALLOCATE, DEALLOCATE statements, see Chapter 10, “HP Fortran Statements.” See also “ALLOCATED(ARRAY)”.

Assumed-size arrays

An assumed-size array is a dummy argument whose size is taken from the associated actual argument. Its declaration specifies the rank and the extents for each dimension except the last. The extent of the last dimension is represented by an asterisk (*), as in the following:

INTEGER :: a(2,5,*)

All dummy array arguments and their corresponding actual arguments share the same initial element and are storage associated. In the case of explicit-shape and assumed-size arrays, the actual and dummy array need not have the same shape or even the same rank. The size of the dummy array, however, must not exceed the size of the actual argument. 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 appear in contexts in which a shape is required, such as a function result or a whole array reference.

The following example, assumed_size.f90, illustrates two assumed-size arrays: x (declared in subr) and i_array (declared in func):

Example 3-2 assumed_size.f90

PROGRAM main
REAL :: a(2,3) ! an explicit-shape array, represented by the
! vector [10, 10]
k = 0
DO i = 1, 3
DO j = 1, 2
k = k + 1
a(j, i) = k
END DO
END DO

PRINT *, 'main: a =', a
CALL subr (a)
END PROGRAM main

SUBROUTINE subr(x)
REAL :: x(2,*) ! an assumed-size array; the subscript for the
! last dimension may take any value 1 - 3

! PRINT *, x ! ILLEGAL, whole array reference not allowed

PRINT *, ‘main: x(2, 2) = ‘, x(2, 2)

PRINT *, 'returned by func: ', func(x), ', the value in x(2,3)'
END SUBROUTINE subr

REAL FUNCTION func(y)
REAL :: y(0:*) ! an assumed-size array; the subscript may
! take any value 0 - 5

func = y(5)
END FUNCTION func

Here are the command lines to compile and execute the program, along with the output from a sample run:

$ f90 assumed_size.f90
$ a.out
main: a = 1.0 2.0 3.0 4.0 5.0 6.0
main: x(2, 2) = 4.0
returned by func: 6.0 , the value in x(2,3)

An assumed-size array is a FORTRAN 77 feature that has been superseded by the assumed-shape array; see “Assumed-shape arrays”.

Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© Hewlett-Packard Development Company, L.P.