[Fortranのはじめ方] Part12: 構造体(TYPE)の定義と利用

これまでのステップでは、基本的なデータ型(数値、文字、論理値)や配列について学んできました。しかし、実際のプログラミングでは、関連する複数の異なる型のデータをひとまとめにして扱いたい場面が多くあります。例えば、人の「名前(文字列)」、「年齢(整数)」、「身長(実数)」などをまとめて管理したい場合です。Fortranでは、このような場合に構造体(TYPE)という機能を使います。構造体を使うことで、独自のデータ型を定義し、プログラムをより整理しやすく、分かりやすくすることができます。


Warning: Undefined array key “is_admin” in /home/c2261046/public_html/omomuki-tech.com/wp-content/themes/sango-theme/library/gutenberg/dist/classes/Toc.php on line 113

Warning: Undefined array key “is_category_top” in /home/c2261046/public_html/omomuki-tech.com/wp-content/themes/sango-theme/library/gutenberg/dist/classes/Toc.php on line 118

Warning: Undefined array key “is_top” in /home/c2261046/public_html/omomuki-tech.com/wp-content/themes/sango-theme/library/gutenberg/dist/classes/Toc.php on line 124

1. 構造体(TYPE)の定義 📝

構造体は、TYPEキーワードを使って定義します。TYPEEND TYPEの間に、構造体に含めたい変数(メンバまたは成分と呼びます)を通常の変数宣言と同じように記述します。

基本的な構文は以下の通りです。


TYPE 型名
  データ型1 :: メンバ名1
  データ型2 :: メンバ名2
  ...
END TYPE 型名
    

例えば、人の情報を格納する構造体 `person_t` を定義してみましょう。名前(最大30文字)、年齢、身長をメンバとして持ちます。


PROGRAM type_definition_example
  IMPLICIT NONE

  ! 構造体 person_t の定義
  TYPE :: person_t
    CHARACTER(LEN=30) :: name
    INTEGER           :: age
    REAL              :: height
  END TYPE person_t

  ! ここで person_t 型の変数を使う (後のセクションで説明)

END PROGRAM type_definition_example
    

この例では、person_tという新しいデータ型を定義しました。この型は、name(文字列)、age(整数)、height(実数)という3つのメンバを持っています。

💡 ポイント: 型名の最後に `_t` をつけるのは、慣習としてよく行われます(必須ではありません)。また、END TYPEの後にも型名を記述することが推奨されます。

2. 構造体変数の宣言 宣言✨

定義した構造体を使うには、その型の変数を宣言します。宣言方法は、INTEGERREALなどの組み込み型と同じです。


PROGRAM type_variable_declaration
  IMPLICIT NONE

  ! 構造体 person_t の定義 (前節と同じ)
  TYPE :: person_t
    CHARACTER(LEN=30) :: name
    INTEGER           :: age
    REAL              :: height
  END TYPE person_t

  ! person_t 型の変数を宣言
  TYPE(person_t) :: student1, teacher

END PROGRAM type_variable_declaration
    

この例では、person_t型の変数としてstudent1teacherを宣言しています。これで、それぞれの変数がname, age, heightというメンバを持つことになります。配列として宣言することも可能です。


  ! person_t 型の配列を宣言 (要素数10)
  TYPE(person_t), DIMENSION(10) :: students
    

3. メンバへのアクセス 👉

構造体変数の個々のメンバにアクセスするには、パーセント記号 % を使います。


変数名 % メンバ名
    

先ほどのstudent1変数を使って、各メンバに値を代入してみましょう。


PROGRAM member_access_example
  IMPLICIT NONE

  TYPE :: person_t
    CHARACTER(LEN=30) :: name
    INTEGER           :: age
    REAL              :: height
  END TYPE person_t

  TYPE(person_t) :: student1

  ! メンバに値を代入
  student1 % name   = 'Yamada Taro'
  student1 % age    = 20
  student1 % height = 175.5

  ! メンバの値を表示
  WRITE(*,*) 'Name  :', student1 % name
  WRITE(*,*) 'Age   :', student1 % age
  WRITE(*,*) 'Height:', student1 % height

END PROGRAM member_access_example
    

実行すると、代入した値が表示されます。


 Name  : Yamada Taro
 Age   :          20
 Height:   175.500000
    

4. 構造体の初期化 🚀

構造体変数は、宣言時に構造体コンストラクタを使って初期化することができます。構造体コンストラクタは、型名を関数のように使い、メンバの値を順番に指定します。


PROGRAM constructor_example
  IMPLICIT NONE

  TYPE :: person_t
    CHARACTER(LEN=30) :: name
    INTEGER           :: age
    REAL              :: height
  END TYPE person_t

  ! 構造体コンストラクタを使って初期化
  TYPE(person_t) :: student2 = person_t('Sato Hanako', 19, 160.2)

  ! 初期化された値を表示
  WRITE(*,*) 'Name  :', student2 % name
  WRITE(*,*) 'Age   :', student2 % age
  WRITE(*,*) 'Height:', student2 % height

END PROGRAM constructor_example
    

実行結果は以下のようになります。


 Name  : Sato Hanako
 Age   :          19
 Height:   160.199997
    
⚠️ 注意: 構造体コンストラクタで指定する値の順序は、TYPE定義でのメンバの宣言順序と一致させる必要があります。また、すべてのメンバの値を指定する必要があります。

5. 構造体の利用例: 2次元座標 🗺️

構造体は、座標のような複数の要素で一つの意味を持つデータを扱うのに便利です。x座標とy座標を持つpoint_t型を定義し、2点間の距離を計算する例を見てみましょう。


PROGRAM point_example
  IMPLICIT NONE

  ! 2次元座標を表す構造体
  TYPE :: point_t
    REAL :: x
    REAL :: y
  END TYPE point_t

  TYPE(point_t) :: p1, p2
  REAL :: distance

  ! 点 P1 と P2 の座標を設定
  p1 = point_t(1.0, 2.0) ! 構造体コンストラクタで初期化
  p2 % x = 4.0          ! メンバごとに代入
  p2 % y = 6.0

  ! 2点間の距離を計算 d = sqrt((x2-x1)^2 + (y2-y1)^2)
  distance = SQRT( (p2%x - p1%x)**2 + (p2%y - p1%y)**2 )

  WRITE(*, '(A, F6.2, A, F6.2, A)') 'Point P1: (', p1%x, ', ', p1%y, ')'
  WRITE(*, '(A, F6.2, A, F6.2, A)') 'Point P2: (', p2%x, ', ', p2%y, ')'
  WRITE(*, '(A, F8.4)') 'Distance:', distance

END PROGRAM point_example
    

このプログラムを実行すると、2点の座標と、それらの間の距離が表示されます。


Point P1: (  1.00,   2.00)
Point P2: (  4.00,   6.00)
Distance: 5.0000
    

このように、構造体を使うことでp1_x, p1_y, p2_x, p2_yのように個別の変数をたくさん用意する代わりに、p1, p2というまとまりでデータを扱えるようになり、プログラムがスッキリしますね! 😊

まとめ 🏁

今回は、Fortranの構造体(TYPE)について学びました。

  • 構造体を使うと、異なる型のデータをひとまとめにした独自のデータ型を定義できます。
  • TYPE ... END TYPE 構文で定義し、TYPE(型名) で変数を宣言します。
  • メンバへのアクセスには % 記号を使います。
  • 構造体コンストラクタ 型名(...) で初期化できます。

構造体は、複雑なデータを効率的に扱うための重要な機能です。特に、シミュレーションやデータ解析など、多くのパラメータや属性を持つ対象を扱う際に非常に役立ちます。

次のステップでは、プログラムを部品化するためのサブルーチンや関数について学んでいきます。構造体をサブルーチンや関数に渡す方法なども、今後重要になってきますので、しっかり基本を押さえておきましょう! 💪

参考情報 📚

より詳しい情報や他の使い方については、以下のリソースも参考にしてください。

  • Fortran Standard Documents (規格文書): Fortranの正確な仕様を知りたい場合は、ISO/IEC 1539シリーズ(最新版はFortran 2018やFortran 2023)を参照してください。規格文書は有料の場合が多いですが、ワーキンググループ(WG5)のサイトで最終ドラフトなどが公開されていることがあります。
  • Fortran-lang tutorial: 公式コミュニティサイトのチュートリアルにも派生型(Derived Types, 構造体のこと)に関する説明があります。
  • GNU Fortran (gfortran) マニュアル: gfortranコンパイラのマニュアルには、Fortranの文法や機能に関する詳細な説明が含まれています。