1

私は Fortran にまったく慣れておらず、プログラミング全般にかなり慣れていません。他の誰かが書いたスクリプトをコンパイルしようとしています。これは私にいくつかの問題を与えています。コードの上半分は次のとおりです。

C 
C Open direct-access output file ('JPLEPH')
C 
OPEN ( UNIT = 12, 
. FILE = 'JPLEPH', 
. ACCESS = 'DIRECT', 
. FORM = 'UNFORMATTED', 
. RECL = IRECSZ, 
. STATUS = 'NEW' )


C
C Read and write the ephemeris data records (GROUP 1070). 
C 
CALL NXTGRP ( HEADER ) 

IF ( HEADER .NE. 'GROUP 1070' ) CALL ERRPRT(1070,'NOT HEADER') 

NROUT = 0 
IN = 0 
OUT = 0 


1 READ(*,'(2i6)')NRW,NCOEFF
if(NRW .EQ. 0) GO TO 1
READ (*,'(3D26.18)',IOSTAT =IN) (DB(K),K=1,NCOEFF) 


DO WHILE ( ( IN .EQ. 0 ) 
. .AND. ( DB(2) .LT. T2) ) 

IF ( 2*NCOEFF .NE. KSIZE ) THEN 
CALL ERRPRT(NCOEFF,' 2*NCOEFF not equal to KSIZE') 
ENDIF 

C
C Skip this data block if the end of the interval is less 
C than the specified start time or if the it does not begin 
C where the previous block ended. 
C 
IF ( (DB(2) .GE. T1) .AND. (DB(1) .GE. DB2Z) ) THEN 

IF ( FIRST ) THEN 
C 
C Don't worry about the intervals overlapping 
C or abutting if this is the first applicable 
C interval. 
C 
DB2Z = DB(1) 
FIRST = .FALSE. 
ENDIF 

IF (DB(1) .NE. DB2Z ) THEN 
C 
C Beginning of current interval is past the end 
C of the previous one.

CALL ERRPRT (NRW, 'Records do not overlap or abut') 
ENDIF 

DB2Z = DB(2) 
NROUT = NROUT + 1

print*,'Out =', OUT

WRITE (12,REC=NROUT+2,IOSTAT=OUT) (DB(K),K=1,NCOEFF)

print*,'Out2 =', OUT


IF ( OUT .NE. 0 ) THEN 
CALL ERRPRT (NROUT, 
. 'th record not written because of error') 
ENDIF 

したがって、「Out」と「Out2」を画面に出力すると、Out=0 と Out2=110 であることがわかります。もはやゼロに等しくないので、プログラムはエラーを出します。したがって、私は基本的にここで何が起こっているのか疑問に思っています:

WRITE (12,REC=NROUT+2,IOSTAT=OUT) (DB(K),K=1,NCOEFF)

12 は、私が開いた (そして作成した) ファイルを参照し、書き込みたいと仮定します。最初のブラケットの残りの部分は何をしますか? そして、2番目のポイントは何ですか?ファイルに入れたい情報が得られますか? 場合によっては、DB はどこでそれで満たされますか?

一般的に、何がうまくいかないのだろうか?OUT が値を変更するのはなぜですか? (私はtが必要です

NCOEFF はプログラムの冒頭で整数として定義されており、DB: は DOUBLE PRECISION DB(3000), DB2Z/0.d0/ として定義されているため、DB は何らかの配列であると想定しています。

4

4 に答える 4

2

ハンドブックを引用するRECことは、読み書きするレコード番号を示します。アドバイスに従って、詳細な説明については、コンパイラに付属のドキュメントを参照してください。

(DB(K),K=1,NCOEFF)DB' 1から。までのすべての要素を意味しNCOEFFます。あなたはio-implied-do声明を見ています。

于 2012-08-01T13:57:02.810 に答える
2

このプログラムでOUTは、writeステートメントが成功したかどうかを示しています。(ステートメントIOSTATへのパラメーターは、write「I/O ステータス」または入出力ステータスを意味します)。I/O 操作が成功した場合は 0 を返し、それ以外の場合はエラー コードの番号を返します。エラー コードの意味については、こちらを参照してください。

私はこのRECパラメーターに詳しくありませんが、自分で調査するための出発点はここにあります。

于 2012-08-01T13:02:31.367 に答える
1

ステートメント

WRITE (12,REC=NROUT+2,IOSTAT=OUT) (DB(K),K=1,NCOEFF)

つまり、メモリが私に役立つ場合、「暗黙のDOループ」と呼ばれます。記述されているように、DB(1)から開始して、配列DBからNCOEFF値を書き込みます。

これは暗黙のDOループと呼ばれます。これは、明示的な形式が(FORTRAN IVでは、古代の人にとっては、より現代的なバリエーションよりもはるかに優れていることを知っています)次のようなものになるためです。

      DO 10 K=1,NCOEFF
      WRITE (12,REC=NROUT+2,IOSTAT=OUT) DB(K)
10    CONTINUE

(最初の2行が6列インデントされていると仮定します。)これはDOループです。暗黙のDO-loop形式を使用すると、「ループ」を入力/出力ステートメントに正しく配置できます。

便利なのは、複数の配列と複数のループを持つことができることです。簡単な例:

WRITE (12,REC=NROUT+2,IOSTAT=OUT) (DB(K), DC(K), K=1,NCOEFF)
于 2012-08-01T13:55:38.767 に答える
0

110 は、WRITE 呼び出しによってスローされたエラー コードです。FORTRAN RTL (ランタイム ライブラリ) リファレンスを確認する必要があります。考えられるエラー コードを一覧表示する必要があります。110 は、倍精度値を整数に変換しようとしていることを意味すると思いますが、その値は整数に格納できるサイズを超えています。多分値をダンプしDBて見てください。

于 2012-08-01T14:54:20.640 に答える