このページの内容 |
---|
関数へのポインタ |
関数へのポインタの配列 |
引数としての関数ポインタ |
ありがたいスポンサー様 |
---|
All About ソフトウエアエンジニア |
ネットで8%割引!自動車保険はアメリカンホーム・ダイレクト |
人生の「チャンス」と「ピンチ」にモビット! |
保険料が一生上がらない、保険料最大50%割引の一生涯の医療保険! |
関数へのポインタは
戻り値の型 (*ポインタ名) (引数の型, ...)
として宣言する。ポインタ名を括弧でくくるのを忘れないように注意が必要。
使い方は以下の例を参照。
int func( double d) ; typedef int (*PFUNC)( double) ; void main(){ // 宣言 int (*pf)(double) = func ; // OK int (*pf2)(double) = &func ; // これでもOK PFUNC pf3 = func; // typedefすれば変数のように宣言できる // 呼び出し (*pf)( 2.0) ; // OK pf( 2.0) ; // これでもOK }
関数へのポインタを配列として保存しておくと、数値と実行する関数を関連付けられる。
#include <stdio.h> void add( void) ; void view( void) ; void remove( void) ; void save( void) ; void load( void) ; typedef void (*PFUNC)( void) ; void main(){ PFUNC functions[] = { add, view, remove, save, load} ; int i ; while( true){ printf( "0. exit\n1. add\n2. view\n3. remove\n4. load\n") ; scanf( "%d", &i) ; if( i <= 0 || i > 4){ break ; } functions[ i](); } }
C++なら、コマンドをオブジェクトにしてCommandObject.fire()とするオブジェクト指向的な方法(Commandパターン)も考えられるが、C言語でオブジェクト指向っぽいことをするならこの方法ぐらいかな。
関数ポインタを引数にとる関数がある。例えば、ランタイムライブラリのqsort関数がそれである。qsort関数は、次のような引数をとる。
void qsort( void *base, // ソートする配列の先頭 size_t num, // 配列の要素数 size_t width, // 配列要素のサイズ int (__cdecl *compare)(const void *elem1, const void *elem2) // 比較関数 );
比較関数は、elem1 の指す要素が elem2 の指す要素より小さい時に負、同じ時に0、大きいときに正を返せばよい。開発者が比較関数へのポインタを指定できることで、任意の規則でソートすることができる。これは、関数へのポインタの有用な利用方法のひとつである。
他にも、Win32関数のうち、Enum〜系の関数は、コールバック関数として関数ポインタを使用する。例えば、EnumWindows関数は、関数へのポインタを使用する。