In many cases, passing the whole extent of an array to a function/subroutine is too tedious (e.g., you have ten arrays with different extents). Sometimes, you don't even know their extents. To overcome this, Fortran 90 offers the so-called assumed-shape arrays. Of course, they must be formal arguments.
lower-bound :
:
and the corresponding formal argument is declared asINTEGER, DIMENSION(-3:3) :: x
then the caller sees array x() as a collection of the following elements:INTEGER, DIMENSION(2:) :: y
Since the extent is lost when passing to an assumed-shape array, the callee would know array y() has 7 elements as follows:x(-3) x(-2) x(-1) x(0) x(1) x(2) x(3)
This is simply because the callee has an assumed-shape array with a lower bound 2. As a result, when the callee uses y(2), y(3), ..., y(8), it actually uses x(-3), x(-2), ..., x(3), respectively.y(2) y(3) y(4) y(5) y(6) y(7) y(8)
Suppose the caller has the following:
The callee could declare an assumed-shape array like the following:INTEGER, DIMENSION(-3:3) :: x .......... CALL SomeOne(x, -3)
SUBROUTINE SomeOne(y, LowerBound)
IMPLICIT NONE
INTEGER, DIMENSION(LowerBound:), INTENT(IN) :: y
..........
END SUBROUTINE SomeOne
In this case, the extent of array y() agrees with that of
actual argument array x().
PROGRAM Example
IMPLICIT NONE
INTEGER, PARAMETER :: LOWER_BOUND = 20
INTEGER, PARAMETER :: UPPER_BOUND = 50
INTEGER, DIMENSION(LOWER_BOUND:UPPER_BOUND) :: Data
REAL, DIMENSION(1:LOWER_BOUND) :: Values
LOGICAL, DIMENSION(21:UPPER_BOUND) :: Answers
..........
CALL First(Data, Value, Answers, LOWER_BOUND, 21)
..........
CONTAINS
SUBROUTINE First(x, y, z, Lower, LL)
IMPLICIT NONE
INTEGER, INTENT(IN) :: Lower
INTEGER, INTENT(IN) :: LL
INTEGER, DIMENSION(Lower:), INTENT(IN) :: x
REAL, DIMENSION(1:), INTENT(OUT) :: y
LOGICAL, DIMENSION(LL:), INTENT(INOUT) :: z
..........
END SUBROUTINE First
END PROGRAM Example
PROGRAM Test
IMPLICIT NONE
INTEGER, PARAMETER :: MAX_SIZE = 1000
REAL, DIMENSION(1:MAX_SIZE) :: Data
INTEGER :: ActualSize
INTEGER :: i
READ(*,*) ActualSize
READ(*,*) (Data(i), i=1, ActualSize)
WRITE(*,*) "Sum = ", Sum(Data, ActualSize)
CONTAINS
REAL FUNCTION Sum(x, n)
IMPLICIT NONE
INTEGER, INTENT(IN) :: n
REAL, DIMENSION(:), INTENT(IN) :: x
REAL :: Total
INTEGER :: i
Total = 0.0
DO i = 1, n
Total = Total + x(i)
END DO
Sum = Total
END FUNCTION Sum
END PROGRAM Test
SUBROUTINE Example(a, Lower)
IMPLICIT NONE
INTEGER, DIMENSION(Lower:Lower+SIZE(a)-1), INTENT(INOUT) :: a
..........
END SUBROUTINE
PROGRAM Bound
IMPLICIT NONE
INTEGER, DIMENSION(-10:10) :: a
INTEGER, DIMENSION(10:20) :: b
INTEGER, DIMENSION(1:100) :: c
INTEGER, DIMENSION(1:40) :: d
WRITE(*,*) "Array a()'s info:"
CALL DisplayInfo(a)
WRITE(*,*) "Array b()'s info:"
CALL DisplayInfo(b)
WRITE(*,*) "Array c()'s info:"
CALL DisplayInfo(c)
CONTAINS
SUBROUTINE DisplayInfo(x)
IMPLICIT NONE
INTEGER, DIMENSION(:), INTENT(IN) :: x
WRITE(*,*) " Size = ", SIZE(x)
WRITE(*,*) " Lower bound = ", LBOUND(x)
WRITE(*,*) " Upper bound = ", UBOUND(x)
WRITE(*,*)
END SUBROUTINE
END PROGRAM Bound