简体   繁体   English

C方法将函数作为参数传递给函数

[英]C Ways To Pass Function As Argument To Function

I've notices that there seem to be different ways to pass a function as a parameter to another function. 我注意到似乎有不同的方法将函数作为参数传递给另一个函数。 The prototypes are: 原型是:

void foo1(double f(double));

and

void foo2(double (*f)(double));

Is there a difference between the two? 这两者有区别吗? Are they implemented in the same way? 他们是以同样的方式实施的吗? Are there any other ways to pass functions? 有没有其他方法来传递函数?

The second is arguably the 'proper' way to write it. 第二种可以说是写“正确”的方式。 It says that the argument to foo1() is a pointer to a function. 它说foo1()的参数是一个指向函数的指针。 The first says that the argument is a function, but you can't pass functions as functions per se, so the compiler treats it as a pointer to function. 第一个说参数是一个函数,但你不能将函数本身作为函数传递,因此编译器将其视为函数的指针。 So, in practice, they are equivalent — in this context. 所以,在实践中,它们是等价的 - 在这种情况下。 But, in other contexts, you would not be able to use the double f(double); 但是,在其他情况下,你将无法使用double f(double); notation to declare a pointer to function. 声明指向函数的符号。

ISO/IEC 9899:2011 §6.7.6.3 Function declarators (including prototypes) ISO / IEC 9899:2011§6.7.6.3函数声明符(包括原型)

¶8 A declaration of a parameter as "function returning type " shall be adjusted to "pointer to function returning type ", as in 6.3.2.1. ¶8参数声明为“函数返回类型 ”应调整为“指向函数返回类型的指针”,如6.3.2.1所述。

Subsidiary question and answer 附属问答

Could you please give an example where double f(double); 你能举一个double f(double);的例子吗double f(double); wouldn't work? 不行吗?

#include <math.h>

double (*pointer)(double) = sin;
double function(double);   // This declares the existence of 'function()'

This is at file scope; 这是在文件范围; it could also be in a block of code, such as inside a function. 它也可以在代码块中,例如在函数内部。 The pointer to function notation works as you intend. 指向函数表示法的指针可以按预期工作。 The plain function simply declares a function — not variable that holds a pointer to function. plain函数只是声明一个函数 - 而不是保存指向函数的指针的变量。

The only places where the notations are (loosely) equivalent is inside a function argument list: 符号(松散地)等效的唯一位置是函数参数列表:

Declarations: 声明:

double integrate(double lo, double hi, double (*function)(double));
double differentiate(double lo, double hi, double function(double));

Definitions: 定义:

double integrate(double lo, double hi, double (*function)(double))
{
    ...
}

double differentiate(double lo, double hi, double function(double))
{
    ...
}

The function or function pointer parameters could be used interchangeably in these declarations and definitions, but only in the parameter list — not in the body of the function. 函数或函数指针参数可以在这些声明和定义中互换使用,但仅在参数列表中使用 - 而不是在函数体中。

Because the explicit 'pointer to function' notation works everywhere and the other notation only works in a very limited set of places, you should generally use the explicit 'pointer to function' notation, even though it is a little more verbose. 因为显式的“指向函数的指针”符号在任何地方都有效,而另一种符号只能在一组非常有限的地方工作,所以你通常应该使用显式的“指向函数的指针”表示法,即使它更加冗长。

Both methods declare the same parameter type. 两种方法都声明相同的参数类型。 There's no difference between the two whatsoever. 两者之间没有任何区别。 A parameter of function type is implicitly adjusted to pointer-to-function type, meaning that the first declaration is interpreted by the compiler as equivalent to the second one. 函数类型的参数被隐式调整为指向函数类型,这意味着编译器将第一个声明解释为等效于第二个声明。 It is a matter of personal preference, which one you want to use in your code. 这是个人偏好的问题,您希望在代码中使用哪一个。

Syntax to pass function as argument to function 将函数作为参数传递给函数的语法

typedef void (*functiontype)();

Declaring a function 声明一个函数

void dosomething() { }

functiontype func = &dosomething;
func();

these are library 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;

Example: 例:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM