(参考) 関数ポインタ


変数を関数で渡す方法は既に学んでいると思いますが,実は関数もポインタを利用してやりとりをする
ことが可能なのです.
以下に例を示したいと思います.

double fnc(double x){
 return x;
}


main(){
 double x;
 double (*pfnc)(double);
 pfnc=fnc;

 x=10.0;

 *pfnc(x);
}
通常の関数を宣言します.






メイン関数内で関数ポインタを宣言します.
先の関数のアドレスを関数ポインタに送ります.



関数ポインタに引数を渡し,先の関数を実行します.

または,

double fnc(double x){
 return x;
}


main(){
 double x;
 double (*pf)(double);
 *pf=fnc;

 x=10.0;

 
}
通常の関数を宣言します.





メイン関数内で関数のポインタを宣言します.
先の関数を関数のポインタの中身に送ります.





のようにしてもやりとりができます.
関数をわざわざポインタにする理由は何かというと,

  1. 関数の再利用性を上げることができる
  2. 関数を動的に何度でも呼び出して利用できる
  3. 関数に対して異なった種類の関数を呼び込むことができる.

既に作っておいた関数を利用する際,ポインタで受け渡しをすることで,例えば関数名が合わなくても
その制約をなくして利用できるので再利用性が向上します.また,関数をモジュール(ユニット)のような
ものとして利用できるので関数内のアルゴリズムの構造を何度も形を変えて利用できるという点があり
ます.何かの数値を算出するための関数ではなく,計算するための仕組みとしての関数にでき,汎用性,
再利用性が格段に上がります.

授業の課題であれば,プログラムが小規模な上に,あまり再利用する機会がないのでメリットがつかみ
にくいと思いますが,自作のプログラムを作る際は大変便利ですので参考にしてみて下さい.

関数ポインタ(補足)
関数ポインタを関数に呼び込む方法が分かりにくいと思いますので,追加説明します.以下の例を見て
下さい.
fnc_1の引数として関数ポインタを用いています.メイン関数内では関数fnc_A, fnc_Bをこのfnc_1に渡して
います.
fnc_1の引数(*fnc)(double)は関数ポインタの中身を表しているので,
(*fnc) = fnc_Aとして関数ごと引き渡すことができると考えて下さい.

#include <stdio.h>

double fnc_1(double (*fnc)(double), double a){
 return *fnc(a);
}

double fnc_A(double a){
 return a;
}

double fnc_B(double a){
 return a*a;
}

main(){
 double h=2;

 printf("fnc_A=%f\n", fnc_1(fnc_A, h));
 printf("fnc_B=%f\n", fnc_1(fnc_B, h));
}