Assumed-size arrays are dummy argument arrays where the size is inherited from the associated actual array, but the rank and extents may differ. They can only be declared inside subprograms.
Assumed_size_spec |
---|
>>-+----------------------------------------+--+----------------+--*->< | .-,-------------------------------. | '-lower_bound--:-' | V | | '---+----------------+--upper_bound-+--,-' '-lower_bound--:-' |
If any bound is not constant, the array must be declared inside a subprogram and the nonconstant bounds are determined on entry to the subprogram. If a lower bound is omitted, its default value is 1.
The last dimension has no upper bound and is designated instead by an asterisk. You must ensure that references to elements do not go past the end of the actual array.
The rank equals one plus the number of upper_bound specifications in its declaration, which may be different from the rank of the actual array it is associated with.
The size is assumed from the actual argument that is associated with the assumed-size array:
then the size of the dummy argument array is:
MAX( INT (T - A + 1) / S, 0 )
For example:
CHARACTER(10) A(10) CHARACTER(1) B(30) CALL SUB1(A) ! Size of dummy argument array is 10 CALL SUB1(A(4)) ! Size of dummy argument array is 6 CALL SUB1(A(6)(5:10)) ! Size of dummy argument array is 3 because there are ! just under 4 elements remaining in A CALL SUB1(B(12)) ! Size of dummy argument array is 1, because the remainder ! of B can hold just one CHARACTER(10) element END SUBROUTINE SUB1(ARRAY) CHARACTER(10) ARRAY(*) ... END SUBROUTINE
INTEGER X(3,2) DO I = 1,3 DO J = 1,2 X(I,J) = I * J ! The elements of X are 1, 2, 3, 2, 4, 6 END DO END DO PRINT *,SHAPE(X) ! The shape is (/ 3, 2 /) PRINT *,X(1,:) ! The first row is (/ 1, 2 /) CALL SUB1(X) CALL SUB2(X) END SUBROUTINE SUB1(Y) INTEGER Y(2,*) ! The dimensions of y are the reverse of x above PRINT *, SIZE(Y,1) ! We can examine the size of the first dimension ! but not the last one. PRINT *, Y(:,1) ! We can print out vectors from the first PRINT *, Y(:,2) ! dimension, but not the last one. END SUBROUTINE SUBROUTINE SUB2(Y) INTEGER Y(*) ! Y has a different rank than X above. PRINT *, Y(6) ! We have to know (or compute) the position of ! the last element. Nothing prevents us from ! subscripting beyond the end. END SUBROUTINE
Notes:
! A is an assumed-size array.
PRINT *, UBOUND(A,1) ! OK - only examines upper bound of first dimension. PRINT *, LBOUND(A) ! OK - only examines lower bound of each dimension. ! However, 'B=UBOUND(A)' or 'A=5' would reference the upper bound of ! the last dimension and are not allowed. SIZE(A) and SHAPE(A) are ! also not allowed.
! A is a 2-dimensional assumed-size array PRINT *, A(:, 6) ! Triplet with no upper bound is not last dimension. PRINT *, A(1, 1:10) ! Triplet in last dimension has upper bound of 10. PRINT *, A(5, 5:9:2) ! Triplet in last dimension has upper bound of 9.