第7章数组主要内容:1、一维数组2、二维数组3、字符数组和字符串重点:数组的定义和数组元素的引用数组概述数组:用于保存一批相同类型的数据属构造类型数组名:一批同类型数据共有的名字。下标:数组中的各个数据用下标来区分。例如,一组实验数据、一批学生成绩、表、矩阵等的处理,均用数组数据类型表示。7.1一维数组例7.1输入50个整数,按逆序输出。main(){inta[50],i;/*定义数组a和循环变量i*/for(i=0;i50;i++)/*从键盘输入50个整数*/scanf(%d,&a[i]);for(i=49;i=0;i--)/*逆序输出50个整数*/printf(%4d,a[i]);}a[0]a[1]a[2]a[3]a[4]……a[49]…..一维数组:每个数组元素只带有一个下标一维数组的一般形式:类型说明符数组名[常量表达式]如:floatscore[30];float是类型说明符,定义了该数组中元素的类型。score是数组名,是这一组数据共有的的名字;30是常量表达式,表示数组的长度,即数组元素的个数。也就是说:数组score可以保存30个float型的数据。注意:定义数组时长度必须是确定的值。例如:intaa[];(error)intn;floatxs[n];(error)数组元素的引用:数组名[下标]如:a[i]是数组a中下标为i的数组元素;a[0]是下标为0的数组元素。C语言的规定:数组的下标从0开始。比如数组a[50]包含50个数组元素,分别是:a[0]a[1]a[2]……a[49]即下标的范围为0~49,不存在数组元素score[50]。若使用a[50]是危险的,为什么?一维数组的存储格式:每个数组占用一片连续的存储单元,按下标次序依次存放各元素。如intdata[10];数组data占2*10=20个字节data[0]data[1]data[2]……data[9]例7.3编程实现:输入某门课30人的成绩(0~100),要求将高于平均分的那些成绩打印出来。分析数据结构:30人的成绩,类型相同,可用一维数组来保存。分析算法:S1:输入30人的成绩并累加,用循环实现,循环体为“输入第k个人的成绩、并累加入部分和”;S2:求平均S3:求高于平均分的成绩。也用循环实现,循环体为“将第k个成绩平均分比较,若高,则输出”;循环条件为“k30,k的初值为0,增值为“k++”.#defineN3main(){floatscore[N],sum,average;intk;printf(\nenter%dscores:,N);sum=0;for(k=0;kN;k++)/*输入N个成绩,存入数组,并累加*/{scanf(%f,&score[k]);sum=sum+score[i];}average=sum/N;/*求平均*/printf(\naverage=%6.1f,average);for(k=1;kN;k++)if(score[k]average)printf(\n%6.1f,score[k]);}例7.4用起泡法对N个整数由小到大排序。起泡排序的基本思想是:相邻两个元素比较,按要求的顺序排放,比较一遍后,最大的元素被换到待排序数列的最后位置。对待排序序列依次重复上述过程,直至全部排完为止。数据结构:N个整数用一维整型数组保存。算法:(设N=5,待排序的数据为:321081)起泡排序过程为:第一遍:238110第二遍:231810第三遍:213810第四遍:123810分析:当待排序数据个数n=5时,共排n-1=4遍,第i遍待排序序列是从第1个元素到第n-i+1个元素。用双重循环实现。流程图:例7.4起泡排序。#defineN5main(){inta[]={0,3,2,10,8,1};intt,i,j;for(i=1;i=N-1;i++)for(j=1;jN-i+1;j++)if(a[j]a[j+1])/*若相邻两数逆序,则交换*/{t=a[j];a[j]=a[j+1];a[j+1]=t;}printf(\n);for(i=1;i=N;i++)printf(%d,a[i]);}数组a的长度为11,由初始值的个数决定。其中a[1]至a[10]为有效数据,a[0]未用,主要是为了符合我们的计数习惯。例7.5求某数列的前20项。该数列的特点:f1=0(n=1)f2=1(n=2)fn=fn-1+fn-2(nisodd)、fn=|fn-1-fn-2|(niseven)分析:数据结构:该数列中的数据均为整型,可用整型的一维数组来保存。算法:S1:从第三项开始,每一项都是前两项的和或差,可用循环实现:每循环一次计算出一项。求出前20项,分别存入数组中相应位置。S2:输出数组中的每一个元素,用循环实现。#includemath.hmain(){intf[21],k;f[1]=0;f[2]=1;for(k=3;k=20;k+=2){f[k]=f[k-1]+f[k-2];f[k+1]=abs(f[k]-f[k-1]);}printf(\nnumberlist:\n);for(k=1;k=20;k++){printf(%10d,f[k]);if(k%6==0)printf(\n);/*控制每行输出6个数*/}}一维数组的初始化一维数组的初始化:定义数组时可以给部分或全部数组元素赋初值,即数组的初始化。数组元素的初值依次放在一对花括号内。(1)只给部分元素赋初值。如:intx[20]={1,2};只给数组元素x[0],x[1]赋初值。(2)对全部数组元素赋初值,数组长度可以省略,由初值的个数决定。如:inta[]={0,3,2,10,8,1};7.2二维数组用于描述类似矩阵、表之类的数据结构特点:1)所有数据同类型,并且是由个数相等的几组数据组成。2)每组数据表示一个完整的含义,可看作是一个整体。比如,2*3的矩阵,共有6个数据,分成两组,每组3个数据,表示一行。可定义数组:intbb[2][3];又如,某班30人,期末考4门课,他们的成绩都是float型,共有120个成绩,分成30组,每组4个,即表示某一个人的成绩;或分成4组,每组30个,即表示某一门课的成绩。如定义数组:floatscore[30][4];可表示30人的成绩,每人4门课。floatsc[4][30];可表示4门课,每门可有30人的成绩。比较:若用一维数组,能表示所有的数据,但不能表示出数据之间的分组关系。例7.6输入某班(30人)期末考试4门课的成绩,计算出每人的平均成绩,按每行10个数据输出平均成绩。分析数据结构:30人4门课的成绩用二维数组表示,30人的平均成绩可用一维数组表示。算法:S1:输入30人(每人4门课)的成绩。S2:计算每人的平均成绩。S3:输出每个人的平均成绩。分别分析每一步如何实现?循环结构程序:main()/*例7.6*/{floatscore[30][4],aver[30],sum;inti,j;for(i=0;i30;i++)/*输入30人的成绩*/{printf(\nenter4scoresforno:%d\n,i+1);for(j=0;j4;j++)/*输入一个人4门课的成绩*/scanf(%f,&score[i][j]);}for(i=0;i30;i++){sum=0;/*循环体:计算每人的平均分*/for(j=0;j4;j++)sum+=score[i][j];aver[i]=sum/4;}/*nextpage*/for(i=0;i30;i++)/*输出每人的平均成绩*/{if(i%10==0)printf(“\n”);/*控制每行10个数据*/printf(%5.1f,aver[i]);}}二维数组定义的一般格式:类型名数组名[常量表达式1][常量表达式2]如floatscore[30][4];其中的数组元素为:score[0][0],score[0][1],score[0][2],score[0][3]score[1][0],score[1][1],score[1][2],score[1][3]score[2][0],score[2][1],score[2][2],score[2][3]……score[29][0],score[29][1],score[29][2],score[29][3]如表示2*3矩阵的数组bb的定义:intbb[2][3];其中的数组元素为:bb[0][0],bb[0][1],bb[0][2]bb[1][0],bb[1][1],bb[1][2]说明:数组每一维的下标均从0开始。(二维数组可看作特殊的一维数组,每个数组元素又是一维数组)存储格式:二维数组同一维数组一样,也占用一片连续的存储单元,且按行存放。数组名代表整个数组的起始地址,数组名与第一维下标代表某一行的起始地址。如score&score[0],score[i]&score[i][0]例7.7求已知矩阵a=的转置矩阵b=分析两个矩阵元素的对应关系:a[i][j]对应b[j][i].987654321963852741/*例7.7*/main(){inta[3][3]={{1,2,3},{4,5,6},{7,8,9}};/*数组a初始化*/intb[3][3],i,j;for(i=0;i3;i++)/*求转置矩阵b*/for(j=0;j3;j++)b[j][i]=a[i][j];printf(“\nmatrixa:\n”);/*输出矩阵a(按行输出)*/for(i=0;i3;i++){for(j=0;j3;j++)printf(%5d,a[i][j]);printf(“\n”);/*输出一行后,换行*/}/*接下页*//*上接页*/printf(“matrixb:\n”);/*输出矩阵b*/for(i=0;i3;i++){for(j=0;j3;j++)printf(%5d,b[i][j]);printf(\n);}}二维数组的初始化:(1)给全部数组元素赋初值:inta[3][3]={{1,2,3},{4,5,6},{7,8,9}};等价于inta[3][3]={1,2,3,4,5,6,7,8,9};或inta[][3]={1,2,3,4,5,6,7,8,9};其中第一维的长度可省略。(按行存储)(2)给部分数组元素赋初值:如intb[2][4]={{1,2},{6,8}};结果只给4个元素赋值为:b[0][0]=1,b[0][1]=2,b[1][0]=6,b[1][1]=8例7.8求N*N矩阵的两条对角线元素之和。(以4*4矩阵为例)分析:对角线有两条,每条有两个对角线元素,第k行的两个对角线元素为a[k][k],a[k][n-k-1]设s1、s2分别表示两条对角线元素的部分和,则对于矩阵的每一行,都要将其对角线元素加入对应的部分和变量中。因此用循环结构。循环体:s1+=a[k][k];s2+=a[k][n-k-1]条件:kNk的初值:0k的增值:k++#defineN4main(){inta[N][N],i,j,s1,s2;printf(“\nentermatrix:”);/*提示信息*/for(i=0;iN;i++)for(j=0;jN;j++)/*输入一行*/scanf(%d,&a[i][j]);s1=s2=0;for(i=0;iN;i++){s1+=a[i][i];s2+=a[i][N-i-1];}printf(\nsum=%d,s1+s2);}7.3字符数组和字符串一维字符数组常用来表示字符串,每个数组元素保存一个字符。例7.9下面程序将从字母‘b’开始的5个字符存入一个字符数组,并察看数组中的个元素。#includestdio.hmain(){charss[5],ch='b';inti;for(i=0;i5;i++){ss[i]=ch;ch++;}for(i=0;i5;i++)/*输出每个字符数组元