很久以前我被告知,在FORTRAN中,一切都是通过价值传递的。因此,我需要这样做(提供mySubroutine
在其他地方适当定义):
double precision :: myArray(2)
myArray(1:2) = (/ 2.3d0, 1.5d0 /)
CALL mySubroutine(myArray)
但是,我还发现如果我这样做,程序会按预期编译和运行
CALL mySubroutine((/ 2.3d0, 1.5d0 /))
无需定义中间数组myArray
。我以为我是通过引用将myArray
传递给mySubroutine
。在第二个版本的引擎盖下发生了什么?编译器是否解压缩子程序调用,声明临时变量只是通过引用传递它?
答案 0 :(得分:3)
在很大程度上,尝试使用pass-by-reference和pass-by-value对Fortran过程调用进行分类并没有太大帮助。您可以在回复this one和this one等问题时找到更多详情。
简而言之,通常过程引用使得过程中变量的更改反映在引用过程的变量中。在某些情况下,编译器可能会选择进行复制/复制,而在其他情况下,编译器必须选择复制。同样,伪参数的value
属性指定要创建匿名副本。
这个问题增加了一些与使用表达式有点不同的内容,例如
call mySubroutine([2.3d0, 1.5d0]) ! Using F2003 array constructor syntax
编译器是否正在创建临时变量?
不可否认,这可能只是术语的松散,但值得一提的是,肯定没有涉及变量。 [2.3d0, 1.5d0]
是表达式,而不是变量。至关重要的是,这意味着它不能在过程中修改(出现在变量定义上下文中)。在使用表达式而不是(临时)变量的情况下适用的限制包括:
intent(inout)
或intent(out)
属性; 现在,如果伪参数具有value
属性,则该过程的效果与引用它的方式相同。
总之,程序可以与表达式一起使用,而不是中间变量。如果不是因为违反了Fortran的某些方面。它的工作原理是编译器而不是程序员的问题。