回 帖 发 新 帖 刷新版面

主题:[讨论]变量的生存周期

本人一直对变量的生存周期有似懂非懂的感觉,还请各位不吝赐教。
(1)比如module,common,函数(子程序或function),同一个子程序里面的独立的两个循环。变量的生存周期关系到参数传递:以什么方式传递确保可以传递过去,没有差错,并且不会出现变量“打架”和相互干扰的问题。
(2)module和common是相互矛盾的吧,就是一个变量只能用其中一个,否则会出错。那么是不是一个module里面的内部函数(contains那种)在外部要使用时use 这个module,为什么会出现有些变量(是数组)可以传递出来,有些不行,为什么呢?不行的那些是不是什么细节没有考虑到。有一次我打印出来两个变量,其中一个可以,另一个打印出来是默认的初始值(即为0),哦对了,这两组变量都是通过文件读入的,通过一个读入子程序来实现。
(3)既然有common和module,那么参数传递是不是可以废止不用了
(4)fortran的子程序或函数的形参、实参,和哑元、实元是一个概念吗?有什么技巧和注意的。
(5)fortran程序在编好前内存就已经配置好了吧。(1)中提到的几种情况,变量分别是什么时候占有内存,到什么时候释放内存的。
(6)变量打架一般 会出现哪些地方,以防止这种情况的出现。
请各位前辈参与讨论,指点迷津,扩展思维,明晰概念,理清思路,谢谢,谢谢了!

回复列表 (共2个回复)

沙发

问题实在太多,带着这些疑问去看 The Fortran 2003 Handbook,这本书可以帮你揭开心中的疑惑。

板凳

问题确实多。

一般来说,变量的生存周期是该程序单元。

Module 里的变量是永久的,每一个 Use 了它的程序单元,都可以直接使用它内部的变量和Contains子程序。

common 于 Module 不矛盾。但不推荐使用 common!!!

变量打架问题很多,需要分别排查,不好一概而论,我也没有归纳过哪些情况会出现。

形参,虚参,哑元是一个东西。
实参,实元也是一个东西。

common 和 Module 不可能代替参数传递。
对于科学计算的角度,计算数据确实可以用 common 和 Module 来代替参数的传递。
但是虚参可以每次不一样,每次调用根据情况而定,而 Module 不行,它需要手动更改。
比如有一个函数,虚参是“男方”“女方”,内容是“结婚”。

Subroutine 结婚( 男方 , 女方 )
 ...
End Subroutine 结婚

第一次调用“结婚”,“男方”=“谢霆锋”,“女方”=“张柏芝”
Call 结婚(谢霆锋,张柏芝)

第二次调用“结婚”,“男方”=“张国立”,“女方”=“邓婕”
Call 结婚(张国立,邓婕)

如果用 Module 代替参数,会非常麻烦,也不如参数传递直观。

从程序设计的角度,Module 和 common 也不适合混编。因为其他语言未必有 Module 和 common,就算有,调用协定也不同。
而参数传递,只要遵循统一的调用协定,那么进行混编就更方便。

内存配置是由编译器完成的,一般在编译时确定地址。
但有例外:
1.allocatable 的数组,地址是运行时确定
2.虚参,子程序局部变量,地址可能是在运行时从堆栈里取出。(也可能在编译时确定,编译器会选择更好的储存方式)
3.临时变量,循环变量,编译器甚至不会在内存里给它们分配空间,而直接使用寄存器。(也可能分配,编译器也会选择更好的方式)

总之,内存的调度是由编译器完成的,不同编译器就会不一样。
同样的代码,不同的编译器,不同的优化选项,数组的大小不同,都可能导致编译器选择不同的内存调度手段。

如果楼主对这个感兴趣,建议学习汇编语言,反汇编调试技术,编译原理。

我来回复

您尚未登录,请登录后再回复。点此登录或注册