首页 理论教育C语言指向二维数组的指针变量应用

C语言指向二维数组的指针变量应用

【摘要】:在C语言中,二维数组是由一维数组作元素的一维数组。当需要用指针指向二维数组时,可以采用一级指针变量和二级指针变量两种处理形式。表8.3指向若干元素构成的一维数组指针变量表示二维数组元素使用指向由若干个元素组成的一维数组的指针处理二维数组。

在C语言中,二维数组是由一维数组作元素的一维数组。例如,int nums[2][3]可以看成由nums[0]和nums[1]两个元素组成的,而nums[0]和nums[1]分别是由3个元素构成的一维数组,如图8.6所示。

图8.6 二维数组结构

二维数组名可以理解为是每个元素都是一维数组的一维数组首地址,而作为元素的一维数组名本身也表示地址,因此二维数组名是二级地址。

按照C语言地址加法的规则,一维数组a[i]的j号元素地址可以表示为a[i]+j和&a[i][j]两种等价形式。根据上一小节讨论的一维数组与指针的关系,a[i]等价于*(a+i),所以有二维数组a的i行j列元素地址有多种等价表示形式:a[i]+j、*(a+i)+j和&a[i][j]。

在二维数组a中,a、a+i、a[i]、*(a+i)、*(a+i)+j、a[i]+j和&a[i][j]都是地址,其中a[i]、a+i和*(a+i)都是数组a的i行首地址,但它们表示的意义是有区别的。使用a+i的方式是将二维数组看成一个用一维数组作为元素的一维数组,其移动的方向是按每次移动过二维数组中的一行(即1个一维数组);而使用*(a+i)或者a[i]的方式则是将数组看成若干个简单变量元素组成的,其移动方向是每次移动二维数组中的一列(即一个元素)。图8.7展示的是一个3行4列数组a的存储示意图以及a+i和*(a+i)两种不同指针形式移动跨距的比较。

图8.7 二维数组行指针和列指针移动比较

从图8.7中可以看出,a+i和*(a+i)都表示一行的起始地址,例如,a+1和*(a+1)都表示二维数组a中1行的首地址;对于行指针a+i而言,每次移动过的元素个数为二维数组一行所具有的元素个数,例如,从a+1到a+2之间有4个数组元素;对于列指针*(a+i)而言,每次移动过的元素为1个,例如,从*(a+1)到*(a+1)+1之间仅有一个数组元素(注意:*(a+1)也可以写为*(a+1)+0)。

对于一个二维数组a,其所占存储区域的首地址有4种表示方式,它们是:a、a[0]、&a[0][0]和*a。这4种地址表示形式的地址级别是不同的,其中a是二级地址,其移动方式是每次移动过一行数组元素,所以其地址单位是二维数组中一行数据所占据的存储单元字节数;其余3个都表示一级地址,其移动方式是每次移动过一个数组元素,所以其地址单位为一个数组元素所占据的存储单元字节数。当需要用指针指向二维数组时,可以采用一级指针变量和二级指针变量两种处理形式。

1.使用一级指针变量指向二维数组

设有定义好的二维数组a和一级指针变量p1,那么p1指向二维数组a可以通过p1=a[0]、p1=&a[0][0]或p1=*a等表达式实现。特别需要注意的是:不能使用p1=a的方式将指针p1指向数组a,原因是p1是一级指针,只能用一级地址值作为其值,而a表示的是二级地址值。

当一个一级指针变量正确地指向了一个见二维数组首地址且指针没有移动时,常用于表示数组元素地址以及元素值的等价表示形式见表8.2。

表8.2 二维数组元素地址和元素值的等价表示形式

【例8.11】 使用不同的指针形式引用二维数组元素示例。

上面程序用3种不同的指针方式实现了二维数组元素的输出,程序执行的输出结果为:

810 540 515 585 914 342 336 825

810 221 575 464 356 234 462 602

810 540 515 585 914 342 336 825

810 221 575 464 356 234 462 602

810 540 515 585 914 342 336 825

810 221 575 464 356 234 462 602

2.使用二级指针变量指向二维数组

二维数组的名字是二级地址,对应能够表达出其行列结构信息的二级指针变量。当一个能够表达出二维数组一行数据个数的二级指针变量指向一个二维数组后,既可以通过该指针变量与整型数据的加法表达式表示二维数组中的某行,也可以通过指针变量的移动指向二维数组的某一行。需要特别注意的是,不能用一个一般的二级指针变量直接指向一个二维数组,其原因是二维数组都具有特定的构造形式(即有指定的行数和列数),直接定义的二级指针不能表达出二维数组的这些特征。例如,下面的C程序代码段是错误的:(www.chuimin.cn)

double a[5][10],**p;

p=a;  //这条C语句是错误的,不能直接将二级指针变量指向二维数组

能够指向二维数组的二级指针变量需要能够表达出二维数组列数(即一行长度)特征。C语言中可以通过指向由若干个元素组成的一维数组的指针变量来实现,指针变量定义的一般形式为:

[存储类别符]数据类型符(*变量名)[常量表达式];

其中,常量表达式的值就是指针变量一次移动所跨过的元素个数(即该指针变量的单位)。例如,int(*p)[10];表示定义了二级指针变量p,指针p的一次移动即可以移动过10个整型数据所占用的连续存储区域。

如果已经根据二维数组的列数定义好了指向由若干个元素组成的一维数组二级指针变量p,而且指针变量已经指向了特定的二维数组a,则二级指针变量p表示二维数组元素地址和元素值的常用形式见表8.3。

表8.3 指向若干元素构成的一维数组指针变量表示二维数组元素

【例8.12】 使用指向由若干个元素组成的一维数组的指针处理二维数组。

上面程序中用指向若干个元素组成一维数组的二级指针变量p指向二维数组a,使用*(*(p+i)+j)形式输出二维数组元素(也可以用*(p[i]+j)形式),程序一次执行的输出结果如下:

5 12 70 84 62 50 24 3

98 90 48 78 50 49 39 44

1 23 87 85 73 97 54 15

10 9 30 74 95 63 20 72