プログラミング演習第12回関数へのポインタ

2000 年 6 月 29 日

目次

1 目標 1 2 関数へのポインタ 1

2.1 1 変数の場合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2.2 2 変数の場合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

3 練習問題 2

1 目標

関数へのポインタを利用して関数電卓を作る．

2 関数へのポインタ

2.1 1 変数の場合

今までは int 型, char 型へのポインタを勉強しましたが, 今日は関数へのポインタについて取り組みます. このことは関数の値を単純に求めるときに必要になります. つまり, キーボードから sin 10 と代入したとき, その値を返すという関数電卓と呼ばれるものです. アイデアとして, 特定の関数を配列を使って登録しておき, sin 10 と打ち込んだときそれを登録しているリストから取ってくるということです. 先週習いました構造体を使えばこれはできますが, ここでは登録する関数を配列の番号で取り出す方法を用います.

配列は

     func[] = {sin, cos, tan, sqrt}
  とすればいいですが, これではfun[0] = sin, fun[1] = cos, func[2] = tan, func[3] = sqrt

と対応はできますが, これではsin, cos, tan, sqrt は単なる文字として取り扱っていることになります. そこで, double 型の関数として扱うために,

     double (*func[])(double) = {sin, cos, tan, sqrt}

と書きます. 一般に, double *a[n] とすれば, a は n 個の double 型へのポインタ配列という意味を表します. double a[n] は, n 個の int 型への配列を意味していたことと比較してください.

この表示を使えば, 次の関数電卓ができます.

ファイル名は 12-1.c です.

     #include <stdio.h>
     #include <math.h>
     main()
     {
        double (*func[])(double) = {sin, cos, tan, sqrt};
        int no;  /* 関数の番号を指定する */
        double x; /* 求める値 */

printf("求める関数の番号とその求める値をスペースを空けて打ち込んでください\n");

      scanf("%d %lf", &no,&x);
      printf("%g \n", func[no](x));
   }

上の%g は, 表示する数値の大きさに合わせて, 表示形態を変えてくれる printf の g 変換です. 表示する桁数に応じて%f 変換, あるいは%e 変換をしてくれます. ちなみに,

6.02 × 10^{23} = 6.02e23

です. (この数は有名なアボガドロ数）

次にこの応用として自分で定義した関数へのポインタを考えてみましょう. 例えば, sin^{2} x とかはどうしたらいいでしょう.

今までのを思い出すと, 関数を定義し, それを上のように配列のリストに入れるということに気がつくはずです.

実習 1 それでは上の配列のリストの中に, sin^{2}x, sin x × cos x を入れてみてプログラムを完成し

てみてください.

プログラム名は 12-2.c です.

2.2 2 変数の場合

これまでの例は 1 変数関数ですが, 2 変数関数へのポインタの配列は次のような形式となります:

   (* func[])(double, double)

実習 2 sinx × cos y の関数と x^{y} をリストに入れてプログラムを作成してみてください. プログラム名は 12-3.c です. 関数 x^{y} は, pow(x,y) として数学ライブラリーに定義されています.

3 練習問題

上の方法を用いて次の課題をしてください.

問題 1 区間 [0, 2π] での定積分で番号 1 で cos^{3} x の積分を, 番号 2 で sin^{2} x の積分値を求めるプログラムを書きなさい. 分割数は 10000 程度.

問題 2 (レポート問題)n ごとに

∫_{0}^{2π} cos^{2n+1}xdx, ∫_{0}^{2π} sin^{2n}xdx

の値を出すプログラムを書きなさい. 分割数は 10000 程度. (これは有名な公式です.)

ファイル名をそれぞれ creportno.12-4, creportno.12-5 とする. レポート問題の締め切りは 7 月 13 日です. creportno.12-4 は提出したら評価します.