Fortran是否通过函数和子程序调用保持内部变量的值? [英] Does Fortran preserve the value of internal variables through function and subroutine calls?
问题描述
经过非常痛苦的调试,我相信我发现了Fortran的一个独特属性,我想在此处进行验证。注意到至少,内部逻辑变量的值在函数或子程序调用中保留。
下面是一些示例代码来说明我的观点: p>
PROGRAM function_variable_preserve
IMPLICIT NONE
CHARACTER(len = 8):: func_negative_or_not!声明函数名称
INTEGER :: input
CHARACTER(len = 8):: output
$ b $ 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)输入,is,输出
20 FORMAT(SUBROUTINE:,I2,2A)
WRITE(*,*)'预期为负值'。
$ b输入= 7
输出= func_negative_or_not(输出)
写入(*,10)输入,是,输出
CALL sub_negative_or_not(输入,输出)
WRITE(*,20)输入,is,输出
WRITE(*,*)'预计正值'
结束程序function_variable_preserve
CHARACTER(len = *)FUNCTION func_negative_or_not(输入)
IMPLICIT NONE
INTEGER,INTENT(IN):: input
LOGICAL :: negative = .FALSE。
IF(输入<0)THEN
负= .TRUE。
END IF
$ b $ IF(负)THEN
func_negative_or_not ='negative'
ELSE
func_negative_or_not ='正值'
END IF
END FUNCTION func_negative_or_not
SUBROUTINE sub_negative_or_not(输入,输出)
IMPLICIT NONE
INTEGER,INTENT(IN):: input
CHARACTER(len = *),INTENT(OUT):: output
LOGICAL :: negative = .FALSE。
IF(输入<0)THEN
负= .TRUE。
END IF
IF(负数)THEN
输出='负数'
ELSE
输出='正数'
END IF
END SUBROUTINE sub_negative_or_not
这是输出:
功能:-9为负值
子路径:-9为负值
预计负值。
功能:7为负值
子路径:7为负值
预期正值。
正如您所看到的,似乎一旦函数或子例程被调用一次,逻辑变量<如果切换到 .TRUE。
,则尽管初始化为负数 code>到
.FALSE。
在类型声明语句中。
当然,我可以更正这个问题只需要添加一行
negative = .FALSE即可。
在我的函数和子程序中声明变量后。
然而,这对我来说很有必要。
为了可移植性和代码的可重用性,每次调用子例程或函数时,语言(或编译器)是否都不需要重新初始化所有内部变量?
回答您的问题:是Fortran通过函数和子例程调用保留内部变量的值
在特定条件下...
如果您声明一个具有SAVE属性的内部变量,从一个呼叫保存到下一个呼叫。当然,这在某些情况下很有用。
然而,在第一次了解Fortran的一个陷阱时,你的问题是一个普遍的反应:如果你初始化一个内部变量它的声明然后它自动获得SAVE属性。你已经完成了你的子程序。这是符合标准的。如果您不希望发生这种情况,请不要在声明中初始化。这是(某些)新手对该语言感到惊讶和抱怨的原因。但是,无论他们抱怨多难,它都不会改变,所以你只需要(a)知道它并(b)意识到这一点。
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
This is the output:
FUNCTION: -9 is negative
SUBROUTINE: -9 is negative
Expected negative.
FUNCTION: 7 is negative
SUBROUTINE: 7 is negative
Expected positive.
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.
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.
For the sake of portability and code reusability, shouldn't the language (or compiler maybe) require re-initialization of all internal variables each time the subroutine or function is called?
To answer your question: Yes Fortran does preserve the value of internal variables through function and subroutine calls.
Under certain conditions ...
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.
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.
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屋!