c - 将成员 C 函数指针分配给另一个成员作为默认参数

标签 c function pointers struct function-calls

假设我有一个 C 结构

struct MULTIPLY{
   int by;            //some factor to multiply, can be seen as instance id/key
   int (*get)(int c); //the function that actually returns the result
} multiply;

并且我想使用以下函数分配 multiply 实例

int product(int a, int b)
{
    return a*b;
}

在 main 中,我想为 multiply->get 分配一个计算 multiply->by 和一个新参数的乘积的函数。我可以通过传递一个指向乘法实例的指针来做到这一点,但我想知道是否有任何方法可以在不更改 get 函数的签名的情况下调用它

multiply->by = 2;
multiply->get(int c) = product(multiply->by, c); ???

multiply->get(5); // 10

谢谢!

编辑:

感谢您的回答。实际上,默认情况下无法在 C 中执行闭包。我一直在寻找解决方法。我找到了 2 个解决方案,但非常有限。一个是 Blocks.h(也适用于 obj-C)需要用 Clang 编译。另一个是 FFCALL ( http://www.haible.de/bruno/packages-ffcall-README.html ),它仅限于某些处理器架构。

因此,在我的例子中,我决定只传递一些指针来访问 id(在本例中为 by)。几乎什么Tomasz Lewowski建议。

最佳答案

一般C不支持partial function application,你需要在编译时设置所有的签名和名字,函数一般不能在运行时定义(内核可以加载它们,但我们忽略它 - 用户空间应用程序不这样做它)。然而……

在某种抽象层次上这是可能的(例如,许多用 C 编写的解释器允许这样做),但对于纯 C 来说,这不是直接可能的,如果你需要这样做,你可能会选择一种错误的语言。

您可以通过模拟面向对象的方法(始终将另一个参数作为 this 指针传递)来解决它。伪代码:

struct MULTIPLY{
   int by;            //some factor to multiply, can be seen as instance id/key

   // intended private
   int (*f)(int, int);
} multiply;

int call(MULTIPLY m, int i) {
  return *(m.f)(by, i);
}

MULTIPLY m = {2, product} // + allocation etc.;
call(m, 5); // actual call

它在真正支持面向对象设计的语言中要好得多,但你也可以在 C 中做到这一点 - 不过,你需要记住这个额外的参数(thiscontext self 或者你想怎么调用它),这有点搞乱了代码。

如果您下定决心不使用任何其他参数来执行此操作,则可以创建一个全局 MULTIPLY 实例并在 call 中使用它。这将是这样的:

// global scope!
MULTIPLY m;
int call(int i) {
    return *(m.f)(m.by, i);
}

// m initialization etc.
// some stuff happening
call(5);

但是,请不要。由于全局绑定(bind),维护起来会非常困难。另外,它不会完全像闭包一样工作——一旦你改变了 m 中的值,你通过 call 的所有地方都会开始表现不同(之前,对象面向的方法将在任何地方正常工作)。

关于c - 将成员 C 函数指针分配给另一个成员作为默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40260484/

相关文章:

c - 如何从c中的套接字读取回复?

c++ - 在 C++ 中声明一个函数指针数组

c++ - 删除具有指针列表的对象并不能真正释放相应的内存

java - 检查 EditText 内容中的特定字符串

c++ - 实现树结构最安全的方法是什么?

c++ - 简单的 C++ 指针转换

c - 具有不同种子的PRNG序列会在C中重叠吗

C线程打印数字序列: with even and odd number printing threads running parallely

java - C JNI 帮助处理复杂代码

javascript - 使用 Javascript 从 onClick 更新数据库