【指针之高级篇】
基于上篇的理解,再继续深入学习下指针。
1. 指向指针的指针
既然指针也是占据内存空间的,那指针也就是有地址的了,那么对于指针的地址又是存放到哪里呢?——指向指针的指针。
首先假设程序中有这样一个变量:int weight = 60;
那么指向该int类型数据的指针的定义:int *pWeight = &weight;
指向pWeight的指针(指向指针的指针)定义:int **ppWeight = &pWeight;
ppWeight 就是指向了一个指针的指针,它本质还是一个指针,那么它仍旧是占用4个字节内存,这4个字节内存中存放着pWeight的首地址,知道了这些,那么指针的指针的指针也就一次类推即可。
2. 指针和数组名的关系
这个问题老生常谈,其实他们之间没有本质的联系,只不过从使用方法上看非常类似,故有了一批批前仆后继者比对进行研究,因为还是总有很多童鞋在这里有疑惑,这里简单说明下:
假设程序中定义了:
Int array[5] = {1, 2, 3, 4, 5};
Int *pArray = &array[0];
那么,
a. 数组名array本身没有专门内存来存储,他是依附于数组而存在的,是数组的一个名字;而指针是系统的一个专门的数据类型,指针变量pArray是有内存来存储的;
b. 具体在使用其进行内存寻址的时候则基本是一样的,按照定义pArray指向了数据array的首地址也就是首个元素的首地址,假如要访问数据中第2个元素那么可以用 array[1] 来表示,也可以使用 pArray[1] 来表示;这里或许会有童鞋有疑问pArray这时时是如何实现了访问数组第二个元素的呢?——回归到指针的本质,指向某种类型数据的首地址。那么根据pArray的定义系统知道pArray是指向了一个int型数据,pArray[1] 就相当于*(pArray+1),而(pArray+1)指向了这样的地址:系统在pArray所指向的地址上加上一个偏移量,这个偏移量是pArray指向数据类型所占的内存空间,在此就是4个。总之,对于指针来说他指向了某种数据的首地址,当该指针+1 时则以该数据类型为单元向后移动。
3. 数组指针和指针数组
对于此不过多解释,理解了前面的知识,这里也比较容易理解,只说明下:
数组指针,本质上就是一个指针,只不过这个指针是指向数组的,定义:int *p1[10];
指针数组,顾名思义本质是一个数组,数组中存放的元素是指针,定义:int (*p2)[10];
图示:
4. 函数指针
这个东东不会每天都用,但是也是有用武之地的,最常见的就是当做参数进行传递和转换表中使用,这个暂不介绍,后续专题再讲解。
5. 二维数组(指针+1操作)
为什么要讲一下二维数组呢?假如有一个二维数组的定义:
int TwoDimenArray[3][5] = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
那么对于TwoDimenArray[0][2]大家都知道表示第一行第三个元素也就是整数3,而TwoDimenArray[1]是什么意思呢?而TwoDimenArray 和TwoDimenArray[0]又有什么区别?
那么来看下实际的输出结果:
TwoDimenArray = 0x001AFCF4
TwoDimenArray[0] = 0x001AFCF4
TwoDimenArray[1] = 0x001AFD08
上面的结果是用实际运行的结果,可以看到TwoDimenArray的首地址为0x001AFCF4,而TwoDimenArray[1]则指向了第二行的首地址,也就是整数6的首地址,如何得出这个结果的呢,就是通过内存偏移来得出的,这是一个整型数的数组,那么一个元素就占用4个字节,在数组首地址0x001AFCF4再偏移5*4 = 20个字节也就是0x001AFCF4,也就是第二行的首地址。
再来看下TwoDimenArray 和TwoDimenArray[0]都指向了该数组的首地址,那么有没有区别呢?验证很简单,让两个地址都+1,看下地址偏移了多少,TwoDimenArray+1 和 TwoDimenArray[0]+1:
TwoDimenArray = 0x0014FCEC
TwoDimenArray[0] = 0x0014FCEC
TwoDimenArray[1] = 0x0014FD00
TwoDimenArray+1 = 0x0014FD00
TwoDimenArray[0]+1 =0x0014FCF0
可以看到地址变化是不同的,也就是说TwoDimenArray 和TwoDimenArray[0]虽然都指向了数组的首地址,但是地址偏移量缺不同,计算偏移量可以得出0x0014FD00 - 0x0014FCEC = 20,移动了一行的偏移量,0x0014FCF0 - 0x0014FCEC = 4,移动了一个元素的偏移量,由此,大家应该可以看明白了,TwoDimenArray是一个指向一维数组(这个一维数组长度为5个整形数)的指针,所以该指针+1就偏移20个字节;TwoDimenArray[0]则是一个指向整形数的指针,所以该指针+1就偏移4个字节。