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

时间:2016-12-04 07:37:39

标签: fortran slice fortran90

假设我将一个数组切片传递给一个操作其输入的子程序:

a

原始a(:,1)的该部分是否已更改,或{{1}}的某些副本已更改?

2 个答案:

答案 0 :(得分:5)

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

Vladimir F's answer着眼于所谓的拷入/拷贝机制; 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没有这个功能。

答案 1 :(得分:4)

这取决于a本身是否连续以及some_subroutine的外观如何。

你可能默默地认为a是连续的,但如果a本身是一个传递为假定形状数组或数组指针的片段,则不一定如此。

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

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