5.1.4 二维数组
二维数组是包含两个下标标号的数组。二维数组是最简单的多维数组,下面就介绍二维数组的定义和初始化以及它在程序中的应用。
1.二维数组的定义
二维数组可以看做是以一维数组为数组元素构成的新的一维数组。二维数组的定义形式如下。
类型说明符数组名[常量表达式1][常量表达式2];
其中,两个方括号中的“常量表达式1”和“常量表达式2”分别定义了该二维数组的行数和列数,整个数组的元素个数为行数和列数的乘积。由于C51语言不支持动态分配数组大小,因此同一维数组一样,在定义二维数组时不能使用变量来表示数组的行数和列数。
二维数组定义的示例如下。
int ab[10][20];
该语句声明ab为(10,20)的二维整型数组,有10行20列,共10×20=200个数组元素。
在C51语言中,使用方括号来区分下标,即用方括号将各维下标括起。另外,二维数组的下标均从0开始计算。例如,要使用数组ab中行标为3、列标为5的元素可以写成如下形式。
ab[3][5]
对二维数组赋值也要和一维数组一样,对数组元素逐个赋值。程序示例如下。
include<stdio.h>//头文件
void main()//主函数
{
int t,i,num[3][4];//定义整型二维数组num
for(t=0;t<3;++t)//使用for循环为其中的数组元素赋值
for(i=0;i<4;++i)
num[t][i]=(t*4)+i+1;
}
该程序可以在KeilµVision3编译环境中执行。在程序执行后,得到如表5.2所示的数组num的数组元素值表。
从上表可以看出,二维数组的存储形式类似于行列矩阵。其中,第一个下标代表行,第二个下标代表列。当按照内存中的实际存储顺序访问数组元素时,右边的下标比左边的下标变化快一些。C51语言中二维数组的第一个下标可以看做是行的指针。二维数组在单片机内存中的存储情况如图5.2所示。
图 5.2 二维数组在内存中的存储
一个二维数组一旦被定义,其中所有的数组元素都将在单片机中分配到相对应的存储空间。二维数组所需的存储空间总字节数的计算公式如下所示。
总字节数=类型字节数×行数×列数。
例如二维数组d[6][5],其被定义为双字节整型,大小为(6,5)。存放该数组时,需要占用单片机6×5×2=60字节的存储空间。
2.二维数组初始化
在C51中,二维数组的初始化可以有以下3种方式。
❑按照顺序逐个给数组元素赋值,示例如下。
int sum[2][5]={-5,0,9,-4,1,6,8,0,3,7};
本例中,在定义二维整型数组sum时,就对其进行了初始化。这里将所有的数组元素值按顺序放在一个花括号中,并用逗号分割数组元素。数组元素的分配顺序按照逐行逐列的方式,即先是第一行的列数从1到5,然后第2行的列数从1到5,依次直至整个数组赋值完毕。
❑逐行给数组元素赋值,示例如下。
int sum[2][5]={
{-5,0,9,-4,1},//第一行
{6,8,0,3,7}};//第二行
本例中,在定义二维整型数组sum时,就对其逐行进行了初始化。数组sum有两行5列,首先用第一个花括号“{-5,0,9,-4,1}”为数组的第一行赋值,第二个花括号“{6,8,0,3,7}”为数组的第二行赋值。每个花括号内都有5个数,正好对应了每行的5个数组元素。
技巧在对二维数组进行初始化时,推荐使用逐行赋值的方式,这样每行元素的值都一目了然,便于程序的阅读以及后续的调试修改。采用这种方式赋值时,注意每一行结束时有一个大括号},在该大括号后面需要有一个逗号,最后一行的结束处不需要逗号,但在最外层的大括号}后面有一个分号。
❑部分初始化二维数组,示例如下。
int num[4][4]={{1,2,3,4},{-2,0,-1,3},{7,10,-9,6}};
本例定义了二维整型数组num,其大小为4行4列。但是在初始化时,只对数组的前3行进行了赋值。在这种情况下,最后一行的4个元素num[3][0]、num[3][1]、num[3][2]和num[3][3],均被系统自动赋值为0。
部分初始化也可以单独对列元素进行赋值,示例如下。
int num[4][4]={{5},{-3},{0},{6}};
上面的语句相当于只对二维数组num的第一列进行赋值,即num[0][0]=5、num[1][0]=-3、num[2][0]=0和num[3][0]=6,而其余元素均被自动赋值为0。
二维数组的程序示例如下。
include<stdio.h>//头文件
void main()//主函数
{
int t,i,j[3][4];//定义整型变量
int j[3][4];//定义二维整型数组j
for(t=0;t<3;++t)//两重循环为数组j赋值
for(i=0;i<4;++i)
j[t][i]=(t*4)+i+1;
for(t=0;t<3;++t)//行循环
for(i=0;i<4;++i)//列循环
{
if(j[t][i]%3==0)//判断是否能被3整除
printf(“j[%d][%d]=%d\n”,t,i,j[t][i]);//如果能够整除,则输出该元素
}
}
该程序可以在KeilµVision3编译环境中执行,运行的结果如下。
j[0][2]=3
j[1][1]=6
j[2][0]=9
j[2][3]=12
本例中,先采用二重循环为二维整型数组j循环赋值,然后再用二重循环对每一个数组元素进行判断,如果数组元素的值是3的整数倍,就输出该数组元素。这样就可以搜索出数组中所有能被3整除的数组元素。