mm2*_*887 8 variables static fortran scope dynamic
对于我的编程语言类,一个小问题问:
FORTRAN中的局部变量是静态的还是堆栈动态的?局部变量是INITIALIZED的默认值是静态还是堆栈动态?向我展示一些代码,并附上解释以备份您的答案.提示:检查此方法的最简单方法是让程序测试子程序的历史敏感度.看看将局部变量初始化为某个值时会发生什么,而不是.您可能需要调用多个子程序才能放心地锁定答案.
我写了几个子程序: - 创建一个变量 - 打印变量 - 将变量初始化为一个值 - 再次打印变量
对子变量进行的每次连续调用都会在变量未初始化时打印出相同的随机值,然后打印出初始值.
当变量未初始化时,这个随机值是多少?
这是否意味着Fortran对每个子例程调用使用相同的内存位置,或者它是否动态创建空间并随机初始化变量?
我的第二个子程序也创建了一个变量,但随后调用了第一个子程序.结果是相同的,除了未初始化变量的随机数打印不同.我很迷茫.请帮忙!
非常感谢.
M. *_* B. 12
在Fortran 77和90/95/2003中,如果你想在子程序调用中保留子程序的局部变量的值,你应该将它声明为"save"属性,例如,(使用Fortran 90样式):
integer, save :: counter
Run Code Online (Sandbox Code Playgroud)
要么
integer :: counter
save :: counter
Run Code Online (Sandbox Code Playgroud)
.或者,如果要将"保存"行为应用于所有变量,只需在子例程中包含一个简单的
save
Run Code Online (Sandbox Code Playgroud)
声明没有任何变量.在Fortran 90中,声明中的变量初始化,
integer :: counter = 0
Run Code Online (Sandbox Code Playgroud)
自动获取保存属性.我不认为Fortran 77就是这种情况.
这是实验可能会产生误导的一个领域 - 它们会告诉您特定编译器的功能,但可能不是Fortran 77语言标准,也不是其他编译器所做的.许多旧的Fortran 77编译器没有在堆栈上放置局部变量,并且隐式地所有变量都具有save属性,而编程没有使用该声明.例如,流行的DEC Fortran编译器就是这种情况.传统的Fortran 77程序通常只与这种类型的特定编译器一起使用,因此现代编译器会出现故障,因为程序员忘记在需要它的变量上使用save属性.最初这不会导致问题,因为所有变量都有效地具有save属性.大多数现代编译器都将局部变量放在堆栈中而不保存,这些程序经常出现故障,因为一些变量需要"保存""忘记"它们在子程序调用中的值.这可以通过识别问题变量并添加save(work),向每个子例程添加一个save语句(减少工作量)来修复,或者许多编译器都有一个选项(例如,gfortran中的-fno-automatic)来恢复旧的行为(简单).
这似乎是一个特殊的问题 - 你不会发现关于"Fortran 77"但关于特定编译器的问题.为什么使用Fortran 77而不是Fortran 95/2003?教授.认为Fortran在1977年停止了?
放大@MSB所做的一点;
Fortran标准没有告诉编译器编写者如何实现标准,他们关心的是程序员可见的程序行为.所以这个问题的答案是"这一切都取决于编译器".OP并没有告诉我们他正在使用哪个(哪些)编译器.
此外,如果您追溯到所有编写的FORTRAN77编译器,我相信您会发现您感兴趣的功能的各种不同实现,其中许多与非常深奥的硬件架构相关联.