复杂声明解析

C语言的指针很久没看了,复习一下,做一下总结。C语言的复杂声明,例如:void (*f(int,int (*)(int)))();怎么样,是不是很复杂?看着摸不到头脑,不知从何说起。看了挺多资料,主要是应用“右左法则”,现总结如下:
1.基本的C语言声明:
①int a;//声明一个整形数a
②int *a;//声明一个指针,该指针指向一个整形数
③int **a;//声明了一个指针,该指针指向一个指针,这个指针指向一个整形数
④int a[10];//声明一个数组,该数组有十个元素,每个元素是一个整形数
⑤int *a[10];//[]运算符的优先级高于*,因此a先与[10]结合,a是一个具有十个元素的数组,每个元素是一个指向int型的指针
⑥int (*a)[10];//()的优先级高于[],因此a是一个指针,这个指针指向一个数组,这个数组具有10个元素,每个元素是一个int型
⑦int *f();//f是一个函数,该函数无参数,返回值是一个指向整形数的指针
⑧int *f(int);//f是一个函数,该函数有一个int型的参数,返回值是一个指向整形数的指针
⑨int (*f)();//f是一个指针(不是函数),该指针指向一个函数,该函数无参数,返回值是一个int型整数。
以上是基础的C语言的声明,上过C语言的都应该很熟悉。但是这个呢,void *(*c)(char,int(*)());仅仅知道上述好像还不足以解析。
2.右左法则:
  The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.
        即:从最里面的圆括号(未定义的标示符标示符)开始,先往右看,在往左看,遇到“)”即调转方向,向左遇到“(”则跳出圆括号,重复这个过程,知道声明解析完毕。看起来有点抽象,上例子:int *(*c)(char,int(*)());
   按照我们的法则走一遍:
   ①从c开始,向右看,是“)”,调转方向,遇到“*”,说明c是一个指针,接着遇到“(”,跳出这层括号,向右;
   ②是一个括号,说明是一个函数,即①中的指针指向这个函数,这个函数有两个参数,一个是char型,进入另外一个;
   ③解析这个参数,从*开始,是一个指针,向右遇到“)”,调转,遇到“(”,跳出圆括号,向右,是一个(),说明是一个无参数 的函数,这个指针指向这个函数,向左,遇到“int” 说明          这个函数的返回值是int型。到此②中的函数的两个参数解析完毕;
   ④(*c)后面的解析完毕,向左,是一个*,说明②中这个函数的返回值是一个指针,接着向左,遇到“int”,说明返回的这个  指针指向int型整数。
   总结上述:c是一个指针,指针指向一个函数1,函数1有两个参数,一个参数是char类型,另一个参数是一个函数指针,这个函数无参数,返回值为int,函数1的返回值是一个指针,指向int类型。
   接着来看:float(*(*b())[10])();
   ①从b开始,向右,遇到“()”,说明b是一个函数,无参数,接着向右遇到“)”,转向;
   ②遇到*,是一个指针,说明这个函数返回值是一个指针,接着向左,遇到“(”,跳出这个括号;
   ③向右,遇到“[10]” ,说明这是一个数组,具有十个元素,说明②中的指针指向一个数组,接着向右;
   ④遇到“)”,转向,遇到“*”,是一个指针,说明③中数组每一个元素是一个指针,接着向左;
   ⑤遇到“(”,跳出该括号,向右遇到“()”,是一个函数,说明④中的指针指向一个函数,无参数,右边完毕,向左;
   ⑥遇到float说明函数的返回值是float类型,完毕。
   总结上述:
   b是一个函数,函数的返回值是一个指针,指针指向一个数组,数组的每一个元素是一个指针,指针指向一个函数,该函数无参数,返回值是float类型。
   再来一个:int *(*(*array[5])()) ()
   从array开始,向右,[5],array是一个具有五个元素的数组,向左,*,每个元素是一个指针,跳出该括号,向右,是(),说明是一个函数,指针指向这个函数,且函数无参数,向右遇到“)”,转向,遇到*,是一个指针,说明该函数的返回值一个指针,向左,遇到“(”,跳出括号,向右,(),是一个函数,无参数,即指针指向该函数,右边完毕,向左,遇到*,说明该函数返回指针,接着左,int,指向int型。
   总结:array是一个数组,数组中有五个元素,每个元素是是一个指针,指向一个函数,这个函数无参数,返回值是一个指针,指向一个函数,这个函数无参数,返回值是一个int型的指针。
   总结上述三个例子:指针有指向,函数有返回和参数,数组有元素类型,把握这几点。
   再来一个:int (*(*pf)(int,int(*)(int,int)))(int,int);
   声明一个函数指针pf,所指向的函数有2个参数分别为int型和一个函数指针,并且这个函数的返回值也是一个函数指针,作为参数和返回值的这两个函数指针所指向的函数都   有两个int型参数,并且返回值也为int型。
   再来一个:int (*(*func)(int *p))[5];
   ①func开始,向右,“)”,向左,*,即func是一个指针,指向。。跳出括号;
   ②(int *p),说明是一个函数,即上述指针指向一个函数,参数是一个int型指针,p是形参名,无意义,返回值为。。。;
   ③转向,*,②中的函数返回值是一个指针,指向。。。。跳出括号,;
   ④向右,[5],是一个数组,③中函数的返回值是一个数组,有五个元素,每个元素的类型。。。。
   ⑤左,int,每个元素的类型是int。完毕
   func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。
   今天讲得是怎么样解析一个已经声明好复杂声明接下来的文章将逆过来,怎么根据功能写出正确的复杂的声明。虽然C语言允许复杂的声明,但是在实际应用中并不提倡。

posted @ 2015-04-13 23:40  sunp823  阅读(210)  评论(0编辑  收藏  举报