一维数组的值是一个指针常量,它的类型是“指向元素类型的指针”,它指向数组的第1个元素。多维数组的也差不多。唯一的区别就是多维数组的第1维的元素实际上是另一个数组。
二维数组
介绍二维数组,例如:
int matrix[3][10];
创建了matrix,它可以看作是一个一维数组,包含3个元素,只是每个元素恰好是包含10个整形元素的数组。
matrix这个名字的值(*matrix)是一个指向它第一个元素的指针,所以matrix是一个指向一个包含10个整形元素的数组的指针
int matrix[3][10]可以看为3行10列的数组形式,如图:
matrix类型是”指向包含10个整形元素的数组的指针“
matrix + 1
表示,如图:
为什么?因为1这个值根据包含10个整形元素的数组的长度进行调整,所以它指向matrix的下一行。如果对其执行间接访问操作,就如上图随箭头选择中间这个子数组。
*(matrix + 1)
所以*(matrix + 1)的值是个常量指针,它指向数组的一个元素。它的类型是”指向整型的指针“。我们可以在下一维的上下文环境中显示它的值:
*(matrix + 1)+ 5
前一个表达式是个指向整型值的指针,所以5这个值根据整型的长度进行调整。整个表达式的结果是个指针,它指向的位置比之前表达式所指向的位置向后移了5个整型元素。
`*(*(matrix + 1)+ 5)`
//访问的正是图中那个整型元素。
*(matrix[1] + 5) == matrix[1][5]
matrix[1]选定一个子数组,所以它的类型是一个指向整型的指针,对指针加5再进行间接访问操作,即访问元素
数组指针
int vector[10], *vp = vector; //合法
int matrix[3][10], *mp = matrix; //非法
因为matrix并不是指向整型的指针,而是一个指向整型数组的指针。我们应该声明:
int (*p)[10]
说明:由于括号存在,首先执行间接访问,所以,P是个指针。接下来执行下标引用,所以P指向某种类型的数组(整型)。
声明没有说p是什么,但推断并不难,当我们对它执行间接访问时,我们得到的是个数组,对该数组进行下标引用操作得到的是一个整型值。所以p是一个指向整型数组的指针。
int (*p)[10] = matrix;
使得p指向matrix的第一行。p是一个指向拥有10个整型元素的数组的指针。当你把p和一个整数相加时,该整数首先根据10个整型值的长度进行调整,然后再执行加法。
例子:
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,14}};
int (*p)[4] = a;//数组指针指向二维数组
printf("p[0]:0x%x,p[1]:0x%x\n",p[0],p[1]);
printf("the a value:0x%x,0x%x\n",a+1,*(a+1));
printf("a+1 value:%d\n",**(a+1));
打印结果:
p[0]:0xbfd09fd0,p[1]:0xbfd09fe0
the a value:0xbfd09fe0,0xbfd09fe0
a+1 value:5