広告
↓発売日:2018年09月22日↓
新品価格 |
またまたポインタのお時間です。
C言語はポインタとは切っても切り離せないのです。
これまでに変数のポインタ、構造体のポインタを学びました。
では今回はと言いますと、関数のポインタについてやっていきたいと思います。
手っ取り早く使い方を説明したいと思います。
関数ポインタも基本は変わりません。
やっぱり先頭にアスタリスクをつけてポインタにしていきます。
まずは普通の関数を作りましょう!
void func(void);
何も受け渡しがない関数「func」ですね!
このカタチをそのままポインタにしていきます!
という事はどこかの先頭に「*」アスタリスクをつけるワケですね!
結論から言いますと
void *func_p(void);
「func」の先頭に「*」アスタリスクをつけます。
そして計算の順序が変わらないように()カッコで→(*func)囲んで
その後ろの「void」は省略できるので、
void (*func_p)();
これが何も受け渡しがない関数ポインタの基本のカタチになります。
そしてここに関数ポインタを保存する時は
void (*func_p)() = func;
このように保存します。
これで関数ポインタに関数「func()」のアドレスが保存されます。
今回は「&」アンパサンドは付けてませんが、
void (*func_p)() = &func;
つけても大丈夫です。
使う時は
(*func_p)();
この()カッコで囲んだカタチのまま使います。
/*十三日目 プログラム1*/ #include <stdio.h> void func(void); int main(){ void (*func_p)() = func; (*func_p)(); return 0; } void func(){ printf("関数ポインタの巻\n"); }
元の関数
void func(void); void func(){ printf("関数ポインタの巻\n"); }
関数ポインタに保存
void (*func_p)() = func;
使う時は
(*func_p)();
カタチで覚えてしまいましょう!
では続けて引数と戻り値がある場合を見てみましょう。
int menseki(int ,int );
このカタチの関数をポインタにしてみます。
int (*menseki_p)(int ,int ) = menseki;
こちらが関数ポインタにしたものになります。
そのまま引数、戻り値を加えた感じですね!
ではこれらを踏まえてプログラミングしてみます。
/*十三日目 プログラム2*/ #include <stdio.h> int menseki(int ,int); int main(){ int kotae = 0; int (*menseki_p)(int ,int ) = menseki; kotae = (*menseki_p)(10,5); printf("長さ縦10,横5の四角形の面積 = %d\n",kotae); return 0; } int menseki(int tate,int yoko){ return tate * yoko; }
元の関数
int menseki(int ,int);
関数ポインタ
int (*menseki_p)(int ,int ) = menseki;
こちらもカタチで覚えてしまいましょう!
広告
ではこの関数ポインタを使って何ができるかと言えば、例えば複数の関数を配列にする事ができます。
/*十三日目 プログラム3*/ #include <stdio.h> void ohayo(void); void konnitiha(void); void konbanha(void); int main(){ int i; void (*aisatu[3])() = {ohayo,konnitiha,konbanha}; for(i=0;i<3;i++){ (*aisatu[i])(); } return 0; } void ohayo(){ printf("おはよう!\n"); } void konnitiha(){ printf("こんにちは!\n"); } void konbanha(){ printf("こんばんは!\n"); }
こうすれば同じような性質を持つ関数群を「for」文などで一気に処理できたりするのでとても便利ですね!
void (*aisatu[3])() = { ohayo, konnitiha, konbanha };
書き方がちょっとややこしいですが、何度も練習して覚えてしまいましょう!
使う時は
(*aisatu[2])();
のように使います。
さらに画期的な事に関数ポインタは関数を保存できる変数のようなものなので引数と戻り値が同じであれば、関数の内容を入れ替える事ができます。
/*十三日目 プログラム4*/ #include <stdio.h> void ohayo(void); void konnitiha(void); void konbanha(void); void (*aisatu)(); int main(){ aisatu = ohayo; (*aisatu)(); aisatu = konnitiha; (*aisatu)(); aisatu = konbanha; (*aisatu)(); return 0; } void ohayo(){ printf("おはよう!\n"); } void konnitiha(){ printf("こんにちは!\n"); } void konbanha(){ printf("こんばんは!\n"); }
これと先ほどの配列を組み合わせれば状況によって変わるメニュー項目などが簡単に作れそうですね!
さきほどのプログラムの前半
#include <stdio.h> /*プロトタイプ宣言*/ void ohayo(void); void konnitiha(void); void konbanha(void); /*関数ポインタをグローバル宣言している*/ void (*aisatu)(); int main(){ /*以下省略*/ }
プロトタイプ宣言とグローバル宣言している関数ポインタ、この違いと
代入する時の書き方
aisatu = ohayo;
このあたりに注意です!
次回は時間と乱数(らんすう)についてやっていきたいと思います。
広告
↓発売日:2016年02月29日↓
12歳からはじめる ゼロからのC言語 ゲームプログラミング教室 新品価格 |
↓発売日:2018年06月22日↓
新品価格 |
↓発売日:2018年03月09日↓
新品価格 |
↓発売日:2017年06月14日↓
新品価格 |
↓発売日:2018年05月21日↓
新品価格 |
↓発売日:2017年12月07日↓
新品価格 |
↓発売日:2017年02月08日↓
新・明解C言語で学ぶアルゴリズムとデータ構造 (明解シリーズ) 新品価格 |
↓発売日:2017年09月26日↓
新品価格 |