↓↓クリックして頂けると励みになります。
【28 | バイナツリー】 << 【ホーム】
C++における関数ポインター(function pointer)は、他の変数やデータと同様に、関数を指すポインターです。
関数ポインターは、関数のアドレスを保持する変数であり、そのアドレスを使って関数を直接呼び出すことができます。
関数ポインターは、特にコールバック関数や動的な関数選択など、実行時に関数を選択する必要がある場合に便利です。
関数ポインターは、配列や構造体のメンバーとして使用することもできますし、関数を引数として受け取る関数の実装にも利用されます。
Visual Studio Codeで以下のヘッダーファイル1つと2つのcppファイルを作成して下さい。
新規作成1 【Draw.h】
/** ヘッダファイル */ /**Draw.h*/ void draw(int max_x, int max_y, int (*func)(int)); #ifdef MAIN int max_x; int max_y; #else extern int max_x; extern int max_y; #endif
新規作成2 【Draw.cpp】
/** 描画モジュール */ /**Draw.cpp*/ #include<iostream> void draw(int max_x, int max_y, int (*func)(int)){ int x; int y; int arr_x[30]; int arr_y[30]; /**配列にx,yの値を格納*/ for(int j=0; j<max_x; j++){ x=j; y=func(x); arr_x[j]=x; arr_y[j]=y; } std::cout << "^"<< std::endl; for(int i=max_y; i>0; i--){ std::cout <<"|"; if(arr_y[i]>=0 && arr_y[i]<max_y){ for(int j=0; j< arr_x[i]; j++) { std::cout << " "; } std::cout << "*"; } std::cout << std::endl; for(int k=0; k<arr_x[i]; k++){ if(arr_y[i]>=0 && arr_y[i]<max_y){ std::cout <<"|"<< std::endl; } } } std::cout <<"+"; for(int l=0; l<max_x; l++){ std::cout <<"--"; } std::cout << ">" << std::endl; }
新規作成3 【Draw_main.cpp】
/** mainモジュール */ /**Draw_main.cpp*/ #include<iostream> #define MAIN #include "draw.h" int func(int x); int main(){ max_x=30; max_y=10; draw(max_x, max_y, func); } int func(int x){ return ((x*x)-2*x+1); }
画面に点を表示するライブラリが「Draw.cpp」で、これを呼び出すプログラムが「Draw_main.cpp」です。
ライブラリ側ではどのような関数が渡されているかはわかりません。
関数func()
をの関数式を書き換えれば違う点を描画します。
draw()
関数は描画するx, y方向の広さと描画する関数のアドレスを渡しています。
draw()内部ではx=0からx=29までfunx(x)
を呼び出し、それがy=0からy=9までに入っていれば配列にその位置を記憶させてループで回し、最後に出力して終了しています。
関数ポインタは関数と同じように利用できます。
引数と返り値を持っています。
C言語の内部では関数名自体が関数へのアドレスそのものとなります。
関数ポインタの宣言は以下のようにします。
関数ポインタの宣言
変数の型 (* 関数名) ();
例 int (* pfunc)();
関数ポインタの使用方法は簡単です。
関数ポインタに関数のアドレスを代入し、後は普通の関数のように利用します。
関数のアドレスは関数の名前がアドレスとなっていますのでこれを代入するようにします。
int test(void); int (*pf)(); pf = test; pf(); /* 呼び出し */
ここで「pf=test();
」と書くと全く違う意味になるので注意が必要です。
関数ポインタの主な使い方は関数の引数に関数のアドレスを渡して関数ポインタで受け取る場合などです。
int test2( int (*pf)() ){ return pf() * pf(); }
この例ではtest2()
に関数を渡すことにより関数test2()
の中でそれらの関数を利用することが出来ます。
実行結果を確認してください。
~/Desktop/Programming/CPP $ g++ Draw.cpp Draw_main.cpp -o main ~/Desktop/Programming/CPP $ ./main ^ | | | | | | | * | | | | | * | | | | * | | | * | +------------------------------------------------------------>
【28 | バイナツリー】 << 【ホーム】
↓↓クリックして頂けると励みになります。