Dynamic Fortran 77中的局部变量是静态的还是堆栈动态的?

Dynamic Fortran 77中的局部变量是静态的还是堆栈动态的?,dynamic,variables,static,scope,fortran,Dynamic,Variables,Static,Scope,Fortran,对于我的编程语言,一类硬件问题要求: FORTRAN中的局部变量是静态的还是堆栈动态的?初始化为默认值的局部变量是静态的还是堆栈动态的?给我一些代码和解释来支持你的答案。提示:检查这一点的最简单方法是让您的程序测试子程序的历史敏感性。看看当您将局部变量初始化为某个值时会发生什么,当您不初始化时会发生什么。您可能需要调用多个子程序才能自信地锁定答案 我写了几个子程序: -创建一个变量 -打印变量 -将变量初始化为一个值 -再次打印变量 每次对子例程的连续调用在变量未初始化时打印出相同的随机值,然后

对于我的编程语言,一类硬件问题要求:

FORTRAN中的局部变量是静态的还是堆栈动态的?初始化为默认值的局部变量是静态的还是堆栈动态的?给我一些代码和解释来支持你的答案。提示:检查这一点的最简单方法是让您的程序测试子程序的历史敏感性。看看当您将局部变量初始化为某个值时会发生什么,当您不初始化时会发生什么。您可能需要调用多个子程序才能自信地锁定答案

我写了几个子程序: -创建一个变量 -打印变量 -将变量初始化为一个值 -再次打印变量

每次对子例程的连续调用在变量未初始化时打印出相同的随机值,然后打印出初始化值

当变量未初始化时,这个随机值是什么

这是否意味着Fortran对子例程的每次调用都使用相同的内存位置,还是动态创建空间并随机初始化变量

我的第二个子例程也创建了一个变量,但随后调用了第一个子例程。结果相同,只是未初始化变量的随机数不同。我很困惑。请帮忙


非常感谢。

在Fortran 77&90/95/2003中,如果希望在子例程调用中保留子例程的局部变量值,则应将其声明为“保存”属性,例如(使用Fortran 90样式):

。 或者,如果希望“保存”行为应用于所有变量,只需在子例程中包含一个简单的

save
没有任何变量的语句。 在Fortran 90语言中,声明中的变量初始化

integer :: counter = 0
自动获取“保存”属性。我认为Fortran 77中的情况并非如此

这是一个实验可能会产生误导的领域——它们会告诉您特定编译器的功能,但可能不会告诉您Fortran 77语言标准是什么,也不会告诉您其他编译器的功能。许多旧的Fortran 77编译器没有在堆栈上放置局部变量,并且隐式地所有变量都具有save属性,而编程没有使用该声明。例如,流行的DEC Fortran编译器就是这样。传统的Fortran 77程序通常只与这种类型的特定编译器一起使用,而现代编译器却出现故障,因为程序员忘记了在需要它的变量上使用save属性。最初这并没有引起问题,因为所有变量实际上都具有save属性。大多数现代编译器在堆栈上放置局部变量而不保存,这些程序经常出现故障,因为一些需要“保存”的变量会在子例程调用中“忘记”它们的值。这可以通过识别问题变量并添加save(work)、向每个子例程添加save语句(更少的工作)来解决,或者许多编译器都有一个选项(例如gfortran中的-fno automatic)来恢复旧行为(easy)


这似乎是一个奇怪的问题——您不会发现关于“Fortran 77”的信息,而是关于某个特定的编译器。为什么使用Fortran 77而不是Fortran 95/2003?教授认为Fortran在1977年停止了吗?

进一步阐述了@MSB提出的一点

Fortran标准并不告诉编译器编写者如何实现这些标准,他们关心的是程序员可以看到的程序的行为。所以这个问题的答案是“这一切都取决于编译器”。OP并没有告诉我们他正在使用哪个编译器


此外,如果您翻过时间的迷雾,查看所有曾经编写过的FORTRAN77编译器,我相信您会发现您感兴趣的功能的各种不同实现,他们中的许多人都与非常深奥的硬件体系结构有关。

fortran在哪里学习?这种语言不是直接教授的。这只是编程语言课程硬件的一部分。它更多的是学习编程语言的结构,并使用像Fortran 77这样的旧语言来真正理解要点。我们的课程主要围绕Java展开。除了我的答案和High Performance Mark的答案之外,我还要补充一点:您正在探索的是“未定义的”——当您在第二次调用子例程时检查一个不带save属性的局部变量的值,而不重新初始化该变量时,您违反了语言标准,行为未定义。任何事情都可能发生,这取决于特定编译器的实现。如果变量在堆栈上,您将看到一些“随机”值。如果将它们放置在固定的内存位置,您将看到上一个值。
save
integer :: counter = 0