讨论最简单的二维数组形式:
int array[4][2]={{2,4},{6,8},{1,3},{5,7}};
1. 我们知道,数组名同时代表数组首元素的地址。array 是这个二维数组的名字,array 也是这个二维数组的首元素的地址。
注意array 这个二维数组一共有4个元素({2,4},{6,8},{1,3},{5,7}),且每个元素都包含两个 int 类型的数组。
所以,首元素的地址为 array=&array[0] 。
2. 元素array[0]本身是包含两个整数的数组,因此array[0]的值同其首元素的地址&array[0][0]相同。可以这样理解:
array[0]是首元素{2,4}的名字,而首元素又是数组,又数组名同时代表数组首元素的地址,所以,array[0]是其首元素的地址,即&array[0][0]。
3. array[0]是一个整数大小对象的地址,因为array[0]是数组的{2,4}的名字!而array是两个整数大小对象的地址,因为array以独立数组为元素,且每个独立数组又包含两个整数类型的数据。
4. 对一个指针(也即地址)加1,会对原来的数值加上一个对应类型大小的数值。也就是说,array[0]+1会加上一个int类型的大小;array+1会加上两个int类型的大小。
5. 对一个指针(也即地址)取值,使用*符号或者索引[]符号。因为array[0]是其首元素array[0][0]的地址,
所以*(array[0])代表存储在array[0][0]中的数值。同理,*array代表其首元素array[0]的值,但是array[0]本身就是一个地址,即&arrray[0][0],因此,*array=&array[0][0]。对这个表达式取值:*(*array)=*&array[0][0]。
总之,array是地址的地址,需要两次取值才可以得到通常的数值。
简单代码运行:
#include<stdio.h>
int main(void)
{
int array[4][2]={{2,4},{6,8},{1,3},{5,7}};
printf("\tarray=%p,\tarray+1=%p\n",array,array+1);
printf("\tarray[0]=%p,\tarray[0]+1=%p\n",array[0],array[0]+1);
printf("\t*array=%p,\t*array+1=%p\n",*array,*array+1);
printf("\tarray[0][0]=%d\n",array[0][0]);
printf("\t*array[0]=%d\n",*array[0]);
printf("\t**array=%d\n",**array);
printf("\tarray[2][1]=%d\n",array[2][1]);
printf("\t*(*(array+2)+1)=%d\n",*(*(array+2)+1));
return 0;
}
注意观察他们地址的变化!!!