Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中是否可以从数组调用函数?_C_Function_Mingw - Fatal编程技术网

在C中是否可以从数组调用函数?

在C中是否可以从数组调用函数?,c,function,mingw,C,Function,Mingw,当我制作终端时,我想知道是否可以通过数组调用函数。 (此代码尚未完成,因此请注意代码有点凌乱。) #包括 #包括 #包括 #包括 #包括 #包括 #定义真1 #定义false 0 typedef int bool; /*静止的*/ 静态字符输入[char_MAX]; 静态字符当前目录[char_MAX]; 静态字符*命令; 静态字符*参数; 静态字符*命令[]={“test”,“test2”}; /*功能*/ int Check_命令(); int测试(); int test2(); /* --

当我制作终端时,我想知道是否可以通过数组调用函数。 (此代码尚未完成,因此请注意代码有点凌乱。)

#包括
#包括
#包括
#包括
#包括
#包括
#定义真1
#定义false 0
typedef int bool;
/*静止的*/
静态字符输入[char_MAX];
静态字符当前目录[char_MAX];
静态字符*命令;
静态字符*参数;
静态字符*命令[]={“test”,“test2”};
/*功能*/
int Check_命令();
int测试();
int test2();
/* --------- */
int main(){
本月月月日日,本月月日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日################;
提示:
printf(“>”);
fgets(输入、字符最大值、标准输入);
int res=检查_命令();
如果(res==0){printf(“未知命令!\n”);}
转到提示;
}
/*Check_Command()函数如果不成功,则返回0,如果成功,则返回1*/
int Check_命令(){
//因为输入变量是静态的,所以不需要发送参数
输入[strcspn(输入,“\r\n”)]=0;
命令=strtok(输入“”);
参数=strtok(NULL,“”);
int x=0;

而(x似乎您希望能够从用户处接收字符串,例如
test2
,然后调用函数
test2()
。有两种主要方法可以实现这一点:

  • 将名称映射到函数指针的自制结构
  • 使用“动态库加载”和函数名解析
  • 结构阵列 对于第一种情况,您可以定义一种结构,例如:

    struct FuncName
    {
        const char *name;
        int (*function)(void);
    };
    
    然后,您可以定义以下内容的数组:

    struct FuncName functions[] =
    {
        { "test",  test  },
        { "test2", test2 },
    };
    enum { NUM_FUNCTIONS = sizeof(functions) / sizeof(functions[0]) };
    
    从用户处获得名称后,可以搜索名称数组并找到要调用的匹配函数指针

    int invoke_function(const char *name)
    {
        for (int i = 0; i < NUM_FUNCTIONS; i++)
        {
            if (strcmp(name, functions[i].name) == 0)
            {
                return (*functions[i].function)();
                // Or just: return functions[i].function();
            }
        }
        return -1;   // No match found
    }
    
    这省略了错误检查,您需要将强制转换从对象指针(
    void*
    )转换为函数指针,因为C标准不要求这样做,但POSIX要求这样做(请参见 已链接到)

    非一致函数签名 对于这两种解决方案,如果所有可调用函数都有相同的接口,那么生活就简单多了。如果不同的函数有不同的接口,生活就更混乱了(因此,有些函数不需要参数,有些函数需要参数,有些函数需要参数,有些函数需要参数,有些函数需要参数,而函数之间参数的类型也不同,返回类型也不同)。希望使用大量强制转换,并准备强迫编译器提交-将代码与其他内容隔离,以便将不可移植部分与主代码分离


    注意:没有向编译器咨询过这些代码的有效性!

    不要忘记
    sizeof
    运算符返回字节大小。这意味着循环条件
    xAs对于您的问题,请对函数指针进行一些研究,并可选地(但推荐)关于使用
    typedef
    的类型别名。这样,为要调用的函数创建第二个数组应该很容易。@OldProgrammer在我问这个问题之前,我碰到了这个答案,但我觉得它看起来不像我的答案。但我尊重你认为它是重复的想法。关于:
    定义true 1定义false 0 typedefint bool;
    最好只使用语句
    #include
    您需要
    函数[i].function()
    @CraigEstey:你说得很对-谢谢你的更正。“当心”脚注是有目的的;你的评论说明了这一目的。我已经建立了一个测试/工作版本,做了同样的事情。你发帖时我正在创建我的答案,所以我觉得没有必要重复。当我回家后,我会测试这个。是的,你的解决方案是Works!我有点意识到了,并尽最大努力不复制你的代码,因为我想学习一些新的东西。
    struct FuncName functions[] =
    {
        { "test",  test  },
        { "test2", test2 },
    };
    enum { NUM_FUNCTIONS = sizeof(functions) / sizeof(functions[0]) };
    
    int invoke_function(const char *name)
    {
        for (int i = 0; i < NUM_FUNCTIONS; i++)
        {
            if (strcmp(name, functions[i].name) == 0)
            {
                return (*functions[i].function)();
                // Or just: return functions[i].function();
            }
        }
        return -1;   // No match found
    }
    
    void *dlh = dlopen(NULL, RTLD_NOW);
    
    int (*funcptr)(void) = (int (*)(void))dlsym("test", dlh);
    
    return (*funcptr)();