【问题标题】:How are quantities referenced in Fortran?Fortran 中如何引用数量?
【发布时间】:2017-07-18 03:34:10
【问题描述】:

很久以前有人告诉我,在 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。第二个版本的引擎盖下发生了什么?编译器是否解包子程序调用,声明一个临时变量只是为了通过引用传递它?

【问题讨论】:

  • 默认情况下,在 fortran 中,所有内容都(或表现得好像)通过引用传递。在第二种情况下,您是正确的,编译器有效地创建了一个临时数组并传递了引用。请注意,如果mysubroutine 修改了它的参数,它将在第一种情况下修改myarray,并在第二种情况下做一些不可预测的事情。

标签: fortran pass-by-reference pass-by-value


【解决方案1】:

在很大程度上,尝试使用传递引用和传递值来分类 Fortran 过程调用并没有太大帮助。您可以在回复this onethis one 等问题时​​找到更多详细信息。

简而言之,通常过程引用是这样的,即对过程中变量的更改会反映在引用该过程的变量中。在某些情况下,编译器可能会选择进行复制输入/复制输出,而在其他情况下,它实际上必须这样做。同样,虚拟参数的value 属性指定制作匿名副本。

这个问题增加了一些不同之处在于使用了诸如 in 之类的表达式

call mySubroutine([2.3d0, 1.5d0])  ! Using F2003 array constructor syntax

编译器是否创建了临时变量?

诚然,这可能只是术语上的松散,但值得一提的是,其中肯定不涉及变量[2.3d0, 1.5d0] 是一个表达式,而不是一个变量。至关重要的是,这意味着它不能在过程中被修改(出现在变量定义上下文中)。适用于使用表达式而不是(临时)变量的情况的限制包括:

  • 与表达式关联的虚拟参数可能没有intent(inout)intent(out) 属性;
  • 如果虚拟参数没有意图属性,则如果关联的实际参数是表达式,则该参数可能不会被修改。

现在,如果虚拟参数具有value 属性,则无论以何种方式引用,过程的效果都是相同的。

总而言之,程序可以与表达式而不是中间变量一起工作。如果不是,那是因为违反了 Fortran 的某些方面。它的工作原理是编译器而不是程序员的问题。

【讨论】:

  • 感谢您的帮助!我问这个问题的动机是这段代码是一个函数的一部分,它将被循环多次,我想知道我是否可以通过将表达式直接插入mySubroutine(其中有@987654330 @)。这样,myArray 就不会一遍又一遍地重新初始化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-06
  • 2012-01-14
  • 2016-05-29
  • 1970-01-01
相关资源
最近更新 更多