协慌网

登录 贡献 社区

如何在 C 中将函数作为参数传递?

我想创建一个函数,该函数对一组数据执行由参数传递的函数。如何在 C 中将函数作为参数传递?

答案

宣言

具有函数参数的函数原型如下所示:

void func ( void (*f)(int) );

这说明参数f将是一个指向具有void返回类型且采用单个int参数的函数的指针。以下函数( print )是一个函数的示例,可以将func ,因为它是正确的类型:

void print ( int x ) {
  printf("%d\n", x);
}

函数调用

使用函数参数调用函数时,传递的值必须是指向函数的指针。为此使用函数名称(不带括号):

func(print);

会调用func ,将 print 函数传递给它。

功能体

与任何参数一样, func现在可以在函数体中使用参数的名称来访问参数的值。假设func将应用传递给数字 0-4 的函数。首先,考虑一下直接调用 print 的循环是什么样的:

for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
  print(ctr);
}

由于func的参数声明说f是指向所需函数的指针的名称,因此我们首先回想一下,如果f是指针,则*f f指向的东西(即,在这种情况下print结果,只需将上面循环中所有出现的 print 替换为*f

void func ( void (*f)(int) ) {
  for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
    (*f)(ctr);
  }
}

来源

这个问题已经有了定义函数指针的答案,但是它们会变得非常混乱,特别是如果要在应用程序中传递它们的话。为避免这种不愉快,我建议您将函数指针键入 defdef 使其更具可读性。例如。

typedef void (*functiontype)();

声明一个返回 void 并且不带参数的函数。要创建指向该类型的函数指针,您现在可以执行以下操作:

void dosomething() { }

functiontype func = &dosomething;
func();

对于返回 int 并接受 char 的函数,您可以这样做

typedef int (*functiontype2)(char);

并使用它

int dosomethingwithchar(char a) { return 1; }

functiontype2 func2 = &dosomethingwithchar
int result = func2('a');

有一些库可以帮助将函数指针转换为可读的类型。 boost 函数库很棒,值得付出努力!

boost::function<int (char a)> functiontype2;

比上面的要好得多。

从 C ++ 11 开始,您可以使用功能库以简洁和通用的方式执行此操作。语法例如是

std::function<bool (int)>

其中bool是单参数函数的返回类型,该函数的第一个参数的类型为int

我在下面提供了一个示例程序:

// g++ test.cpp --std=c++11
#include <functional>

double Combiner(double a, double b, std::function<double (double,double)> func){
  return func(a,b);
}

double Add(double a, double b){
  return a+b;
}

double Mult(double a, double b){
  return a*b;
}

int main(){
  Combiner(12,13,Add);
  Combiner(12,13,Mult);
}

不过,有时使用模板函数会更方便:

// g++ test.cpp --std=c++11

template<class T>
double Combiner(double a, double b, T func){
  return func(a,b);
}

double Add(double a, double b){
  return a+b;
}

double Mult(double a, double b){
  return a*b;
}

int main(){
  Combiner(12,13,Add);
  Combiner(12,13,Mult);
}