Fortran/プログラムのフロー制御

選択 編集

If-then(-else) 編集

条件付き実行は、以下の構成のifthenelse文を使って行われます。

 if (<condition 1>) then
    ! Block of code
 else if (<condition 2>) then
    ! Block of code
 else
    ! Block of code
 end if

else if文はいくつあっても構いません。

次の演算子を使用して条件式を作成できます:

関係演算子の一覧
演算 Modern Fortran Old FORTRAN
未満(Less than) < .LT.
より大(Greater than) > .GT.
以上(Greater than/equal) >= .GE.
以下(Less than/equal) <= .LE.
一致(Equal) == .EQ.
不一致(Not equal) /= .NE.
論理一致(Logical equivalent) .EQV.
論理不一致(Logical not equivalent) .NEQV.
論理否定(Logical not) .NOT.
論理積(Logical and) .AND.
論理和(Logical or) .OR.
註:Fortranの標準では、.EQ..NEQ.は論理式と一緒に使用することはできませんが、一部のコンパイラは標準を適用しない場合があります。

複数の文をチェックするには、括弧を使用します。

if ((a .gt. b) .and. .not. (a .lt. c)) then

次のプログラムは0から1の間のランダムな数値を生成し、その数値が0から0.3の間、0.3から0.6の間、または0.6から1.0の間にあるかどうかをテストします。

program xif
    implicit none
    real :: x
    real, parameter :: x1 = 0.3, x2 = 0.6

    call random_seed()
    call random_number(x)
    if (x < x1) then
        print *, x, "<",x1
    else if (x < x2) then
        print *, x, "<", x2
    else
        print *, x, ">=", x2
    end if
end program xif

IFの興味深い古い形式には、2つあります:

     IF (<logical expression>) GOTO <statement_label>
     IF (<arithmetic expression>) <first label>, <second label>, <third label>

最初の形式では、事柄は非常に明確です。2番目の形式では、算術式が評価されます。 式が負の数に評価されると、実行は最初の文番号で続行されます。式がゼロに評価されると、実行は2番目の文番号で続行されます。それ以外の場合、実行は3番目の文番号で続行されます。

SELECT CASE 編集

Fortranには、SELECT CASE文があります。これは、複数の条件のテストを行い、条件に応じて異なるブロックのコードを実行するために使用されます。

構文
SELECT CASE (selector)
    CASE (value1)
        ! value1に対応するコード
    CASE (value2)
        ! value2に対応するコード
    CASE DEFAULT
        ! 上記のいずれの条件にも該当しない場合のコード
END SELECT

IFブロックが単一の変数に対する繰り返しテストから成る場合、select case構造に置き換えることができる場合があります。たとえば、次のコード

if (month=="January" .or. month=="December") then
    num_days = 31
else if (month=="February") then
    num_days = 28
else if (month=="March") then
    num_days = 31
else
    num_days = 30
end if

は次のように置き換えることができます

select case (month)
    case ("January", "December")
        num_days = 31
    case ("February")
        num_days = 28
    case ("March")
        num_days = 31
    case default
        num_days = 30
end select

Fortranにはbreak文が必要ありません。

ループ 編集

Fortranには、DOループがあります。これは、指定された回数だけコードを繰り返し実行するために使用されます。

構文
DO index = start, end, [step]
    ! ループ内で実行するコード
END DO

次のループは、1から10までの整数の二乗を出力します。

do i=1,10
    print *, i**2
end do

以下のコードは、整数の二乗が25を超えるまでの整数の二乗を出力します。

do i=1,10
    isquare = i**2
    if (isquare > 25) exit
    print *, isquare
end do

ループを入れ子にすることができます。次のコードは、1から10までの整数の2乗から4乗を出力します。

do i=1,10
    do ipower=1,3
        print *, i, ipower, i**ipower
    end do
end do

古い形式( archaic form) のDOでは、ループが終了する文番号が使用されます。以下は、ラベル1が各ループの最終行であることを明示的に述べた同じループです。

訳註
複数のループでのラベルの共有は、Fortran95からは禁止されています。
      DO 1 i=1,10
          DO 1 ipower=1,3
              1 PRINT *, i, ipower, i**ipower
1     CONTINUE

古い形式を使用する場合、ループはIFまたはGO TO文で終了してはなりません。 1ラベルのアンカーとしてCONTINUE文を使用できます。

doループを宣言する際にオプションの増分引数もあります。次の例は2ごとにカウントアップします。2, 4, 6, ...

do i=2,10,2
    write (*,*) i
end do

doループへの引数は数値である必要はなく、プログラムの他の場所で定義された任意の整数であることができます。 first, lastincrementは任意の変数名であって構いません。

do i=first,last,increment
    ! Code goes here
end do

フロー制御文 編集

Fortranにおける制御フローを変更するために使用されるいくつかのキーワードがあります。それぞれのキーワードの目的と使用方法について説明します:

  1. GOTO: GOTO文は、プログラムの実行を特定のラベルにジャンプさせます。ただし、GOTO文はプログラムの可読性を低下させ、理解しにくいコードを生成する可能性があるため、構造化プログラミングの観点からは避けることが推奨されます。
    GOTO 100
    
  2. STOP: STOP文は、プログラムの実行を停止します。一般的にはエラーが発生した場合や特定の条件が満たされた場合に使用されます。STOP文には、オプションの引数があります。これは、停止するときの終了コードを指定するために使用されます。
    STOP 1
    
  3. EXIT: EXIT文は、ループ内で使用され、ループを抜けるために使います。EXITが実行されると、ループからの制御が直ちに終了し、次の文に進みます。
    DO i = 1, 10
        IF (i > 5) THEN
            EXIT  ! ループを抜ける
        END IF
        PRINT *, i
    END DO
    
  4. CONTINUE: CONTINUE文は、ループの次のイテレーションに進むことを示します。一般的に、古い形式のDOループで使用されますが、構造化プログラミングの観点からは非推奨です。
          DO 1 i=1,10
              1 PRINT *, i
    1     CONTINUE  ! ループの終端
    
  5. CYCLE: CYCLE文は、ループ内で使用され、次のイテレーションに進むことを示します。
    DO i = 1, 10
        IF (i == 5) THEN
            CYCLE  ! 次のイテレーションに進む
        END IF
        PRINT *, i
    END DO
    
  6. RETURN: RETURN文は、サブルーチンまたは関数から抜けるために使用されます。サブルーチン内でRETURNが実行されると、それ以降のコードは実行されず、サブルーチンが呼び出された場所に制御が戻ります。
    SUBROUTINE example_subroutine()
        PRINT *, "Inside subroutine"
        RETURN  ! サブルーチンを終了する
    END SUBROUTINE
    

これらのキーワードを使用することで、プログラムの制御フローを効果的に変更できます。