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

时间:2022-02-06 21:49:16

I want to create a function that performs a function passed by parameter on a set of data. How do you pass a function as a parameter in C?

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

5 个解决方案

#1


601  

Declaration

宣言

A prototype for a function which takes a function parameter looks like the following:

一个函数的原型,它接受一个函数参数如下:

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

This states that the parameter f will be a pointer to a function which has a void return type and which takes a single int parameter. The following function (print) is an example of a function which could be passed to func as a parameter because it is the proper type:

这说明参数f将是一个指向具有空返回类型的函数的指针,该函数只接受一个int参数。下面的函数(print)是一个函数的例子,它可以作为参数传递给func,因为它是合适的类型:

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

Function Call

函数调用

When calling a function with a function parameter, the value passed must be a pointer to a function. Use the function's name (without parentheses) for this:

当使用函数参数调用函数时,传递的值必须是指向函数的指针。使用函数的名称(没有括号):

func(print);

would call func, passing the print function to it.

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

Function Body

函数体

As with any parameter, func can now use the parameter's name in the function body to access the value of the parameter. Let's say that func will apply the function it is passed to the numbers 0-4. Consider, first, what the loop would look like to call print directly:

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

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

Since func's parameter declaration says that f is the name for a pointer to the desired function, we recall first that if f is a pointer then *f is the thing that f points to (i.e. the function print in this case). As a result, just replace every occurrence of print in the loop above with *f:

由于func的参数声明说f是指向所需函数的指针的名称,所以我们首先回想一下,如果f是一个指针,那么*f就是f指向的对象(即在本例中打印的函数)。因此,只需将上面循环中出现的每次打印替换为*f:

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

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

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

#2


104  

This question already has the answer for defining function pointers, however they can get very messy, especially if you are going to be passing them around your application. To avoid this unpleasantness I would recommend that you typedef the function pointer into something more readable. For example.

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

typedef void (*functiontype)();

Declares a function that returns void and takes no arguments. To create a function pointer to this type you can now do:

声明返回void且不接受参数的函数。要创建指向该类型的函数指针,您现在可以:

void dosomething() { }

functiontype func = &dosomething;
func();

For a function that returns an int and takes a char you would do

对于返回int并获取char的函数,可以这样做

typedef int (*functiontype2)(char);

and to use it

和使用它

int dosomethingwithchar(char a) { return 1; }

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

There are libraries that can help with turning function pointers into nice readable types. The boost function library is great and is well worth the effort!

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

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

is so much nicer than the above.

比上面的好多了。

#3


41  

Since C++11 you can use the functional library to do this in a succinct and generic fashion. The syntax is, e.g.,

由于c++ 11,您可以使用函数库以一种简洁而通用的方式来实现这一点。语法是,例如,

std::function<bool (int)>

where bool is the return type here of a one-argument function whose first argument is of type int.

这里bool是一个单参数函数的返回类型,它的第一个参数是int类型。

I have included an example program below:

下面是一个示例程序:

// 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);
}

Sometimes, though, it is more convenient to use a template function:

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

// 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


7  

Pass address of a function as parameter to another function as shown below

将函数的地址作为参数传递给另一个函数,如下所示

#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();
}

Also we can pass function as parameter using function pointer

我们还可以使用函数指针传递函数作为参数

#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


2  

You need to pass a function pointer. The syntax is a little cumbersome, but it's really powerful once you get familiar with it.

您需要传递一个函数指针。语法有点麻烦,但是一旦你熟悉了它,它就会变得非常强大。

#1


601  

Declaration

宣言

A prototype for a function which takes a function parameter looks like the following:

一个函数的原型,它接受一个函数参数如下:

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

This states that the parameter f will be a pointer to a function which has a void return type and which takes a single int parameter. The following function (print) is an example of a function which could be passed to func as a parameter because it is the proper type:

这说明参数f将是一个指向具有空返回类型的函数的指针,该函数只接受一个int参数。下面的函数(print)是一个函数的例子,它可以作为参数传递给func,因为它是合适的类型:

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

Function Call

函数调用

When calling a function with a function parameter, the value passed must be a pointer to a function. Use the function's name (without parentheses) for this:

当使用函数参数调用函数时,传递的值必须是指向函数的指针。使用函数的名称(没有括号):

func(print);

would call func, passing the print function to it.

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

Function Body

函数体

As with any parameter, func can now use the parameter's name in the function body to access the value of the parameter. Let's say that func will apply the function it is passed to the numbers 0-4. Consider, first, what the loop would look like to call print directly:

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

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

Since func's parameter declaration says that f is the name for a pointer to the desired function, we recall first that if f is a pointer then *f is the thing that f points to (i.e. the function print in this case). As a result, just replace every occurrence of print in the loop above with *f:

由于func的参数声明说f是指向所需函数的指针的名称,所以我们首先回想一下,如果f是一个指针,那么*f就是f指向的对象(即在本例中打印的函数)。因此,只需将上面循环中出现的每次打印替换为*f:

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

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

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

#2


104  

This question already has the answer for defining function pointers, however they can get very messy, especially if you are going to be passing them around your application. To avoid this unpleasantness I would recommend that you typedef the function pointer into something more readable. For example.

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

typedef void (*functiontype)();

Declares a function that returns void and takes no arguments. To create a function pointer to this type you can now do:

声明返回void且不接受参数的函数。要创建指向该类型的函数指针,您现在可以:

void dosomething() { }

functiontype func = &dosomething;
func();

For a function that returns an int and takes a char you would do

对于返回int并获取char的函数,可以这样做

typedef int (*functiontype2)(char);

and to use it

和使用它

int dosomethingwithchar(char a) { return 1; }

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

There are libraries that can help with turning function pointers into nice readable types. The boost function library is great and is well worth the effort!

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

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

is so much nicer than the above.

比上面的好多了。

#3


41  

Since C++11 you can use the functional library to do this in a succinct and generic fashion. The syntax is, e.g.,

由于c++ 11,您可以使用函数库以一种简洁而通用的方式来实现这一点。语法是,例如,

std::function<bool (int)>

where bool is the return type here of a one-argument function whose first argument is of type int.

这里bool是一个单参数函数的返回类型,它的第一个参数是int类型。

I have included an example program below:

下面是一个示例程序:

// 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);
}

Sometimes, though, it is more convenient to use a template function:

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

// 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


7  

Pass address of a function as parameter to another function as shown below

将函数的地址作为参数传递给另一个函数,如下所示

#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();
}

Also we can pass function as parameter using function pointer

我们还可以使用函数指针传递函数作为参数

#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


2  

You need to pass a function pointer. The syntax is a little cumbersome, but it's really powerful once you get familiar with it.

您需要传递一个函数指针。语法有点麻烦,但是一旦你熟悉了它,它就会变得非常强大。