これまでのステップでは、基本的なデータ型(数値、文字、論理値)や配列について学んできました。しかし、実際のプログラミングでは、関連する複数の異なる型のデータをひとまとめにして扱いたい場面が多くあります。例えば、人の「名前(文字列)」、「年齢(整数)」、「身長(実数)」などをまとめて管理したい場合です。Fortranでは、このような場合に構造体(TYPE)という機能を使います。構造体を使うことで、独自のデータ型を定義し、プログラムをより整理しやすく、分かりやすくすることができます。
1. 構造体(TYPE)の定義
構造体は、TYPE
キーワードを使って定義します。TYPE
とEND 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つのメンバを持っています。
END TYPE
の後にも型名を記述することが推奨されます。 2. 構造体変数の宣言 宣言
定義した構造体を使うには、その型の変数を宣言します。宣言方法は、INTEGER
やREAL
などの組み込み型と同じです。
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
型の変数としてstudent1
とteacher
を宣言しています。これで、それぞれの変数が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の文法や機能に関する詳細な説明が含まれています。
- GNU Fortran Documentation (Derived Types のセクションを参照)