来自 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.

请注意,您的同事可能会将数组部分复制并存储在临时数组中。

如果关联到=> BA会正确写成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)不是一个完整的数组,LBOUNDreturns1,所以在这种情况下B的下界本身就是1.

B 的下界可以是 1 以外的东西:选择器是整个数组。在

associate(B => A)
end associate

B 将具有 A.

的下限

总而言之:关联实体有可能具有除 1 以外的下限,但前提是它关联的事物是整个数组。特别是,在与数组的一部分关联时(可以包括数组的 all,例如 B => A(:)A(:) 不是整个数组)关联实体总是有下界 1.

正如 Vladimir F 在另一个答案中所说,指针可以将边界控制为指针赋值的一部分。