图7.14 二维数组表示
设有整型二维数组a[3][4]如下:
0 1 2 3
4 5 6 7
8 9 10 11
在程序中可作如下的定义:
int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
设数组a的首地址为1000 H,各下标变量的首地址及其值如图7.15所示。
C语言允许把一个二维数组分解为多个一维数组来处理,即可以把一个二维数组看成若干个行向量,每个行向量都是一个一维数组。因此,数组a可分解为三个一维数组,即a[0]、a[1]、a[2]。每一个一维数组又含有四个元素。
图7.15 二维数组分解示意图
从二维数组的角度来看,a是二维数组名,a代表整个二维数组的首地址,也是二维数组第0行的首地址,等于1000 H。a+1代表第一行的首地址,等于1010 H。a+2代表第二行的首地址,等于1020H。
a[0]是第一个一维数组的数组名和首地址,因此也为1000H。*(a+0)或*a是与a[0]等效的,它表示一维数组a[0]的0号元素的首地址,也是1000H。&a[0][0]是二维数组a的0行0列元素的首地址,同样为1000H。因此,a、a[0]、*(a+0)、*a、&a[0][0]是相等的。
同理,a+1是二维数组第1行的首地址,等于1010H。a[1]是第二个一维数组的数组名和首地址,因此也为1010H。&a[1][0]是二维数组a的1行0列元素地址,也是1010H。因此,a+1,a[1]、*(a+1)、&a[1][0]是等同的。由此可得出:a+i、a[i]、*(a+i)、&a[i][0]是等同的。
此外,&a[i]和a[i]也是等同的。因为在二维数组中不存在元素a[i],所以不能把&a[i]理解为元素a[i]的地址。C语言规定,a[i]是一种地址计算方法,表示数组a的第i行首地址。由此得出:a[i]、&a[i]、*(a+i)和a+i也都是等同的。
另外,a[0]也可以看成是a[0]+0,即一维数组a[0]的0号元素的首地址,而a[0]+1则是a[0]的1号元素首地址,由此可得出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+i)+j),如图7.16所示。
图7.16 a[i]+j与a+i的关系示意图
若有“int*p;”,对于任意二维数组a(i行j列)而言,a[i]是指向第i行第一个元素的地址,当p=a[i]时,可以用指针p对a进行访问。
例如:
for(p=a[i];p<&a[3];p++)
*p=0; //对i行的所有元素清零
同样,作为数组a的第一个元素a[0][0],当p=&a[0][0],p指向了数组的第一个元素地址,可以利用p访问所有数组元素。
例如:
for(p=&a[0][0];p<&a[3][4];p++)
sum+=*p; //对数组a的元素求和
对数组a还可以写成:
p=&a[0][0];
while(p<&a[3][4])(www.xing528.com)
sum+=*p++
需要注意:*p++方式是指针遍历数组元素最常用的方法。
【例7.13】输出二维数组有关的值。
程序内容如下:
1 #include<stdio.h>
2 void main()
3 {
4 int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
5 printf("%d\n",a);
6 printf("%d\n",*a);
7 printf("%d\n",a[0]);
8 printf("%d\n",&a[0]);
9 printf("%d\n",&a[0][0]);
10 printf("%d\n",a+1);
11 printf("%d\n",*(a+1));12 printf("%d\n",a[1]);
13 printf("%d\n",&a[1]);
14 printf("%d\n",&a[1][0]);
15 }
程序结果如图7.17所示:
图7.17 例7.13程序结果图
【例题中关键问题说明】
(1)a、*a、a[0]、&a[0]都表示的是数组a的首地址,所以再输出时显示的即为a的首地址。
(2)a+1、*(a+1)、a[1]、&a[1][0]都表示的是数组a的1行0列元素地址。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。