数値解析法及び演習 第六回

サブルーチン
  1. サブルーチン
  2. 今日の宿題

[1] サブルーチン

プログラム中で同じ処理を何度も行いたい場合がよくある.そのたびごとに同じプログラムを何度も書くのは馬鹿げている.同じ処理はサブルーチンとして外部手続きとしておくと都合がよい.

サブルーチンを呼び出す側のプログラムは「主プログラム(main program)」と呼ばれる.サブルーチンは主プログラムのend文以降に,主プログラムと独立に次のように書く. subroutine文以下end subroutineまでがサブルーチンである.

       program example
       implicit none
       double precision :: d,f,g
       ......

       call S(f,g,d)

       ......
       end program example


       subroutine S(a,b,c)
       implicit none

       double precision intent(in) :: a
       double precision intent(out) :: b
       double precition intent(inout) :: c
       ......
       ......
       return
       end subroutine

サブルーチン文 S(a,b,c) サブルーチンの定義をおこなう
S サブルーチン名:英文字で始まる31文字以内の英数字
a,b,c 仮引数:使う変数は型宣言すること
intent(in) :: a aが入力引数であることを明示
intent(out) :: b bが出力引数であることを明示
intent(inout) ::c cが入出力引数であることを明示

call 文 call S(f,g,d) サブルーチンを呼び出す
f,g,d 実引数:仮引数と順序, 型を一致させる必要あり

サブルーチンはend subroutine文で終わらなければならない.サブルーチンから,呼ばれた場所に強制的に戻るには

       return
を書く.return文は何個あってもよい(end subroutineは一個:end subroutine文のみでreturn文がない場合はend subroutineにおいて呼ばれた場所に戻る).それでは次のプログラム を入力して実行してみよう.

プログラム2-1
      program example1
      implicit none
      double precision :: a,b,c

      a = 1.D0
      b = 2.D0
      call wa(a,b,c)
      write(*,*) c     
      end program example1



      subroutine wa(a,b,c)
      implicit none

      double precision, intent(in) :: a,b
      double precision, intent(out) :: c
      double precision :: d ! サブルーチン内のみで使われる変数にはintentをつけない

      c = a + b
      d = a * c   ! このdの値はメインプログラムに渡されない
      return
      end subroutine

呼ぶ方(call wa(a,b))と呼ばれる方(subroutine wa(a,b))の引数は順序,個数,型を一致させなければならない.逆に言うと,引数の個数,型が一致していれば名前は違っていてもよい.サブルーチンを使う場合は, サブルーチンとの変数, 配列のやりとりに注意すること.どれが入力でどれが出力かを頭にいれてプログラムを作成すること. カッコの中に含まれている変数配列のみがメインプログラムとやりとりされることに注意. 次のプログラムは何をするのか考えてみよう.

プログラム2-2
      program example2
      implicit none

      double precision :: a,b,c,d,e

      a=1.D0
      b=2.D0
      d=3.D0
      e=4.D0
      call wa(a,b,c)
      write(*,*) c
      call wa(d,e,c)
      write(*,*) c
      
      end program example2

      subroutine wa(a,b,c)
      implicit none
      double precision, intent(in) :: a,b
      double precision, intent(out) :: c
      c=a+b
 
      
      end subroutine


練習問題1

以下のプログラムを正しく修正せよ.どのプログラムも1行のみ修正すれば動作する..エラーメッセージをよく読むこと.

プログラム2-3

      program error1
      implicit none
      double precision :: a,b

      a=1.D0
      b=2.D0
      call sum(a,b)
      write(*,*) b
      
      end program error1

      subroutine sum(a,b)
      implicit none
      double precision, intent(in) :: a
      double precision, intent(in) :: b
      b=a+b
 
      end subroutine sum

プログラム2-4

      program error2
      implicit none
      double precision :: a,b

      a=1.D0
      b=2.D0
      call sum(a,b)
      write(*,*) b
      
      end program error2

      subroutine sum(a,b)
      implicit none
      integer, intent(inout) :: a,b
      b=a+b
 
      end subroutine sum

プログラム2-5

      program error3
      implicit none
     
      double precision :: a(2),b

      a(1)=1.D0
      a(2)=2.D0
      b=0.D0
      call sum(a,b)
      write(*,*) b
      
      end program error3

      subroutine sum(a,b)
      implicit none
      double precision, intent(in) :: a
      double precision, intent(out) :: b

      b=a(1)+a(2)
 
      end subroutine sum

練習問題2

プログラム2-3を,a,bの積を計算するサブルーチンに書きかえよ. これを用いて変数a,bの積(答えは2.D0)を算出せよ.

練習問題3

変数a,bに代入された値を入れ替えるサブルーチンswap(a,b)を作成せよ.サブルーチンに変数a,bが代入され,実行後はa,bの中身が入れ替わる.a, bは実数とする.

練習問題4

  1. n!を計算するサブルーチン subroutine fact(n,ans)を作成せよ.ここでn, ans は整数とする.
  2. n個のものからm個のものを取り出す組み合わせの数 nCmを計算するサブルーチン subroutine comb(n,m,ans) を作成せよ.
  3. 二項定理によると,f=(x+y)**nは
    (x+y)**n=ΣnCm x**(n-m)*y**m
    となる.nCmを求めるサブルーチンを用いてfを計算するプログラムを作成せよ.x=0.3D0,y=0.7D0,n=10として実行し,結果がほぼ1.D0になることを確かめよ.

[2] 今日の宿題(1点)

練習問題4-3のプログラム, 答えを送ること. 〆切は11/22.

追加の宿題(1点:11/22まで)

実数が10個格納された配列a(10)から,最大値を見つけるサブルーチンmax(a, amax)を作成せよ.サブルーチンには配列aが代入され,実行後にamaxに最大値が出力される.




日程表へ戻る <<