DO 構文

DO 構文は、ステートメント・ブロックの実行の繰り返しを指定します。 このように繰り返し実行されるブロックをループと呼びます。

ループの繰り返し回数は、無限でない限り、DO 構文の実行の開始時に決定されます。

CYCLE ステートメントを使用して特定の繰り返しを短縮したり、EXIT ステートメントを使用して ループを終了することができます。



>>-DO_statement------------------------------------------------><
 
 
>>-statement_block---------------------------------------------><
 
 
>>-+-END_DO_statement---+--------------------------------------><
   '-terminal_statement-'
 
 

DO_statement
構文の詳細については、DOを参照してください。

END_DO_statement
構文の詳細については、END (構文)を参照してください。

terminal_statement
DO 構文を終了するステートメントです。 以下の記述を参照してください。

DO ステートメントに DO 構文名を指定する 場合、同じ構文名が指定されている END DO ステートメントでその構文を 終了しなければなりません。 逆に、DO ステートメントに DO 構文名を 指定せずに、END DO ステートメントで DO 構文を 終了させる場合は、END DO ステートメントに DO 構文 名を指定してはいけません。

終端ステートメント

終端ステートメントは、DO ステートメントの後に 位置し、実行可能でなければなりません。 終端ステートメントとして使用できるステートメントの 一覧については、ステートメントおよび属性を参照してください。DO 構文の 終端ステートメントが論理 IF ステートメントの場合、 その終端ステートメントには、論理 IF ステートメントに関する制約と 矛盾しない任意の実行可能ステートメントを含めることができます。

DO ステートメントにステートメント・ラベルを指定した場合は、同じステートメント・ラベルの付いた ステートメントで DO 構文を終了させなければなりません。

ラベル付き DO ステートメントは、一致するステートメント・ラベルが 付いた END DO ステートメントで終了しなければなりません。 ラベルの付いていない DO ステートメントは、ラベルなし END DO ステートメントで終了しなければなりません。

ネストされたラベル付きの DO 構文および DO WHILE 構文は、終端ステートメントがラベル付きで かつ END DO ステートメントでなければ、同じ終端ステートメントを共用する ことができます。

DO 構文の範囲

DO 構文の範囲には、DO ステートメント以後、 終端ステートメントまでの間にあるすべての実行可能ステートメントが含まれ ます (終端ステートメントも含まれます)。 構文の範囲に関する規則が適用されるだけでなく、 最も内側の共用 DO 構文から 共用終端ステートメントへのみ、制御を移すことができます。

アクティブ DO 構文および非アクティブ DO 構文

DO 構文は、アクティブか非アクティブのどちらかになっています。DO 構文は、最初は非アクティブで、DO ステートメントが 実行されると、アクティブになります。 アクティブになった DO 構文が非アクティブになるのは次の場合だけです。

DO 構文が非アクティブになると、DO 変数は、 割り当てられた最後の値を保持します。

DO ステートメントの実行

無限 DO には、繰り返しカウントの制限または終了条件はありません。

ループが無限 DO でない場合、DO ステートメントは、 初期パラメーター、終端パラメーター、およびオプションで増分値を 含みます。

  1. DO ステートメント式 (a_expr1a_expr2、 および a_expr3) を計算して得られた値が、 初期パラメーター m1、 終端パラメーター m2、 および増分値 m3 に設定されます。 式を計算する場合、必要に応じて、算術変換の 規則にしたがって、DO 変数の型への変換が行われます。 (算術変換を参照してください。) a_expr3 を 指定しないと、m3 の 値は 1 になります。m3 の 値をゼロにしてはなりません。
  2. DO 変数は、 初期パラメーター (m1) の値によって、 定義済み状態になります。
  3. 繰り返し回数は、以下の式によって決定されて、設定されます。
    MAX (INT ( (m2 - m1 + m3) / m3), 0)
    

    次の場合には、繰り返し回数がゼロになることに注意してください。

    m1 > m2 and m3 > 0, or
    

    m1 < m2 and m3 < 0
    

DO 変数が定義されていないと、繰り返し回数を計算することは できません。 この構文を無限 DO 構文といいます。

+----------------------------------IBM 拡張----------------------------------+

kind 1、2、または 4 の整変数の場合、 繰り返し回数は 2**31 - 1 を超えることはできません。 kind 8 の整変数の場合、2**63 - 1 を超えることはできません。 計算時にオーバーフローまたはアンダーフロー状態になる場合は、 回数は未定義になります。

+------------------------------End of IBM 拡張-------------------------------+

DO ステートメントの実行が完了すると、ループ制御の処理が 開始されます。

ループ制御の処理

ループ制御の処理は、DO 構文の範囲を、それ以上実行する 必要があるかどうかを判断します。 繰り返し回数が調べられ、 回数がゼロでなければ、 DO 構文の範囲内の最初のステートメントの実行が開始されます。 繰り返し回数がゼロならば、DO 構文は非アクティブになります。 その結果、当該 DO 構文を 共用しているすべての DO 構文が 非アクティブになる場合は、その終端ステートメントの後に ある次の実行可能ステートメントが実行されて、通常の実行が続けられます。 ただし、終端ステートメントを共用している DO 構文で、 アクティブのものがある場合は、実行は最も内側のアクティブな DO 構文の 増分値の処理に進みます。

DO 実行範囲

DO 構文の範囲には、ステートメント・ブロック内のすべてのステートメントが含まれます。 これらのステートメントは、終端ステートメントに到達するまで実行されます。 DO 構文の範囲の実行中に DO 変数を再定義することも、未定義にすることもできません。 この変数は、増分処理でのみ再定義されます。

終端ステートメントの実行

終端ステートメントは、通常の実行シーケンスの結果として、あるいは、 制御の移動の結果として実行されます (この場合も DO 構文の 範囲外から範囲内へ、制御を移すことはできません)。 終端ステートメントが実行された結果、制御が移動しない場合、 増分値の処理に進みます。

増分値の処理

  1. 最後に実行された DO ステートメントで始まる アクティブな DO 構文の、DO 変数、繰り返し回数、および増分値 が処理の対象として選択されます。
  2. DO 変数の値が m3 の値だけ 増やされます。
  3. 繰り返し回数から 1 が引かれます。
  4. 実行が、繰り返し回数が 1 減分された DO 構文の、 ループ制御の処理に進みます。



マイグレーションのためのヒント:


  • GOTO ステートメントの
    代わりに、EXIT ステートメント、CYCLE ステートメント、
    および無限 DO ステートメントを使用します。

FORTRAN 77 ソース

        I = 0
        J = 0
20      CONTINUE
        I = I + 1
        J = J + 1
        PRINT *, I
        IF (I.GT.4) GOTO 10   ! Exiting loop
        IF (J.GT.3) GOTO 20   ! Iterate loop immediately
        I = I + 2
        GOTO 20
10      CONTINUE
        END

Fortran 90 または Fortran 95 ソース

        I = 0 ; J = 0
        DO
          I = I + 1
          J = J + 1
          PRINT *, I
          IF (I.GT.4) EXIT
          IF (J.GT.3) CYCLE
          I = I + 2
        END DO
        END

INTEGER :: SUM=0
OUTER: DO
  INNER: DO
    READ (5,*) J
    IF (J.LE.I) THEN
      PRINT *, 'VALUE MUST BE GREATER THAN ', I
      CYCLE INNER
    END IF
    SUM=SUM+J
    IF (SUM.GT.500) EXIT OUTER
    IF (SUM.GT.100) EXIT INNER
  END DO INNER
  SUM=SUM+I
  I=I+10
END DO OUTER
PRINT *, 'SUM =',SUM
END
IBM Copyright 2003