関数へのポインターを変数に代入しておいて、その変数を用いて呼び出す、 ということが出来ます。
#include <stdio.h> /* 引数を取らない void 型の関数の型を vvfunc と名づける */ typedef void vvfunc(void); /* vvfunc へのポインタ変数 a を定義 */ vvfunc *a = NULL; void f(void) { printf("Hello\n"); } void g(void) { printf("Bye\n"); } int main() { a = f; a(); a = g; a(); return 0; } |
bash-3.2$ cc -o prog1 prog1.c bash-3.2$ ./prog1 Hello Bye bash-3.2$ |
関数へのポインターを配列に収めておくことも出来ます。
#include <stdio.h> /* 引数を取らない void 型の関数の型を vvfunc と名づける */ typedef void vvfunc(void); void f(void) { printf("Hello\n"); } void g(void) { printf("Bye\n"); } int n = 0; vvfunc *commands[10]; void register_command(vvfunc *F) { commands[n++] = F; } void all_commands(void) { int i; for (i = 0; i < n; i++) commands[i](); } int main() { register_command(f); register_command(g); all_commands(); return 0; } |
oyabun% cc -o prog2 prog2.c oyabun% ./prog2 Hello Bye oyabun% |
工夫すると、個々の関数に何かキー (ここでは文字) を対応させておいて、 そのキーで関数を呼び出すことが出来ます。 ここまで出来ると色々応用が効きます。
#include <stdio.h> /* 引数を取らない void 型の関数の型を vvfunc と名づける */ typedef void vvfunc(void); void f(void) { printf("Hello\n"); } void g(void) { printf("Bye\n"); } /* --------------------------------------------------- */ int n = 0; vvfunc *commands[10]; char keys[10]; void register_command(vvfunc *F, char c) { keys[n] = c; commands[n++] = F; } void command(char c) { int i; for (i = 0; i < n; i++) if (c == keys[i]) { commands[i](); return; } } /* --------------------------------------------------- */ int main() { register_command(f, 'H'); register_command(g, 'B'); command('H'); command('B'); return 0; } |
oyabun% cc -o prog3 prog3.c oyabun% ./prog3 Hello Bye oyabun% |