【问题标题】:How to make a function which returns a function pointer in an array of function pointers如何在函数指针数组中创建一个返回函数指针的函数
【发布时间】:2021-07-02 08:14:58
【问题描述】:

我需要使用整数调用函数。 我真的是 C 语言的新手,函数指针非常混乱。

目标

  1. 我有这么多乱七八糟的函数,如果我把它们写在main.c 中,它们就会一团糟。
  2. 所以我把那些乱七八糟的函数写到另一个c文件messy_functs.c
  3. 在main.c 中,我需要选择其中一个杂乱的函数并调用它,这取决于从我的算法中获得的整数。这些函数通常需要两个参数,int input 和 int *output。
  4. 被调用函数会将结果存储在output 中,并作为指针传递

我的计划

  1. 在messy_functs.c 中,创建一个数组function_list[],其中包含全局范围内的函数指针。
  2. 在messy_functs.c。创建一个函数get_function_by_index(int function_index),它返回一个由参数索引的函数指针。
  3. 在main.c中,调用messy_function传递function_index,然后调用返回的函数传递两个参数int input和int *output得到结果。

问题

我的代码如下。但因错误而失败 error: too many arguments to function.。请忽略一些错别字。

// main.c
#include "messy_functs.h"
...

void get_result(int func_idx, int input, int *output)
{
    (*get_function_by_index(func_idx))(input, output);
}

int main() {
    int result, data, func_idx;

    ...

    func_idx, data = some_algorithm_i_made(~~);
    get_result(func_idx, data, &result);
    printf("Got the result %d\n", result);

}

============
// messy_functs.c
#define FUNCTION_NUM 100
const void (*function_list[FUNCITON_NUM])(int input, int *output) = {func1, func2, func3, func_m, func_qwer, func_abab, ...(many functions) };

void (*get_function_by_index(int func_id)){
    return function_list[func_id];
}

void func1(int input, int *output) {...}
void func2(int input, int *output) {...}
(... other functions)

我已尝试修复,但遇到了不同的错误,例如 void value not ignored as it ought to be。 我知道一定有其他好的帖子可以解决我的问题。我已经阅读了很多关于函数指针和函数指针数组的帖子,但无法做到。

【问题讨论】:

  • 就个人而言,我会回避使用函数指针,只需要一系列if 语句,适当地调用正确的函数。它更容易理解和阅读。根据我的经验,使用函数指针有意义的时候很少,特别是如果你是“C 语言的新手”
  • 如果你真的接受函数指针表的想法,回调和直接函数指针是指针类型别名(即在 typedef 别名中隐藏指针类型)仅有的两个地方之一实际上有帮助。您可能要考虑这一点。您不必必须这样做,但随着您的发现,代码可以很快变得非常神秘。
  • @MANA624 感谢您的友好评论。我一直在使用 Python,通常按名称或通过在列表中索引函数名称来调用函数。所以我有一些愿望以这种方式编写我的代码。但如果if 语句在 C 语言中更好,我会考虑它。如果我必须全部输入,我会打断我的手指。我想我已经使用 Python 生成了代码。
  • void (*get_function_by_index(int func_id))中的函数指针参数不用指定吗?所以像void (*get_function(int func_id))(int, int *)?
  • @WhozCraig 感谢您的友好评论。是不是像Wikipedia 中介绍的那样?

标签: c function-pointers


【解决方案1】:

数组的正确定义是:

void (* const function_list[FUNCITON_NUM])(int input, int *output) = ...

对于get_function_by_index 将是:

void (*get_function_by_index(int func_id))(int, int*)

在传递或返回函数指针时,非常为函数指针类型提供 typedef 以使其更易于管理。

typedef 可以在 messy_functs.h 中为函数指针类型创建:

typedef void (*messy_func)(int, int *);

然后在 messy_funct.c 中,对数组使用这个类型:

const messy_func function_list[FUNCITON_NUM] = {func1, func2, func3, func_m, ... };

对于get_function_by_index的返回类型

messy_func get_function_by_index(int func_id) {
    return function_list[func_id];
}

你可以这样调用这个函数:

void get_result(int func_idx, int input, int *output)
{
    get_function_by_index(func_idx)(input, output);
}

【讨论】:

  • 正如您所回答的,我使用 typedef 并修复了函数列表(可能错过了 qual '=',对吧?),并在 get_result 函数中调用了该函数。最后,它建立了!并且代码看起来更清晰。非常感谢!
  • @hskim 在几乎所有情况下,在 typedef 别名中隐藏指针类型都会适得其反,通常会使代码更难阅读、更难维护,并且没有最终的好处。只有两个合法的案例可以真正带来好处,而您的情况,函数指针管理,就是其中之一(另一个是黑盒句柄 API)。正如您从这个答案中看到的那样,在此处使用别名为代码带来了极大的清晰度。
  • @hskim 是的,缺少一个 =。这已经解决了。很高兴我能帮上忙。如果您觉得有用,请随时 accept this answer。
猜你喜欢
  • 2020-01-12
  • 2011-01-12
  • 2021-06-25
  • 2018-03-07
  • 2018-11-11
  • 1970-01-01
  • 2011-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多