代码之家  ›  专栏  ›  技术社区  ›  andrewrk

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

  •  518
  • andrewrk  · 技术社区  · 16 年前

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

    6 回复  |  直到 6 年前
        1
  •  653
  •   andrewrk    9 年前

    宣言

    采用函数参数的函数的原型如下所示:

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

    这说明参数 f 将是指向具有 void 返回类型,需要一个 int 参数。以下功能( print )是可以传递给 func 作为参数,因为它是正确的类型:

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

    函数调用

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

    func(print);
    

    会打电话 芬克 ,将打印函数传递给它。

    功能体

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

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

    自从 芬克 的参数声明说 f 是指向所需函数的指针的名称,我们首先回忆一下 f 是指针,那么 *f 是这样的吗? f 指向(即功能 打印 在这种情况下)。因此,只需将上面循环中每次出现的打印内容替换为 *f :

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

    http://math.hws.edu/bridgeman/courses/331/f05/handouts/c-c++-notes.html

        2
  •  114
  •   roo    16 年前

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

    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 function 图书馆很棒,值得我们付出努力!

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

    比上面好多了。

        3
  •  52
  •   Richard    7 年前

    因为C++ 11,你可以使用 functional library 以一种简洁和一般的方式来做这件事。语法是,例如,

    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);
    }
    
        4
  •  12
  •   Yogeesh H T    9 年前

    通过 作为另一个函数参数的函数地址 如下所示

    #include <stdio.h>
    
    void print();
    void execute(void());
    
    int main()
    {
        execute(print); // sends address of print
        return 0;
    }
    
    void print()
    {
        printf("Hello!");
    }
    
    void execute(void f()) // receive address of print
    {
        f();
    }
    

    我们还可以使用 函数指针

    #include <stdio.h>
    
    void print();
    void execute(void (*f)());
    
    int main()
    {
        execute(&print); // sends address of print
        return 0;
    }
    
    void print()
    {
        printf("Hello!");
    }
    
    void execute(void (*f)()) // receive address of print
    {
        f();
    }
    
        5
  •  3
  •   Haacked    16 年前

    你需要通过 function pointer . 语法有点繁琐,但一旦熟悉它,它就非常强大。

        6
  •  0
  •   doppelheathen    6 年前

    函数可以作为函数指针“传递”,如6.7.6.3p8所示: 参数声明为函数返回类型应调整为指向函数返回类型的指针,如6.3.2.1所示。 “。例如,这:

    void foo(int bar(int, int));
    

    相当于:

    void foo(int (*bar)(int, int));