我想有一个关联,指向一个数组(或其中的一部分),而不是一个索引。下面的程序说明了这个问题:
program test_associate
implicit none(type, external)
integer, parameter :: N = 10
integer :: i, A(0 : N - 1)
A = [(i, i = lbound(A, 1), ubound(A, 1))]
write(*, *) A(0), A(9)
associate(B => A(0 : N - 1))
write(*, *) B(9) ! This writes 8 but should write 9
end associate
end program
我试着
associate(B(0 : N - 1) => A(0 : N - 1))
write(*, *) B(9)
end associate
,但这是无效的语法。(至少在我的编译器gfortran 9.3)
语法
associate (B(0:N-1) => ...)
end associate
在Fortran中无效:关联项的左侧必须是名称。如果只是一个名称(这里是B
),则不可能指定诸如边界之类的属性。
关联实体数组(同样,这里是B
)的边界由在右侧使用LBOUND
(选择器)的结果给出(Fortran 2018, 11.1.3.3 p.1):
各维数的下界是对选择器
的相应维数应用内禀函数LBOUND
(16.9.109)的结果。
LBOUND
的引用描述解释了在这种情况下如何计算绑定。
因为A(0:N-1)
不是一个完整的数组,所以LBOUND
返回的是1
,所以在这种情况下,B
的下界本身就是1
。
B
的下界可能是1
以外的东西:选择器是一个完整的数组。在
associate(B => A)
end associate
B
将有A
的下界。
总结:关联实体可能有1
以外的下界,但只有当它关联的东西是一个完整的数组时。特别是,在关联数组的一部分时(可以包括数组的所有,例如B => A(:)
, A(:)
不是整个数组),关联实体总是具有1
的下界。
正如Vladimir F在另一个回答中所说,指针的边界可以作为指针赋值的一部分来控制。
我认为这是不可能的。A(0 : N - 1)
是一个子数组,它是一个表达式,不再是原来的数组。A(0 : N - 1)
的下界是1,不是0。
你可以试试
dimension A(0:9)
print *,lbound(A(0:8))
end
它将打印1
。
请注意,您的伙伴可能会将数组段复制并存储在临时数组中。
如果与=> B
关联,A
将正确写入9
。
可以使用指针指向这样的section
program test_associate
implicit none(type, external)
integer, parameter :: N = 10
integer, target :: A(0 : N - 1)
integer, pointer :: B(:)
integer :: i
A = [(i, i = lbound(A, 1), ubound(A, 1))]
write(*, *) A(0), A(9)
B(0:N-1) => A(0:N-1)
write(*, *) B(9) ! This writes 9
end program