在下面的代码中,我声明了一个数组mass
有 20 个元素。当传递给子程序时foo
, foo
被告知mass
只有 10 个元素。但是,我仍然可以访问第 20 个元素。我的问题是:
为什么我可以将数组传递给子例程并告诉子例程错误的数组大小?
为什么我仍然可以访问第 20 个元素,即使子例程认为它只有 10 个元素?
我会对数组中的第 20 个元素进行任何更改吗?foo
保留在数组中,就像一样foo
知道数组的正确大小吗?
这是代码:
program test
implicit none
integer num2,i
real*8 mass(20)
num2=10
do i = 1,num
mass(i) = 1.d0
end do
call foo(num2,mass)
end
subroutine foo(num2,mass)
integer num2
real*8 mass(num2)
write(*,"(A20,E15.9)") "first one:",mass(1)
write(*,"(A20,E15.9)") "tenth one:",mass(10)
write(*,"(A20,E15.9)") "twentieth one:",mass(20)
continue
end
注意:子例程被告知数组大小错误的这种情况是我在尝试修改以供自己使用的其他人的代码中遇到的一种情况。
您的问题背后存在一些误解,我将在这个答案中解决。一些实际意义在M. S. B. 的回答 https://stackoverflow.com/a/34522159.
你说你声明了一个数组mass
有二十个元素,但是foo
据说只有十个。这是不正确的。
你所拥有的实际上是两个不同的实体:一个数组mass
在主程序中,有二十个元素和一个数组(也称为mass
) 子程序中大小为 10 的foo
.
“通过”就是建立一个关联(所谓论证关联)在这两个实体之间。数组称为mass
主程序中是子程序中的实际参数和名为的数组mass
子程序中是虚拟参数。
虚拟参数是一个具有显式形状、范围的数组num2
(这也是与num2
主程序)。首先num2
虚拟参数的元素与第一个相关联num2
实际论证的要素。 [这导致要求至少有num2
主程序中数组中的元素。]
所以,你的第一个问题的答案
为什么我可以将数组传递给子例程并告诉子例程错误的数组大小?
只是这样:您没有告诉它错误的大小,您只是说子例程中的数组对应于第一个num2
论证的要素。
来到
为什么我仍然可以访问第 20 个元素,即使子例程认为它只有 10 个元素?
这是一个编程错误。不允许使用大于数组范围的下标值。当你尝试这样做时会发生什么取决于编译器。正如另一个答案所说,这很可能只是访问(由于关联的实现方式)内存中与实际参数的大元素相对应的位置。但同样,编译器可能会抱怨(特别是那些检查所选编译选项的情况),或者如果通过临时复制完成传递,则可能会崩溃。 [后者不太可能。]
Finally
在 foo 中对数组中的第 20 个元素所做的任何更改是否会保留在数组中,就像 foo 知道数组的正确大小一样?
这又是特定于实现的。没有正确的 Fortran 答案,因为您的程序不符合要求。与上一点一样,如果这是与实际参数的适当元素相对应的内存区域,并且没有进行边界检查,则更改可能会持续存在。如果编译器选择进行复制,则可能会发生崩溃,或者返回时可能会忽略超出范围的更改。 [同样,最后两个不太可能,因为它需要编译器“聪明”。]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)