传递函数指针

关于如何将指针传递给指针函数,我有点困惑。 我有一个函数,它指向一个我理解没有问题的函数(ExecBlock)。 但是我给了另一个函数原型(ExecBlock2),它接受了解引用指针(我不确定它到底是什么),如果传递函数有任何参数,也会接受参数。 如果有人可以解释优先级以及解释指针函数究竟会做什么。 这不仅仅是传递函数本身吗? 在这种情况下(void *)做什么?

int ExecBlock (void (*f) (void), int isSet) { return ExecBlock2( HOW TO PASS HERE? , NULL, isSet); } int ExecBlock2(void *(*f)(void *), void *arg, int isSet) { ... more code } 

谢谢!

 void (*f) (void) 

指向函数的指针,没有返回void的参数。

 void *(*f)(void *) 

表示函数获取void指针并返回void指针的指针。

由于类型不同,编译器不允许您在不进行强制转换的情况下将一个传递给另一个。 (请注意,在这里,强制转换并不是正确的答案,正如@detly指出的那样,会导致未定义的行为。)

至于解除引用函数的指针,你不必在函数指针之前显式地设置“*”来调用它。 例如,您可以通过执行来调用函数指针f

 f(); 

一个函数指针示例

假设您有一个函数f ,您希望将其传递给名为takes_a_function的函数。 takes_a_function可能会有类似的类型

 void takes_a_function(void (*f)(void *data), void *data); 

请注意takes_a_function ,函数指针和指向某些数据的void指针有两个参数。 另请注意,函数f碰巧将void指针作为参数。 我们的想法是你可以将数据传递给takes_a_function ,然后将它传递给f 。 例如, takes_a_function可以定义为

 void takes_a_function(void (*f)(void *), void *data) { f(data); } 

现在,让我们编写一个传递给takes_a_function的函数。 我们的函数只会打印一个传递给它的int。

 void prints_an_int(void *data) { // The idiom for converting a void pointer to another kind // of pointer. NO NEED TO CAST. Note this behavior is only // defined if the pointer data really does point to an int. int *i = data; printf("%d", *i); } int i = 0; takes_a_function(prints_an_int, &i); 

关于这个例子的几个关键点:

  • prints_an_intprints_an_int所期望的函数指针具有相同的类型。 不需要施放。
  • 无需使用&运算符来创建对函数的引用。 这就是为什么我们可以直接将prints_an_int传递给takes_a_function 。 但我们也可以说takes_a_function(&prints_an_int, &i) ,它会是一样的。
  • void*基本上是指“指向未知类型的指针”。 要实际执行任何操作,必须将void*类型的变量分配给您期望的类型的另一个指针变量。 如果你实际传入正确的指针类型,这只能保证工作! 在这个例子中,我们可以将data分配给int* ,因为数据确实指向了int。 如果你想要更多的数据而不仅仅是一个整数,一个常见的模式就是创建你自己的结构类型,它包含你想要的所有字段,然后传递它。
  • 作为一种特殊情况,编译器在将void指针分配给其他指针时不要求您进行强制转换,反之亦然。 但同样,如果最终将void指针转换回正确的类型,则只会获得已定义的行为。

例如,你有一个function

 void * abc(void *) { //... } 

 int ExecBlock (void (*f) (void), int isSet) { return ExecBlock2( abc , NULL, isSet); //use name of the function which have void * as parameter type list and return type void * } int ExecBlock2(void *(*f)(void *), void *arg, int isSet) { ... more code } 

请参阅函数指针