27.1.1 宣言

関数へのポインタを保持する関数ポインタを宣言するのは少しややこしい。 何故ならば関数には返り値があるので、関数ポインタを使って関数を呼び出し た場合には当然そうした値が返るのであるから、関数ポインタはその値の 型を持たなければならない。 これは実は奇妙な問題を引き起こす。

例えば、int 型の関数へのポインタというものを仮に考えて、もしそれが 以下のように書けたとしよう。

    int * pfunc;    /* 間違い */

さて、こう書いてみるとこのポインタは int * と区別が付かない ことが分かる。つまり、int型へのポインタと int 型の関数へのポインタ の区別が付かないのである。そこで、関数だと分かるように以下のように 後ろに () をつけることにする。

    int * pfunc();   /* 間違い */

しかし、これも実は問題がある。まず、何型へのポインタかという問題と 同時に関数宣言と区別できなくなってしまっている。 やはり、ポインタである限り、これまでの書き方は変えない方が良いであろう。 従って、* pfunc*int * という意味なのか、 関数ポインタという意味なのかが区別できるような書き方が必要になる。 そこで、少しややこしいが以下のように記述する。

    int (* pfunc)();   /* 正しい */

つまり、後ろの () で関数についての宣言であることを明示し、 (* pfunc) でポインタ変数であることを、最初の int で int型であることを示しているのである。これによって、返り値の型と ポインタを混同せずに記述できるので以下のような関数へのポインタも 記述することができる訳である。

    int  * (* ptest1)();
    char * (* ptest2)();

上の例で、ptest1,ptest2 は関数へのポインタ変数であり、それぞれ ptest1 は int * 型、ptest2 はchar * 型を返り値に返すような関数を ポイントできるのである。



最初のページ 戻る 次へ 最後のページ 目次
Hiroyasu Asami