为什么Fortran的DO循环索引在循环结束后大于上限?

5

我正在研究一款用Fortran编写的空气质量模型代码,并对Fortran如何从do-loops传递变量有些疑问。

以下示例说明了我的意思:

   PROGRAM carla
   IMPLICIT NONE
   !
   INTEGER, PARAMETER :: LM = 24, DEZASSEIS = 16
   INTEGER            :: L, VARIAVEL, SOMA
   !
   DO L=1,LM
   WRITE(*,*) 'L = ', L
   END DO
   !
   WRITE(*,*) 'I am now ouside of the DO loop.'
   WRITE(*,*) 'I would expect L=LM=24... And SOMA=40'
   WRITE(*,*) 'L = ', L
   SOMA = DEZASSEIS + L
   WRITE(*,*) 'SOMA = ', SOMA
   END PROGRAM carla

我希望L=LM=24,SOMA=40,但实际得到的结果是:
   L =           25
   SOMA =           41

我不明白为什么一旦我们跳出 DO 循环,L 就不再保留最后一个值(因此 SOMA 应该等于40),而是继续增加...

有人能给我一些提示吗?


循环结束后,您看到的L和SOMA的值是多少? - Scott Hunter
2个回答

4

Fortran不是那样工作的。(它不像Matlab:P)

如果在DO循环之外使用索引变量,请小心,因为变量在循环结束时递增,即它将比最终值多一个stepsize。

http://www.oc.nps.edu/~bird/oc3030_online/fortran/do/do.html

这就解释了为什么循环后L=25

编辑:下面的内容是错误的。请参见M.S.B.的评论。

在Fortran中,DO变量...不应在没有先显式赋值的情况下在循环外引用。 - http://www.esm.psu.edu/~ajm138/fortranexamples.html


3
海报的问题显示L的值为25,这正是您引用Fortran规则所期望的。我认为有关DO变量永远不应在循环外部被引用的说法有些言过其实,不应被视为“法律”......这是一个避免混淆的典型做法,可以接受。 - M. S. B.
感谢您的澄清。根据您的评论,我已经编辑了我的答案。(原始发布者在发布后不久可能已经编辑了他的问题,但在发布前我没有刷新,我发誓当我回复时L=25的信息还没有出现) - GummiV
你在 psu 的链接不应该太过认真: 第一个例子显然会在使用“静态”局部变量的编译器上失败,正如示例2中所解释的那样。教授错误的技巧,甚至无法在 DO 循环上运行,正如你注意到的那样。 - user1220978
正如@eriktous在另一个答案下评论的那样,循环外的值已经被完美地定义了,并且引用该值也是完全没问题的。 - Vladimir F Героям слава

1

从1到24循环,当达到25时,循环结束。

Think of it as 
(pseudocode)
LL = 1
While LL < 25
 LL = LL + 1;

正如GummiV所说,不要这样做。循环是编译器优化的主要目标,循环执行后其中的内容无法保证。可能会变成0,某些机器上,一种优化方式将计数反转,因为检测LL = 0比LL > 24更快。虽然速度差别不大,但编译器开发人员确实有一个难题。

8
“本来也可能是0”——不,Fortran的规则指定循环后循环变量的值。其他情况可能是编译器的错误。 - M. S. B.
这取决于编译器,即使对于Fortran的所有编译器都是如此也不一定正确。对于其他语言/编译器来说肯定不是这样的。为了避免麻烦,请不要在循环之外使用循环变量。 - Tony Hopkinson
我不想在循环外部使用循环变量!这个问题源于代码中的一个错误——一个变量在循环外部被使用(但已经被更正),我想要了解模型运行旧代码时的行为... - carla
从来没有说过你想要做什么,但你却这样做了,这导致了你意料之外的行为,我解释了原因,你也接受了答案。我的评论是针对@M.S.B的,抱歉造成了困惑。 - Tony Hopkinson
5
@Tony:除非编译器存在错误,否则它不会依赖于编译器。我完全没有理由不在循环外使用循环变量的值。正如已经说过的那样,这是清楚定义的。其他语言所做的事情并不重要。 - eriktous
我看到了一个原因。和 OP 一样的原因。这个值可能被明确定义,但并不清晰。至于其他语言是否重要,我们中的一些人会编写多种语言的代码。在不同语言之间养成良好的习惯是简单的自我保护。 - Tony Hopkinson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接