第6章数组的定义和引用6.1一维数组6.1.1一维数组的定义由一组类型相同的相关数据项构造而成的集合称为数组(Array),在内存中占据连续的存储空间。构成数组的数据项称为数组的元素(elementofArray)。同一数组中的元素,具有相同的数据类型。1.一维数组的定义格式:[存储类型]数据类型数组名[数组长度]2.说明:(1)存储类型是auto类型或static类型,缺省时系统默认为auto类型。如果定义为auto类型,数组存放在动态存储区;如果定义为static类型,数组存放在静态数据区。(2)数据类型表示的是数组中各元素的数据类型,可以是任何基本类型和构造类型。但同一数组中的各元素必须属于同一数据类型。(3)数组名的命名应该符合C语言中标识符命名规则。(4)定义数组时,数组的长度是数组中元素的个数,只能用常量或符号常量表示,不能是变量或包含变量的表达式。例:inta[7];表示定义了一个自动存储类型,数组名为a,数组长度为7的整型数组。它是一个变量的集合,a数组中共包含有7个元素。数组元素的下标从0开始,因此a数组中的元素依次为a[0]、a[l]、a[2]、a[3]、a[4]、a[5]、a[6]。a数组在存储时,占用连续的存储单元,存储单元内的值是随机的。如图6-1所示。数组元素:a[0]a[1]a[2]a[3]a[4]a[5]a[6]存储单元:-235-413246684-9336-545图6-1数组a的内存分配图6.1.2一维数组元素的引用对数组元素的引用就是对数组元素的使用,数组定义之后就可以对数组元素引用和操作了。在C语言中,只能逐个引用数组元素,不能一次引用整个数组。一个数组元素就是一个变量,其使用规则与同类型的变量的使用是一样的。数组元素的引用格式:数组名[下标]它表示数组中的某个元素。下标是数组元素在数组中的排列序号,可以是整型常量、变量或表达式。例如:a[0]=a[1]+3+a[2*2]+a[9-3]〖例6-1〗一维数组的定义及引用。程序清单:#includestdio.hvoidmain(){inti,a[10];/*定义一个整型的一维数组*/for(i=0;i=9;i++)a[i]=i;/*对数组各元素赋值*/for(i=9;i=0;i--)printf(a[%d]=%d,i,a[i]);/*逆向输出数组元素的值*/}输出结果:a[9]=9a[8]=8a[7]=7a[6]=6a[5]=5a[4]=4a[3]=3a[2]=2a[1]=1a[0]=06.1.3一维数组的初始化数组的初始化可以在定义时完成,也可以在数组定义之后对数组元素逐个赋值。1.在定义时进行初始化的格式:数据类型数组名[数组长度]={数据1,数据2,…,数据n};例如:doubleb[4]={1.0,3.2,6,5.0};在定义b数组的同时完成了初始化,数组中的每个元素按照先后次序得到相应的赋值,即:b[0]=1.0,b[1]=3.2,b[2]=6.0,b[3]=5.0。2.说明:(1)花括弧中的数据应与定义的类型一致,否则系统会进行自动类型转换。(2)可以只给数组的前面一部分元素赋值。例如:inta[6]={0,3,2};a数组的前3个元素依次得到相应的赋值,而后3个元素则由系统自动赋为0。(3)在对数组全部元素赋值时,可以省略数组的长度。例如:inta[]={0,3,2,6,-9,10,45,78};系统会根据花括弧中初值的个数自动定义a数组的长度为8。对于static类型的未赋初值的数组,系统会自动将数组的全部元素初始化为0;而对于auto类型的数组,C编译器不对其进行初始化,必须在程序中进行初始化。6.1.4一维数组的应用〖例6-2〗输入10个数,输出其中的最大值和最小值。#includestdio.h#defineN10voidmain(){inti;floata[N],max,min;printf(input10numbers::\n,N);for(i=0;i=N-1;i++)scanf(%f,&a[i]);max=min=a[0];for(i=0;i=N-1;i++){if(a[i]max)max=a[i];if(a[i]min)min=a[i];}printf(max=%f\tmin=%f\n,max,min);}程序运行情况如下:input10numbers::1223134525678899034max=90.000000min=2.000000〖例6-3〗用冒泡法实现对10个数排序(升序)。冒泡法排序算法:将待排序的数据存放到一维数组a中。首先比较相邻两个数a[0],a[1],若a[0]a[1],则交换它们的值,然后用a[1]与a[2]相比较,若a[1]a[2],再交换它们的值,…,直到a[8]与a[9]比较处理完毕。经过第一轮9次比较之后,最大的数将“沉底”,小数将“上浮”;然后再对剩下的9个数进行第二轮比较,比较8次,…,直到最后一轮(第9轮)两个数比较,完成对所有数的排序。若对n个数排序,比较n-1轮,第一轮比较n-1次,第二轮比较n-2次,第i轮比较的次数是n-i。6.2二维数组相对于一维数组而言,二维数组是较为复杂的数组形式,可以用来建立更加复杂的数据结构。二维数组的定义、初始化和引用与一维数组类似。二维数组可以看成是特殊形式的一维数组,它由多行数据排列组合在一起构成。6.2.1二维数组的定义二维数组的定义格式:存储类型数据类型数组名[第一维长度][第二维长度]第一维长度代表数组矩阵的行数,第二维长度代表数组矩阵的列数。例如:inta[2][3];表示定义了一个auto类型,数组名为a的2行3列(共有6个元素)的整型二维数组。它可以看成一个特殊的一维数组,该数组的元素组成如下:a[0][0],a[0][1],a[0][2]a[1][0],a[1][1],a[1][2]二维数组在内存中是按先行后列的顺序存放。即先存放第一行元素,然后依次存放第二行、第三行、……。图6-4是数组a的内存分配图,各存储单元的值是随机值。数组元素:a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]存储单元:384500-9567678-783图6-4数组a的内存分配图6.2.2二维数组的引用同一维数组一样,二维数组也是必须先定义后引用,二维数组的引用也是通过下标来实现。格式为:数组名[行下标][列下标]其中,行下标和列下标表示数组元素所在的行和列,下标可以是常量,变量,或整数表达式。并且每个下标都必须用方括号括起来,行下标和列下标都不能超出定义范围。例:inta[3][4];a[0][3]表示二维数组a的第0行第3列的元素,a[i][j]表示a数组的第i行第j列的元素。对a数组中各元素引用时,行下标的范围为0~2,列下标的范围为0~3。应该注意的是,在使用二维数组时只能引用数组元素,而不能整行或整列的引用数组。〖例6-4〗二维数组的定义和引用程序清单:#includestdio.hvoidmain(){inti,j,a[4][5];for(i=0;i4;i++)/*给每个数组元素赋值*/for(j=0;j5;j++)a[i][j]=i*j;for(i=0;i4;i++){for(j=0;j5;j++)/*输出一行元素的值*/printf(a[%d][%d]=%2d,i,j,a[i][j]);printf(\n);/*每输出一行就回车换行*/}for(i=0;i4;i++){for(j=0;j5;j++)printf(%d,a[i][j]);/*按矩阵格式输出*/printf(\n);}}输出结果:a[0][0]=0a[0][1]=0a[0][2]=0a[0][3]=0a[0][4]=0a[1][0]=0a[1][1]=1a[1][2]=2a[1][3]=3a[1][4]=4a[2][0]=0a[2][1]=2a[2][2]=4a[2][3]=6a[2][4]=8a[3][0]=0a[3][1]=3a[3][2]=6a[3][3]=9a[3][4]=120000012340024680369126.2.3二维数组的初始化二维数组初始化可以在定义时完成,也可以在程序当中逐个赋值。1.在定义时初始化的一般格式为:数据类型数组名[第一维长度][第一维长度]={{数据行1},{数据行2},…,{数据行n}}或者写为:数据类型数组名[第一维长度][第一维长度]={数据1,数据2,…,数据n}数据行是指数组矩阵中某行数据按从左至右的次序排列起来的集合,数据行中的各数据项之间用逗号隔开。例如:inta[3][4]={{1,2,4,5},{3,2,9,6},{8,7,5,4}};数组a被初始化为:a[0][0]=1a[0][1]=2a[0][2]=4a[0][3]=5a[1][0]=3a[1][1]=2a[1][2]=9a[1][3]=6a[2][0]=8a[2][1]=7a[2][2]=5a[2][3]=4使用第二种形式进行初始化时,系统将按数组矩阵每个数据在内存中排列的顺序依次对数组元素赋值。上例可写成inta[3][4]={1,2,4,5,3,2,9,6,8,7,5,4};当二维数组的长度较小时,利用这种格式对数组进行初始化显得简洁方便。但当数组长度较大时,则容易引起混乱,而且不易修改,而利用第一种格式比较直观且方便修改。2.说明:(1)可以只给部分元素赋初值,此时系统将自动给剩余的元素赋0值。例如:inta[3][4]={{1,2},{3,2,6},{8,5}};数组a被初始化为:a[0][0]=1a[0][1]=2a[0][2]=0a[0][3]=0a[1][0]=3a[1][1]=2a[1][2]=6a[1][3]=0a[2][0]=8a[2][1]=5a[2][2]=0a[2][3]=0如果只对第二行元素赋初值,则可以写成:inta[3][4]={{0},{1,5,3}};当位于数组后面大部分的元素值为0时,使用第二种格式给数组矩阵赋初值。例如:inta[3][4]={1,0,5,2,3};数组a初始化为:a[0][0]=1a[0][1]=0a[0][2]=5a[0][3]=2a[1][0]=3a[1][1]=0a[1][2]=0a[1][3]=0a[2][0]=0a[2][1]=0a[2][2]=0a[2][3]=0(2)给全部元素赋值时,可省略一维数组长度。当使用上述两种初始化格式对二维数组的全部元素都赋初值时,可以省略第一维长度,但不能省略第二维长度。例如:inta[][4]={{0,2},{0},{2,5,6}};也可写成:inta[][4]={0,2,3,0,4,5,7,8,2,4,0,0};〖例6-5〗二维数组的初始化及使用。程序清单:#includestdio.hvoidmain(){inta[][4]={0,2,9,0,3,6,7,0,2,0,0};inti,j;for(i=0;i3;i++){for(j=0;j4;j++)printf(%d,a[i][j]);printf(\n);}}6.2.4二维数组应用举例〖例6-6〗编写程序,求3×4矩阵中值最小的元素的值,及其所在的行号、列号。分析:根据题目要求,可用一个二维数组存放矩阵,从二维数组所有元素中找出最小值,并记录其所在的行号,列号。算法如图6-5所示。程序清单:#defineROW3#defineCOL4#includestdio.hvoidmain(){inti,j,row,column,min;staticinta[ROW][COL]={{1,22,13,43},{345,3,-500,96},{-103,10,3,20}};min=a[0][0];for(i=0;i3;i++)for(j=0;j4;j++)if(a[i][j]min){min=a[i][j];row=i;column=j;}printf(最小值为:%d,位于第%d行,第%d列。\