假设有以下声明:
int multiArray [4] [2] //声明一个int类型的二维数组
数组名multiArray是该数组首元素( multiArray[0] )的地址。
在本例中,multiArray的首元素是一个内含两个int值的数组,所以multiArray是这个内含两个int值的数组的地址。如下图所示:
#include <stdio.h>
int main(void){
int multiArray[4][2] ={{2,4},{6,8},{1,3},{5,7}};
printf(" multiArray=%p, multiArray+1 =%p \n",multiArray,multiArray+1);
printf(" multiArray[0]=%p, multiArray[0]+1 =%p \n",multiArray[0],multiArray[0]+1);
printf(" *multiArray=%p, *multiArray+1 =%p \n",*multiArray,*multiArray+1);
printf(" multiArray[0][0]=%d \n",multiArray[0][0]);
printf(" *multiArray[0]=%d\n",*multiArray[0]);
printf(" **multiArray=%d\n",**multiArray);
printf(" multiArray[2][1]=%d \n",multiArray[2][1]);
printf(" *(*(multiArray+2)+1)=%d \n",*(*(multiArray+2)+1));
return 0;
}
Output:
multiArray=0x7ffeefbff540, multiArray+1 =0x7ffeefbff548
multiArray[0]=0x7ffeefbff540, multiArray[0]+1 =0x7ffeefbff544
*multiArray=0x7ffeefbff540, *multiArray+1 =0x7ffeefbff544
multiArray[0][0]=2
*multiArray[0]=2
**multiArray=2
multiArray[2][1]=3
*(*(multiArray+2)+1)=3
下面我们从指针的属性进一步分析。
1.我们发现,multiArray,multiArray[0], *multiArray
的值相同,这是为什么呢??
- 因为multiArray是数组首元素的地址,所以multiArray的值与&multiArray[0]的值相同。而multiArray[0]本身是一个内含两个整数的数组,所以multiArray[0]的值和它的首元素(一个整数)的地址(即&multiArray[0] [0]的值)相同。 multiArray[0]表示的是第一个数组中第一个元素的地址。
- 简单而言,multiArray[0]本质就是一个占用一个int大小对象的地址,因为multiArray[0]表示的是第一个数组中第一个元素的地址(注意这里是用了一个方括号,与用两个方括号不同!比如multiArray[0][0]表示的是第一个元素的值),而multiArray是一个占用两个int大小对象的地址,因为multiArray是数组首元素(如文章开始的图所示)的地址。
- 由于multiArray和multiArray[0]的地址都是各自数组首元素的地址,所以multiArray和multiArray[0]的值相同。
- 我们知道解引用一个指针(在指针前使用*)或者在数组名后使用带下标的[]运算符,得到引用对象代表的值。multiArray 代表该数组首元素( multiArray[0] ) 的值,而 multiArray[0] 本身是一个int类型值的地址,所以*multiArray就是表示该数组首元素的地址值。即,与
multiArray,multiArray[0]
的值同为multiArray[0][0]的地址值。
2.既然,multiArray,multiArray[0], *multiArray
的值相同,为什么multiArray+1,multiArray[0]+1,*multiArray+1
的值不同呢???
- multiArray是一个内含2个int类型值的数组的地址,所以multiArray指向一个8字节的数据对象,因此multiArray+1,它所指向的地址加8字节(十六进制中,38+8=40)
- 而multiArray[0]指向一个4字节的数据对象,multiArray[0]+1,其值加4(十六进制中,38+4得3c)
- *multiArray指向一个4字节的数据对象,与multiArray[0]同理,其值相同。
3.为什么multiArray[0][0], *multiArray[0],**multiArray
的值相等??
- 因为对二维数组解引用一次,相当于获取到了一维数组的地址,两次解引用才能得到二维数组的值。 可以用*,也可以用[]来解引用。所以
multiArray[0][0],*multiArray[0],**multiArray
的值都为一个具体的int数值
4.*(*(multiArray+2)+1)=3
是什么意思??
- multiArray ⬅️表示二维数组首元素的地址(每个元素都是内含两个int类型元素的一维数组)
- multiArray+2 ⬅️表示二维数组的第三个元素的地址
- *(multiArray+2) ⬅️表示二维数组的第三个元素的首元素的地址
- *(multiArray+2)+1 ⬅️表示二维数组的第三个元素的第二个元素的地址
- ((multiArray+2)+1)=3 ⬅️表示二维数组的第三个元素的第二个元素的值,即multiArray[3][2]的值