[Fortranのはじめ方] Part9: 繰り返し処理(DOループ、DO WHILE)

Fortran

プログラミングでは、同じような処理を何度も繰り返したい場面がたくさんあります。例えば、1から100までの数字を足し合わせたり、配列の各要素に特定の操作を行ったりする場合です。Fortranでは、このような繰り返し処理を効率的に行うために、DOループDO WHILEループという2つの主要な構文が用意されています。

このステップでは、これらのループ構文の基本的な使い方と、ループを制御するための便利な機能について学んでいきましょう!✨

DOループ(カウンタ付きループ)🔢

DOループは、指定した回数だけ処理を繰り返す場合に最もよく使われます。ループの回数を制御するためのカウンタ変数を使います。

基本的な構文

基本的な構文は以下のようになります。

DO カウンタ変数 = 開始値, 終了値 [, 増分]
  ! 繰り返したい処理
END DO
  • カウンタ変数: ループの回数を数えるための整数型の変数です。ループが1回実行されるごとに、その値が自動的に更新されます。
  • 開始値: カウンタ変数の初期値です。
  • 終了値: カウンタ変数がこの値を超えるとループは終了します(増分が正の場合)。
  • 増分 (省略可能): ループが1回実行されるごとにカウンタ変数に加算される値です。省略した場合、デフォルトで1が設定されます。負の値を指定することも可能です。

コード例: 1から10までの和を計算する

PROGRAM sum_1_to_10
  IMPLICIT NONE
  INTEGER :: i, total_sum

  total_sum = 0 ! 合計値を初期化
  DO i = 1, 10 ! iを1から10まで1ずつ増やしながら繰り返す
    total_sum = total_sum + i
    PRINT *, 'i = ', i, ', current sum = ', total_sum
  END DO

  PRINT *, 'Final sum = ', total_sum

END PROGRAM sum_1_to_10

このプログラムでは、変数 `i` がカウンタ変数として使われています。`i` は最初に1になり、ループ内の処理(`total_sum`への加算とPRINT文)が実行されます。その後、`i` は自動的に1増やされて2になり、再びループ内の処理が実行されます。これが `i` が10になるまで繰り返され、`i` が11になろうとするときにループは終了します。

増分を指定する例

増分を2にして、偶数のみを足し合わせる例です。

PROGRAM sum_even
  IMPLICIT NONE
  INTEGER :: i, even_sum

  even_sum = 0
  DO i = 2, 10, 2 ! iを2から10まで2ずつ増やしながら繰り返す
    even_sum = even_sum + i
  END DO

  PRINT *, 'Sum of even numbers = ', even_sum ! 2 + 4 + 6 + 8 + 10 = 30

END PROGRAM sum_even

無限ループと EXIT 文

カウンタを指定しない `DO` 文を使うと、無限ループを作成できます。無限ループは何らかの条件が満たされるまで処理を続けたい場合に便利ですが、ループを終了させるための条件と `EXIT` 文を必ず記述する必要があります。`EXIT` 文は、現在のループから即座に抜け出すために使われます。

PROGRAM infinite_loop_example
  IMPLICIT NONE
  INTEGER :: counter

  counter = 0
  DO ! 無限ループ開始
    counter = counter + 1
    PRINT *, 'Counter: ', counter
    IF (counter >= 5) THEN
      PRINT *, 'Counter reached 5. Exiting loop.'
      EXIT ! counterが5以上になったらループを抜ける
    END IF
    ! ここに他の処理を書くこともできる
  END DO

  PRINT *, 'Loop finished.'

END PROGRAM infinite_loop_example
注意: 無限ループを使う場合は、必ず `EXIT` 文につながる条件を設けてください。さもないとプログラムが終了しなくなってしまいます。😱

CYCLE 文

`CYCLE` 文を使うと、ループ内の残りの処理をスキップして、次の繰り返しにジャンプすることができます。特定の条件の場合だけ処理を飛ばしたいときに便利です。

PROGRAM cycle_example
  IMPLICIT NONE
  INTEGER :: i

  PRINT *, 'Printing odd numbers from 1 to 10:'
  DO i = 1, 10
    IF (MOD(i, 2) == 0) THEN ! iが偶数かどうかチェック (MODは余りを計算する組込み関数)
      CYCLE ! 偶数の場合は以降の処理をスキップして次のiへ
    END IF
    PRINT *, i ! 奇数のみが出力される
  END DO

END PROGRAM cycle_example

DOループのネスト(入れ子)

DOループの中にさらにDOループを入れることができます。これをネスト(入れ子)と呼びます。九九の表を作成するような場合に利用できます。

PROGRAM multiplication_table
  IMPLICIT NONE
  INTEGER :: i, j

  DO i = 1, 3 ! 外側のループ (行)
    DO j = 1, 3 ! 内側のループ (列)
      PRINT *, i, ' * ', j, ' = ', i * j
    END DO
    PRINT * ! 各行の後に改行を入れる
  END DO

END PROGRAM multiplication_table

内側のループは、外側のループが1回実行されるたびに、指定された回数だけ完全に実行されます。

DO WHILEループ(条件付きループ)❓

DO WHILEループは、指定した条件が真(`.TRUE.`)である間、処理を繰り返します。繰り返しの回数が事前に決まっていない場合に特に役立ちます。

構文

DO WHILE (論理式)
  ! 論理式が真 (.TRUE.) の間、繰り返したい処理
END DO
  • 論理式: 真(`.TRUE.`)または偽(`.FALSE.`)を評価する式です。この式が `.TRUE.` である限り、ループ内の処理が実行されます。ループの各繰り返しの前に評価されます。

コード例: 特定の値になるまで入力を促す

PROGRAM guess_number
  IMPLICIT NONE
  INTEGER :: input_number

  input_number = 0 ! 初期化

  DO WHILE (input_number /= 10) ! 入力された数値が10でない間、繰り返す (/= は等しくない)
    PRINT *, 'Enter the number 10: '
    READ *, input_number
    IF (input_number /= 10) THEN
      PRINT *, 'Incorrect. Try again!'
    END IF
  END DO

  PRINT *, 'Correct! You entered 10.'

END PROGRAM guess_number

この例では、ユーザーが `10` を入力するまで、`DO WHILE` ループが繰り返されます。ループの開始前に `input_number /= 10` という条件が評価され、真であればループ内の処理(入力の促し、読み込み、チェック)が実行されます。ユーザーが `10` を入力すると、次のループ反復の開始時に条件 `input_number /= 10` が偽 (`.FALSE.`) となり、ループが終了します。

EXIT 文と CYCLE 文

DO WHILEループでも、DOループと同様に `EXIT` 文や `CYCLE` 文を使用できます。`EXIT` は条件が満たされたかどうかに関わらずループを強制的に終了させ、`CYCLE` はループの残りをスキップして条件判定に戻ります。

注意: DO WHILEループでは、ループ内の処理によっていつか必ず条件式が偽 (`.FALSE.`) になるように注意深く設計する必要があります。さもないと、意図しない無限ループに陥る可能性があります。🐛

まとめ: DO と DO WHILE の使い分け 🤔

どちらのループを使うかは、状況によって判断します。

ループの種類 主な用途 特徴
DOループ (カウンタ付き) 繰り返す回数が事前に決まっている場合 カウンタ変数が自動で増減する。構文がシンプル。
DO WHILEループ 特定の条件が満たされるまで繰り返したい場合(回数不定) 柔軟な条件設定が可能。無限ループに注意が必要。
DOループ (無限ループ + EXIT) ループの途中で終了条件が決まる場合や、複雑な終了条件を持つ場合 ループのどこからでも脱出できる。終了条件の記述が必須。

これらの繰り返し処理をマスターすれば、より複雑で実用的なプログラムを作成できるようになります。色々なパターンで試してみてくださいね!🚀

参考情報 📚

  • Fortran Standard Documents (WG5): Fortranの公式仕様書。最新の機能や正確な定義を確認できます。
    https://wg5-fortran.org/standards.html

  • Fortran-lang – Learn: Fortranコミュニティによる学習リソース。チュートリアルやベストプラクティスが紹介されています。
    https://fortran-lang.org/learn/

  • GFortran ドキュメント (GNU): gfortranコンパイラのドキュメントですが、Fortranの文法についても詳しく解説されています。
    https://gcc.gnu.org/onlinedocs/gfortran/

コメント

タイトルとURLをコピーしました