モジュールの初歩
モジュールの記述形式
module モジュールの名称
... (モジュールの内容)
end module モジュールの名称
モジュールサブルーチンの記述形式
module モジュールの名称
implicit none
contains
subroutine サブルーチンの名称(仮引数,仮引数,...)
... (サブルーチンの内容)
end subroutine サブルーチンの名称
... (他のサブルーチンも同様に記述できる)
end module モジュールの名称
プログラミングのポイント
各プログラム単位内で,implicit none宣言を行うこと.
モジュール使用宣言
use モジュールの名称
モジュールサブルーチンの使用例
! モジュールサブルーチンの使用例
! 分数の入出力を行うサブルーチン
! 分数の和を計算する関数
!
module bs ! モジュールの記述
implicit none
! 構造体 bunsuuの定義
type :: bunsuu
integer :: bunsi, bunbo
end type bunsuu
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 module bs
program ex03
use bs !モジュールの使用宣言
! 以下では構造体bunsuuが使える.
implicit none
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
end program ex03
実行例
$ ex03
a=
1,2
b=
1,3
c=
1,6
a+b = 5 / 6
c+d = 36 / 36
a+b+c = 36 / 36
モジュールを使わない例
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
モジュール関数の使用例
! モジュール関数の使用例
! 血液型をABO型の区別とRh型の区別の組として扱う構造体
! 血液型が一致するか判定する関数
!
module blood_type ! モジュールの記述
implicit none
! 構造体 btypeの定義
type :: btype
character(2) :: abo
character(1) :: rh
end type btype
contains !以下では構造体btypeが使える
! 血液型が一致しているか確認する関数
function match(bt1,bt2) result (ma)
implicit none
type (btype), intent(in) :: bt1,bt2 !関数の引数
character(9) ma ! 関数の戻り値
if ( (bt1%abo == bt2%abo) .and. (bt1%rh == bt2%rh) )then
ma = 'Match'
else
ma = 'Not match'
endif
return
end function match
end module blood_type
program ex04
use blood_type !モジュールの使用宣言
implicit none
type (btype) :: bt1, bt2
! 文字型のmatchの宣言は不要
bt1%abo='A'; bt1%rh='+'
bt2%abo='A'; bt2%rh='+'
write(*,*)bt1%abo, bt1%rh
write(*,*)bt2%abo, bt2%rh
write(*,*)match(bt1,bt2)
write(*,*)
bt1%abo='A'; bt1%rh='+'
bt2%abo='A'; bt2%rh='-'
write(*,*)bt1%abo, bt1%rh
write(*,*)bt2%abo, bt2%rh
write(*,*)match(bt1,bt2)
stop
end program ex04
実行例
$ ex04
A +
A +
Match
A +
A -
Not match
publicとprivateの使用例
!
! publicとprivateの使用例
!
module sample_mod
implicit none
private !モジュール内の全ての変数・サブルーチン・関数が外部から参照できなくなる.
integer, save :: ia=1,ib=2
public ib,sub !指定された変数などを外部から参照できるようにする.
contains
subroutine sub
integer, save :: id=4
write(*,*)'sub: ia,id=',ia,id
end subroutine sub
end module sample_mod
program chk_module
use sample_mod
implicit none
!!! 下の文をコメントアウトするとエラーになる(iaはsample_modの中でしか使えない)
!!! write(*,*)'chk_module: ia=',ia
write(*,*)'chk_module: ib=',ib
! モジュールsample_mod0の使用宣言を行うことにより,containsより前に宣言された
! サブルーチンsubを,他のプログラム単位で参照できる.
call sub
!!! 下の文をコメントアウトするとエラーになる(idはsubの中でしか使えない)
!!! write(*,*)'chk_module: id=',id
end program chk_module
実行例
$ ex06
chk_module: ib= 2
sub: ia,id= 1 4
エラーとなる例(外部から参照できない変数を参照しようとした)
!
! publicとprivateの使用例
!
module sample_mod
implicit none
private !モジュール内の全ての変数などは外部から参照できなくなる.
integer, save :: ia=1,ib=2
public ib,sub !指定された変数などを外部から参照できるようにする.
contains
subroutine sub
integer, save :: id=4
write(*,*)'sub: ia,id=',ia,id
end subroutine sub
end module sample_mod
program chk_module
use sample_mod
implicit none
!!! 下の文をコメントアウトするとエラーになる(iaはsample_modの中でしか使えない)
write(*,*)'chk_module: ia=',ia
write(*,*)'chk_module: ib=',ib
! モジュールsample_mod0の使用宣言を行うことにより,containsより前に宣言された
! サブルーチンsubを,他のプログラム単位で参照できる.
call sub
!!! 下の文をコメントアウトするとエラーになる(idはsubの中でしか使えない)
write(*,*)'chk_module: id=',id
end program chk_module
コンパイル例
ifort -c -CB -traceback -fpe0 -r8 ex06.f90
ex06.f90(21): error #6404: This name does not have a type, and must have an explicit type. [IA]
write(*,*)'chk_module: ia=',ia
------------------------------^
ex06.f90(30): error #6404: This name does not have a type, and must have an explicit type. [ID]
write(*,*)'chk_module: id=',id
------------------------------^