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

Loops 为什么Fortran DO循环索引大于循环后的上限?,loops,fortran,Loops,Fortran,我正在查看用fortran编写的空气质量模型的代码,对fortran从do循环中传递变量的方式有一些疑问 这个非常简单的例子说明了我的意思: PROGRAM carla IMPLICIT NONE ! INTEGER, PARAMETER :: LM = 24, DEZASSEIS = 16 INTEGER :: L, VARIAVEL, SOMA ! DO L=1,LM WRITE(*,*) 'L = ', L END

我正在查看用fortran编写的空气质量模型的代码,对fortran从do循环中传递变量的方式有一些疑问

这个非常简单的例子说明了我的意思:

   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),并不断增加


谁能给我一个提示吗?

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

如果在DO循环之外使用索引变量,请务必小心 因为变量在循环结束时递增,即 步长将大于最终值

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

编辑:以下内容不正确。见下文M.S.B.的评论

在Fortran中,DO变量。。。在未明确指定值的情况下,不得在循环外部引用。-

循环从1到24, 所以当它达到25时,循环就完成了

Think of it as 
(pseudocode)
LL = 1
While LL < 25
 LL = LL + 1;
将其视为
(伪代码)
LL=1
而LL<25
LL=LL+1;

正如古米夫所说,不要这样做。循环是编译器优化的主要目标,不能保证在循环执行后会有什么。可能同样容易为0,一次优化会反转计数,因为在某些机器上检测LL=0比LL>24快。不会快很多,但编译器人员对此有一个真正的问题。

那么,在循环之后,您看到的L和SOMA的值是多少?海报问题显示L的值是25,这正是您引用的Fortran规则所期望的值。我认为DO变量不应该在循环外引用的说法是言过其实的,不应该被视为“定律”。。。这是避免混淆的典型做法,好的。谢谢你的澄清。我已经根据你的评论编辑了我的答案。(原始海报必须在发布后不久编辑了他的等式,但我在发布前没有刷新,我可以发誓在回复时L=25信息不在那里)您的链接不应该太认真:第一个示例显然在使用“静态”局部变量的编译器上注定会失败,如示例2所述。教坏的技巧,甚至像你注意到的那样在做循环时失败。“可能也很容易是0”--不,Fortran的规则在循环后指定循环变量的值。另一个问题是编译器错误。这取决于编译器,即使在Fortran中对所有编译器都是如此。对于其他语言/编译器来说,这肯定不是真的。省去了很多麻烦,不要在循环外使用循环变量。我不想在循环外使用循环变量!这个问题源于代码中的一个错误-一个变量在循环外被使用(但它已经被更正)-我想了解模型在运行旧代码时的行为…从来没有说你想,但你是,这给了你意想不到的行为,我解释了,你接受了答案。我的评论是对@M.S.B的,为这一混乱道歉。@Tony:这不取决于编译器,除非它有bug。我完全没有理由不在循环之外使用循环变量的值。如前所述,它的定义是明确的。其他语言做什么并不重要。