構造体の初歩

例1

2つの分数の足し算

program ex01
  implicit none
! 構造体 bunsuuの定義
  type :: bunsuu
    integer :: bunsi, bunbo
  end type bunsuu
! bunsuu型の変数a,b,cの宣言
  type (bunsuu) :: a,b,c
  a=bunsuu(1,2)
  b=bunsuu(1,3)
  c%bunbo=a%bunbo*b%bunbo
  c%bunsi=a%bunsi*b%bunbo+b%bunsi*a%bunbo
!
! 解説
!
! a=a1/a2, b=b1/b2のとき,
!
!         a1   b1   a1*b2 + b1*a2
! c=a+b = -- + -- = -------------
!         a2   b2       a2*b2
!
! 結果の出力
  write(*,*)a%bunsi,'/',a%bunbo,'+'
  write(*,*)b%bunsi,'/',b%bunbo,'='
  write(*,*)c%bunsi,'/',c%bunbo
  stop
end program ex01

実行例

$ ex01
           1 /           2 +
           1 /           3 =
           5 /           6

例2

構造体を扱うサブルーチンと関数の例

program ex02
!
! 構造体を扱うサブルーチンと関数の例
!  分数の入出力を行うサブルーチン
!  分数の和を計算する関数
!
  implicit none
! 構造体 bunsuuの定義
  type :: bunsuu
    integer :: bunsi, bunbo
  end type bunsuu
! bunsuu型の変数a,b,cの宣言
  type (bunsuu) :: a,b,c,d,e,f
! 分数a,b,cを読み込む
  call yomu('a=',a)
  call yomu('b=',b)
  call yomu('c=',c)
  d=wa(a,b)
  e=wa(c,d)
  f=wa(wa(a,b),c)
  call kaku('a+b = ',d)
  call kaku('c+d = ',e)
  call kaku('a+b+c = ',f)
  stop
contains !以下では構造体bunsuuが使える
!分数の足し算を行う関数
  function  wa(a,b)
    implicit none
    type (bunsuu) :: wa
    type (bunsuu), intent(in) :: a,b
!   waの分子の計算
    wa%bunsi=a%bunsi*b%bunbo+b%bunsi*a%bunbo
!   waの分母の計算
    wa%bunbo=a%bunbo*b%bunbo
   return
  end function wa
! 分数の読み込みを行うサブルーチン
  subroutine yomu(ji,a)
    implicit none
    character(*), intent(in) :: ji
    type (bunsuu), intent(out) :: a
    write(*,*)ji
    read(*,*) a%bunsi, a%bunbo
    return
  end subroutine yomu
! 分数の書き出しを行うサブルーチン
  subroutine kaku(ji,a)
    implicit none
    character(*), intent(in) :: ji
    type (bunsuu), intent(in) :: a
    character(14) :: fmt='(1x,a,i3,a,i3)'
    write(*,fmt)ji,a%bunsi,'  /',a%bunbo
    return
  end subroutine kaku
end program ex02

実行例

$ ex02
 a=
1,2
 b=
1,3
 c=
1,6
 a+b =   5  /  6
 c+d =  36  / 36
 a+b+c =  36  / 36

配列を構成要素にもつ構造体の例

!
! 配列を構成要素にもつ構造体の例
!
module lorenz
  private
  integer, public, parameter :: ndim1=2,ndim2=3
! 構造体systemの定義
  type, public :: system
!   構成要素はx1とx2
    real,dimension (ndim1) :: x1
    real,dimension (ndim2) :: x2
  end type system
end module lorenz
program ex03
  use lorenz
  implicit none
! 派生型の変数aを宣言(構成要素は配列x1とx2)
  type (system) :: a
  a%x1(1)=1
  a%x1(2)=2
  a%x2(1)=11
  a%x2(2)=12
  a%x2(3)=13
  write(*,*)'a%x1'
  write(*,*)a%x1
  write(*,*)'a%x2'
  write(*,*)a%x2
  write(*,*)'a'
  write(*,*)a
end program ex03

実行例

$ ex03
 a%x1
   1.00000000000000        2.00000000000000    
 a%x2
   11.0000000000000        12.0000000000000        13.0000000000000    
 a
   1.00000000000000        2.00000000000000        11.0000000000000    
   12.0000000000000        13.0000000000000  

配列を構成要素にもつ構造体の例

派生型が配列になる例

!
! 配列を構成要素にもつ構造体の例
! 派生型が配列になる例
!
module lorenz
  private
  integer, public, parameter :: ndim1=2,ndim2=3
! 構造体systemの定義
  type, public :: system
!   構成要素はx1とx2
    real,dimension (ndim1) :: x1
    real,dimension (ndim2) :: x2
  end type system
end module lorenz
program ex04
  use lorenz
  implicit none
! 派生型の配列aを宣言(構成要素は配列x1とx2)
  type (system) :: a(2)
  integer i
  a(1)%x1(1)=1
  a(1)%x1(2)=2
  a(1)%x2(1)=11
  a(1)%x2(2)=12
  a(1)%x2(3)=13
  a(2)%x1(1)=21
  a(2)%x1(2)=22
  a(2)%x2(1)=31
  a(2)%x2(2)=32
  a(2)%x2(3)=33
  do i=1,2
    write(*,*)'i=',i
    write(*,*)'a(i)%x1'
    write(*,*)a(i)%x1
    write(*,*)'a(i)%x2'
    write(*,*)a(i)%x2
    write(*,*)'a(i)'
    write(*,*)a(i)
    write(*,*)
  enddo !i
end program ex04

実行例

$ ex04
 i=           1
 a(i)%x1
   1.00000000000000        2.00000000000000    
 a(i)%x2
   11.0000000000000        12.0000000000000        13.0000000000000    
 a(i)
   1.00000000000000        2.00000000000000        11.0000000000000    
   12.0000000000000        13.0000000000000    
 
 i=           2
 a(i)%x1
   21.0000000000000        22.0000000000000    
 a(i)%x2
   31.0000000000000        32.0000000000000        33.0000000000000    
 a(i)
   21.0000000000000        22.0000000000000        31.0000000000000    
   32.0000000000000        33.0000000000000