前へ 上へ 次へ
前へ 上へ 次へ
17 ポインタ
Fortran には変数や配列を指し示すためのポインタの仕組みが提供されています。 ポインタには大きく分けてデータポインタと(Fortran 2003 より導入された)手続ポインタがありますが、本セクションではデータポインタについての説明をします。17.1 ポインタ概要
ポインタの宣言は以下の例のように POINTER 属性を指定する事により行うことが可能です。real, pointer :: x double precision, pointer :: y(:) integer, pointer, dimension(:,:) :: z上記例では 単精度実数スカラを指し示すためのポインタ x、倍精度実数1次元配列を指し示すためのポインタ y、整数2次元配列を指し示すためのポインタ z をそれぞれ宣言しています。
ポインタが指し示す先は指示先と呼ばれます。 指示先としては既存の変数が指定できる他、下記の例のように nullify 文を用いて明示的に空状態のポインタとする事も可能です。 (空状態のポインタは何も指し示していない事を意味します。)
nullify( x, y, z )また他にも、下記の例のように allocate 文を用いて新しい格納領域を指示先として割り付ける事が可能です。
allocate( x, y(10), z(5,3) )
17.2 ポインタの参照
ポインタは通常の変数と同じように式の中に指定することができます。 (※ 有効な指示先が指し示されている事が前提です。)以下に例を示します。
program pointer_ref implicit none integer, pointer :: p, q(:) allocate( p, q(3) ) ! 指示先として新たな格納領域を割り付ける ! 以下のように通常の変数と同じように利用可能 p = 10 q(1) = 100 q(2) = 200 q(3) = 300 print *, p, q end program pointer_ref[ pointer-ref.f90 ] - ポインタの参照を示すプログラム例
出力例
10 100 200 300
17.3 ポインタ代入
ポインタの指示先を設定したい場合にはポインタ代入文が利用可能です。通常の代入文ではポインタが指し示す先(指示先)がその対象となります。 しかしながら場合によってはポインタの指示先自体を設定したい場合があります。 このような場合にポインタ代入文を利用します。
ポインタ代入文は以下の例のように => を指定して行います。
program pointer_assignment implicit none integer, pointer :: a, b allocate(b) b = 10 a => b ! これにより a と b が同じ指示先を持つことになる a = a + 1 print *, "a =", a print *, "b =", b end program pointer_assignment[ pointer-assignment.f90 ] - ポインタ代入文のプログラム例
出力例
a = 11 b = 11上記コードの a => b の部分により aと b が同一の格納領域を示すことになり、よって print 文により出力される a と b の値は同一となっています。
ポインタは宣言時には未定義です。未定義な状態はそれを確かめる方法がないこともあり望ましい状態ではありません。 下記の例のように null() 組込み関数を用いて空状態の初期値を与え、これを防ぐことが可能です。
real, pointer :: x => null() double precision, pointer :: y(:) => null() integer, pointer, dimension(:,:) :: z => null()
17.4 ASSOCIATED 組込み関数
ポインタが結合状態(有効な指示先がある状態)であるか調べるには、組込み関数 ASSOCIATED を利用します。 ASSOCIATED 関数は論理値(.TRUE. もしくは .FALSE.)を返します。
下記に例を示します。
program associated_intrinsic implicit none real, pointer :: x, y allocate(x) nullify(y) print *, "x association status =", associated(x) print *, "y association status =", associated(y) end program associated_intrinsic[ associated-intrinsic.f90 ] - ASSOCIATED 組込み関数を利用するプログラム例
出力例
x association status = T y association status = F尚、ASSOCIATED 組込み関数に未定義なポインタを与えてはいけません。
17.5 構造型の成分としてのポインタ
構造型の成分をポインタとする事も許されています。 これにより連結リストを含む様々な実用的なデータ構造を実装する事が可能です。以下に連結リストの各ノードを表す構造型の成分としてポインタを宣言する例を示します。
type node type(node), pointer :: next_node integer value end type上記例では type(node) 型を指し示すポインタ next_node が type(node) 型の一成分として含まれています。
下記に整数の値を格納する連結リストのプログラム例を示します。
program linked_list implicit none type node type (node), pointer :: next_node integer value end type node integer num type (node), pointer :: first_node, new_node, p nullify (first_node) do print *, 'Input a positive number: (Enter negative number to end)' read *, num if (num<0) exit ! リストの最初に新しい値を追加 allocate (new_node) new_node%next_node => first_node new_node%value = num first_node => new_node end do p => first_node print *, "================================" do while (associated(p)) print *, p%value p => p%next_node end do end program linked_list[ linked-list.f90 ] - ポインタを利用した連結リストのプログラム例
出力例
Input a positive number: (Enter negative number to end) 10 Input a positive number: (Enter negative number to end) 20 Input a positive number: (Enter negative number to end) 30 Input a positive number: (Enter negative number to end) -1 ================================ 30 20 10
前へ 上へ 次へ