我有一堆C函数被分配给一个函数指针数组,按照以下几行:
typedef int (*func)(int);
int SomeLongName1(int a) {
// ...
}
// ...
int SomeLongName1000(int a) {
// ...
}
func f[] = { SomeLongName1, ... , SomeLongName1000 };
这是很多工作要创建并且容易出错。例如,函数名中可能存在拼写错误,使得有效函数仍然被命名,但错误的函数仍然存在。或者,如果最后添加了一个新函数,则可能会忘记进入并将其显式添加到函数指针列表中。
为了避免必须显式声明函数指针数组,我尝试了各种技巧,例如宏,这使得代码难以理解,并且需要知道宏如何工作,而且我通常对它们不满意。
我想做的是这样的事情:
typedef int (*func)(int);
func f[] = {
int SomeLongName1(int a) {
// ...
}
// ...
int SomeLongName1000(int a) {
// ...
}
};
这样,数组会自动创建,如果有一些方法可以在末尾放置一个空指针,那么我可以确定有多少函数指针也很好。
然而,上面的内容并不是有效的C,而且我会以任何方式完成此任务。如果它是编译器特定的(例如GCC扩展),那就没问题。
所有函数在编译时都是静态知道的,所以我想避免必须对函数指针数组进行任何运行时初始化 - 而不是我找到了一种方法来这样做。
这个相关的问题How to define an array of functions,似乎提出了同样的问题,但并未将其纳入其逻辑结论。具体来说,我不想重新键入我已输入的任何内容,以节省时间并避免错误。
答案 0 :(得分:4)
如果您不关心数组中函数的顺序,并且愿意使用GCC扩展,那么您可以使用一大堆初始化器(构造函数)函数来实现您想要的功能。这显然不是理想的,因为定义了额外的功能,但它肯定是你可以考虑的一种方法。它在运行时构造数组。
定义函数append
以将单个函数附加到数组(如果需要,可以重新分配)。然后,代码基本上是
#define ARRAYFUNC(name) int name(int); \
void __attribute__((constructor)) __init_##name(void) { append(func); } \
int name(int a)
ARRAYFUNC(func1) {
...
}
ARRAYFUNC(func2) {
...
}
答案 1 :(得分:3)
您可以使用C预处理器(X-Macros):
#include <stdio.h>
// define a list of function names and bodies
#define FUNCS \
FUNC(add, { return a+b; }) \
FUNC(mul, { return a*b; }) \
FUNC(div, { return a/b; })
// let the preprocessor make up the actual function implementations
#define FUNC(name, body) int name(int a, int b) body
FUNCS
#undef FUNC
typedef int (*func)(int, int);
// let the preprocessor populate the array of function pointers
func f[] = {
#define FUNC(name, body) name,
FUNCS
#undef FUNC
};
// use it:
int main () {
int a = 2, b = 3, i = 0;
for (; i < sizeof(f)/sizeof(*f); i++) {
printf("%d\n", f[i](a,b));
}
return 0;
}
输出结果为:
$ gcc test.c && ./a.out
5
6
0
答案 2 :(得分:2)
我认为没有其他办法可以做你想做的事。
你写的是什么
func f[] = { SomeLongName1, ... , SomeLongName1000 };
已经做了最好的事情。
也许你可以用前缀0000到1000来命名你的函数,这样你就可以确保每个函数都在函数指针数组中的正确位置。
另外,如果你真的有1000种不同的功能,它们肯定是共同的东西,可以引导你在几个数组中对它们进行排序,减少编号工作量,并且不易出错。
答案 3 :(得分:2)
我将用什么来解决这种情况(当然,当我无法避免它时),就是使用预处理。不是C预处理器提供的那个,它不提供合理语法所需的功能,而是一个非常强大的语法,如m4
。
使用m4
,您的代码可能如下所示:
define(`functionList', `, 0')
define(`functionArrayMember', `define(`functionList', `$1, 'FunctionList)$1')
define(`buildFunctionArray', `{ functionList }')
int functionArrayMember(SomeLongName1)(int a) {
return a+1;
}
//...
int functionArrayMember(SomeLongName1000)(int a) {
return a+1;
}
func f[] = buildFunctionArray();
您只需要为m4
和functionArrayMember()
提供正确的buildFunctionArray()
定义,并且您拥有所需的功能。