3.分析(*(*X[3]())先进行分解,先用ptr替代正题*x[3](),这样就等效为(* ptr)形式了,结合2)知道 (*ptr)就等效于一个一维指针了,那这你想到什么?显然要用二维指针了,即ptr表示一个二维指针
常见列子:
Int **Dptr;
Int *ptr=*Dptr;//对Dptr进行解运算
(引导: 关于二维指针我久不多说了,直接给个列子
Int a=3;//假设a的地址依然0X00000006
Int **p=(int**)&a;
Int *q=(int*)&a;
//这个时候p和q保存的内容都市0X00000006!),只是表示的类型不同!…..
)
容易推理得到 ptr是一个二维指针了!
再看ptr等价于(*x[3])()了,看类型久知道这里x[3]是一个函数指针,不管,用pFunc替代
即ptr等价于(*pFunc)()了,ptr表示一个二维指针,可以推导出最可能的函数声明
Char** (*pFunc)() ;//char** 是一个返回类型,这里返回一个二维char型指针,函数不带参数列表
附:(何谓地址?啰嗦一下,也帮你复习一下,首先要充分理解p,q是一个地址!(当然也是占用内存的,地址要达到寻址4GB(windows 32位系统),显然要32位,所以一般c++中指针都是32位即四个字节表示一个地址(指针),p,q都是占用内存中的4个字节并且以一个32位整数表示地址!,所以p,q虽然是地址,但实际上可以理解p,q表示的是存储内容!即p,q是一个32位整数,你可能想到,竟然是一个整数,那么为什么一个Int型为什么不可以用一个指针赋值?事实上是可以的!当然直接这样用
int a=3;//假如a在内存中的存储地址是 0X00000006
int *p=&a;//p就表示0X00000006了(p=0X0000006)
Int b=p; //错误,因为p虽然是一个整数,而且数据值是0x00000006,但是类型不匹配!
//即使p值是一个整数(表示一个地址)
Int b=(int)p;//这个是可以的 这个时候b=6!(注意不是3!)
理解到这一点,很自然的猜到,既然p是一个存储内容,那么p是不是也有一个自己的地址,当然,p也是有地址的!int b=(int)&p;这个时候就可以直接通过printf(“%d”,b)输出p的地址的十进制值了
)
C指针声明解读之左右法则
C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的:
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.