パソコン活用研究シリコンバレー(C、C++、の活用研究)

関数のポインタ

関数のポインタという言葉を聞いてもピンとこないと思いますが、これもC言語のわかりにくい
部分のひとつです。

ともかく以下のプログラムを見てください。。
関数addは単純な足し算をしています。

/* 関数のポインタのテスト coded by Tsuyoshi Kasai for TurboC,LSIC */

#include <stdio.h>

int add(int,int);

main(){

int x,y,result;
printf("整数を2つ入力 2つの数字の間はスペースで区切って下さい: ");
scanf("%d %d",&x,&y);
printf("\n");
printf("関数のアドレス(エントリポイント) %d \n",add);

result=add(x,y);
printf("足し算の答え %d",result);
}

int add(int a, int b){
int c;
c=a+b;
return (c);
}

ちょっと、あれっと思ったのは
printf("関数のアドレス(エントリポイント) %d \n",add);
の行ではないでしょうか。

関数int add(int, int) の関数名であるaddを表示させています。
ともかく実行してみちゃいましょう。
なんか、数字が表示されていますが、これは関数のエントリポイント(関数の先頭アドレス)
なのです。
少し配列とにていますね。a[10]という配列があるとき、aはその配列の先頭アドレスを示して
いたのと同じ感じですね。

そこで、関数ポインタという仕組みの登場です。

int (*func)(int, int);
という定義をしてやると、なんと
func=add;
ということが可能になります。

そうするとですよ、
func(num1, num2); みたいな書き方でadd関数を呼び出すことができちゃうのです。
これは、
(*func)(num1, num2); という書き方で呼び出すこともできます。

ちょっとまとめておくと、関数ポインタは
型 (*変数名)(仮引数)
という記述をします。
関数ポインタの型は、参照する元の関数の型と同じ型で宣言しておきます。

下のプログラムでは、funcと(*func)の両方でaddを呼び出していますが、当然のことながら
問題なく同じ結果になっています。funcも(*func)もaddのエントリポイントを指しています。

/* 関数のポインタのテスト coded by Tsuyoshi Kasai for TurboC,LSIC */

#include <stdio.h>

int add(int,int);

main(){
int (*func)(int n1, int n2);
int x,y,result;
printf("整数を2つ入力 2つの数字の間はスペースで区切って下さい: ");
scanf("%d %d",&x,&y);
printf("\n");
func=add;
printf("関数のアドレス(エントリポイント) %d \n",add);
printf("func: %d \n", func);
result=func(x,y);
printf("足し算の答え %d\n",result);

printf("*func: %d \n", *func);
result=(*func)(x,y);
printf("足し算の答え %d",result);
}

int add(int a, int b){
int c;
c=a+b;
return (c);
}

なんか、わかったようなわかんないような感じかもしれませんが、C言語ではこんな使い方が
できるようになっています。

今回の例では、関数ポインタを使う意義があまり感じられなかったと思いますが、関数ポインタを
使うと便利な局面もあります。


TopPage