Fortran是否通过函数和子程序调用保持内部变量的值? [英] Does Fortran preserve the value of internal variables through function and subroutine calls?

查看:350
本文介绍了Fortran是否通过函数和子程序调用保持内部变量的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



经过非常痛苦的调试,我相信我发现了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆