20-指向多维数组的指针
10.7.1 指向多维数组的指针
如何声明一个指针变量 pz 指向一个二维数组(如, zippo )?在编写处理类似 zippo 这样的二维数组时会用到这样的指针。把指针声明为指向 int 的类型还不够。因为指向 int 只能与 zippo[0] 的类型匹配,说明该指针指向一个 int 类型的值。但是 zippo 是它首元素的地址,该元素是一个内含两个 int 类型值的一维数组。因此, pz 必须指向一个内含两个 int 类型值的数组,而不是指向一个 int 类型值,其声明如下:
int (* pz)[2]; // pz指向一个内含两个int类型值的数组
以上代码把 pz 声明为指向一个数组的指针,该数组内含两个 int 类型值。为什么要在声明中使用圆括号?因为 [] 的优先级高于*。考虑下面的声明:
int * pax[2]; // pax是一个内含两个指针元素的数组,每个元素都指向int的指针
由于 [] 优先级高,先与 pax 结合,所以 pax 成为一个内含两个元素的数组。然后表示 pax 数组内含两个指针。最后, int 表示 pax 数组中的指针都指向 int 类型的值。因此,这行代码声明了两个指向 int 的指针。而前面有圆括号的版本,先与 pz 结合,因此声明的是一个指向数组(内含两个 int 类型的值)的指针。程序清单10.16演示了如何使用指向二维数组的指针。
程序清单10.16 zippo2.c 程序
/* zippo2.c -- 通过指针获取zippo的信息 */
#include <stdio.h>
int main(void)
{
int zippo[4][2] = { { 2, 4 }, { 6, 8 }, { 1, 3 }, { 5, 7 } };
int(*pz)[2];
pz = zippo;
printf(" pz = %p, pz + 1 = %p\n", pz, pz + 1);
printf("pz[0] = %p, pz[0] + 1 = %p\n", pz[0], pz[0] + 1);
printf(" *pz = %p, *pz + 1 = %p\n", *pz, *pz + 1);
printf("pz[0][0] = %d\n", pz[0][0]);
printf(" *pz[0] = %d\n", *pz[0]);
printf(" **pz = %d\n", **pz);
printf(" pz[2][1] = %d\n", pz[2][1]);
printf("*(*(pz+2) + 1) = %d\n", *(*(pz + 2) + 1));
return 0;
}
下面是该程序的输出:
pz = 0x0064fd38, pz + 1 = 0x0064fd40
pz[0] = 0x0064fd38, pz[0] + 1 = 0x0064fd3c
*pz = 0x0064fd38,000 *pz + 1 = 0x0064fd3c
pz[0][0] = 2
*pz[0] = 2
**pz = 2
pz[2][1] = 3
*(*(pz+2) + 1) = 3
系统不同,输出的地址可能不同,但是地址之间的关系相同。如前所述,虽然 pz 是一个指针,不是数组名,但是也可以使用 pz[2][1] 这样的写法。可以用数组表示法或指针表示法来表示一个数组元素,既可以使用数组名,也可以使用指针名:
zippo[m][n] == *(*(zippo + m) + n)
pz[m][n] == *(*(pz + m) + n)