関数へのポインターを変数に代入しておいて、その変数を用いて呼び出す、 ということが出来ます。
#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% |