我有一个包含数千个或更多独特案例的switch case语句。用户很难通过案例编号记住每个案例。所以,我为每个案例使用一个唯一的字符串并对其进行散列以获得给定字符串的选择'sel':
% Example c code
sel =hashfunction(string)
switch (sel) {
case 0:
func0();
case 1:
func1();
......
......
case 10000:
func10000();
}
但是,此代码变得非常大,因为它必须在单个文件中,并且还违反了100行的编码准则。因为有一个唯一的情况映射到函数调用,我假设我可以使用指针在一个for循环中的函数来调用它们。这将比开关盒紧凑。非常感谢任何帮助实现这一目标。
答案 0 :(得分:5)
如果每个函数具有相同的类型和命名约定,并且如果您使用的是POSIX,则可以使用动态链接加载器来计算要调用的函数的名称并动态执行它。
每个例子:
#include <stdio.h>
#include <dlfcn.h>
typedef void (*funcptr)(void);
void func1(void) {
printf("in func1");
}
void func2(void) {
printf("in func2");
}
void call_some_func(int sel) { /* where sel is the return val of hashfunction */
void* dl = dlopen(NULL, RTLD_LAZY);
if (dl == NULL) { /* handle error */ }
char sym_name[64];
snprintf(sym_name, sizeof sym_name, "func%d", sel);
void* sym = dlsym(dl, sym_name);
if (sym == NULL) { /* handle error */ }
((funcptr)sym)();
}
此处,调用call_some_func(1)
将执行func1()
等等。
为了使其正常工作,您需要链接dl
库并导出可执行文件的符号。在海湾合作委员会:
gcc source.c -Wall -ldl -rdynamic
请记住,使用-rdynamic
进行编译会增加可执行文件的大小。
答案 1 :(得分:3)
如果所有的情况都是简单的函数调用[希望不叫func1,func2,func3等],那么我相信一个长的switch语句是解决这个问题最干净,最简单的方法。编码标准是该死的 - 在我的书中,它不够复杂,不值得做其他事情。
另一个选择是构建一个函数指针数组(PaulR的建议):
我假设你的例子对于不带参数的函数是正确的,所以:
typedef void (*funcptr)(void);
funcptr funcarr[10000] = { func1, func2, .... func9999, func10000 };
// If coding standard allows 10 initializations on a row, you can even do it
// in 102 lines.
sel = hashfunction(string);
funcarr[sel](); // Calls the function.