2020/9/211例求一个班100个学生的平均成绩,然后统计高于平均分的人数。使用简单变量和循环结构相结合的方法求平均成绩:aver=0;for(i=1;i=100;i++){scanf(“%f”,&mark);aver=aver+mark;}aver=aver/100;2020/9/212若要统计高于平均分的人数,则无法实现。mark是一个简单变量,存放的是最后一个学生的成绩。用已有知识解决方法:1.再重复输入成绩,带来两个问题:(1)输入数据的工作量成倍增加;(2)若本次输入的成绩与上次不同,则统计的结果不正确。2.使用100个变量mark1,mark2,……,mark99,mark100。2020/9/213分析:1.此100个变量均为学生成绩,表示同一类对象。2.数据类型相同。3.可以用序号区分不同的变量。解决此问题的根本方法,引入数组,始终保持输入的数据,一次输入,多次使用。除了int、float、char等基本数据类型外,C语言还提供了构造数据类型,来满足不同应用的需要。构造数据类型是由基本数据类型按一定规则组成的,也称作“导出类型”。构造数据类型包括数组、结构体、共用体。数组(array)能将具有相同类型的数据组合在一起,通常是用于处理批量数据。Anarrayisadatatypethatusessubscriptedvariablesandmakespossibletherepresentationofalargenumberofhomogeneousvalues.第4章数组和指针数组中能唯一确定数组元素的下标的个数称为数组的维数一维数组:只用一个下标就能区分数组中的不同元素的二维数组:要用两个下标才能区分数组中的不同元素1×6一维数组3×4二维数组2×3×4三维数组inta[6];intb[3][4];intc[2][3][4];1.一维数组定义类型定义符数组名[整型常量表达式];【例如】inta[6];/17a[0]0145a[1]a[2]a[3]a[4]a[5]23a数组名表示内存首地址,是地址常量编译时系统分配连续内存内存字节数=数组维数*sizeof(元素数据类型)数组a在内存占24字节(6*4字节)Aone-dimensionalarraydeclarationisatypefollowedbyanidentifierwithabracketedconstantintegralexpression.Thevalueoftheexpression,whichmustbepositive,isthesizeofthearray.Itspecifiesthenumberofelementsinthearray.Thearraysubscriptscanrangefrom0tosize-1.Thelowerboundofthearraysubscriptsis0andtheupperboundissize-1.【例如】floatscore[50];charname[20];注意:不能用变量定义数组的长度。floatscore[n];×当定义数组语句中不同时给变量赋值时,方括号内不得为空。inta[];×数组一旦定义,数组的大小就不能再改变。常用的办法是用符号常量来指定元素个数。#definesize50floatscore[size];/172.一维数组初始化类型定义符数组名[常量]={值1,值2,…,值n};例如:inta[6]={1,2,3,4,5,6};inta[]={1,2,3,4,5,6};两者等价于:a[0]=1;a[1]=2;a[2]=3;a[3]=4;a[4]=5;a[5]=6;例如:inta[6]={1,2};等价于:a[0]=1;a[1]=2;a[2]=0;a[3]=0;a[4]=0;a[5]=6;intc[10]={0};//将0赋给c[0]~c[9]inta[]={1,2};//等价于:a[0]=1;a[1]=2;/171.数组元素的引用数组名[下标]注意:(1)数组元素的下标从0开始(2)引用数组元素时,只能单个引用,不能一次引用整个数组inta[6];a={3,4,5,6,7};×a[6]={3,4,5,6,7};×(3)下标不要超出数组的范围,否则导致错误的程序结果。/172.数组的赋值可以在定义数组时对数组中的全部变量或部分变量赋值(即数组的初始化)。可以在语句中为变量赋值。利用循环依次为每个数组元素赋值或输入值。main(){inti,a[5];for(i=0;i5;i++)a[i]=i;//用循环结构直接对数组赋初值for(i=0;i5;i++)printf(%d,,a[i]);printf(\n);}运行结果为:0,1,2,3,4,main(){inti,a[5];for(i=0;i5;i++)printf(a[%d]=,i),scanf(%d,&a[i]);for(i=0;i5;i++)printf(%d,,a[i]);printf(\n);}例:定义长度为10的整型类型一维数组并完成以下功能:⑴从键盘输入10个整数,分别存放在10个数组元素中;⑵输出数组中的各元素值;⑶按逆序输出数组中的各元素值。main(){inti,a[10];for(i=0;i10;i++)printf(第%d个数据:,i+1),scanf(%d,&a[i]);for(i=0;i10;i++)printf(%4d,a[i]);printf(\n);for(i=9;i=0;i--)printf(%4d,a[i]);printf(\n);}在C语言中,有N个元素的数组其元素下标的允许取值范围为0到N-1,不存在下标为N的元素。例如这段代码本意是要设置数组a中的10个元素均为0。但通常编译器按内存递减方式分配内存,使得内存中a[9]之后的4个字节分配给i。本来计数器i的值为10,循环体内将并不存在的a[10]设为0,实际是将i值设为0,就陷入死循环!main(){inti,a[10];for(i=1;i=10;i++){a[i]=0;printf(%d,a[i]);}}由键盘输入10个数,按由小到大排序输出解题方法:1.将10个数存入数组a2.将a(0)与a(1)、a(2)……a(9)依次比较,哪个元素的值比a(0)小,就将它与a(0)的值交换,这样就将最小的数送到了a(0)中。3.再将a(1)与a(2)、a(3)……a(9)依次比较,哪个元素的值比a(1)小,就将它与a(1)的值交换,这样就将最小的数送到了a(1)中。4.重复以上步骤。对于n个数,比较排序法的总运行次数为:(n-1)+(n-2)+…+3+2+1=n*(n-1)/2./17初始数列:51229479181350382第1趟:21229479181350385第2趟:25294712181350389第3趟:25947291813503812第4趟:25912472918503813第5趟:25912134729503818第6趟:25912131847503829第7趟:25912131829504738第8趟:25912131829385047第9趟:259121318293847501.比较法排序#includestdlib.hmain(){inti,j,a[10];srand(time(0));for(i=0;i10;i++){a[i]=rand()%101;printf(%4d,a[i]);}putch('\n');for(i=0;i9;i++){for(j=i+1;j10;j++)if(a[i]a[j])a[i]^=a[j]^=a[i]^=a[j];}for(i=0;i10;i++)printf(%4d,a[i]);}是一种交换类排序方法,它是通过相邻数据元素的交换逐步将线性表变成有序。1.首先将a[0]与a[1]、a[1]与a[2]、a[2]与a[3]、……a[n-2]与a[n-1]相邻两个数进行比较,若为逆序(比如a[0]a[1])则两者交换,这样就将将最大的数放在a[n-1]中;2.再将a[0]、a[1]、……a[n-2]这n-1个数进行同样的相邻两数比较,若为逆序则两者交换,这样就将这n-1个数中最大的数被放在a[n-2]中;3.重复以上步骤,经过n-1趟比较交换完成冒泡法排序。/17/17用冒泡法排序将10个整数按从小到大的次序排列出来。初始数列:51229479181350382第1趟:51229918134738250第2趟:51291813293824750第3趟:59121318292384750第4趟:59121318229384750第5趟:59121321829384750第6趟:59122131829384750第7趟:59212131829384750第8趟:52912131829384750第9趟:259121318293847502.冒泡法排序/17#includestdio.h#defineN10//数据的个数main(){inta[N]={5,12,29,47,9,18,13,50,38,2};inti,j,k,t;for(i=0;iN-1;i++){for(j=0;jN-i;j++)if(a[j]a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}}printf(\n最后的排序结果:\n);for(i=0;iN;i++)printf(%5d,a[i]);}2.冒泡法排序向一个有序数组中插入一个数字,插入后不改变原有顺序a[0]1a[1]2a[2]3a[3]4a[4]6a[5]7a[6]8a[7]9a[8]10a[9]0a[0]1a[1]2a[2]3a[3]4a[4]5a[5]6a[6]7a[7]8a[8]9a[9]10插入数字前插入数字后/17方法1:找到插入点后再移位。从前向后循环,从第1个元素开始依次将数组元素与要插入的数x比较,当xa[i]时,将a[i]~a[8]依次向后移动,这时a[i]就可以存放x了。for(i=0;i9;i++){//将要插入的数与每个元素比较,找插入的位置if(xa[i]){//依次将插入点后的元素向后移位for(j=8;j=i;j--)a[j+1]=a[j];a[i]=x;//插入数据后退出整个循环break;}}数组应用II--插入/17方法2:边找插入点边移位。从后向前循环,直接从最后1个元素开始,将其与要插入的数x比较,如果xa[i],说明x要插在a[i]的前面,那么a[i]元素就要向后移位;再将下标i--,做同样的比较,直到找到插入点退出循环,这时的a[i]x,因此x要赋值给a[i+1]。//从最后1个元素开始,依次将要插入的数与每个元素比较for(i=8;i=0;i--){//如果要插入的数比元素值小,则该元素直接向后移位if(xa[i])a[i+1]=a[i];elsebreak;//表示找到插入点,退出循环}a[i+1]=x;//插入数据数组应用II--插入main(){inti,j,del=0,inta[10]={1,2,3,4,5,6,7,8,9,10},x=5;for(i=0;i10;i++)printf(%4d,a[i]);putch('\n');for(i=0;i10-del;i++){//删除后数组的容量减小一if(x==a[i]){for(j=i;j10;j++)a[j]=a[j+1];i--;//还原到删除位置,以处理连续删除del++;}}for(i=0;i10-del;i++)printf(%4d,a[i]);}删除前:12345578910删除后:123478910二分法检索(在序列x[]中检索y的位置)前提:有序数列(以递增序为例)原理:等分区间;若y小于中间数,则取左半边,否则取右半边。再等分,再比较…例:对于区间[a,b]等分为若y==x[k]则位置为k