Fortran 是否通过函数和子例程调用保留内部变量的值? [英] Does Fortran preserve the value of internal variables through function and subroutine calls?
问题描述
经过痛苦的调试,我相信我找到了 Fortran 的一个独特属性,我想在 stackoverflow 上验证它.
After much painful debugging, I believe I've found a unique property of Fortran that I'd like to verify here at stackoverflow.
我注意到的是,至少,内部逻辑变量的值在函数或子例程调用中被保留.
What I've been noticing is that, at the very least, the value of internal logical variables are preserved across function or subroutine calls.
这里有一些示例代码来说明我的观点:
Here is some example code to illustrate my point:
PROGRAM function_variable_preserve
IMPLICIT NONE
CHARACTER(len=8) :: func_negative_or_not ! Declares function name
INTEGER :: input
CHARACTER(len=8) :: output
input = -9
output = func_negative_or_not(input)
WRITE(*,10) input, " is ", output
10 FORMAT("FUNCTION: ", I2, 2A)
CALL sub_negative_or_not(input, output)
WRITE(*,20) input, " is ", output
20 FORMAT("SUBROUTINE: ", I2, 2A)
WRITE(*,*) 'Expected negative.'
input = 7
output = func_negative_or_not(output)
WRITE(*,10) input, " is ", output
CALL sub_negative_or_not(input, output)
WRITE(*,20) input, " is ", output
WRITE(*,*) 'Expected positive.'
END PROGRAM function_variable_preserve
CHARACTER(len=*) FUNCTION func_negative_or_not(input)
IMPLICIT NONE
INTEGER, INTENT(IN) :: input
LOGICAL :: negative = .FALSE.
IF (input < 0) THEN
negative = .TRUE.
END IF
IF (negative) THEN
func_negative_or_not = 'negative'
ELSE
func_negative_or_not = 'positive'
END IF
END FUNCTION func_negative_or_not
SUBROUTINE sub_negative_or_not(input, output)
IMPLICIT NONE
INTEGER, INTENT(IN) :: input
CHARACTER(len=*), INTENT(OUT) :: output
LOGICAL :: negative = .FALSE.
IF (input < 0) THEN
negative = .TRUE.
END IF
IF (negative) THEN
output = 'negative'
ELSE
output = 'positive'
END IF
END SUBROUTINE sub_negative_or_not
这是输出:
FUNCTION: -9 is negative
SUBROUTINE: -9 is negative
Expected negative.
FUNCTION: 7 is negative
SUBROUTINE: 7 is negative
Expected positive.
如您所见,一旦函数或子例程被调用一次,逻辑变量 negative
,如果切换到 .TRUE.
,尽管如此,仍然保持原样在类型声明语句中将negative
初始化为.FALSE.
.
As you can see, it appears that once the function or subroutine is called once, the logical variable negative
, if switched to .TRUE.
, remains as such despite the initialization of negative
to .FALSE.
in the type declaration statement.
当然,我可以通过添加一行来纠正这个问题负数 = .FALSE.在我的函数和子程序中声明变量之后.
I could, of course, correct this problem by just adding a line negative = .FALSE. after declaring the variable in my function and subroutine.
然而,这对我来说似乎很奇怪.
However, it seems very odd to me that this be necessary.
为了可移植性和代码可重用性,语言(或编译器可能)不应该在每次调用子例程或函数时重新初始化所有内部变量吗?
推荐答案
回答您的问题:是的,Fortran 确实通过函数和子例程调用保留了内部变量的值.
在特定条件下...
如果你用 SAVE 属性声明一个内部变量,它的值会从一次调用保存到下一次调用.当然,这在某些情况下很有用.
If you declare an internal variable with the SAVE attribute it's value is saved from one call to the next. This is, of course, useful in some cases.
但是,您的问题是第一次了解 Fortran 的一个陷阱时的常见反应:如果您在其声明中初始化一个内部变量,那么它会自动获取 SAVE 属性.你已经在你的子程序中做到了这一点.这是符合标准的.如果您不希望这种情况发生,请不要在声明中初始化.
However, your question is a common reaction upon first learning about one of Fortran's gotchas: if you initialise an internal variable in its declaration then it automatically acquires the SAVE attribute. You have done exactly that in your subroutines. This is standard-conforming. If you don't want this to happen don't initialise in the declaration.
这是(一些)语言新手感到惊讶和抱怨的原因.但无论他们如何抱怨,它都不会改变,所以你只需要 (a) 了解它并 (b) 规划并意识到它.
This is the cause of much surprise and complaint from (some) newcomers to the language. But no matter how hard they complain it's not going to change so you just have to (a) know about it and (b) program in awareness of it.
这篇关于Fortran 是否通过函数和子例程调用保留内部变量的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!