指向参数数组目标的 Fortran 指针

Fortran pointer to parameter array target

我在一个模块中有几个不同名称的参数数组:

real*8, parameter :: para1(*) = [43.234, 34.0498, ...
real*8, parameter :: para2...

在此模块的例程中

subroutine sub(n,...
...
end

我想在 n=1 时使用 para1,在 n=2 时使用 para2,等等。有一些解决方案,一个是制作一个数组 paras= [para1,para2...] 并正确索引,效果很好。但我想尝试使用指针

real*8, pointer :: ptr(:) 

并根据n分配给不同的参数数组,但问题是“PARAMETER attribute conflicts with TARGET attribute at (1)”。如果我删除 parameter 属性,则例程不那么安全,并且假定 SAVE 属性。

我是不是遗漏了什么或者为什么我们不能合并 parametertarget?是否有解决此问题的好方法?

parametertarget属性确实有冲突。具有 target 属性的对象必须是变量(Fortran 2018 8.5.17,C861);命名常量(具有 parameter 属性的对象)不是变量(F2018、8.5.13、C850)。

然后,要使用目标数组,您必须使用变量。拥有一个 "safe" 的变量是很棘手的,因为它的值被编程错误等修改了。有几个注意事项禁止变量出现在 变量定义上下文 中。如果你能安排这样的状态,那么编译器可能有机会检测到你的错误。这很容易发生吗?

在纯过程和 intent(in) 伪参数之外,最诱人的禁止是受保护的模块变量:

module pars
  real, save, target, protected :: para1(74) = [...]
  real, save, target, protected :: para2(1) = [6]
end module

subroutine sub (...)
  use pars
  real, pointer :: p
  p => para1
end subroutine sub

受到保护,这些值不会在模块外被修改pars? las,即使这是真的也无济于事:受到保护,我们甚至不能将指针指向模块变量。

总而言之,您的编译器不会轻易检测到修改变量目标数组的编程错误,因此如果您想使用数组作为目标,则必须小心。

根据@ja72 在评论中的建议,这是对参数使用单个二维数组的尝试。这适用于 gfortran-8.2(在 MacOS10.11 上)。

program main
    implicit none
    integer i
    integer, parameter :: para1(*) = [1, 2, 3, 4, 5]
    integer, parameter :: para2(*) = [6, 7]
    integer, parameter :: N1 = size(para1), N2 = size(para2), N = max(N1, N2)
    integer, parameter :: params(N, 2) = &
            reshape( [ para1, (0, i = 1, N - N1), &
                       para2, (0, i = 1, N - N2) ], [N, 2] )

    print *, "para1 = ", params( :, 1 )
    print *, "para2 = ", params( :, 2 )

    print *, "Input i"
    read *, i
    print *, params( :, i )
end

$ gfortran-8 test.f90 && ./a.out

 para1 =            1           2           3           4           5
 para2 =            6           7           0           0           0
 Input i
1
           1           2           3           4           5

但是,由于代码变得有点复杂(因为重塑)并且可能不适用于旧的编译器,所以使用 non-parameter 数组可能会更直接...