void foo(int var, int var1)
{
printf("%d\n", var);
printf("%d\n", var1);
}
void foo_for_foo( void (*some_function)(int, int))
{
int x = 5;
some_function(x, x);
}
int main()
{
void (*ptr_foo); // <- look here
ptr_foo = &foo;
foo_for_foo(ptr_foo);
return 0;
}
如何定义指向函数的指针是否重要:
1) void (*ptr_foo);
2) void (*ptr_foo)(int, int);
我的编译器收到两个版本
事先感谢解释差异
答案 0 :(得分:6)
这两种形式并不相同。
void (*ptr_foo)
根本不是函数指针。这是一个普通的非函数void指针。括号是多余的和误导性的。就像你写过void* ptr_foo
一样。
void (*ptr_foo)(int, int)
是声明一个函数指针的正确方法,该函数指向一个函数,该函数占用两个int
并返回void
。
这有效的唯一原因是因为在C中,void
指针可以隐式转换为任何其他类型的指针。也就是说,您可以将任何其他指针指定给void*
,并且可以将void*
指定给任何其他指针。
但是,这个在这个例子中起作用的事实本质上是语法的意外。您通常无法将void (*foo)(int, int)
替换为void (*foo)
。
如果您尝试在some_function
的参数列表中使用foo_for_foo
执行此操作,则当您尝试调用some_function
时,编译器会抱怨,因为它不是函数指针。
同样,如果您的foo
函数碰巧返回int
而不是void
,您会立即发现问题。将ptr_foo
声明为int (*ptr_foo)
会导致语句ptr_foo = &foo
出错,因为与void
指针不同,int
指针不能隐式转换为其他指针类型。
简而言之,始终使用第二种形式。尽管存在这种不稳定的情况,但这是唯一一个正确的。
答案 1 :(得分:0)
语句void (*ptr_foo);
声明了void *
类型的变量。函数指针在语句ptr_foo = &foo;
中强制转换为此类型,并在调用foo_for_foo
时返回指向正确函数指针类型的指针。如果使用gcc -Wall
(或编译器支持的任何额外偏执设置)进行编译,您应该会看到有关此转换的警告。