それぞれが多くの関数を指す3つの関数配列があります。
3つのテーブルからこれらの関数を呼び出すことができます。
今、私は3つの配列を関数ポインタの単一の配列に逆参照したいと思いますが、私はそれを動作させることができません!
void afunc1(void);
void afunc2(void);
void afunc3(void);
void bfunc1(void);
void bfunc2(void);
void bfunc3(void);
void cfunc1(void);
void cfunc2(void);
void cfunc3(void);
void(*FuncTbla[])(void) = { afunc1, afunc2, afunc3 };
void(*FuncTblb[])(void) = { bfunc1, bfunc2, bfunc3 };
void(*FuncTblc[])(void) = { cfunc1, cfunc2, cfunc3 };
void (*AllFuncTbls[])(void) = { &FuncTbla, &FuncTblb, &FuncTblc };
int TblNo = 1, FuncNo = 1; // tblNo 1 = table b
bFunc2(); // calls bFunc2 directly
FuncTblb[FuncNo](); // Calls Function bFunc2 via function table b
// Call same function using table of function tables
AllFuncTbls[TblNo][FuncNo](); // Does not compile - expression must be a pointer to a complete object type!!!
回答 3 件
2つのこと:まず最初に、配列は最初の要素へのポインターに自然に減衰することを覚えておいてください。次に、関数型に型エイリアスを使用すると、非常に簡単になります。
その知識があれば、たとえば
// Type-alias to simplify using function pointers typedef void (*function_type)(void); // The three tables function_type FuncTbla[] = { &afunc1, &afunc2, &afunc3 }; function_type FuncTblb[] = { &bfunc1, &bfunc2, &bfunc3 }; function_type FuncTblc[] = { &cfunc1, &cfunc2, &cfunc3 }; // A table of pointers to the first elements of each array function_type *AllFuncTbls[] = { FuncTbla, FuncTblb, FuncTblc };
AllFuncTbls
を使用して関数を呼び出すには と同じくらい簡単ですAllFuncTbls[TblNo][FuncNo]();
typedefを使用する場合、動作します:
void afunc1(void); // ... typedef void (*funcPtr)(void); // void(*FuncTbla[])(void) = { afunc1, afunc2, afunc3 }; // ... funcPtr FuncTbla[] = { afunc1, afunc2, afunc3 }; funcPtr FuncTblb[] = { bfunc1, bfunc2, bfunc3 }; funcPtr FuncTblc[] = { cfunc1, cfunc2, cfunc3 }; //void (*AllFuncTbls[])(void) = { &FuncTbla, &FuncTblb, &FuncTblc }; funcPtr* AllFuncTbls[] = { FuncTbla, FuncTblb, FuncTblc }; // Use an Array of pointers to function pointers here, not an array of function pointers! // ... // Call same function using table of function tables AllFuncTbls[TblNo][FuncNo](); // Compiles now
変更する必要がある行をコメントアウトしました。
typealiasesを使用することはより良いアプローチですが、もしあなたがそれなしでそれをする方法に興味があるなら: