二维数组元素和指针之间的对应关系:
例如,有如下定义:
int a[3][4]={{10,20,30,40,},{50,60,70,80},{90,91,92,93}};
则数组a有3个元素,分别为a[0]、a[1]、a[2]。而每个元素都是一个一维数组,各包含4个元素,如a[1]的4个元素是a[1][0]、a[1][1]、a[1]2]、a[1][3]。
若有:
int *p=a[0];
则数组a的元素a[ i ][ j ]对应的指针为:p + i * 4 + j
元素a[1][2]也就可以表示为:*( p + i * 4 + j)
对上述二维数组 a,虽然 a [0 ]、a都是数组首地址,但二者指向的对象不同。
a[ 0 ]是一维数组的名字,它指向的是一维数组 a[ 0 ]的首元素 a[ 0 ][ 0 ],对其进行 “ * ” 运算,得到的是一维数组元素 a[ 0 ][ 0 ] 的值,即 *a[ 0 ]与a[ 0 ][ 0 ]是同一个值。
而 a 是一个二维数组的名字,它指向的是二维数组 a 的首元素 a[ 0 ],对 a 进行 “ * ” 运算,得到的是一维数组 a[ 0 ]的首地址,即 *a 与 a[ 0 ] 是同一个值。它的指针移动单位是“行”,所以 a + i 指向的是第 i 个行数组,即指向 a[ i ]。
当用 int *p;定义指针 p 时,p 的指向是一个 int 型数据,而不是一个地址,因此,用 a[ 0 ]对 p 赋值是正确的,而用 a 对 p 赋值是错误的。
另外,由上述说明,我们还可以得到二维数组元素的一种表示方法:
对于二维数组 a,其 a[ 0 ]数组由a指向,a[ 1 ]数组则由 a + 1指向,a[ 2 ]数组由 a + 2 指向,以此类推。因此,*a 与 a[ 0 ] 等价、*(a + 1) 与 a[ 1 ] 等价、*(a + 2) 与 a[ 2 ] 等价,┅,即对于 a[ i ] 数组,由 *(a + i) 指向。
由此,对于数组元素 a[ i ][ j ],用数组名 a 的表示形式为:*(*(a + i) + j)
指向该元素的指针为:*(a + i) + j
数组名虽然是数组的地址,但它和指向数组的指针变量不完全相同。指针变量的值可以改变,即它可以随时指向不同的数组或同类型变量,而数组名自它定义时起就确定下来,不能通过赋值的方式使该数组名指向另外一个数组。