我对如何将指针传递给指针函数感到困惑。我有一个函数,它指向一个我理解没有问题的函数(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
}
答案 0 :(得分:37)
void (*f) (void)
表示指向函数的指针,没有返回void的参数。
void *(*f)(void *)
表示指向函数的指针,它接受一个void指针并返回一个void指针。
由于类型不同,编译器不允许您在不进行强制转换的情况下将其传递给另一个。 (请注意,在这里,强制转换并不是正确的答案,正如@detly指出的那样,会导致未定义的行为。)
至于解除引用函数的指针,您不必在函数指针之前显式地设置“*”来调用它。例如,您可以通过执行
来调用函数指针ff();
假设您有一个函数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_int
与takes_a_function
期望的函数指针具有相同的类型。无需施放。&
运算符来创建对函数的引用。这就是我们可以直接将prints_an_int
传递给takes_a_function
的原因。但我们也可以说takes_a_function(&prints_an_int, &i)
,它会是一样的。void*
基本上是指“指向未知类型的指针”。要实际执行任何操作,必须将类型为void*
的变量分配给您期望类型的另一个指针变量。如果您实际传入正确的指针类型,这只能保证工作!在此示例中,我们可以将data
分配给int*
,因为数据确实指向了int。如果你想要更多的数据而不仅仅是一个整数,一个常见的模式就是创建你自己的结构类型,其中包含你想要的所有字段,然后传递它。答案 1 :(得分:1)
例如,你有一个功能
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
}