澄清fortran隐含循环

澄清fortran隐含循环,fortran,do-loops,Fortran,Do Loops,很多年前,我使用过一点FORTRAN,最近我的任务是维护一个旧的FORTRAN程序(F77)。以下代码不熟悉: READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS, . ( BUFFER(BIX), BIX=1, NUM_WORDS ) 回顾一些在线论坛,发现让我困惑的部分,继续线,是一个隐含的循环。因为我的程序给我带来了麻烦,我想把它转换成一个常规的DO循环。转换它也可能有助于下一个可怜的懒汉,从现在起5年后拿起

很多年前,我使用过一点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  
但当我只做了这个更改时,正在工作的测试用例停止了工作。我仍然觉得这里发生的是两种不同的读取(第一种读取NUM_单词,第二种读取循环数据),所以我尝试了一种不太剧烈的更改,将其转换为两个语句,但保留了隐含的循环:

  READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS  
  READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) ( BUFFER(BIX), BIX=1, NUM_WORDS )  
但是仅仅是这个改变也会导致好的测试用例失败。在我的两次修改中,NUM_单词的值都如预期的那样通过了,因此循环似乎是失败的地方

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

谢谢

文件是如何打开的?也就是说,它是ACCESS='sequential',ACCESS='direct'还是ACCESS='stream'(最后一个不太可能,因为它是一个F2003添加项)。其次,它是格式化的还是未格式化的?我将假设它是无格式的序列,因为在read语句中既没有REC=说明符,也没有格式说明符

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

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

|长度(4字节)|数量(4字节?)|缓冲区(1)|缓冲区(2)|……|长度|

现在,如果您尝试用一条read语句读取num_单词,它将正确地从文件中读取num_单词,然后它将向前跳,直到下一条记录开始。然后,当您尝试使用单独的read语句读取缓冲区时,您已经在文件中遥遥领先了

如果您有点作弊并使用F90+数组语法,您可能会逃脱惩罚

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

(虽然我不确定你是否可以在写它的同一个声明中引用num_单词)

谢谢你的回答,janneb。您关于文件打开的假设是正确的;我使用的是未格式化的序列。从你的回答中,我发现更重要的问题是阅读,我忘记了阅读记录的事实。