C:如何将单个函数指针数组用于具有可变参数计数的函数?

发布于 2024-12-08 16:43:59 字数 466 浏览 1 评论 0原文

这个问题几乎说明了一切。

我不知道如何做到这一点,并且还没有接近任何有效的方法。

这里有一些示例函数:

add(int x, int y) {
  return x+y;
}

并且,

mean(int x1, int y1, int x2, int y2) {
  return (x1 + y1 + x2 + y2) / 4;
}

到目前为止,我已经尝试将 typedef 与两者一起使用,但我不知道如何使某些内容指向任一类型:

typedef int (*mathfunc2)(int x, int y);
typedef int (*mathfunc4)(int x1, int y1, int x2, int y2);

????? func_table[2] = {add, mean};

The question pretty much says it all.

I'm not sure how to do this and haven't come anywhere near anything that works.

Here's some example functions:

add(int x, int y) {
  return x+y;
}

and,

mean(int x1, int y1, int x2, int y2) {
  return (x1 + y1 + x2 + y2) / 4;
}

So far I've tried using typedef with both, but I can't figure how to make something point to one of either type:

typedef int (*mathfunc2)(int x, int y);
typedef int (*mathfunc4)(int x1, int y1, int x2, int y2);

????? func_table[2] = {add, mean};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

兔小萌 2024-12-15 16:43:59

您需要选择一个函数指针类型用作“通用函数指针”,使用该类型来定义数组,并使用显式强制转换。将一种函数指针类型转换为另一种函数指针类型,然后再转换回来,可以保证保留该值。

换句话说:

typedef int (*generic_fp)(void);

generic_fp func_table[2] = { (generic_fp)add, (generic_fp)mean };

然后调用add,你需要将其转换回正确的类型:

result = ((mathfunc2)func_table[0])(x, y);

如果你觉得它更容易接受,你可以定义一些宏:

#define FUNC_2(f, p1, p2) ((mathfunc2)(f))(p1, p2)
#define FUNC_4(f, p1, p2, p3, p4) ((mathfunc4)(f))(p1, p2, p3, p4)

result = FUNC_2(func_table[0], x, y);

You need to pick a function pointer type to use as a "generic function pointer", use that type to define your array, and use explicit casts. Casting one function pointer type to another and then back again is guaranteed to preserve the value.

In other words:

typedef int (*generic_fp)(void);

generic_fp func_table[2] = { (generic_fp)add, (generic_fp)mean };

Then to call add, you need to cast it back to the right type:

result = ((mathfunc2)func_table[0])(x, y);

You can define some macros if you find it more palatable:

#define FUNC_2(f, p1, p2) ((mathfunc2)(f))(p1, p2)
#define FUNC_4(f, p1, p2, p3, p4) ((mathfunc4)(f))(p1, p2, p3, p4)

result = FUNC_2(func_table[0], x, y);
川水往事 2024-12-15 16:43:59

您可以像这样使用 外观模式

int add(int x, int y);
int mean(int x1, int y1, int x2, int y2);

typedef int (*operation_fp)(int argc, int* argv);

int add_wrapper(int argc, int* argv) { return add(argv[0], argv[1]); }
int mean_wrapper(int argc, int* argv) { return mean(argv[0], argv[1], argv[2], argv[3]); }

operation_fp func_table[2] = { add_wrapper, mean_wrapper };

虽然代码很丑陋,但它可以完成工作。您应该在包装器中添加一些验证逻辑。

You could use the Facade Pattern like this:

int add(int x, int y);
int mean(int x1, int y1, int x2, int y2);

typedef int (*operation_fp)(int argc, int* argv);

int add_wrapper(int argc, int* argv) { return add(argv[0], argv[1]); }
int mean_wrapper(int argc, int* argv) { return mean(argv[0], argv[1], argv[2], argv[3]); }

operation_fp func_table[2] = { add_wrapper, mean_wrapper };

Although the code is ugly, it does the job. You should add some validation logic in wrappers.

篱下浅笙歌 2024-12-15 16:43:59
int (*func[])() = { add, mean };
int (*func[])() = { add, mean };
夏至、离别 2024-12-15 16:43:59

这两种函数类型不兼容。严格来说,它们可以使用完全不同的参数传递来实现。例如,实现可能会选择所有最多具有 3 个参数的函数通过寄存器接收它们,而所有其他函数通过堆栈接收它们。

不过,您可以做的是使用 varargs 参数定义两个函数,以使它们遵循相同的参数传递方案。

无论如何,您打算如何调用这些函数,而不知道它们需要多少个参数?

These two function types are incompatible. Strictly speaking, they could be implemented using completely different argument passing. An implementation might choose, for example, that all functions with up to 3 parameters receive them via registers, and all other functions receive them via the stack.

What you can do though is to define both functions with varargs parameters to make them follow the same parameter passing scheme.

How did you intend to call these functions anyway, not knowing how many parameters they expect?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文