10

我需要 Fortran (90) 中的(真实)数组的深层副本,但我不确定如何获得一个,因为我不完全了解引用的工作原理。直觉上,我希望这能得到我想要的:

do i=1,n
  b(i) = a(i)
end do

但是,最近有人向我指出,这b(1:n) = a(1:n)相当于上面的代码。直观地说,我希望这b(1:n) = a(1:n)只会导致引用b(1:n)指向a(1:n)内存中的位置。

b(1:n) = a(1:n)深拷贝吗?为什么?与 相对的底层引用发生了b = a什么?

4

2 回答 2

16

您提到的复制数组的三种方法,do循环b(1:n) = a(1:n)b = a,都是等效的;他们将数组的内容复制a到数组中ba并且b只是数组,而不是花哨的指针或任何东西,因此分配a = b与数学表达式基本相同。引用的进行(用户需要了解)并没有什么魔力,这就是为什么 Fortran 是一种非常简单易学的语言的原因。您可以在 Fortran 中使用指针数组,但这是另一个问题。

M Metcalf 和 J Reid解释的 Fortran 90/95始终是有关 Fortran 语言功能咨询的良好参考。从第 48 页开始:

3.11 数组赋值

通过内在赋值,可以将数组表达式分配给相同形状的数组变量,这被解释为好像表达式的每个元素都被分配给了变量的相应元素。例如,使用声明

real, dimension(10, 20) :: a

那作业

a = a  + 1.0

替换a(i,j)a(i,j) + 1.0fori=1,2..,10j=1,2,..,20

另请注意,标量表达式可以分配给数组,在这种情况下, saclar 值会广播到所有数组元素

就这一切实际上是如何实现的而言,这就是我认为您提出问题的目的,Fortran 标准完全没有说明这一点。此类事情未指定,以允许编译器编写者进行他们喜欢的任何优化。例如,在 assignmenta = b中,元素的b复制顺序a未由标准指定,因此不同的编译器可以以不同的方式执行此操作。您需要知道的是,对于这个问题,如果ab不是指针,那么ab是不同的数组,并且更改一个元素不会更改另一个元素的相应元素。所以感觉,a=b是“深拷贝”,您可以将其视为将所有项目复制ba.

于 2012-08-03T16:56:38.397 回答
10

a = b 将整个数组 b 复制到 a 中。如果您只希望数组的部分尺寸大于 n,那么您可以使用下标表示法 a(1:n) = b(1:n)。那是 Fortran 90——它是一种比 FORTRAN 77 更高级别的语言。我们可以看出“a = b”是一个副本,并且没有将指针 a 与目标 b 相关联,因为该语句使用了运算符“=”。指针关联使用 =>。

编辑:通过复制,它会复制,可能与您的 do 循环具有相同的机器代码。指针关联在不执行 do 循环以复制所有数组元素的情况下进行引用。

请参阅http://en.wikipedia.org/wiki/Fortran_95_language_features

于 2012-08-03T16:55:08.413 回答