在 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 没有此功能。
假设我将一个数组的一部分传递给一个子程序来处理它的输入:
some_subroutine(a(:,1))
原始 a
的那部分是否被更改,或者 a(:,1)
的某些副本是否被更改?
这取决于 a
本身是否连续以及 some_subroutine
看起来如何。
您可能默默地假设 a
是连续的,但如果 a
本身是作为假定形状数组或数组指针传递的某个切片,则不必如此。
即使 a
不连续,因此 a(:,1)
也不连续,如果 some_subroutine
接受假定的形状参数,则不需要副本
subroutine some_sub(b)
real :: some_sub(:)
还有一些其他答案,它们可能解决了略有不同(但相关)的问题。在这里,我将尝试调和它们。
总的来说,效果如下
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 没有此功能。