首页 理论教育C语言程序设计基础:二维数组和多维数组

C语言程序设计基础:二维数组和多维数组

【摘要】:图6.3二维数组a[3][4]示意图多维数组定义的一般形式为:数据类型符数组名[常量表达式][常量表达式]…图6.4二维数组存储示意图图6.5三维数组存储示意图根据多维数组在存储器中按行存储的规则和多维数组的行列顺序可以计算出多维数组元素存储时在线性连续存储单元中的排列序号。

在程序设计中如果需要处理诸如矩阵、平面的或立体的图形等数据信息,使用一维数组显然不方便,此时可使用二维、三维以至更多维的数组。一维数组存储线性关系的数据,二维数组则可以存储平面关系的数据,三维数组可以存储立体信息,依次类推可以合理地使用更高维数的数组。

1.二维数组和多维数组的定义

C语言中对多维数组概念的解释是:n维数组是每个元素均为n-1维数组的一维数组。由此可以推论出二维数组是由若干个一维数组作为数组元素的一维数组,三维数组则是由若干个二维数组作为元素的一维数组,多维数组的这种概念对理解多维数组的存储、处理都有很大的帮助。

二维数组定义的一般形式为:

数据类型符 数组名[常量表达式1][常量表达式2];

二维数组的元素个数为整型常量表达式1与整型常量表达式2的乘积。各维元素的下标仍然从0开始。

例如int a[3][4]是表示3行4列的二维数组,共12个元素,每个元素均是int型数据,如图6.3所示。

图6.3 二维数组a[3][4]示意图

多维数组定义的一般形式为:

数据类型符 数组名[常量表达式][常量表达式]…;

例如,int a[3][4],matrix[10][10][10];就定义了整型二维数组a和三维数组matrix,其中a由3行4列共12个元素构成;matrix由10×10×10共1 000个元素组成。

C语言中规定数组按“行”存储,由于计算机系统内存是一个线性排列的存储单元集合,所以当需要将二维或多维数组存放到系统存储器中时,必须进行二维空间或多维空间向一维空间的投影。例如,有定义语句:int a1[2][2],a2[2][2][2];,则数组a1和a2在内存中存放的形式如图6.4和图6.5所示。

图6.4 二维数组存储示意图

图6.5 三维数组存储示意图

根据多维数组在存储器中按行存储的规则和多维数组的行列顺序可以计算出多维数组元素存储时在线性连续存储单元中的排列序号。

设有m×n(m行n列)二维数组a,用i、j表示行列下标,则二维数组元素a[i][j]在数组的连续存储区域中的单元序号计算公式为:

i×n+j;  //行号×列数+列号例如,有二维数组定义int a[5][5];,则数组中的元素a[2][3]在线性存储区域中的序号为:2×5+3=13,即将二维数组投影为一维序列存储后,二维空间中的2行3列元素是一维空间中的13号元素。

设有p×m×n(p页m行n列)三维数组a,则三维数组元素a[i][j][k]在数组的连续存储区域中的单元序号计算公式为:

i×m×n+j×n+k;//页号×行数×列数+行号×列数+列号

例如,有三维数组定义int a2[2][2][2];,则数组中元素a2[0][1][1]在线性存储区域中的序号为:0×2×2+1×2+1=3,即将三维数组投影为一维序列存储后,三维空间中的0页1行1列元素是一维空间中的3号元素。

2.二维数组和多维数组的初始化

多维数组也可以进行初始化,以二维数组和三维数组为例,初始化的方式有两种:

(1)分行赋值初始化方式

二维(多维)数组分行初始化方式是将二维(多维)数组分解为若干个一维数组,然后依次向这些一维数组赋初值,赋值时使用大括号(花括号)嵌套的方法区分每一个一维数组,例如:

int a[2][3]={{1,1,1},{2,2,2}};

int a1[2][3][3]={{{1,1,1},{2,2,2},{3,3,3}},{{4,4,4},{5,5,5},{6,6,6}}};

(2)单行赋值初始化方式

二维(多维)数组单行初始化方式是使用一个数据序列为多维数组赋初值。使用这种方式时将所有的初始化数据依次写在一个大括号中,书写时要注意数据正确的排列顺序。例如:

int a[2][3]={1,1,1,2,2,2};

int a1[2][3][4]={1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6};

在对二维数组或多维数组进行初始化时,还需要注意以下几点:

①初始化数据序列中只给出部分数组元素的初始值。这种方法称为部分初始化,此时未初始化元素值为0(字符类为'\0')。例如,int a[2][3]={{1,1},{2,2}};,则初始化后二维数组a的取值形式如图6.6所示。

图6.6 二维数组部分初始化

图6.7 二维数组部分初始化

例如,int arr[2][3]={1,1,2,2};,则初始化后二维数组arr的取值形式如图6.7所示,读者应该特别注意上面两个初始化示例以及图6.6与图6.7的区别。同样,如果需要将二维数组或多维数组的所有元素值初始化为0,可按如下所示的部分初始化形式即可:(www.chuimin.cn)

int b[10][20]={0};    /*将数组b的200个元素初始化为0值*/

int c[100][100][50]={0};/*将数组c的50万个元素初始化为0值*/

②由初始化元素值的个数确定数组最高维的长度。初始化时,如果多维数组最高维的长度没有指定,则系统通过对初始化序列中数值的个数的统计计算来确定多维数组最高维的长度;或者说如果在初始化时给出了全部的数组元素初始值,可以不指定多维数组最高维的长度。

例如,int a[][3]={{1,1,1},{2,2,2}}; /*初始化时给出了所有元素值*/

例如,int a1[][3]={1,1,1,2,2,2};/*初始化时给出了所有元素值*/

③多维数组初始化数值的个数必须在各维规定的范围内。例如,下面多维数组初始化形式是错误的:

int a1[2][3]={1,1,1,2,2,2,3,3,3};/*初始化表中的数值个数太多*/

3.二维数组的基本操作

二维数组和多维数组元素的下标表示分别为:

数组名[下标][下标]; 和 数组名[下标][下标]…;

其中,下标值应该是整型常数、变量或表达式,该值表示了数组元素在多维数组中的位置,如果下标值是实型数据,系统会自动将其取整。

对于二维数组,可以像普通变量一样对其任一元素进行处理,当需要数组中所有元素参与运算时,则使用二重循环的形式进行处理。

设有定义语句:int a[2][3],i,j;,下面展示了二维数组常见处理的代码段:

(1)按行输入二维数组各元素值

(2)按列输入二维数组各元素值

(3)求二维数组各元素最大值

习惯上采用先行后列的形式处理多维数组中的各个元素。在多重循环结构中,也可以改变下标变量的取值范围,按列优先、倒序等方式输入、输出、处理二维或多维数组。

【例6.3】 从键盘上输入一个3行3列矩阵的各个元素的值,然后输出2条主对角线元素之和。

程序运行结果如下所示:

【例6.4】 在二维数组a[3][4]中依次选出各行最大元素值存入一维数组b[3]的对应元素中。

程序运行结果如下所示: