将成员C函数指针与另一个成员一起指定为默认参数

时间:2016-10-26 10:58:11

标签: 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;
}

在主要内容中,我想指定 multiply-> get 一个函数来计算乘以>乘以和新参数的乘积。我可以通过传递一个指向乘法实例的指针来做到这一点,但我想知道是否有任何方法可以在不改变 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(在本例中)。几乎Tomasz Lewowski建议的内容。

2 个答案:

答案 0 :(得分:1)

不,你不能在C中做那样的闭包。

您也不能运行时定义函数,因为C是一种编译语言,当代码运行时编译器不可用。

答案 1 :(得分:1)

通常C不支持部分函数应用程序,并且您需要在编译时设置所有签名和名称,并且函数通常无法在运行时定义(内核可以加载它们,但让我们忽略它 - 用户空间应用程序不做它)。然而...

在某种程度的抽象这是可能的(例如,用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,{ {1}}或者你想要调用它),这有点混淆代码。

如果您在没有任何其他参数的情况下过于坚定地执行此操作,则可以创建一个全局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); 中的值,你通过m的所有地方将开始表现不同(以前,面向对象的方法将适用于所有地方)。