A..2 コマンドを登録して呼び出す

関数へのポインターを変数に代入しておいて、その変数を用いて呼び出す、 ということが出来ます。


#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% 



桂田 祐史