午前中に書いた 関数ポインタのみ!の続き。
関数ポインタってどんな風に使うのでしょう?
普通にポインタで貼っているだけなら、わざわざポインタを使う必要がないのですが、ポインタの配列を使うと威力が発揮できます。
デリゲートと同様に戻り値と引数が同じ関数を配列にすることで、「何番目の関数を呼び出す」という動きが使えます。記述方法としては、
戻り値 (*ポインタ名[])(引数リスト);
?
これもあまりよい使い方ではないのですが、使用例です。
#include
/* 足し算 */
double calcAdd(int a, int b) {
return a + b;
}
/* 引き算 */
double calcSub(int a, int b) {
return a - b;
}
/* 掛け算 */
double calcMux(int a, int b ) {
return a * b;
}
/* 割り算 */
double calcDiv(int a, int b) {
return (double)a / b;
}
int main() {
/* 関数ポインタを配列化する */
double (*calc[])(int, int) = { calcAdd, calcSub, calcMux, calcDiv };
int a,b,i;
/* 演算元を入力 */
printf("実行元の変数Aを入力 > ");
scanf("%d",&a);
printf("実行元の変数Bを入力 > ");
scanf("%d",&b);
/* 逐次呼び出しで上記関数を実行 (わざとループにしてます) */
for ( i = 0 ; i < 4 ; i++ ) {
switch ( i ) {
case 0:
printf("Function[%d] 実行結果 = %f\n", i, calcAdd(a,b));
break;
case 1:
printf("Function[%d] 実行結果 = %f\n", i, calcSub(a,b));
break;
case 2:
printf("Function[%d] 実行結果 = %f\n", i, calcMux(a,b));
break;
case 3:
printf("Function[%d] 実行結果 = %f\n\n", i, calcDiv(a,b));
}
}
/* ループで上記関数を順次実行 */
for ( i = 0 ; i < 4 ; i++ ) {
printf("Function[%d] 実行結果 = %f\n", i ,calc[i](a,b) );
}
return 0;
}
実行すると、引数Aと引数Bをコンソールで入力すると、それぞれの四則演算を行います。
実行元の変数Aを入力 > 3
実行元の変数Bを入力 > 2
Function[0] 実行結果 = 5.000000
Function[1] 実行結果 = 1.000000
Function[2] 実行結果 = 6.000000
Function[3] 実行結果 = 1.500000
Function[0] 実行結果 = 5.000000
Function[1] 実行結果 = 1.000000
Function[2] 実行結果 = 6.000000
Function[3] 実行結果 = 1.500000
関数名を明示的にソースコード上にかかなくても、「配列にしまっておいた何番の関数」といった呼び出しができます。
上記の場合はループで行っていますが、コマンドの番号によって処理を分岐するといったルーチンを作成するときに、switch文やif文で切り分けなくても呼び出したい関数を登録しておくことで、動的に関数を呼び出したりすることができるようになりますね。
投稿日時 : 2007年10月25日 17:42