構造体に関数を登録する & 関数の引数の個数はバラバラ
アセンブルのエミュレータを作る課題が出てます。
オペコードを分析して、その命令モジュールを実行という作業をスマートに行いたいので、
構造体に関数ポインタを保持して実行するテストプログラムを作ってみました。
#include <stdio.h> #include <stdarg.h> struct exesample_str{ int x; int (*execute)(int, ...); }; typedef struct exesample_str exesample; int func1(int a, int b, int c); int func2(int a, int b); int func3(int a); int main(void){ const exesample test[3] = { {3, func1}, {2, func2}, {1, func3}, }; int i; int tmp; for (i = 0; i < 3; i++){ switch(test[i].x){ case 3 : tmp = test[i].execute(5,4,3); break; case 2 : tmp = test[i].execute(5,4); break; case 1 : tmp = test[i].execute(5); break; default : tmp = -1; } printf("test[%d] -> %d\n",i,tmp); } return 0; } int func1(int a, int b, int c){ return a * b * c; } int func2(int a, int b){ return a + b; } int func3(int a){ return a; }
結果
$ gcc -Wall -o kahencho kahencho.c kahencho.c: In function `main': kahencho.c:19: warning: initialization from incompatible pointer type kahencho.c:20: warning: initialization from incompatible pointer type kahencho.c:21: warning: initialization from incompatible pointer type $ ./kahencho test[0] -> 60 test[1] -> 9 test[2] -> 5
おお、動いた。初めて関数ポインタ使ってみたけど簡単ですね。
関数の引数の個数はバラバラなので、可変長引数の関数ポインタを使ってみました。
warningが出てしまうので、もっといいやり方があるんでしょうけど。そこは課題としておきます。
参考リンク
第6回 構造体に「関数」を登録する | 日経 xTECH(クロステック)
http://www.ecl.sys.hiroshima-u.ac.jp/~shintaku/cpp_1-04.html