次のような宣言を含む構造体があります。
void (*functions[256])(void) //Array of 256 functions without arguments and return value
そして別の関数でそれを定義したいのですが、256の関数があります!私はこのようなことをすることができます:
struct.functions[0] = function0;
struct.functions[1] = function1;
struct.functions[2] = function2;
などなどですが、これは面倒です。私の質問は、このようなことを行う方法はありますか?
struct.functions = { function0, function1, function2, function3, ..., };
[〜#〜] edit [〜#〜]:ChrisLutzが言ったように構文エラーが修正されました。
次のような宣言を含む構造体があります。
いいえ、しません。これは構文エラーです。あなたが探しています:
_void (*functions[256])();
_
これは関数ポインタの配列です。ただし、void func()
は「引数を取らず何も返さない関数」ではないことに注意してください。これは、不特定の数またはタイプの引数を取り、何も返さない関数です。 「引数なし」が必要な場合は、次のようにする必要があります。
_void (*functions[256])(void);
_
C++では、void func()
doesは「引数を取らない」ことを意味し、混乱を引き起こします(特に、Cがvoid func()
に指定する機能は疑わしい値であるため)。
いずれにせよ、関数ポインタをtypedef
する必要があります。これにより、コードが非常に理解しやすくなり、構文が間違ってしまう可能性は1回だけです(typedef
で)。
_typedef void (*func_type)(void);
// ...
func_type functions[256];
_
とにかく、配列に割り当てることはできませんが、配列を初期化してデータをコピーすることはできます。
_static func_type functions[256] = { /* initializer */ };
memcpy(mystruct.functions, functions, sizeof(functions));
_
私は同じ問題を抱えていました、これは解決策をテストするための私の小さなプログラムです。とてもわかりやすいように見えるので、将来の訪問者のために共有したいと思いました。
#include <stdio.h>
int add(int a, int b) {
return a+b;
}
int minus(int a, int b) {
return a-b;
}
int multiply(int a, int b) {
return a*b;
}
typedef int (*f)(int, int); //declare typdef
f func[3] = {&add, &minus, &multiply}; //make array func of type f,
//the pointer to a function
int main() {
int i;
for (i = 0; i < 3; ++i) printf("%d\n", func[i](5, 4));
return 0;
}
あなたはそれを動的に行うことができます...これはmallocで割り当てられた動的関数配列の小さな例です...
#include <stdio.h>
#include <stdlib.h>
typedef void (*FOO_FUNC)(int x);
void a(int x)
{
printf("Function a: %d\n", x);
}
void b(int x)
{
printf("Function b: %d\n", x);
}
int main(int argc, char **argv)
{
FOO_FUNC *pFoo = (FOO_FUNC *)malloc(sizeof(FOO_FUNC) * 2);
pFoo[0] = &a;
pFoo[1] = &b;
pFoo[0](10);
pFoo[1](20);
return 0;
}
私の頭のてっぺんから、テストされていません。
// create array of pointers to functions
void (*functions[256])(void) = {&function0, &function1, &function2, ..., };
// copy pointers to struct
int i;
for (i = 0; i < 256; i++) struct.functions[i] = functions[i];
[〜#〜] edit [〜#〜]:ChrisLutzが言った構文エラーを修正しました。
post-{func1, func2, ...}
のようなフォームを使用して配列を初期化する場合、これは次の方法で実行できます(GCCを使用)。
[〜#〜] upd [〜#〜](ありがとう Chris Lutz コメント)
次のようなマクロを定義します。
#define FUNCTION_VECTOR_COPY(destVec, sourceVec) memcpy(destVec, sourceVec, sizeof(sourceVec))
そして、次のように Compound Literals を使用してソースベクトルを渡します。
#include <string.h>
...
void (*functions[256])();
...
FUNCTION_VECTOR_COPY (functions, ((void(*[])()) {func1, func2, func3}));
構造体インスタンスを宣言しながら、これを行うことができます。
function_structur fs = { struct_field1,
struct_field2,
{function0, function1, ..., function255},
struct_field3,
... };
配列が宣言された後、このショートカットを使用して配列を初期化することはできません。これを行う必要がある場合は、動的に行う必要があります(ループ、memcpy
などを使用)。