関数のポインタ
関数のポインタという言葉を聞いてもピンとこないと思いますが、これも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言語ではこんな使い方が
できるようになっています。
今回の例では、関数ポインタを使う意義があまり感じられなかったと思いますが、関数ポインタを
使うと便利な局面もあります。