在 Fortran 中,切片数组是否会在内存中创建一个副本?

In Fortran, does slicing an array create a copy in memory?

假设我将一个数组的一部分传递给一个子程序来处理它的输入:

some_subroutine(a(:,1))

原始 a 的那部分是否被更改,或者 a(:,1) 的某些副本是否被更改?

这取决于 a 本身是否连续以及 some_subroutine 看起来如何。

您可能默默地假设 a 是连续的,但如果 a 本身是作为假定形状数组或数组指针传递的某个切片,则不必如此。

即使 a 不连续,因此 a(:,1) 也不连续,如果 some_subroutine 接受假定的形状参数,则不需要副本

subroutine some_sub(b)
  real :: some_sub(:)

还有一些其他答案,它们可能解决了略有不同(但相关)的问题。在这里,我将尝试调和它们。

looks at the so-called copy-in/copy-out mechanism; bfletch's answer最后对参数的影响。

总的来说,效果如下

integer i(2,2)
i=0
call dosomething(i(1,:))   ! Just to make it not contiguous.

contains
  subroutine dosomething(j)
    integer j(2)  ! or j(*), or j(:)
    j=1
  end subroutine
end program

是数组i有一些元素设置为1,其他元素设置为0。所以,是的:无论是否有临时副本(来自一个答案),调用后可以观察到的是实际参数本身被修改了。

自然有一个例外:value属性。1如果上面的子程序改为

subroutine doseomthing(j)
  integer, value :: j(2)
  j=1
end subroutine

那么确实有一个论据的真实副本。对伪参数 j 的修改不会反映在 i.

的实际参数中

1这适用于当前的 Fortran。正如标记的那样,Fortran 90 没有此功能。