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

Whole arrays and array subobjects

» 

Technical documentation

» Feedback
Content starts here

 » Table of Contents

 » Glossary

 » Index

An array may be referred to either as a whole or in part. Any part of an array that may be referenced independently of other parts of the array is known as a subobject of the array, and includes either an array element or an array section. These terms are explained below.

Array elements

An individual element of an array is a scalar and has the same type and type parameters as the array; an element of an array may be referred to by an array element reference that takes the form of the array name followed by a subscript list enclosed in parentheses. A subscript list is an ordered set of subscript expressions separated by commas, one expression for each array dimension. Each subscript expression must be scalar and of type integer and must have a value that lies within the declared bounds for that dimension.

HP Fortran 90 also allows a subscript expression of type real; the expression will automatically be converted to type integer after it has been evaluated.

An array element may be used in any expression in which a scalar is allowed.

The following example declares various arrays and then shows how elements of these arrays may be referenced. The example also contains some invalid array element references and explains why they are illegal.

SUBROUTINE foo(a,b,c,n)
INTEGER :: n
INTEGER :: a(:)
! a is an assumed-shape array
REAL    :: b(-100:n)
! b is an adjustable dummy array
REAL    :: c(100,100)
! c is an explicit-shape dummy array
REAL, ALLOCATABLE :: d(:,:,:)
! d is an allocatable array
REAL, POINTER     :: e(:,:)
! e is a pointer to a rank-2 array
REAL, TARGET      :: f(5,5)
! f is an explicit-shape array with rank 2 and
! size 25
INTEGER :: i,j
!  examples of valid array element references
a(1) = 100b(a(n)) = b(a(n)) + ABS(c(10*i,j)) / 
ABS(a(n))
ALLOCATE(d(10,10,n))     
! allocate d with shape [10, 10, n]
d(5,5,n) = LOG10 (n)
e => f 
! associate pointer e with array f
e(1,1) = n
! assign n to the first array element of e,
! this is equivalent to assigning n to f(1,1)
!  examples of INVALID array element references
a(0) = 100
! illegal - a reference outside the array
! bounds, the default lower bound of an
! assumed shape array is 1
c(100) = 123
! illegal - the array has a rank of two but 
only! one subscript has been specified
c(101,1) = 0.0
! illegal - the subscript 101 is outside the 
! bounds of its dimension
END SUBROUTINE foo

Whole arrays

All the elements of an array are referenced if the array name is used without any bracketed subscript list; this is known as a whole array reference. Whole array references may be used in such contexts as input/output statements and argument lists, and also in any array valued expression. An array valued expression is an expression whose value is an array and may be formed from operations involving arrays; this is discussed in more detail in a following section.

The subroutine in the following example illustrates various contexts in which a whole array reference may be used. It also contains some examples of simple array operations which will be explained later in the section “Array expressions”.

SUBROUTINE change (a,b)
! examples of references to a whole array
REAL, DIMENSION(:,:) :: a,b
! declare a and b to be rank-two assumed-shape
! arrays
REAL, ALLOCATABLE    :: temp(:,:)
! temp is an allocatable array, it will be
! assigned storage below
ALLOCATE(TEMP(SIZE(a,1),SIZE(a,2))
! create temp with the same shape as the
! assumed-shape array a
temp = a 
! copy all of array a into temp
a = b - 1.0
! subtract 1.0 from each element of b and
! assign to the corresponding element of a
b = b - temp
! decrement each element of b by the
! corresponding element in temp
WRITE(*,*) b
DEALLOCATE(temp)
END SUBROUTINE change

Array sections

The term array section is used in Fortran 90 to denote an array that is a selected portion of another array, known as the parent. An array section is an array even if it consists of only one element (or possibly none) and can therefore be specified wherever an array name may be specified.

In Fortran 90, an array section may be defined:

  • By a section subscript list

  • By an array of derived-type components

  • By an array of character substrings

Each of these will be described in turn below.

Section subscript list

There are two subscript forms used to describe a section: subscript triplets and vector subscripts.

  • The subscript triplet notation enables a lower bound, an upper bound, and a stride to be specified for any dimension of the parent array. A subscript triplet selects elements in a regular manner from a dimension; the stride can, for example, be used to select every second element.

  • A vector subscript is any expression that results in a rank-one integer value; the values of the array select the corresponding elements of the parent array for a given dimension. Vector subscripts can be used to describe an irregular pattern and may be useful for indirect array addressing such an indexing by a table.

Syntax

An array section reference using a section subscript list is:

array-name ( section-subscript-list )
section-subscript-list

is a comma-separated list of section-subscript.

section-subscript

is one of:

  • subscript

  • subscript-triplet

  • vector-subscript

subscript

is

scalar-integer-expression
subscript-triplet

is

[subscript] : [subscript]  [: stride] 
stride

is

scalar-integer-expression
vector-subscript

is a rank-one integer array expression.

A section -subscript -list must specify a section -subscript for each dimension of the parent array. The rank of the array section is the number of subscript -triplets and vector -subscripts that appear in the section -subscript-list; and because an array section is also an array, at least one subscript -triplet or vector -subscript must be specified.

Subscript triplet

The first subscript of a subscript triplet specifies the lower bound for the dimension, the second subscript specifies the upper bound, and the stride defines the increment between subscript values. All three components of a subscript triplet are optional; if a bound is left out, then that bound is taken from the parent array; if the stride is omitted, then the increment between subscript values is assumed to be one. An upper bound must, however, be specified if a subscript triplet is used in the last dimension of an assumed-sized array.

The stride must not be zero; if it is positive then the subscripts range from the lower bound up to and including the upper bound, in steps of stride. Note that when the difference between the upper bound and lower bound is not a multiple of the stride then the last subscript value selected by the subscript triplet will be the largest integer value that is not greater than the upper bound; thus the array expression a(1: 9: 3) will select subscripts 1, 4, and 7 from a.

It therefore follows that a bound in a subscript triplet need not be within the declared bounds for that dimension of the parent array so long as all the elements selected are within its declared bounds.

Strides may be negative as well as positive. A negative stride selects elements from the parent array starting at the lower bound and proceeds backwards through the parent array in steps of the stride down the last value that is greater than the upper bound. For example, the expression a(9: 1:- 3) will select the subscripts 9, 6, and 3 in that order from a.

If the section bounds are such that no elements are selected in a dimension, the section has zero-size; for example, the section a(2:1).

The following example shows the power of the subscript triplet notation in assigning the same value to a regular pattern of array elements.

INTEGER, DIMENSION(3,6) :: x,y,z
! x, y, and z are 3x6 arrays.
x = 0; y = 0; z = 0
! These are whole-array assignments.
x(3,2:4:1)  = 1
y(2,2:6:2)  = 2
z(1:2,3:6)  = 3
! Using subscript triplets, elements of x, y,
!    and z have been assigned, as follows.
!       X                Y                Z
!  0 0 0 0 0 0      0 0 0 0 0 0      0 0 3 3 3 3
!  0 0 0 0 0 0      0 2 0 2 0 2      0 0 3 3 3 3
!  0 1 1 1 0 0      0 0 0 0 0 0      0 0 0 0 0 0
Vector subscripts

A vector subscript is an array expression that evaluates into a rank-one integer array. The values of the expression represent the subscript value of the elements to be selected. For example, if v represents a rank-one array initialized with the values 4, 3, 1, 7, then the array section a(v) is a rank-one array composed of the array elements a(4), a(3), a(1), and a(7) — in that order. Note that vector subscripts are commonly specified using array constructors that are described in the next section; as an example of these, the expressions a(v) and a((/ 4, 3, 1, 7/)) have the same section of the array a.

There are various restrictions associated with the use of an array section with vector subscript; they may not appear:

  • On the right hand side of a pointer assignment statement.

  • In an I/O statement as an internal file.

  • As an actual argument that is associated with a dummy argument declared with INTENT(OUT) or INTENT(INOUT) or with no INTENT.

It is permissible for a vector subscript to specify the same element more than once. When a vector subscript of this form is used to specify an array section, the array section is known as a many-one array section. An example of a many-one array section is:

a( (/ 4, 3, 4, 7/) )

where element 4 has been selected twice. Fortran 90 does not define the order in which elements are selected in array operations and it is therefore illegal for a many-one array section to appear in either an input list or on the left-hand side of an assignment statement.

A vector subscript allows irregular patterns of elements to be selected as opposed to subscript triplets that select elements in a uniform pattern.

The following example illustrates the concept of an array section using a section subscript list.

INTEGER, DIMENSION(4) :: m = (/ 2, 3, 8, 1/)
! m is a rank-1 array that has been
! initialized with the values of an array
! constructor
INTEGER :: i
REAL, DIMENSION(10) :: a = (/ (i*1.1, i=1,10) /)
! a is a rank-1 array that has been
! initialized with the values
! 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9,
! 11.0
REAL, DIMENSION(4,2) :: b
! b is an uninitialized 4x2 array
PRINT *,a(m)
! prints 2.2, 3.3, 8.8, and 1.1
b(:,1) = a( (/ 5, 10, 6, 5/) )
! assigns the values 5.5, 11.0, 6.6, and 5.5
! to the first column of b; this is an example
! of a many-one array section
b(:,2) = b(MIN(m,4),1)
! the vector subscript MIN(m,4) represents a
! rank-1 array with the values 2, 3, 4, 1 and
! the second column of b is assigned with
! 11.0, 6.6, 5.5, 5.5
a(m) = a(m) + 20.0
! increments a(2), a(3), a(8), and a(1) by 20.0
PRINT *,a
! prints 21.1, 22.2, 23.3, 4.4, 5.5, 6.6, 7.7,
! 28.8, 9.9, 11.0

Array of derived-type components

Chapter 3 describes how derived types may be declared. They may be scalars or arrays and may contain components which are scalars or arrays of intrinsic type. The components may also be variables of derived type nested to any arbitrary level. Fortran 90 requires that in any variable name reference at most one component of the name has a non-zero rank and a reference to an array of derived-type components is one in which a component of the name, but not the last, is an array. Thus given the declaration:

TYPE sampletype
  character(8) :: time
  real         :: reading
  logical      :: flags(4)
END TYPE sampletype
TYPE (sampletype) :: sample(100)

then the operands below are examples of a whole array:

sample
sample(n)%flags

and the following operand is an example of an array of derived-type components:

sample%reading

This array has a rank of 1 and a size of 100; it consists of the array elements sample(1)%reading, sample(2)%reading, ..., sample(100)%reading.

Similarly the operand below:

sample%time

represents a CHARACTER(8) array, its rank is 1, its size is 100, and it is composed of the elements sample(1)%time, sample(2)%time, ..., sample(100)%time.

This concept may be taken one step further, for although the term sample%flags is not allowed, sample%flags(4) is valid and represents an array of derived-type components that is composed of all the final elements of the component flags that belong to the array sample.

The following subroutine includes the declaration of the derived-type sample and demonstrates some simple uses of an array of derived-type components.

SUBROUTINE process(sample,case)
TYPE sampletype
     CHARACTER(8):: time
     REAL        :: reading
     LOGICAL     :: flags(4)
END TYPE sampletype
TYPE (sampletype) :: sample(100)
! declare sample to be a rank-1 dummy array
! of type sampletype, the array has 100
! elements
INTEGER :: case
IF (case == 1) THEN
   sample%reading = 0.0
   ! initializes every component reading of the
   ! array sample to zero
ENDIF
IF (case == 2) THEN
   sample%reading = DIM(sample%reading,0.0)	
   ! any negative value in the array
   ! sample%reading is replaced by zero
ENDIF
IF (case == 3) THEN
   WRITE(*,10) & 
(sample(i)%time,sample(i)%reading, i=1,100)
   ! prints two columns, the first column
   ! contains the 100 components time and the
   ! second column contains the 100 components
   ! reading
ENDIF
10 FORMAT(A,E15.7)
END SUBROUTINE process

Array of character substrings

An array section of type character may also have a substring range specified. An array section of this form is known as an array substring and is composed of array elements whose values only include the specified substring from each corresponding element of the array section.

The following example illustrates the concept of an array substring.

CHARACTER(11) :: dates(40)
dates(5:10)(8:) = "1996"

The variable dates(5:10) is an array section that includes elements 5 through to 10 of the parent array dates, and the variable dates(5:10)(8:11) is also an array section of the array dates but only contains the last 4 character positions of the elements 5 through to 10.

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