関数へのポインターを変数に代入しておいて、その変数を用いて呼び出す、 ということが出来ます。
1 #include <stdio.h> 2 3 /* 引数を取らない void 型の関数の型を vvfunc と名づける */ 4 typedef void vvfunc(void); 5 /* vvfunc へのポインタ変数 a を定義 */ 6 vvfunc *a = NULL; 7 8 void f(void) { printf("Hello\n"); } 9 10 void g(void) { printf("Bye\n"); } 11 12 int main() 13 { 14 a = f; 15 a(); 16 a = g; 17 a(); 18 return 0; 19 } |
oyabun% gcc -o prog1 prog1.c oyabun% ./prog1 Hello Bye oyabun% |
関数へのポインターを配列に収めておくことも出来ます。
1 #include <stdio.h> 2 3 /* 引数を取らない void 型の関数の型を vvfunc と名づける */ 4 typedef void vvfunc(void); 5 6 void f(void) { printf("Hello\n"); } 7 8 void g(void) { printf("Bye\n"); } 9 10 int n = 0; 11 vvfunc *commands[10]; 12 13 void register_command(vvfunc *F) 14 { 15 commands[n++] = F; 16 } 17 18 void all_commands(void) 19 { 20 int i; 21 for (i = 0; i < n; i++) 22 commands[i](); 23 } 24 25 int main() 26 { 27 register_command(f); 28 register_command(g); 29 all_commands(); 30 return 0; 31 } |
oyabun% gcc -o prog2 prog2.c oyabun% ./prog2 Hello Bye oyabun% |
工夫すると、個々の関数に何かキー (ここでは文字) を対応させておいて、 そのキーで関数を呼び出すことが出来ます。 ここまで出来ると色々応用が効きます。
1 #include <stdio.h> 2 3 /* 引数を取らない void 型の関数の型を vvfunc と名づける */ 4 typedef void vvfunc(void); 5 6 void f(void) { printf("Hello\n"); } 7 8 void g(void) { printf("Bye\n"); } 9 10 /* --------------------------------------------------- */ 11 int n = 0; 12 vvfunc *commands[10]; 13 char keys[10]; 14 15 void register_command(vvfunc *F, char c) 16 { 17 keys[n] = c; 18 commands[n++] = F; 19 } 20 21 void command(char c) 22 { 23 int i; 24 for (i = 0; i < n; i++) 25 if (c == keys[i]) { 26 commands[i](); 27 return; 28 } 29 } 30 /* --------------------------------------------------- */ 31 32 int main() 33 { 34 register_command(f, 'H'); 35 register_command(g, 'B'); 36 command('H'); 37 command('B'); 38 return 0; 39 } |
oyabun% gcc -o prog3 prog3.c oyabun% ./prog3 Hello Bye oyabun% |
桂田 祐史