当前位置:嗨网首页>书籍在线阅读

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)