关于c语言中的复杂原型声明

来源:互联网 发布:上古卷轴5捏脸数据女 编辑:程序博客网 时间:2024/06/05 17:06

c语言中的复杂原型声明是很多人都头痛的事,下面我说一下自己的理解。主要是从理解的角度说明声明的内容。

 

 1.首先是从左往右找到未声明的标识符,
2.再找将未声明标识符括起来的最里层的小括号的一大块,再根据运算符的等级(提醒越是里面的小括号优先级比外面的小括号就有优先,如(*(*func)(int *))将*func括起来的比将*(*func)(int *)括起来的优先)和结合性来分析,当分析时遇到指针时的下一步就应该确定指针指向什么类型 /遇到数组时下一步就确定数组的元素内容是什么个数是多少 /遇到函数时的下一步就确定函数的类型(函数的类型即函数参数是什么返回又是什么)
3.每分析完一层小括号就往外跳到又是将未声明标识符括起来的一大块,再根据第2步,如此循环直至将整块声明都分析完

下面开始来例子(声明例子来源于网上的,大家可以在网上找一些关于例子中声明的分析)

实例1如下:
int (*func)(int);
(网上的分析)
先看标识符,(*func)是一个整体标识符
再看右边,有(),故这个标识符是表示一个函数,其有一个int型的参数
最后看左边,有个int,表示这个函数是返回整形
再回溯,(*func)是一个函数,那么func自然是一个指向函数的指针
综上,func是一个函数指针,该函数有一个整形参数,并返回整形值
上例出自C吧的贴子http://tieba.baidu.com/f?kz=925000075
int (*func)(int);
(根据整理的方法分析)
首先从左往右找到未声明的标识符(这里是func).再找将标识符括起来的所有小括号中最里层的那个小括号,最里层的小括号括起来的一大块是(*func),修饰标识符func的是*,所以func是一个指针,现在就开始确定指针指向什么类型,这里因括号里的内容分析完了就跳出来找第二个将它包起来的小括号(由里往外数最里层的小括号为一),往外数这里没有第二个将标识符括起来的小括号,而只剩int (      ) (int);。再根据优先级来看 int (      ) (int) 中(int)比 int 要高。 所以指针func是一个指向函数的指针(此时要确定函数类型即参数和返回值各是什么) (int)里面是函数的参数即为int, 在int (      ) (int)左边的int 是函数的返回值

func是一个指针(指向什么),该指针指向一个函数(函数是什么类型即参数和返回值各是什么)。该函数指针指向的函数类型是带一个int型参数,返回一个int。
或直接说
func是一个指向一个类型(这类型是指指针指向函数的类型)为带int整形参数返回一个int的函数指针

 

 

 

实例2如下:
int (*func[5])(int *p);
(网上的分析)
func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int
int (*func[5])(int *p);
(根据整理的方法分析)
首先找未声明的标识符再找将该标识符括起来的最里层的小括号,即是
(*func[5])根据优先级知func是一个数组(数组元素的内容是什么),此时括号里还有*没分析。所以*修饰func[ ],即数组元素的内容是指针(指针指向什么),跳出括号再根据优先级得 ( ) 比 int 高,即指针指向函数(函数的参数和返回值是什么),函数的类型带一个(int *p)参数返回值一个 int。
综合可得:
func是一个元素个数为5数组(数组元素的内容是什么),数组元素的内容是一个指针(指向什么),该指针指向一个函数(参数和返回值各是什么),函数指针指向的函数类型是带一个(int *p)参数,返回一个int.
或说:
func是一个元素个数为5的指针数组,该指针数组的内容指向一个类型是带一个(int *p)参数返回一个int的函数指针
再下面的说法不知行不行?
func是一个元素内容为指向类型是带一个(int *p)参数返回一个int的函数指针数组,该函数指针数组大小为5

 

 

 

8楼

实例3如下:
int *func(int *)[5];
(根据整理方法的分析)
首先找到未声明标识符,这里是func,再找小括号(这里没将它括起来的小括号),根据等级知 ( ) 比 * 高,func是一个函数,函数带一个(int *)参数,返回什么? 有根据等级知 [ ] 比 * 高,即函数返回一个元素个数为5的数组,数组的元素内容是什么,*修饰数组的内容是指针,int表该指针指向一个int。
综合来说:
func是一个函数,函数带一个(int *)形参,返回一个数组元素个数为5的数组,数组元素的内容是指针,该指针指向的类型是int。
或说:
func是一个带(int *)参数返回一个元素个数为5的指针数组的函数,
指针数组的内容是(int*)。
但函数返回一个元素个数为5的数组正确吗? NO
则该声明int *func(int *)[5]不符合规则
若用小括号将*func(int *)括起来呢?
即int ( *func(int *) )[5],请自己动手试试分析该声明以及判断正确与否
请根据方法自行分析以下声明以及判断正确与否
int *func[5](int*);

 

 

 

实例4如下:
int (*(*func)[5])(int *p);
(网上的分析)
func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。
int (*(*func)[5])(int *p);
(根据整理的方法分析)
首先找未声明的标识符再找将该标识符括起来的最里层的小括号,即(*func)可知func是一个指针(指向什么),跳出括号即到(*(      )[5]),根据优先级知 [ ] 比 * 高;所以指针func指向一个元素个数为5的数组(数组元素的内容是什么),(括号里还有*即)*是修饰数组的元素内容是指针(指针指向什么),再跳出括号即为int (*(      )[ ])(int *p),优先级中( ) 比 * 高,所以指针指向函数(函数的参数和返回是什么),指针指向函数的类型是带一个(int *p)参数返回一个int。
则综合分析:
func是一个指针,该指针指向元素个数为5的数组,数组元素的内容是指针,该指针指向类型是一个带(int *p)参数返回一个int的函数指针。
或说:
func是一个指向元素个数为5的数组指针,该数组元素的内容是一个指向类型为带一个(int *p)参数返回一个int的函数指针

 

 

 

 

实例7如下:
int (*(*(*func)(int *))[5])(int *);
(网上的分析)
func是一个函数指针,这类函数的返回值是一个指向数组的指针,所指向数组的元素也是函数指针,指向的函数具有int*形参,返回值为int。
(根据整理的方法分析)
(分析提醒:将未声明的标识符func括起来的小括号有三个(在这例里将*func括起来的小括号(红色)是第一个/最里层,将*(*func)(int *)括起来的小括号(蓝色)是第二个,将*(*(*func)(int *))[5]括起来的小括号(绿色)是第三个/最外层,最里的( )优先级会先屏蔽相对于它来说属外的( ) ,即在分析时应该是红色的小括号/(最里的小括号)会屏蔽蓝色的小括号/(由里往外数是第二个小括号),分析到蓝色的小括号时,蓝色的小括号会绿色的小括号/(由里往外数是第三个小括号) ,以此类推 …………
综合来说就是越是里面的小括号优先级比外面的小括号就有优先级))
int (*(*(*func)(int *))[5])(int *);
首先找到将未声明的标识符扩起来的最里层小括号,这里是(*func),所以func是一个指针,括号里的全部都分析完了就跳出括号,即到(*(      )(int *)),因( )比*高所以指针func指向函数,指针指向的类型是一个函数,该函数的参数是(int *),*修饰带一个(int*)形参函数的返回值是指针,第二个括号里的全部也都分析完了就跳出括号即( * ( (     )(     )) [5] ) 因 [ ] 比 * 高,所以函数返回的指针指向元素个数为5的数组,此时括号里的*修饰的是数组元素的内容为指针,第三个括号里的全部也都分析完了就跳出括号
即int (   (   (      ) ( ) ) [ ] )   (int *)又根据优先级知数组元素内容是一个指向函数的指针,该函数类型带一个(int *)参数,返回一个int数。
则   int (*(*(*func)(int *))[5])(int *);
func是一个指针,指针指向的类型是带一个(int *)参数返回一个指针,该指针指向元素个数为5的指针数组,该指针数组的元素内容是一个指向类型为带一个(int *)参数返回一个int的函数指针。
或:
func是一个指向类型为带一个(int *)参数返回一个指向个数为5的指针数组的函数指针,该指针数组的元素内容指向一个类型为带(int *)返回int的函数指针

 

 

以下两例子请自己分析,总结的答案在下面给出(建议读者学完后到网上找一些更为复杂的例子来巩固对复杂声明的分析和理解)
void (*signal(int signum,void(* handler)(int)))(int);
(上面的声明是signal.h下signal的声明)

int (*(*func[7][8][9])(int*))[5];

……
……
……
……
……
……
……
……
void
(   *signal ( int signum,void(* handler)(int) )   )
(int);
signal是一个带( int signum,   void(* handler)(int) )参数返回一个指向类型为带一个(int)参数无返回的函数指针,signal带的第一个参数是int,第二个参数是指向类型带一个int参数无返回的函数指针。

int (*(*func[7][8][9])(int*))[5];
func是一个7*8*9(三维)指针数组,7*8*9(三维)指针数组的元素内容是一个指向类型为一个带(int*)参数返回一个指向元素个数为5且指向类型为int的数组指针的函数指针
int (*(*func[7][8][9])(int*))[5];
func是一个指向类型是带一个(int*)返回一个指向元素个数为5且类型是int的数组指针的函数指针数组,该函数指针数组大小为7*8*9.

 

原创粉丝点击