C语言指针之《碟中碟》全面瓦解篇

通俗的定义咱们不说,都懂,可是一旦指针牵扯到函数指针、指针数组、二维数组指针可就让许多朋友蒙逼了。我也探究了较久,找到了一种比较“平易近人”的好方法来理解并解决问题。

首先我们看看简单的指针代码:

int (*p1)(int ,int );//函数指针(指向函数的入口地址)
int (*p2)[3];//二维数组指针(指向一个二维数组的指针)
int *p3[3];//指针数组(一个数组所有元素都是指针则称这个数组为指针数组)  //等价于int *(p3[3])

函数指针与指针数组不难理解,先谈谈二维数组指针,假设有一个二维数组a[3][3]={{0,1,2},{3,4,5},{6,7,8}},初始元素a[0][0]地址是1000(显然不可能,便于演示)废话不多说,直接来图趴:
在这里插入图片描述
在这里插入图片描述

相信大家看到图就应该很容易理解了。

接下来是重点:
C语言的标准规定:对于一个符号的定义,编译器总是从它的名字开始读取,然后按照优先级顺序依次解析!这是理解形式复杂的指针的关键所在。
要知道编译器开发商都是按照C语言组织制定好的标准来进行开发的。
对于对于指针中包含的符号的优先级顺序从高到低是:
定义中被括号()括起来的部分
后缀操作符:如func()中的()表示函数,a[]中的[]表示一个数组
前缀操作符:星号*p表示p为指向某一个地址的指针
了解了
上面的编译器原理,再复杂的指针也不攻自破;不信?继续往下看你就恍然大悟了。我将下面的方法称之为“逆剥洋葱法”,从里往外一层层的剥开并分析理解。
首先分析简单的指针代码:
int (*p1)(int ,int ),先看括起来的部分,是一个指针,那么它指向谁呢?再往外看,发现它有一个后缀(int,int),按照上面说的不正是表示指向一个函数,开头的int 说明该函数返回值是int类型。综上所述,int (*p1)(int ,int )是一个指向返回值为int类型的指针。
int (*p2)[3],先看先看括起来的部分,是一个指针,那么它指向谁呢?再往外看,发现它有一个后缀[],按照上面说的不正是表示指向一个数组,开头的int 说明该数组是int类型。综上所述,int (*p2)[3]是一个指向有三个元素的int类型的指针。
分析了这两个,剩下那一个也就非常容易了,在这里大家可以自己推演加深印象。

最后咱们再来一个复杂的趴:

int(*(*(*fun)(int*))[6])(int*)

看到这小伙伴们可能会叹气:我的天呐,这不是要人老命吗?但是别急,只要会了“逆剥洋葱法”,再复杂的指针也会土崩瓦解。请看下面的分析:
步骤一:从名字fun开始理解,表明fun是一个指针;
步骤二:跳出括号,看两边,左边是*右边是(int *),那么根据优先级规则,就应该先看后缀即右边的,(int *)是一个函数的参数列表,再看左边是 *,就知道这个指针指向一个返回值是 一个指针类型的函数,但指针指向的数据尚不清楚;
步骤三:再向外跳一层,左边是 *,右边是[6],右边[]优先级高,先看右边,表示这是一个数组,再看左边的 表示数组的每个元素都是指针。那么现在知道了,[5]是一个含有5个指针的指针数组,在步骤二中返回的指针就指向这样一个数组;
步骤四:再向外调一层来到最外层,先看后缀为形参列表,故为一个函数,再看前缀,表示函数的返回类型。说明步骤三推导出来的指针数组的每一个元素都指向返回值为int 类型的函数(函数原型为int func(int *));
综上四个步骤所述:fun是一个函数指针,该函数的返回值是一个指向指针数组的指针,而指针数组中的每一个指针都指向返回值为int类型的函数(函数原型为int func(int *));
到这里大家也许会有点晕,但是只要有耐心,看上一遍不太懂,就再看一遍,就一定可以搞懂。
嘿嘿,相信大家看完并理解之后一定是对指针醍醐灌顶,茅塞顿开,拨云见日!
我相信世间一切复杂的东西都是由简单模块构成,只要我们仔细耐心的分析,再难的知识也终将理解!

发布了8 篇原创文章 · 获赞 8 · 访问量 925

猜你喜欢

转载自blog.csdn.net/weixin_44225901/article/details/104307524