2 関数副プログラム

2.1 どのような時につかうか

教科書の例にならい、次のような関数を計算する場合、どうするか考えよう。

$\displaystyle f(x)=\begin{cases}\sqrt{1-x^2} & \text{$-1 \le x \le 1$のとき}\\ 0 & \text{それ以外のとき} \end{cases}$ (1)

この関数を1回のみ計算する場合は、IF文を使うことで対処できますが、何回も 計算する場合は厄介です。通常のプログラムでは似たような計算を大量に行 うので、できるだけ同じ処理はまとめたほうが効率的です。先の関数を何億回 も計算することは、決して珍しくありません。

そのために、この関数を定義して、いつでも呼び出せるようにすると便利です。 あたかも、$ \sin(x)$のように$ x$を入れれば、計算してくれるようにすれば非 常に便利です。一つの解決方法が文関数ですが、これは1行で関数を定義 する必要があるので、式(1)のようにIF文を使って、 場合分けが必要の時には使えません。文関数で定義できない複雑な関数を定義す るときに、関数副プログラムを使います。

もう一度、文関数と関数副プログラムの違いをまとめておくと次のようになり ます。

文関数
1行で定義できる簡単な関数のときに使います。
関数副プログラム
複数の行で定義する必要がある複雑な関数のときに 使います。

2.2 実際のプログラム

教科書の例を用いて説明しよう。教科書のプログラムは分かりにくいので、実 際、通常のプログラマーが記述するように書くと以下のようになります。

メインルーチンを見るだけで、このプログラムの動作が分かると思います。関 数F(X)の値をX=0.5から0.1ステップで1.5まで計算して、書き出していると想 像できます。実際の関数は、関数副プログラムを見ればすぐに分かるようになっ ています。

関数F(X)はどこからでも使うこともでき便利です。同じ処理を何回も書かない ですむということです。これは、関数を変えたい場合、プログラムを書き直す のは1箇所で済みます。これにより、プログラムは分かりやすくなり、作成時 間も非常に短くできます。

 *=======================================================
 * MAIN ROUTINE
 *=======================================================
      PROGRAM MAIN

      DO 10 X=0.5, 1.5, 0.1
        Y=F(X)
        WRITE(6,601) X,Y
  601   FORMAT(2E20.8)
   10 CONTINUE
      
      STOP
      END

 *=======================================================
 *     USEER DEFINEDED FUNCTION
 *=======================================================
      FUNCTION F(X)

      IF(ABS(X).LE.1.0)THEN
        F=SQRT(1.0-X*X)
      ELSE
        F=0.0
      ENDIF

      RETURN
      END

これを関数副プログラムを使わないで書くと、以下のようになります。これだ とプログラムの意図した内容がわかりにくく、保守が難しくなります。また、 長いプログラムを書く場合も大変です。

      PROGRAM KEISAN

      DO 10 X=0.5, 1.5, 0.1

        IF(ABS(X).LE.1.0)THEN
          Y=SQRT(1.0-X*X)
        ELSE
          Y=0.0
        ENDIF

        WRITE(6,601) X,Y
  601   FORMAT(2E20.8)

   10 CONTINUE
      
      STOP
      END

2.3 関数副プログラムの文法

2.3.1 関数の呼び出し

関数は、関数名で呼び出して、算術代入文で変数に入れるのが普通です。関数 名は、組み込み関数と異なれば、任意の名前をつけることができます。実引数 並びは、関数の独立変数で、複数個が許されます。多変数関数に対応している ということです。また、配列も許されます。ただし、実引数と仮引数の数と型 は一致させる必要があります。

同様に、関数の戻り値の型と代入される変数の型も一致させる必要があります。

      代入される変数=関数名(実引数並び)

ただし、関数の名前と型が暗黙の型宣言に従わない場合、呼び出し側でも型宣 言が必要である。たとえば、次のように場合である。

 *=======================================================
 * MAIN ROUTINE
 *======================================================= 
      INTEGER WA
      
      I=2
      J=3
      K=WA(2,3)

      STOP
      END

 *=======================================================
 * FUNCTION
 *=======================================================      
      INTEGER FUNCTION WA(M,N)
      
      WA=M+N

      RETURN
      END

2.3.2 関数の定義

関数の定義は以下のように行います。関数の型は、REALやINTEGER等、変数の場合 と同じように書きます。これは、戻り値の型を示します。ただし、これは省略 可能で、その場合は関数名に従い暗黙の型宣言3になります。

仮引数並びと実引数並びは、同じ数で型でなくてはなりません。ただし、引数 の変数名は異なっても、何ら問題はありません。関数の処理の部分は、今まで 学習してきたFORTRANのプログラムを書けばよいのです。計算のみならず、 WRITE文やREAD文も書けます。ただし、最後に関数名に値を代入する必要があ ります。これが戻り値になります。

関数副プログラム内で使われた変数は、引数以外は全く、メインルーチンに影 響を及ぼしません。メインルーチンと同じ名前の変数が使われていても、その 結果が反映されることはありません。

      関数の型 FUNCTION 関数名(仮引数並び)
      宣言文
    
    実行文(関数の値を求めるための処理)

    関数名=処理の結果の関数の値

    RETURN
      END



ホームページ: Yamamoto's laboratory
著者: 山本昌志
Yamamoto Masashi
平成19年8月20日


no counter