Fortran 入門

前へ   上へ   次へ

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



前へ   上へ   次へ
大学生協限定キャンペーン情報
ご案内
関連情報
© 日本ニューメリカルアルゴリズムズグループ株式会社 2024
Privacy Policy  /  Trademarks