将具有两个参数的函数传递给接受具有一个参数的函数的函数作为C中的输入

Passing a function with two parameters into a function that accepts a function with one parameter as input in C

我正在用 C 编写代码。我想将接受两个参数并将一个参数设置为一个值的函数传递给接受一个参数作为输入的函数的函数。

void fTwoParameters( float a, float b ){
}

void outerFunction( void (*fOneParameter)(float) ){
}

void main( void ){
  // How can I do that?
  for( int i=1, i<1000, i++ ){
    // I would like to pass fTwoParameters into outerFunction with b set to the value of i
    outerFunction( /* Problem is Here */ )
  }
}

我认为这可以用全局变量来完成。有没有不用全局变量的方法?

outerFunction is an optimization function called binary search. It optimizes an objective function of one parameter. I have an objective function of two parameters. I want to iterate over the second parameter and for each value, perform binary search to determine the optimal first parameter. That is, I want to do an exhaustive search over the second parameter. Thoughts?

从一开始就明确这一点可以避免任何混淆。

你不能(即使是全局变量也不行)。如果您无法更改 outerFunctionfTwoParameters 的代码,那么您必须自己创建一个新的不同函数。


旧答案

你不能。 C 不允许传递与函数签名中定义的类型不同的类型。无论你想用它实现什么,你都需要以不同的方式来实现。

例如,您可以创建一个带有附加参数的通用函数来指示参数的数量(在这种情况下将函数转换为 void (*)(void)):

void outerFunction(unsigned nargs, void (*funcptr)(void)) {
    if (nargs == 1) {
        void (*realfunc)(float) = (void (*)(float))funcptr;
        realfunc(1.0);
    } else if (nargs == 2) {
        void (*realfunc)(float, float) = (void (*)(float, float))funcptr;
        realfunc(1.0, 2.0);
    } /* ... */
}

虽然你真的不需要传递函数。您可以使用您想要的任何第二个参数从另一个函数(或 main)调用它。


针对您的编辑,您只需执行以下操作:

void outerFunction(void (*funcptr)(float, float), float b) {
    funcptr(1, b);
}

for (int i = 1; i < 1000; i++){
    outerFunction(fTwoParameters, i);
}

甚至:

for (int i = 1; i < 1000; i++){
    fTwoParameters(1, i);
}

没有真正需要传递任何函数指针。您应该创建一个更好的示例来解释您 真正 尝试做的事情以及为什么这样做有意义,因为从您当前的问题来看,它确实没有意义。这看起来像 XY problem.

不幸的是,标准 C 在这里帮不了你太多。您 可以 设置一个全局变量,尽管这往往会使程序更难理解。

解决此问题的标准方法是确保您定义的任何函数 outer 接受指向另一个函数 inner 的指针,接受刚传递给 inner。 (这个参数通常是 void*,特别是在库的情况下,这样它就可以传递任何东西。)

int inner(int x, void* user_data) {
  int y = *((int*)user_data);
  return x * y;
}

int outer(int (*inner)(int, void*), void* user_data) {
  return inner(42, user_data);
}

int main(void) {
  int y = 17;
  return outer(&inner, &y);
}

如果您使用的是 GCC,则可以使用嵌套函数,但请注意,这些函数是 GNU 扩展,可能不适用于其他编译器。

float twoParameters(float a, float b) {
  return a * b;
}

void main(void) {
  const float a = 42.0;

  float oneParameter(float b) {
    return twoParameters(a, b);
  }

  outerFunction(&oneParameter);
}