【发布时间】:2014-04-06 09:32:27
【问题描述】:
在 Fortran 中定义一个数组:
real, dimension(a,b) :: matrix
如果给定matrix,我如何获得a 和b?
【问题讨论】:
在 Fortran 中定义一个数组:
real, dimension(a,b) :: matrix
如果给定matrix,我如何获得a 和b?
【问题讨论】:
Vladimir F's answer 说明了我们真正需要了解的关于问题的数组matrix 的所有信息。但是,我们可以更笼统地涵盖其他情况及其局限性。
在此之前,一些术语。数组具有rank(维度或下标的数量)、extents(每个维度中的元素数量)以及上下边界。标量的秩为零。
matrix 问题有:
a 和b
1和1;上限 a 和 b。可以使用内部函数查询这些属性中的每一个(仅来自 Fortran 2018 的排名):
RANK(a) 返回一个等级为 a 的标量整数
SIZE(a,dim=i) 返回一个标量整数,其范围为a 的i-th 维度(SIZE(a) 返回所有a 中的元素总数)SHAPE(a) 返回一个整数数组,其大小等于 a 的秩(对于标量 a 为零),每个元素对应一个维度的范围LBOUND(a) 和 UBOUND(a) 返回相似的整数数组,每个元素都是维度的下限和上限LBOUND(a,i) 和 UBOUND(a,i) 返回具有 i-th 维度下限和上限的标量整数。对于显式形状数组,除非指定了维度的下限,否则它将为1,并且维度的范围将与指定的上限相同。类似地,对于假定形状的虚拟参数数组,除非另外给出,否则下限为 1,无论实际参数的边界如何:
real, intent(in) :: a(:,:) ! Lower bounds 1
范围与实际参数相同。
延迟形状数组(可分配和指针)也可以使用这些内在函数进行查询,但必须分配可分配且指针必须与指针关联:
real, intent(in), allocatable :: a(:,:) ! Same bounds as the actual argument if allocated
real, intent(out), allocatable :: b(:,:) ! Definitely not allocated: no bounds
这里a 与假定的形状参数不同,它的下限可能不同于1,但LBOUND 会安全地告诉我们。
对于假定的 size 参数,情况有所不同:
real, intent(in) :: a(2:5,*)
在这里,我们不能使用SHAPE来询问a,但我们可以放心地使用LBOUND,并且我们可以在某些方面使用UBOUND和SIZE:
LBOUND(a) ! Allowed: can ask about lower bound for all dimensions
LBOUND(a,1)
LBOUND(a,2) ! Both allowed individually
UBOUND(a) ! Not allowed: this would include asking about the second upper bound
UBOUND(a,1) ! Allowed: first bound is defined
UBOUND(a,2) ! Not allowed: bad second bound
SIZE(a) ! Not alllowed: as for UBOUND
SIZE(a,1) ! Allowed
SIZE(a,2) ! Not allowed
RANK(a) ! Allowed (we know it will be 2).
(Fortran 2018)假设 rank 参数仍然略有不同:
real, dimension(..), intent(in) :: a
print *, RANK(a) ! Allowed
print *, SHAPE(a) ! ""
print *, LBOUND(a) ! ""
print *, UBOUND(a) ! ""
print *, SIZE(a) ! ""
print *, LBOUND(a,1) ! Allowed only if a is rank at least 1
print *, UBOUND(a,1) ! ""
print *, SIZE(a,1) ! ""
如果假定的排名变量是标量,则不允许该维度的值(0,这是必要的,在任何情况下都不是有效维度)。
但事情可能会变得很奇怪:SHAPE(a) 可能会为某些元素返回 -1:
implicit none
real a(6)
call s1(a)
contains
subroutine s1(a)
real a(2,*)
call s2(a)
end subroutine s1
subroutine s2(a)
real a(..)
print *, SHAPE(a)
end subroutine s2
end program
如果你确实得到了-1,你就知道你不能使用UBOUND 来获取相应维度的上限,也不能使用SIZE 来获取其范围。但是,您可以使用 LBOUND 来获得它的下限。
最后,数组表达式在每个维度上总是有下界1,上界等于extent:
real a(4:7)
print *, LBOUND(a), UBOUND(a)
print *, LBOUND(a(:)), UBOUND(a:))
print *, LBOUND(a+1), UBOUND(a+1)
【讨论】: