指针扫盲--复杂指针解析

来源:互联网 发布:气味图书馆淘宝 编辑:程序博客网 时间:2024/06/18 16:40
 

其实也就笔试的时候遇到过让解释复杂指针,平时到也没太这样用过;

在网上搜了一些资料,大体解释都相同,应该都是出自一个人或者一本书一手吧;

我身边广为流传是megaboy同学的指针扫盲,学习;

记录下,基本例子是摘自指针扫盲第八章附加自己的理解;

指针是c的核心,希望自己以后能有自己的见解...

 

指针扫盲--复杂指针解析首先介绍一个概念,[左右法则]..

右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。

简单调整法则:从未定义标识符开始读起,之所以是未定义的标识符,是因为一个声明里面可能有多个标识符,但未定义的标识符只会有一个。

---小小疑问: 为什么未定义标识符只有一个,因为是函数名称的原因吗?..遇到括号跳转方向指的是什么?

 

 指针扫盲--复杂指针解析举例说明: 有简入深

1 int (*func)(int *p);

--func是唯一未定义标示符;

--外面有括号,所以先看括号内,右边没有,左右是个*,说明func是指针;

--出括号,右边是一个括号,说明*func指向函数

--so func是一个指向函数的指针,该函数入参是一个int类型的指针,出参是int类型的值

2 int (*func)(int *p, int (*f)(int*));

--找到func

--括号内*func,说明func是指针

--右边是一个括号说明func是指向函数的指针

--既然是函数,那左边肯定是返回类型,右边就是实参

--右边想对复杂,重点看右边,int *p,int (*f)(int*)

---说明有两个形参,一个是int类型的指针,一个是指向函数类型的指针(形参为指针,返回类型为int)

--so func是一个指向函数的指针,该函数返回类型为int,具有两个实参,一个是int类型,一个是指向函数类型的指针

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

--找到func

--右边[],左边*,[]优先级比*高;因此func是一个有五个元素的数组,*修饰改数组;func[5]数组存放指针

--跳出括号,是一个括号,说明,func数组是指向函数的指针

--so you know ,func是一个指针数组,即数组里面都是指针类型的元素;

  它指向一个返回为int,形参为指针类型的函数

--也就是该指针数组是指向函数的指针数组,数组内能容乃5个指向函数的指针;

 

说到这,顺便提一下指针数组,和数组指针:

指针数组:还是数组,数组里面存放的元素类型是指针;像整型数组,字符型数组..*pa[]样式

数组指针:还是指针,指针指向一个一维数组;也就是指针每一移动一步就移动了一个数组的长度;常用于二维数组;..(*p)[]..

二维数组暂时不做详解,有时间在学习...

 

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

--找到func

--括号内,func是指针

--跳出括号,右边是[],说明func是指向数组的指针..简称数组指针

--左边,是*,说明数组的元素是指针,到这和到一起就是func是指向数组元素为指针的数组指针;

--分析好func周围的东东,把它当做一个整体是个指针,右边是个(),说明改指针指向函数,返回类型形参略

--so 总结下自己的小经验

把func当做一个单位,看最外层,也可以说是离形参括号最近的一层,

(*(p)[]) --p表示*func

p是一个指针数组,右边是(),既同例三,该指针数组存放的是指向函数的指针

在把p展开,func是一个指针..

--so 由下而上,func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数

 

-----话说到这我也有点晕晕了..知道这样说,但是不知道;

-----这是用指针来操作一个里面是函数指针的数组不,这样一说又清晰了,上面仿佛又吧他复杂化了..

     写过就保留吧,不同的思维不同帮助呢/

 

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

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

 

有些是非法的..

 

6 int func(void) [5];

func是一个返回值为具有5个int元素的数组的函数。但C语言的函数返回值不能为数组,这是因为如果允许函数返回值为数组,那么接收这个数组的内容的东西,也必须是一个数组,但C语言的数组名是一个右值,它不能作为左值来接收另一个数组,因此函数返回值不能为数组。

 

7 int func[5](void);

func是一个具有5个元素的数组,这个数组的元素都是函数。这也是非法的,因为数组的元素除了类型必须一样外,每个元素所占用的内存空间也必须相同,显然函数是无法达到这个要求的,即使函数的类型一样,但函数所占用的空间通常是不相同的。

 

--tips:数组[]靠近啥,就说明数组里面是啥...

 

8 复杂练习 指针扫盲--复杂指针解析

int (*(*func)[5][6])[7][8]; 
 func是一个指向数组的指针,这类数组的元素是一个具有5X6int元素的二维数组,而这个二维数组的元素又是一个二维数组。 
int (*(*(*func)(int *))[5])(int *); 
 func是一个函数指针,这类函数的返回值是一个指向数组的指针,所指向数组的元素也是函数指针,指向的函数具有int*形参,返回值为int 
int (*(*func[7][8][9])(int*))[5]; 
 func是一个数组,这个数组的元素是函数指针,这类函数具有int*的形参,返回值是指向数组的指针,所指向的数组的元素是具有5int元素的数组。  

实践当中,需要声明一个复杂指针时,如果把整个声明写成上面所示的形式,对程序可读性是一大损害。应该用typedef来对声明逐层分解,增强可读性,例如对于声明:

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

可以这样分解:

typedef  int (*PARA)[5];typedef PARA (*func)(int *); 
typedef  不是特别熟悉..备录指针扫盲--复杂指针解析 
原创粉丝点击