等效紧凑的"开关案例"声明

Sha*_*han 3 c pointers function-pointers function switch-statement

我有一个包含数千或更多独特案例的switch case语句.用户很难通过案例编号记住每个案例.所以,我为每个case使用一个唯一的字符串并对其进行散列以获得给定字符串的选择'sel':

   % Example c code
   sel =hashfunction(string)
   switch (sel) {
     case 0:
          func0(); 

     case 1:
          func1();
     ......
     ......
    case 10000:
         func10000();
   }
Run Code Online (Sandbox Code Playgroud)

但是,此代码变得非常大,因为它必须在单个文件中,并且还违反了100行的编码准则.因为有一个唯一的情况映射到函数调用,我假设我可以使用指针在一个for循环中的函数来调用它们.这将比开关盒紧凑.非常感谢任何帮助实现这一目标.

net*_*der 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)();
}
Run Code Online (Sandbox Code Playgroud)

在这里,调用call_some_func(1)将执行func1()等.

为了使其工作,您需要链接dl库并导出可执行文件的符号.在GCC:

gcc source.c -Wall -ldl -rdynamic
Run Code Online (Sandbox Code Playgroud)

请记住,编译-rdynamic将增加可执行文件的大小.