简体   繁体   English

澄清一个fortran隐含的循环

[英]Clarifying a fortran implied loop

I used FORTRAN a little, many years ago, and have recently been tasked to maintain an old FORTRAN program (F77). 很多年前我使用过FORTRAN,并且最近负责维护一个旧的FORTRAN程序(F77)。 The following code was unfamiliar: 以下代码不熟悉:

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

Reviewing some on-line forums revealed that the part that was confusing me, the continuation line, is an implied loop. 回顾一些在线论坛发现,让我感到困惑的部分,即延续线,是一个隐含的循环。 Since my program is giving me trouble right here, I want to convert this to a conventional DO-loop. 由于我的程序在这里给我带来麻烦,我想将其转换为传统的DO循环。 Converting it might also help the next poor slob that picks this thing up cold 5 years from now! 转换它也可能有助于下一个从现在起5年后冷却这个东西的可怜的邋!! Anyway, my best guess at the DO-loop equivalent is 无论如何,我对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  

But when I made only this change, test cases which were working stopped working. 但是,当我只进行此更改时,正在运行的测试用例停止工作。 I still felt that what was going on here was two different READs (the first to get NUM_WORDS, and the second to loop through the data), so I tried a less drastic change, converting it to two statements but retaining the implied loop: 我仍然觉得这里发生的是两个不同的READ(第一个获得NUM_WORDS,第二个循环数据),所以我尝试了一个不那么激烈的改变,将它转换为两个语句但保留隐含的循环:

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

But just this change also causes the good test cases to fail. 但只是这种变化也会导致良好的测试用例失败。 In both of my alterations, the value of NUM_WORDS was coming through as expected, so it seems that the loop is where it is failing. 在我的两个改动中,NUM_WORDS的值正如预期的那样,所以看起来循环就是它失败的地方。

So, what is the equivalent DO-loop for the original implied loop? 那么,原始隐含循环的等效DO循环是什么? Or am I on the wrong track altogether? 或者我完全走错了路?
Thanks 谢谢

How is the file opened? 该文件是如何打开的? Ie is it ACCESS='sequential', access='direct', or access='stream' (well, the last is unlikely as it's a F2003 addition). 即它是ACCESS ='顺序',访问='直接',或访问='流'(嗯,最后一个是不可能的,因为它是F2003添加)。 Secondly, is it formatted or unformatted? 其次,它是格式化还是未格式化? I'm going to assume it's unformatted sequential since there is no REC= specifier nor a format specifier in your read statements. 我将假设它是未格式化的顺序,因为在read语句中没有REC =说明符和格式说明符。

The reason why what you're trying to fails is that each read statement reads a separate record. 您尝试失败的原因是每个读取语句都读取一个单独的记录。 Prior to the introduction of access='stream' in F2003, Fortran I/O was completely record based, which is slightly alien to those of us used to stream type files as seen in most other languages. 在F2003中引入access ='stream'之前,Fortran I / O完全基于记录,这与我们用于流式文件的人相比有些陌生,如大多数其他语言所示。

Records for unformatted sequential files are typically separated by "record markers" at each end of the record, typically 4 bytes specifying the length of the record. 未格式化的顺序文件的记录通常在记录的每一端用“记录标记”分隔,通常是4个字节,指定记录的长度。 So the record (on disk) likely looks something like 所以记录(在磁盘上)可能看起来像

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

Now if you try to read, say, num_words with one READ statement, it will correctly read num_words from the file, THEN it will skip forward until the start of the next record. 现在,如果您尝试使用一个READ语句读取num_words,它将正确读取文件中的num_words,然后它将向前跳过,直到下一条记录开始。 And when you then try to read buffer with a separate READ statement you're already too far ahead in the file. 然后,当您尝试使用单独的READ语句读取缓冲区时,您已经在文件中处于领先地位。

If you cheat a bit and use F90+ array syntax, you might get away with 如果你作弊并使用F90 +数组语法,你可能会侥幸逃脱

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

(though I'm not sure if you're allowed to reference num_words in the same statement where it's being written to) (虽然我不确定你是否被允许在写入的同一语句中引用num_words)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM