関数へのポインタ


関数へのポインタを保持し、そのポインタを通じて関数を 呼び出すことが出来る。

一番簡単な例は、次のような感じ。

#include <stdio.h>

int func(int x)
{
    return x * x;
}

int main()
{
    int (*p)(int);

    p = &func;

    printf("%d\n", (*p)(3));

    return 0;
}
funcpointer.c

なお、後者2つは、少し省略して と書いてもよい。

この例は関数へのポインタを使う意味は無いが、「どの関数を呼び出すか 実行時に決めたい」ようなときに役に立つ。 例えば、次のようなNewton法のプログラムを考える。

#include <stdio.h>

double func(double x)
{
    return x * x - 2.;
}

double newton(double x)
{
    int i;
    double d;

    for (i=0; i<10; i++) {
        d = (func(x + 0.01) - func(x)) / 0.01;
        x = x - func(x) / d;
    }

    return x;
}

int main()
{
    printf("%.15g\n", newton(1.));

    return 0;
}
newton1.c

funcは解きたい方程式 (x2-2=0) を表している。 newtonでは、刻み0.01の差分で微分値を近似しつつ、Newton法を10回 行っている。 このような書き方だと、解きたい方程式を変えたいときや、 同じプログラム中で解きたい方程式が複数あったとき、newtonの中の 関数呼び出し部分(func)を書き換える必要が出てしまう。 このままでは、newton関数がNewton法を行うための汎用の「部品」にならない。 この問題は、次のようにnewton関数が解くべき問題を関数ポインタで渡してやる ことにより解決できる。

#include <stdio.h>

double func(double x)
{
    return x * x - 2.;
}

double func2(double x)
{
    return x * x * x - 5.;
}

double newton(double x, double (*f)(double))
{
    int i;
    double d;

    for (i=0; i<10; i++) {
        d = (f(x + 0.01) - f(x)) / 0.01;
        x = x - f(x) / d;
    }

    return x;
}

int main()
{
    printf("%.15g\n", newton(1., func));
    printf("%.15g\n", newton(1., func2));

    return 0;
}
newton2.c

こう書けば、関数newtonに解きたい問題が埋め込まれず、汎用の関数と することが出来る。


関数へのポインタ /