澄清一个fortran隐含的循环

时间:2014-05-08 21:10:15

标签: fortran do-loops

我多年前使用过FORTRAN,并且最近负责维护一个旧的FORTRAN程序(F77)。以下代码不熟悉:

      READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS,  
   .    ( BUFFER(BIX), BIX=1, NUM_WORDS )  

回顾一些在线论坛后发现,让我感到困惑的部分,即延续线,是一个隐含的循环。由于我的程序在这里给我带来麻烦,我想将其转换为传统的DO循环。转换它也可能有助于下一个从现在起5年后冷却这个东西的可怜的邋!!无论如何,我对DO循环等效的最好猜测是

  READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS  
  DO BIX=1, NUM_WORDS  
    READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) BUFFER(BIX)  
  ENDDO  

但是,当我只进行此更改时,正在运行的测试用例停止工作。我仍然觉得这里发生的是两个不同的READ(第一个获得NUM_WORDS,第二个循环数据),所以我尝试了一个不那么激烈的改变,将它转换为两个语句,但保留隐含的循环:< / p>

  READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS  
  READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) ( BUFFER(BIX), BIX=1, NUM_WORDS )  

但是这种改变也会导致好的测试用例失败。在我的两次修改中,NUM_WORDS的值都按预期通过,所以似乎循环就是失败的地方。

那么,原始隐含循环的等效DO循环是什么?还是我完全走错了路? 感谢

1 个答案:

答案 0 :(得分:3)

文件是如何打开的?即它是ACCESS ='顺序',访问='直接',或访问='流'(好吧,最后一个不太可能,因为它是F2003添加)。其次,它是格式化还是未格式化?我将假设它是未格式化的顺序,因为在read语句中没有REC =说明符或格式说明符。

您尝试失败的原因是每个读取语句都读取单独的记录。在F2003中引入access ='stream'之前,Fortran I / O完全基于记录,这与我们用于流式传输文件的人略有不同,如大多数其他语言中所见。

未格式化顺序文件的记录通常在记录的每一端用“记录标记”分隔,通常是4个字节,指定记录的长度。所以记录(在磁盘上)可能看起来像

|长度(4字节)| num_words(4个字节?)|缓冲区(1)|缓冲区(2)| ...... |长度|

现在,如果您尝试使用一个READ语句读取num_words,它将正确读取文件中的num_words,然后它将向前跳过,直到下一条记录开始。然后,当您尝试使用单独的READ语句读取缓冲区时,您已经在文件中处于领先地位。

如果你有点作弊并使用F90 +数组语法,你可能会躲过

READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS, BUFFER(1:NUM_WORDS)

(虽然我不确定你是否被允许在写入的同一语句中引用num_words)