|Fortran Language Reference Manual, Volume 1 - S-3692-51|
|Prev Section||Chapter 6. Using Data||Next Section|
An array is a collection of scalar elements of any intrinsic or derived type. An object of any type that is specified to have the DIMENSION attribute is an array. All of the elements of an array must have the same type and kind parameter. There can be arrays of structures. The value returned by a function can be an array. The appearance of an array name or designator has no implications for the order in which the individual elements are referenced unless array element ordering is specifically required.
An array consists of elements that extend in one or more dimensions to represent columns, rows, planes, and so on. There can be up to seven dimensions in an array declaration. The number of dimensions in an array is called the rank of the array. The number of elements in a dimension is called the extent of the array in that dimension. The shape of an array is determined from the rank and the extents; to be precise, the shape is a vector where each element of the vector is the extent in the corresponding dimension. The size of an array is the product of the extents; that is, it is the total number of elements in the array.
Example 1: Consider the following statement:
REAL X(0:9, 2)
The rank of X is 2 because X has two dimensions. The extent of the first dimension is 10; the extent of the second dimension is 2. The shape of X is 10 by 2, that is, a vector of two values, (10, 2). The size is 20, the product of the extents.
An object can be given the DIMENSION attribute in a type declaration or in one of several other specification statements.
DIMENSION A(10, 15, 3) REAL, DIMENSION(10, 15, 3) :: A REAL A(10, 15, 3) COMMON A(10, 15, 3) TARGET A(10, 15, 3)
Arrays of nonzero size have a lower and upper bound for each dimension. The lower bound is the smallest subscript value for a dimension; the upper bound is the largest subscript value for that dimension. The default lower bound is 1 if the lower bound is omitted in the declaration. Array bounds can be positive, zero, or negative.
Example 3: Consider the following statement:
REAL Z(-3:10, 12)
The first dimension of Z ranges from -3 to 10, that is, -3, -2, -1, 0, 1, 2, . . ., 9, 10. The lower bound is -3; the upper bound is 10. In the second dimension, the lower bound is 1; the upper bound is 12.
The bounds for array expressions are described in Section 188.8.131.52.
Some arrays are named. The name is either an array variable name or the name of a constant. If the array name appears without a subscript list or section subscript list, all of the elements of the array are referenced and the reference is considered to be a whole array reference.
An array element is one of the scalar elements that make up an array. A subscript list is used to indicate which element is referenced. Assume that A is declared to be a one-dimensional array, as follows:
REAL, DIMENSION(10) :: A
A(1) refers to the first element, A(2) to the second, and so on. The number in the parentheses is the subscript that indicates which scalar element is referenced. Assume that B is declared to be a seven-dimensional array, as follows:
REAL B(5, 5, 5, 5, 4, 7, 5)
B(2,3,5,1,3,7,2) refers to one scalar element of B, indexed by a subscript in each dimension. The set of numbers that indicate the position along each dimension in turn (in this case, 2,3,5,1,3,7,2) is called a subscript list.
Sometimes only a portion of an array is needed for a calculation. It is possible to refer to a selected portion of an array as an array; this portion is called an array section. A parent array is the whole array from which the portion that forms the array section is selected.
An array section is specified by an array variable name and a section subscript list that consists of subscripts, triplet subscripts, or vector subscripts. At least one subscript must be a triplet or vector subscript; otherwise, the reference indicates an array element, not an array section. The following example uses a section subscript to create an array section:
REAL A(10) . . . A(2:5) = 1.0
The parent array A has 10 elements. The array section consists of the elements A(2), A(3), A(4), and A(5) of the parent array. The section A(2:5) is an array itself and the value 1.0 is assigned to all four of its elements.
For a data reference to be classified as an array section, exactly one part reference must have nonzero rank, and either the final part reference must have a section subscript list with nonzero rank or another part reference must have nonzero rank.
The format of an array section is a data reference followed by an optional substring range enclosed in parentheses. This is defined as follows:
The format of a substring range is found in Section 6.2.
A part name in a data reference can be followed by an optional section subscript list, as follows:
Each subscript and stride must be a scalar_int_expr. A vector_subscript must be an integer array expression of rank one.
For a data reference to be classified as an array element, every part reference must have rank zero and the last part reference must contain a subscript list.
In an array section that is a data reference followed by a substring range, the rightmost part name must be of type character.
In an array section of an assumed-size array, the second subscript must not be omitted from a subscript triplet in the last dimension.
A section subscript must be present for each dimension of an array. If any section subscript is simply a subscript, the section will have a lesser rank than its parent.
If any part of a reference is an array section, the reference is considered to be an array section reference. In a data reference, there may be at most one part with rank greater than zero.
Examples of array elements and array sections are as follows:
ARRAY_A(1,2) ! array element ARRAY_A(1:N:2,M) ! rank-one array section ARRAY_B(:,:,:)(2:3) ! array. elements are substrings of ! of length 2 SCALAR_A%ARRAY_C(L) ! array element SCALAR_A%ARRAY_C(1:L) ! array section SCALAR_B%ARRAY_D(1:N)%SCALAR_C ! array section ARRAY_E(1:N:2)%ARRAY_F(I,J)%STRING(K)(:) ! array section
In the last example above, each component of the type definition is an array and the object ARRAY_E is an array. The reference is valid because each component in the reference is scalar. The substring range is not needed because it specifies the entire string; however, it serves as a reminder that the last component is of type character.
The following examples demonstrate the allowable combinations of scalar and array parents with scalar and array components.
TYPE REPAIR_BILL REAL PARTS(20) REAL LABOR END TYPE REPAIR_BILL TYPE(REPAIR_BILL) FIRST TYPE(REPAIR_BILL) FOR_1990(6)Scalar parent:1. FIRST % LABOR ! structure component 2. FIRST % PARTS(I) ! array element 3. FIRST % PARTS ! component (array-valued) 4. FIRST % PARTS(I:J) ! array section 5. FOR_1990(K) % LABOR ! structure component 6. FOR_1990(K) % PARTS(I) ! array element 7. FOR_1990(K) % PARTS ! component (array-valued) 8. FOR_1990(K) % PARTS(I:J) ! array sectionArray parent:9. FOR_1990 % LABOR ! component and array section 10. FOR_1990 % PARTS(I) ! array section 11. FOR_1990 % PARTS ! ILLEGAL 12. FOR_1990 % PARTS(I:J) ! ILLEGAL 13. FOR_1990(K:L) % LABOR ! component and array section 14. FOR_1990(K:L) % PARTS(I) ! array section 15. FOR_1990(K:L) % PARTS ! ILLEGAL 16. FOR_1990(K:L) % PARTS(I:J) ! ILLEGAL
References 11, 12, 15, and 16 are illegal because only one component may be of rank greater than zero. References 3 and 7 are compact (contiguous) array objects and are classified as array-valued structure components. References 9, 10, 13, and 14 are noncontiguous array-section objects. These distinctions are important when such objects are actual arguments in procedure references.
In an array element reference, each subscript must be within the bounds for that dimension. A subscript can appear in an array section reference. Whenever this occurs, it decreases the rank of the section by one. A subscript used in this way must be within the bounds for the dimension. The Cray Fortran Compiler allows overindexing, which may produce incorrect results because of optimization. For information on overindexing and optimization, see Fortran Language Reference Manual, Volume 3 or Cray Fortran Compiler Commands and Directives Reference Manual.
Note: The Fortran standard does not address overindexing.
The first subscript in a subscript triplet is the lower bound; the second is the upper bound. If the lower bound is omitted, the declared lower bound is used. If the upper bound is omitted, the declared upper bound is used. The stride is the increment between successive subscripts in the sequence. If it is omitted, it is assumed to be 1. The stride must not be 0. If the subscripts and stride are omitted and only the colon (:) appears, the entire declared range for the dimension is used.
When the stride is positive, an increasing sequence of integer values is specified from the first subscript in increments of the stride, up to the last value that is not greater than the second subscript. The sequence is empty if the first subscript is greater than the second. If any subscript sequence is empty, the array section is a zero-sized array, because the size of the array is the product of its extents. For example, given the array declared A(5,4,3) and the section A(3:5,2,1:2), the array section is of rank 2 with shape (3,2) and size 6. The elements are as follows:
A(3,2,1) A(3,2,2) A(4,2,1) A(4,2,2) A(5,2,1) A(5,2,2)
When the stride is negative, a decreasing sequence of integer values is specified from the first subscript, in increments of the stride, down to the last value that is not less than the second subscript. The sequence is empty if the second subscript is greater than the first, and the array section is a zero-sized array. For example, given the array declared B(10) and the section B (9:4:-2), the array section is of rank 1 with shape (3) and size 3. The elements are as follows:
B(9) B(7) B(5)
However, array section B(9:4) is a zero-sized array.
A subscript in a subscript triplet is not required to be within the declared bounds for the dimension as long as all subscript values selected by the triplet are within the declared bounds. For example, given an array declared B(10), section B(3:11:7) is permitted. It has rank 1 with shape (2) and size 2. The elements are as follows:
While subscript triplets specify values in increasing or decreasing order with a specified stride to form a regular pattern, vector subscripts specify values in arbitrary order. The values must be within the declared bounds for the dimension. A vector subscript is a rank-one array of integer values used as a section subscript to select elements from a parent array.
INTEGER J(3) REAL A(30) . . . J = (/ 8, 4, 7 /) A(J) = 1.0
The last assignment statement assigns the value 1.0 to A(4), A(7), and A(8). The section A(J) is a rank-one array with shape (3) and size 3.
If J were assigned (/ 4, 7, 4 /) instead, the element A(4) would be accessed in two ways: as A(J(1)) and as A(J(3)). Such an array section is called a many-to-one array section. A many-to-one section must not appear on the left of the equal sign in an assignment statement or as an input item in a READ statement. The reason is that the result will depend on the order of evaluation of the subscripts, which is not specified by the language. The results would not be predictable and the program containing such a statement would not be portable.
Array sections with vector subscripts are array expressions, so there are places, such as the following, where array sections with vector subscripts must not appear:
As internal files
As pointer targets
As actual arguments for INTENT(OUT) or INTENT(INOUT) dummy arguments
Subscripts, subscript triplets, and vector subscripts can be mixed in a single section subscript list used to specify an array section. A triplet section can specify an empty sequence (for example 1:0), in which case the resulting section is a zero-sized array.
Example 1: Assume that B is declared as follows:
REAL B(10, 10, 5)
B(1,6,3) B(1,8,3) B(4,6,3) B(4,8,3)
The stride along the first dimension is 3, resulting in a subscript-value list of 1 and 4. The stride along the second dimension is 2, resulting in a subscript-value list of 6 and 8. In the third position there is a subscript that reduces the rank of the section by 1. The section has shape (2, 2) and size 4.
Example 2: Assume IV is declared as follows:
INTEGER, DIMENSION(3) :: IV = (/ 4, 5, 4 /)
Then the section B(8:9, 5, IV) is a 2 x 3 array consisting of the following six elements:
B(8,5,4) B(8,5,5) B(8,5,4) B(9,5,4) B(9,5,5) B(9,5,4)
B(8:9, 5:4, IV) is a zero-sized array of rank 3.
When whole arrays are used as operands in an executable statement, the indicated operation is performed element-by-element, but no order is implied for these elemental operations. They can be executed in any order or simultaneously. Although there is no order of evaluation when whole array operations are performed, there is an ordering of the elements in an array itself. An ordering is required for the input and output of arrays and for certain intrinsic functions such as MAXLOC(3i). The elements of an array form a sequence whose ordering is called array element order. This is the sequence that occurs when the subscripts along the first dimension vary most rapidly, and the subscripts along the last dimension vary most slowly. Thus, for an array declared as REAL A(3, 2), the elements in array element order are: A(1, 1), A(2, 1), A(3, 1), A(1, 2), A(2, 2), A(3, 2).
The position of an array element in this sequence is its subscript order value. Element A(1, 1) has a subscript order value of 1. Element A(1, 2) has a subscript order value of 4. Figure 6-1, shows how to compute the subscript order value for any element in arrays of rank 1 through 7.
The subscript order of the elements of an array section is that of the array object that the section represents. That is, given the array A(10) and the section A(2:9:2) consisting of the elements A(2), A(4), A(6), and A(8), the subscript order value of A(2) in the array section A(2:9:2) is 1; the subscript order value of A(4) in the section is 2 and A(8) is 4.