本章学习目标 .掌握数组的概念、定义和数组元素的引用方法。 .掌握一维数组、二维数组在程序设计中的应用。 .掌握字符数组和字符串的应用。 数组是C语言提供的一种构造类型数据,用来有效地处理一批同类型的相关数据。数 组是一组相同类型数据的有序集合,每一个数据称为数组元素,这些数组元素有一个共同的 名字即数组名,不同元素由其在数组中的序号即下标(从0开始编号)标识。本章介绍数组 的概念、定义和数组元素的引用方法,以及一维数组、二维数组、字符数组和字符串在程序设 计中的应用。 5.一维数组的定义和引用 1 C语言中,变量必须先定义,然后才能使用。数组也一样,在使用数组前要对它加以定 义。数组定义的主要目的是确定数组的名称、数组的大小和数组的类型。 数组是一组相同类型数据的有序集合,每一个数据称为数组元素,这些数组元素有一个 共同的名字称为数组名,不同元素由其在数组中的序号即下标来标识。用1个下标确定元 素的数组称为一维数组,用2个下标确定元素的数组称为二维数组,用3个及3个以上下标 确定元素的数组称为多维数组。C程序中用得比较多的是一维数组和二维数组,5. 1节先介 绍一维数组,5. 2节将介绍二维数组。 1.一维数组的定义 5.1 一维数组定义的一般形式为: 94 数组类型 数组名[常量表达式]; 其中,数组类型为C语言的类型说明符,标识数组元素的类型;数组名由用户指定,但必须符 合C语言标识符命名规则;常量表达式应为正整数常量,表示数组的长度即数组元素的个 数;[]是数组的标识。 数组定义后,C语言编译系统就在计算机内存中为数组分配一块连续的存储空间,用来 依次存放数组中各元素的值。 例如: int a[10]; 表示定义了数组a,数组的类型是int,该数组包含10个元素,分别是a[0]、a[1]、a[2]、a[3]、 a[4]、a[5]、a[6]、a[7]、a[8]、a[9],每一个元素可以用来表示一个int类型的数据,C编译系 统在内存中为int类型数组a分配10*sizeof(int)字节的连续空间,作为这10个元素的存储 区域,数组名a同时表示这一片连续存储空间的开始地址。 数组定义时需要注意,数组长度的定义不能用变量。例如: int n=10, a[n]; 是错误的。 在定义数组的同时,也可以同时为数组元素赋初值,称为数组的初始化。例如: int a[10]={1,2,3,4,5,6,7,8,9,10}; 则C语言在为数组分配存储单元的同时,还为数组各元素赋初值,a[0]的初值为1、a[1]的初 值为2、……、a[8]的初值为9、a[9]的初值为10。 一维数组的初始化有以下几点规则: (1)如对数组的所有元素赋初值,则可以不指定数组的长度。 例如: int a[]={1,2,3,4,5,6,7,8,9,10}; 与上面数组a的定义等价,这时数组的长度根据初值的个数确定。 (2)如对部分元素赋初值,则从数组第一个元素起按顺序给出初值,未赋初值的数值类 型数组元素初值为0、字符型数组元素初值为\' 0'。 例如: int a[10]={1,2,3}; 使a数组前3个元素的值依次为1、2、3,其余元素值为0。 char b[5]={'+','-'}; 使b数组前两个元素的值依次为'+'、'-',其余元素值为\' 0'。 95 (3)初值的个数不能多于数组长度。 例如:语句inta[5]={1,2,3,4,5,6,7,8,9,10};是错误的。 5.1.2 一维数组元素的引用 数组定义后,就可以在程序中使用了。对数组的使用是通过引用数组元素实现的,不能 将数组作为一个整体加以引用。一维数组元素的引用方式如下: 数组名[下标表达式] 下标表达式可以是整型表达式或字符型表达式,其取值范围是0~数组长度-1。一个 数组元素就是一个变量,称为下标变量。 例如: int a[10]; //数组定义 a[0]=5; //第1 个元素赋值为5 a[1]=2*a[3/4]; //第2 个元素值为2*a[0],即10 a[5]=a[3%2]+a['f'-'e']; //第6 个元素值为a[1]+a[1],即20 【例5.1】 用数组求斐波那契数列前40项,并打印输出。 程序设计分析:斐波那契数列的前两个数是1、1,第三个数是前两个数的和,以后的每 个数都是其前两个数的和。即: F1=1 (n=1) F2=1 (n=2) Fn=Fn-1+Fn-2 (n ≥3) #include void main() { int i; long int f[40]={1,1}; for(i=2;i<40;i++) //第5 行 f[i]=f[i-2]+f[i-1]; for(i=0;i<40;i++) { if(i%5==0) printf("\n"); //第8 行 printf("%10ld",f[i]); } } 程序运行: 96 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 程序说明:数组f的前两个元素f[0]、f[1](注意C语言数组的下标从0开始)通过初 始化赋初值,所以第5行的循环语句i从2起;程序第8行的if语句用于控制每一行输出5 个数。 【例5.2】 编程,输入一个班级学生(不多于50人)的一门功课成绩,计算平均成绩,并 统计高于平均成绩的学生人数。 #include void main() { float score[50],sum=0,aver; int i,n,k=0; printf("请输入学生人数:\n"); scanf("%d",&n); printf("请输入%d 个学生成绩:\n",n); for(i=0;i=aver) k++; printf("平均成绩:%.2f\t 高于平均分人数:%d\n",aver,k); } 程序运行: 请输入学生人数: 10 ↙ 请输入10 个学生成绩: 60 70 65 75 78 90 54 77 93 68 ↙ 平均成绩:73.00 高于平均分人数:5 程序说明:要处理的数据个数不确定,但有一个范围,即不多于50个,因此所定义的数 97 组长度为50。实际所处理的数据要根据人数n决定,n在运行时首先输入。第8行的循环 语句用来输入学生成绩和求成绩累加和,score[i]为数组元素,相当于一个普通变量,它的地 址为&score[i];第13行的循环语句用来统计高于平均成绩的人数。 初学者往往将这类问题的数组按下面的方法定义: float sum=0,aver; int i,n,k=0; printf("请输入学生人数:\n"); scanf("%d",&n); float score[n]; 这是不行的,数组长度的定义不能用变量。 5.2 二维数组的定义和引用 二维数组的每个数据有行列之分,用两个下标标识一个数组元素,适合于矩阵处理等应 用。二维数组的每一行元素其实就是一个一维数组,所以二维数组也被称作“数组的数组”。 5.2.1 二维数组的定义 与一维数组相同,二维数组也必须先定义,后使用。二维数组定义形式为 数组类型数组名[常量表达式] [常量表达式]; 其中:数组类型为C语言的类型说明符,标识数组元素的类型;数组名也由用户命名;常量 表达式应为正整数常量,第一个常量表达式表示数组的行数,第二个常量表达式表示每一行 的元素个数;[]是数组的标识。 例如: float a[3][4]; 表示定义了二维数组a,数组的类型是float,该数组包含3行4列共12个元素,分别是 a[0][0]、a[0][1]、a[0][2]、a[0][3]、a[1][0]、a[1][1]、a[1][2]、a[1][3]、a[2][0]、 a[2][1]、a[2][2]、a[2][3],每一个元素可以用来表示一个float型的数据,C语言编译系 统在内存中为float型数组a分配3*4*sizeof(float)字节的连续空间,作为这12个元素的 存储区域。 同样,不能用变量定义数组长度。如intn=3,m=4,a[n][m];是错误的;另外在定义 二维数组时,行列长度要分别用一对方括号括起来,写成inta[3,4]是不正确的。 定义数组后,C语言编译系统就在计算机内存中为二维数组分配一块连续的存储空间, 各元素在该区域内的存放顺序为以行为主序存放,即先依次存放第1行各元素,再依次存放 第2行各元素,以此类推。 98 在定义二维数组的同时也可以初始化各数组元素,方法与一维数组初始化相似,格式 如下: 二维数组定义={{表达式列表1},{表达式列表2},… } 或 二维数组定义={表达式列表} 第一种方法按行初始化,将表达式列表1中的数值给数组的第一行、表达式列表2中的 数值给数组的第二行、……;第二种方法将所有初始化数据写在一对大括号内,自动按行初 始化,没有初始化到的数组元素值为0。 例如: int a[3][4]={{1,2,3},{4,5}}; 则为数组a第1行各元素a[0][0]、a[0][1]、a[0][2]、a[0][3]依次赋值1、2、3、0;为第2 行各元素a[1][0]、a[1][1]、a[1][2]、a[1][3]依次赋值4、5、0、0;而第3行各元素初值均 为0。 当对二维数组初始化时,可以省略数组定义中的第一维长度,此时数组行数由初始化数 据的个数和列数决定。例如: inta[][4]={{1,2},{3,4,5},{6}};与inta[3][4]={{1,2},{3,4,5},{6}};等价。 intb[][3]={1,2,3,4,5,6,7};表示数组b是3行3列数组。 而inta[][]={1,2,3,4,5,6};不正确,不能确定每一行数组元素的个数。 本节开始时讲过,二维数组是“数组的数组”,每一行元素就是一个一维数组。例如: float a[3][4]; 定义了3行4列的二维数组,它由三个一维数组组成,即 (1)a[0][0]、a[0][1]、a[0][2]、a[0][3],数组名a[0]。 (2)a[1][0]、a[1][1]、a[1][2]、a[1][3],数组名a[1]。 (3)a[2][0]、a[2][1]、a[2][2]、a[2][3],数组名a[2]。 5.2.2 二维数组元素的引用 与一维数组相同,二维数组也是由一组相同类型的元素组成的,每一元素是一个下标变 量,对这些变量的引用和操作与一维数组相似。二维数组元素的引用方式为 数组名[下标表达式1][下标表达式2] 其中,下标表达式1和下标表达式2为整型表达式或字符型表达式,取值应限制在0~行长 度-1和0~列长度-1。 例如,有定义: 99 int x[2][3]; 则数组元素为x[0][0]、x[0][1]、x[0][2]、x[1][0]、x[1][1]、x[1][2]。每一元素是一个整 型变量,可以参加相应运算。如: scanf("%d",&x[0][0]); //输入数组元素x[0][0]的值 x[1][3-1]=x[0][0]%10; //将x[0][0]的个位数赋值给x[1][2] x[1][2]++; //x[1][2]自增1 【例5.3】 矩阵转置。 程序设计分析:矩阵转置即行列互换,原矩阵第i行数据转置后变成第i列。用二维数 组表示矩阵,矩阵的转置操作就是将数组元素a[i][j]与a[j][i]互换。程序如下: #define N 4 #include void main() { float a[N][N],temp; int i,j; for(i=0;i void main() { float a[M][N],max; int i,j,maxi,maxj; for(i=0;i