有人可以解释为什么“void func_dec(void(*)(int)funcptr);”是非法的

时间:2017-01-04 08:50:37

标签: c function-pointers function-declaration

当声明一个将函数指针作为参数的函数时,如下所述,编译器会抛出错误。

 void func_dec(int x, void(*)() funcptr);

虽然它接受以下声明,

 void func_dec(int x, void(*funcptr)());

为什么编译器无法识别前一个声明,尽管它看似合乎逻辑。

3 个答案:

答案 0 :(得分:2)

这是非法的,因为语言标准中的正式定义是这样说的。至于它是这样的原因,它真的看起来很模糊,这里是:

来自The New C Standard: An Economic and Cultural Commentary (v 1.2 from June 24, 2009, section 6.7 Declarations)

  

此语法的目的是使标识符的声明符具有   与该标识符的实例相同的视觉外观   表达。例如,在:

     

int x [3],* y,z(void);

     

char(* f(int))[];

     

标识符x可能会作为索引显示在源中   数组,y作为解除引用的指针,z作为函数调用。一个   使用f调用结果的表达式示例   (* F(42))[1]。

同样来自The Development of the C Language by Dennis M. Ritchie

  

因此,

     

int i,* pi,** ppi;

     

声明一个整数,一个指向整数的指针,a   指向整数指针的指针。这些声明的语法   反映了i,* pi和** ppi都产生int类型的观察结果   在表达式中使用时。类似地,

     

int f(),* f(),(* f)();

     

声明   返回一个整数的函数,一个返回指针的函数   整数,指向返回整数的函数的指针;

     

int * api [10],(* pai)[10];

     

声明一个指向整数的指针数组,以及指向的指针   一个整数数组。在所有这些情况下,变量的声明   类似于在表达式中的用法,该表达式的类型是以   声明的负责人。

答案 1 :(得分:1)

这是因为,

 void(*)() funcptr

的语法无效。

在编写函数声明时,只需提供类型

void func_dec(int , void(*) ());

它应该足够了。否则,如果还要指定变量名,请写

 void func_dec(int x, void(*funcptr) ());

答案 2 :(得分:1)

函数参数名称应与声明函数时函数名称相同。

功能声明:

void func();  // correct syntax
void() func;  // incorrrect syntax

函数指针声明:

void (*func_ptr)();  // correct syntax
void (*)() func_ptr; // incorrect syntax

如果使用以下技巧,则声明函数指针变得更容易:

采取功能声明。如果您想要一个未命名的版本,请将功能名称替换为(*pointerName)(*)

示例:

 int func1(char* parm1);        // function
 int (*func1_ptr)(char* parm1); // function pointer

 // function taking a function pointer as parameter:
 void foo(int (*func1_ptr)(char*));
 // The same declaration with an unnamed parameter:
 void foo(int (*)(char*));