你能用C指定参数值的函数指针吗?

Etw*_*wus 14 c function-pointers

我想指向类似的东西add(2, 1)然后调用它而不需要指定参数.有没有办法用函数指针做到这一点?

Gre*_*con 18

作为对你的问题的评论,Basile Starynkevitch建议阅读关于闭包的内容.从本质上讲,一个闭包结合了一个被调用的函数和一些上下文,在文献中称为函数的环境.

面向对象的语言具有类似的概念,称为委托,其中特定实例可以成为稍后调用的环境,其中调用站点不直接了解底层对象.支持闭包的语言本身自动捕获或"关闭"环境中提供的绑定.这似乎是一种奇怪的语言特征,但它可以表达和有用,因为你的问题背后的动机暗示.

下面是在C程序中工作的闭包概念的一个简单示例,由程序员明确指示捕获.

你想最终调用的函数加上一些前面的事情是

#include <stdio.h>

int
add_two_numbers(int a, int b)
{
  return a+b;
}
Run Code Online (Sandbox Code Playgroud)

闭包是一种与其环境相结合的函数.在C中,要调用的函数是指向函数的指针.注意f与那些参数对齐的参数add_two_numbers.

typedef struct {
  struct {  /* environment */
    int a;
    int b;
  } env;

  int (*f)(int, int);  /* function to be called */
} closure;
Run Code Online (Sandbox Code Playgroud)

我们想创建一个闭包,即设置参数值的关联,以便在我们准备好时调用要调用的函数.在这个简单的例子中,make_adder留下了为其调用者分配闭包空间的问题.

void
make_adder(int a, int b, closure *c)
{
  c->env.a = a;
  c->env.b = b;
  c->f = add_two_numbers;
}
Run Code Online (Sandbox Code Playgroud)

既然您知道如何创建我们的简单闭包之一,那么您可以调用或调用它

int invoke_closure(closure *c)
{
  return c->f(c->env.a, c->env.b);
}
Run Code Online (Sandbox Code Playgroud)

最后,用法看起来像

int main(void)
{
  closure c;
  make_adder(2, 1, &c);

  printf("The answer is %d.\n", invoke_closure(&c));

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出

The answer is 3.

进一步阅读

  • 有些人称C接力棒是一种密切相关的技术.所以,如果你看到`void*baton`那就是它. (2认同)

R S*_*ahu 9

虽然简短的回答是"不",但有办法完成你想做的事情.

要记住的第一件事是add需要两个参数.无论你做什么,你都必须提供两个参数.

要记住的第二件事是,如果你想打电话,最终调用一个函数add(2, 1),你必须有存储或硬编码的值2,并1让他们的地方可以使用.

我能想到有几种方法可以做到这一点.

  1. 创建一个包装函数,调用add(2, 1)并让代码调用包装函数.

    int add2And1()
    {
       return add(2, 1);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    然后add2And1在你的通话中使用.

  2. 创建依赖于全局数据的包装函数.在使用包装函数之前先设置全局数据.

    int param1 = 0;
    int param2 = 0;
    
    
    int addParams()
    {
       return add(param1, param2);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    然后使用:

    param1 = 2;
    param2 = 1;
    
    Run Code Online (Sandbox Code Playgroud)

    在调用之前的代码中addParams.


bol*_*lov 6

int add(int a, int b) { return a + b; }
Run Code Online (Sandbox Code Playgroud)

不,你不能指向add具有指定参数值的指针.但是你可以这样做:

int add_2_1() { return add(2, 1); }
Run Code Online (Sandbox Code Playgroud)

但我不明白这有多大帮助......