モジュールの記述形式
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 kakuend module bsprogram 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) stopend 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) stopcontains !以下では構造体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 kakuend 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 matchend module blood_typeprogram 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) stopend program ex04実行例
$ ex04 A + A + Match A + A - Not matchpublicと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 subend module sample_modprogram 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=',idend 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 subend module sample_modprogram 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=',idend program chk_moduleコンパイル例
ifort -c -CB -traceback -fpe0 -r8 ex06.f90ex06.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------------------------------^