関数ポインタの使用方法は簡単である。関数ポインタに関数のアドレスを代入し、 後は普通の関数のように利用すれば良い。関数のアドレスは、関数の名前が アドレスとなっているので(これは配列に良く似ている)これを代入するようにする。
int test(void); int (* pf)(); pf=test; (*pf)(); /* 古い呼び出し方法 */ pf(); /* 新しい呼び出し方法 */ |
ここで pf=test();
と書くと全く違う意味になることに注意しよう。
test()
は test()関数の呼び出しであるからだ。そのために、
pf=test()
は test()関数の返り値を pf に代入するという意味に
なってしまう。
さて、このように test() のアドレスをもった関数ポインタpf は当然
関数 test() を呼び出すために利用される。この呼び出しは古い C の
スタイルでは (*pf)()
と書かれる。これは pf が関数へのポインタ
なので (*pf)
でポインタの中身(つまりは関数)を取り出すという
意味なのであるが、新しい C では実際には意味がないので pf()
という書き方でも良いように決められた。実際、test がアドレスならば、
pf もアドレスを意味しているので同じであると解釈するのも合理的であろう。
関数ポインタを使う最も強力なパターンは関数の引数に関数のアドレスを 渡して、関数ポインタで受け取る場合である。
int test2( int (*pf)() ){ return pf() * pf(); } |
この例では、test2() に関数を渡すことにより、関数 test2() の中でそれら の関数を利用することができる。勿論、渡す関数の引数や、返り値は全て 同じでなければならないが、その条件さえ満たしていれば色々な関数を 渡すことができる訳である。
さて、このような関数ポインタを使う意味はどこにあるのだろうか。 例えば画面に様々な描画をするようなプログラムを考えよう。こうした プログラムでは何をどのように書くかという問題は別にすれば、画面に 描画するという点では同じであるので、画面に描画するようなプログラム はライブラリとしてあれば便利である。しかし、ここで問題となるのは 描画する側はライブラリなので何を書くのかということが分からない 点にある。勿論、データの集合として(つまりは点の集合など)描画する ものをライブラリに渡しても良いが、その場合画面がどういう大きさか とか、縮尺かとか言った内容を知った上でデータの集合を準備する必要 があり、ライブラリを使うには少し面倒である。そこで、ライブラリが ある関数を呼び出せば、どこに点を描くかを答えるようになっていれば、 画面の大きさや、縮尺などについてライブラリを呼び出す側で考える 必要はなくなる。
以上のように、関数ポインタを使う場面とは簡単に言えば、どの関数が 実行されるのかが予め分からないような場合であり、ライブラリから ユーザーの関数を呼び出すような場合に有効なのである。