正确的方法来定义函数的指针

时间:2010-09-28 22:11:55

标签: c

大家,我有这段代码:

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

我的编译器收到两个版本

事先感谢解释差异

2 个答案:

答案 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(或编译器支持的任何额外偏执设置)进行编译,您应该会看到有关此转换的警告。