《C Primer Plus 5th》读书笔记-----指针和多维数组

回归基础,感觉《C Primer Plus 5th》上面有一段话对于指针和多维数组的关系解释比较清楚,所以本博文算是补回以前没有记下的笔记 。

----------------------------------------------------------分割线---------------------------------------------------------

为简单讨论,我们采用比较小的数组。假设有如下的声明:

int zippo[4][2] ; /*整数数组的数组*/

数组名zippo同时也是数组首元素的地址(定理之一)。在本例中,zippo的首元素本身又是包含两个int(元素)的数组,因此zippo也是包含两个int(元素)的数组 的地址。下面从指针属性进一步分析:

@  因为zippo是数组首元素的地址,所以zippo的值和&zippo[0]相同。另一方面,zippo[0]本身是包含两个整数的数组,因此zippo[0]的值(一个包含两个整数的数组,个人觉得姑且可以认为就是一个数组名)同其首元素(一个整数)的地址&zippo[0][0]相同。简单地说,zippo[0]是一个整数大小对象的地址,而zippo是两个整数大小对象的地址。因为一个整数和两个整数组成的数组开始于同一个地址,因此zippo和zippo[0]具有相同的数值。


@ 对于一个指针(也即地址)加1,会对原来的数值加上一个对应类型大小的数值。在这方面,zippo和zippo[0]是不一样的,zippo所指向对象的大小是两个int(包含两个整数的数组组成的数组),而zippo[0]所指向对象的大小是一个int(一个包含两个整数的数组)。因此zippo+1和zippo[0]+1的结果不同。


@对一个指针(也即地址)取值(使用运算符*或者带有索引的[]运算符)得到的是该指针所指向对象的数值。因为zippo[0](一个包含两个整数的数组)是其首元素zippo[0][0]的地址,所以*(zippo[0])代表存储在zippo[0][0]中的数值,即一个int数值。同样,*zippo代表其首元素zippo[0]的值,但是zippo[0]本身就是一个int数的地址,即&zippo[0][0],因此*zippo是&zippo[0][0]。对这两个表达式同时应用取值运算符将得到**zippo等价于*&zippo[0][0],后者简化后即为一个int数zippo[0][0]。简言之,zippo是地址的地址,需要两次取值才可以得到通常的数值。地址的地址或指针的指针是双重间接的典型例子

-----------------------分割线-----------------

这两段话看上去很复杂,其实搞清楚两个点就可以弄明白了。zippo是一个以数组为元素的数组,那么zippo[0]、zippo[1]、zippo[2]等等都是数组。既然这些是数组,那么zippo[X]就是代表该数组的地址了。


附上书代码:

#include<stdio.h>


int main(void)
{
	int zippo[4][2] = {{2,4},{6,8},{1,3},{5,7}} ;

	printf("zippo = %p, zippo + 1 = %p\n",zippo,zippo+1) ;
	printf("zippo[0] = %p, zippo[0] + 1 = %p\n",zippo[0],zippo[0]+1) ;
	printf("*zippo = %p, *zippo + 1 = %p\n",*zippo,*zippo+1) ;
	printf("zippo[0][0] = %d\n",zippo[0][0]) ;
	printf("*zippo[0] = %d\n",*zippo[0]) ;
	printf("**zippo = %d\n",**zippo) ;
	printf("zippo[2][1] = %d\n",zippo[2][1]) ;
	printf("*(*(zippo+2)+1) = %d\n",*(*(zippo+2)+1)) ;

	return 0 ;
}







你可能感兴趣的:(《C Primer Plus 5th》读书笔记-----指针和多维数组)