使用“洋葱法”求解复杂指针

       看到《The C Programming Language》Page112页,讲到复杂指针,由于本人对此处一直比较敬畏,虽然在大二的时候读过一遍《C 与指针》,但由于久疏运用,忘得也差不多了。今天准备好好研究一下。

       文章参考的supermegaboy的文章复杂指针解析,并没有抄袭的意思,只是想自己留作参考查看之用,如不小心观测此文,不妨去原文瞻仰一番大牛之作。

       首先是一个面试题目“int (*a[10](int))是什么含义?”

       如果对指针的理解不到位的话,我相信对这个题目还是一筹莫展,根据supermegaboy文章中的方法解析即为:

a的右侧有[10]说明a是一个数组,再看左侧有个*,说明数组的元素是指针,在看括号右边是(int),说明指针的类型是个函数指针,此指针指向的函数具有int类型的形参,最左边的int说明函数的返回值为int.因此本题目的答案即为:a数组的元素是函数类型的指针,它所指向的函数具有int类型的形参,返回值类型为int。
先把我觉得有点意思的地方写清楚,免得遗忘:标号前面的*的位置很重要,结合的顺序不同意思也不同。

*意味着是指针,具体指针是指向的啥还要前后左右的分析

例如 int a[10]意思为:a是一个数组,数组元素为整形

        int (*a)[10]意思为:a是一个指向数组的指针,数组的元素为整形

        int *a[10]意思为:a是一个数组,数组的元素为整形指针。

貌似上面的意思就是大家所说的指针数组与数组指针,具体哪个我也记不清了。这地方查阅石虎的C后添加。

 int *a()意思为: 函数a的返回值为int*类型

 int (*a)()意思为:a是以个函数指针,它所指向的函数具有空参,返回值为int


这类题目可以理解为三段式:【(数组类型)(标识)(数组)】组合于【(函数返回值)(标识)(函数)】组合于【(指针)(标识)(空)】具体属于哪一种要根据第三段的类型区分([]意味着数组,第一段就为数组类型;与之相对,()意味着函数,第一段就为函数返回值)

洋葱法解析:

洋葱法就像杨宗纬剥洋葱,不过是由内而外:每层的判断顺序为(2-3-1),首先定位到第二段标识,然后根据第三段剥洋葱判断是数组还是函数,接着由第一段得到数组元素类型或者函数返回值类型。逐层去掉每个括号就像剥掉每层洋葱,直到得到求解完毕。

备注:这类题目的特征是第一段的类型总是个指针,因为只有这样才能跟下一层洋葱联系起来。

具体实例:

int (*func[5])(int *p);

func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。

(洋葱法:func是一个数组,数组的元素是指针,指针指向啥?剥掉一层,指针指向一个函数,函数的形参为int*p,函数的返回值为int。func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int)

 

int (*(*func)[5])(int *p);

func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。

(洋葱法:func是一个指针,指针指向啥?剥掉一层,指针指向一个数组,数组的元素是指针,指向啥?再剥掉一层,指向一个函数,函数的形参为int*p,函数的返回值为int。func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。)

根据三段原理此处*必须添加,意味着标志,数组元素为指针,否则int ((*func)[5])(int *p);数组元素的类型就是未知了


int (*(*func)(int *p))[5];

func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。

(洋葱法:func是一个指针,指针指向啥?剥掉一层,指针指向一个函数,函数的形参为int*,返回值为指针,指针指向啥?在剥掉一层,指针指向一个数组,数组的长度为5,数组每个原色的类型为int,func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。


char (*(*x())[])()
   x是一个没有参数的函数, 它的返回值是指向一个数组的指针, 而这个数组的元    素是函数指针, 指向的函数没有参数, 且返回char.

(洋葱法:x是一个函数,函数无形参,返回值是一个指针,这个指针指向啥?剥掉一层,指针指向一个数组,数组的元素为指针,这个指针指向啥?在剥掉一层,指针指向一个无形参返回值为char的函数。即无参函数x返回一个数组指针,它所指向的数组是一个指针数组,数组的每个指针元素指向的参数没有形参,返回值为char)


char (*(*x[3])())[5]
   x是一个函数指针数组,函数没有参数,返回char (*)[5]的数组指针

(洋葱法:x是一个数组,数组的元素是指针,指针指向啥?剥掉一层,指针指向一个函数,这个函数函数没有形参返回值仍然是指针,函数返回的指针指向啥?再剥掉一层,指针指向一个长度为5的数组,数组的元素为char类型。即x数组的元素是函数类型的指针,它所指向的函数没有参数,返回值为char (*)[5]的数组指针。)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值