IF/GOTO 也使用 Fortran 77 DO 标签

Fortran 77 DO label also used by IF/GOTO

提问人:xaratustra 提问时间:11/3/2023 最后编辑:xaratustra 更新时间:11/4/2023 访问量:88

问:

我有一个旧的 fortran 77 代码,我喜欢尽可能保持不变。由于给出循环警告,我正在考虑将非阻塞循环更改为阻塞模式。但后来我意识到有些语句也使用相同的循环标签。现在我不确定编译器在标签后面的语句方面的行为方式。gfortranGOTO

所以我的问题是我是否可以“现代化”这个示例代码:

      INTEGER i
      DO 30 i = 1, 14
      IF <SOME CONDITION> GOTO 30
      <SOME COMMANDS HERE>
  30  WRITE(*,*) i
      <SOME FOLLOWING STATEMENTS>

对此:

      INTEGER i
      DO 30 i = 1, 14
      WRITE(*,*) i
      IF <SOME CONDITION> GOTO 30    
      <SOME COMMANDS HERE>  
  30  CONTINUE  
      <SOME FOLLOWING STATEMENTS>

甚至这个:

      INTEGER i
      DO i = 1, 14
      WRITE(*,*) i
      IF <SOME CONDITION> GOTO 30    
      <SOME COMMANDS HERE>  
      END DO
  30  <SOME FOLLOWING STATEMENTS>

在后一种形式中,我不确定标签是否应该转到以下语句或以下语句?END DO

福特兰 Gfortran

评论

1赞 Vladimir F Героям слава 11/3/2023
始终使用标签 fortran。如果相关,您可以添加版本标记。
1赞 PierU 11/3/2023
在初始版本中,test+goto 是完全没用的,因为下一个执行的指令始终是 .在第二个版本中,测试也是无用的write(*,*) i
0赞 francescalus 11/3/2023
如果更改代码,答案似乎是“使用或”,而不是担心编译器和其他代码读者的确切解释的清晰度。有真正的理由保留吗?cycleexitgo to
1赞 steve 11/3/2023
如果要使用代码并消除循环警告,并且使用的是 gfortran,请使用以下选项。-std=legacy -w
1赞 steve 11/4/2023
请看@PierU的答案。如果你打算触摸代码以避免(无腿)警告,那么你应该考虑将其带入 21 世纪。

答:

4赞 PierU 11/4/2023 #1

带有循环终止标签的行属于循环(即指令在每次迭代时执行),这意味着在初始版本中,循环始终执行到 i=15。因此,您的第 3 个版本是错误的。第二个版本还可以。

但是,如果要使代码现代化,可以改为编写:

      INTEGER i
      DO i = 1, 14
         IF (.NOT.<SOME CONDITION>) THEN    
            <SOME COMMANDS HERE>
         END IF
         WRITE(*,*) i
      END DO  
      <SOME FOLLOWING STATEMENTS>

或者

      INTEGER i
      DO i = 1, 14
         WRITE(*,*) i
         IF (<SOME CONDITION>) CYCLE ! directly starts the next iteration
         <SOME COMMANDS HERE>
      END DO  
      <SOME FOLLOWING STATEMENTS>

评论

0赞 xaratustra 11/11/2023
关于这个问题的最后一个问题:如果我将标签放在 ?END DO
0赞 PierU 11/12/2023
@xaratustra为什么不尝试:)呢?