来自 associate 的非单索引数组
Non-one indexed array from associate
我想要一个指向数组(或其部分)的关联,而不是一个索引。
下面的程序说明了这个问题:
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)
我不认为这是可能的。 A(0 : N - 1)
是一个子数组,是一个表达式,不再是原来的数组。 A(0 : N - 1)
的下界是 1,不是 0。
你可以试试
dimension A(0:9)
print *,lbound(A(0:8))
end
它将打印 1
.
请注意,您的同事可能会将数组部分复制并存储在临时数组中。
如果关联到=> B
,A
会正确写成9
。
您可以使用指针指向这些部分
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
语法
associate (B(0:N-1) => ...)
end associate
在 Fortran 中无效:关联项的左侧必须是 名称。仅使用名称(此处为 B
)无法指定边界等属性。
关联实体数组的边界(同样,这里是 B
),由在右侧使用 LBOUND
的结果给出(选择器) (Fortran 2018, 11.1.3.3 p.1):
The lower bound of each dimension is the result of the intrinsic function LBOUND
(16.9.109) applied to the corresponding dimension of selector
LBOUND
的参考描述解释了在这种情况下如何计算界限。
因为A(0:N-1)
不是一个完整的数组,LBOUND
returns1
,所以在这种情况下B
的下界本身就是1
.
B
的下界可以是 1
以外的东西:选择器是整个数组。在
associate(B => A)
end associate
B
将具有 A
.
的下限
总而言之:关联实体有可能具有除 1
以外的下限,但前提是它关联的事物是整个数组。特别是,在与数组的一部分关联时(可以包括数组的 all,例如 B => A(:)
、A(:)
不是整个数组)关联实体总是有下界 1
.
正如 Vladimir F 在另一个答案中所说,指针可以将边界控制为指针赋值的一部分。
我想要一个指向数组(或其部分)的关联,而不是一个索引。 下面的程序说明了这个问题:
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)
我不认为这是可能的。 A(0 : N - 1)
是一个子数组,是一个表达式,不再是原来的数组。 A(0 : N - 1)
的下界是 1,不是 0。
你可以试试
dimension A(0:9)
print *,lbound(A(0:8))
end
它将打印 1
.
请注意,您的同事可能会将数组部分复制并存储在临时数组中。
如果关联到=> B
,A
会正确写成9
。
您可以使用指针指向这些部分
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
语法
associate (B(0:N-1) => ...)
end associate
在 Fortran 中无效:关联项的左侧必须是 名称。仅使用名称(此处为 B
)无法指定边界等属性。
关联实体数组的边界(同样,这里是 B
),由在右侧使用 LBOUND
的结果给出(选择器) (Fortran 2018, 11.1.3.3 p.1):
The lower bound of each dimension is the result of the intrinsic function
LBOUND
(16.9.109) applied to the corresponding dimension of selector
LBOUND
的参考描述解释了在这种情况下如何计算界限。
因为A(0:N-1)
不是一个完整的数组,LBOUND
returns1
,所以在这种情况下B
的下界本身就是1
.
B
的下界可以是 1
以外的东西:选择器是整个数组。在
associate(B => A)
end associate
B
将具有 A
.
总而言之:关联实体有可能具有除 1
以外的下限,但前提是它关联的事物是整个数组。特别是,在与数组的一部分关联时(可以包括数组的 all,例如 B => A(:)
、A(:)
不是整个数组)关联实体总是有下界 1
.
正如 Vladimir F 在另一个答案中所说,指针可以将边界控制为指针赋值的一部分。