1.一维数组与指针
int a[10]; int *p = a;
a[i] <=>*(a+i)<=>*(p+i)
a作为一维数组的数组名,它的值是固定的。当数组名用作函数参数时,形参数组名是作为指针变量来处理的。如果用指针变量作实参,必须先使指针变量有确定值,指向一个已定义的对象。
2.二维数组与指针
定义一个二维数组int a[3][4];
从二维数组角度看,a代表二维数组首元素的地址,现在的首元素不再是一个简单的整型元素,而是由4个整型元素所组成的一维数组,因此,a代表的是首行的首地址,a + 1代表序号为1的行的首地址。如果二维数组的首行地址是2000,一个整型数据占4个字节,则a + 1的值应该是2000 + 4*4 = 2016。a[0],a[1],a[2]既然是一维数组名,而C语言又规定了数组名代表数组首元素的地址,因此a[0]代表一维数组a[0]中第0列元素的地址,即&a[0][0]。a[i][j]=*(a[i] + j)=*(*(a + i) + j)。如果a是一维数组名,则a[i]代表a数组序号为i的元素的存储单元。a[i]是有物理地址的,是占存储单元的。但如果a是二维数组,则a[i]是一维数组名,它只是一个地址,并不代表某一元素的值(如同一维数组名只是一个指针常量一样)。a + 1和*(a + 1)的值都是2016,但是含义是不同的,a + 1是1行首地址,*(a + 1)等价于a[1],代表的是1行0列元素a[1][0]的地址。
二维数组名是指向行的,一维数组名是指向列的。在指向行的指针前面加一个*,就转换为指向列的指针。例如,a和a + 1是指向行的指针,在它们前面加一个*就是*a和*(a+1),它们就成为指向列的指针,分别指向a数组0行0列元素和1行0列的元素。反之,在指向列的指针前面加&,就成为指向行的指针。例如a[0]是指向0行0列元素的指针,在它前面加一个&就成为&a[0],由于a[0]与*(a+0)等价,因此&a[0]与&*a等价,也就是与a等价,它指向二维数组的0行。不要把&a[i]简单的理解为a[i]元素的物理地址,因为并不存在a[i]这样一个实际的数据存储单元。它只是一种地址的计算方法,能得到第i行的首地址,&a[i]和a[i]的值是一样的,但它们的含义是不同的。&a[i]或a+i指向行,a[i]或*(a + i)指向列。
int a[3][4] = { {1,2,3,4},{1,2,3,4},{1,3,4,4} }; int (*p)[4]; //定义p为一个指针变量,指向包含4个整型元素的一维数组 p = a; printf("%d", *(*(p + 1) + 2));
3.