Fortran 66中的“DO”循环如何工作?

5
我正在阅读一本在二手书店找到的旧书(又再次开始了)。这本书名为《Fortran技术-特别是非数值应用》,作者是A. Colin Day,由剑桥大学出版社于1972年出版。毕竟,跟上软件开发的最新动态非常重要;)
据称,这本书涵盖Fortran-66(X3.9-1966),也称为Fortran-IV,并针对与此标准不相关的DATA语句进行微小偏离。
问题在于,这本书似乎留下了很多猜测空间,而我的猜测在DO循环方面非常不确定。这是第一章,所以不是一个非常好的迹象。
以下是一个例子...
    DO 15 I = 1, 87
    J = I - 44

DO行中,1和87似乎表示循环的包容范围 - I取值从1到87,因此J取值从-43到+43。但是,15代表什么?
另一个例子是...
    N = 1
    DO 33 I = 1, 10
    ...
33  N = N + N

在这种情况下,33看起来像一个标签或行号 - 可能是循环重复(或退出)前执行的最后一行。但是,33作为一个任意的标签选择的数字有点奇怪。编辑那是一个错误 - 请参见duffymo的答案 - Fortran 66中的DO循环如何工作?接下来的例子是 ...
    DO 33 I = 1, 10
    N = 2 ** (I-1)

再次使用相同的33,但没有任何行被明确地标记为它。

我是不是因为这些都是短语断片而感到困惑?在DO n ...中,n代表什么?


@eriktous - 我找了一些教程,但没有涵盖Fortran IV或66-77似乎是最古老的版本。我没有想到去查找标准 - 我想可能存在版权问题,即使是针对古老版本的语言。学习77可能更好 - 这并不是那么严重,也没有特别的理由选择一个版本而不是另一个版本,除了这本书,它似乎更像是一个“片段”书籍,而不是语言教程或参考资料。 - user180247
3
F66和F77标准可以在NAG(Numerical Algorithms Group)的ftp服务器上公开获取,该服务器作为标准委员会工作文件的托管站点(ftp://ftp.nag.co.uk/sc22wg5/ARCHIVE/)。您也可以在那里找到后续版本的草案。特定标准的最终草案基本上与官方标准相同。gfortran wiki有一个很好的链接收藏,可链接到各种文档(http://gcc.gnu.org/wiki/GFortranStandards)。除非您必须使用旧代码,否则真的没有不学习现代Fortran的好理由。 - eriktous
@eriktous - 谢谢 - 这些链接会很有用。我学习Fortran的唯一原因是为了更好地理解编程语言设计的历史,而学习更新的版本对此并没有帮助。 - user180247
3个回答

5

行号告诉代码在循环结束时要去哪里。

是的,这些数字是奇怪的、任意的和毫无意义的。它是使FORTRAN难以阅读和理解的一部分。


1
我发现的一份Fortran 77教程 - http://folk.uio.no/steikr/doc/f77/tutorial/ - 建议每个循环的结尾都应该标记为continue。如果程序结束时没有任何未完成的DO循环,那么会自动执行continue吗?作者是不是只是忘了加上continue以混淆读者? - user180247
1
不,continue是语言的后期添加。最初它是所有行标签号码。 - duffymo
嗯,我仍然感到困惑 - 不清楚Fortran如何知道在循环内执行哪些行,以及是否包括标记行 - 但我不认为这是我的错。 - user180247
所有DO(包括)和continue / labeled行(不包括)之间的所有行。标记行只是您退出时着陆的位置。 - duffymo
如果这是排他性的,我猜问题中的第二个例子一定是书中的错误 - 除非标记行包含在循环中,否则它无法实现所声称的功能 - 其他例子按你所描述的更有意义(标记行不包括在循环中)。谢谢。 - user180247
显示剩余2条评论

5
这是一个完整的程序,应该可以回答你的一些问题。你可以轻易地测试这个历史问题......尽管FORTRAN IV的部分内容已经被正式淘汰或者在我看来应该被淘汰,但它仍然被许多编译器支持。我使用g77和gfortran编译并检查了这个程序。
下面是示例程序:
      implicit none

      integer i
      real q

      q = 1.0
      do i=1, 10
         q = q * 1.5
      end do
      write (6, *) "modern loop: q =", q

      q = 1.0
      do 100 i=1, 10
         q = q * 1.5
  100 continue
      write (6, *) "loop with continue: q =", q

      q = 1.0
      do 200 i=1, 10
  200 q = q * 1.5
      write (6, *) "loop without continue: q =", q

      stop
      end

如何使用gfortran进行编译:

gfortran -ffixed-form -ffixed-line-length-none -std=gnu test_loops.for -o test_loops.exe

关于您的问题:如果您以标记行作为循环的终止语句,并且该标记行是可执行代码,那么该行是否属于循环的一部分?程序的输出清楚地表明该标记行是循环的一部分。以下是gfortran的输出:

现代循环: q = 57.665039
带continue语句的循环: q = 57.665039
不带continue语句的循环: q = 57.665039


-2
15这个数字被程序员称为“标签”,这是由程序员决定的。根据组织的标准,这些数字受到控制,并遵循特定的规则。尽管有些程序员没有遵守标准,他们的代码一团糟;但大多数人还是遵循了注释和行缩进的标准。

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