1第七章数组7.1一维数组的定义和引用7.3字符数组27.1一维数组的引出及使用一、一维数组的引出例:某班有40名学生,求该班成绩的平均分#includestdio.hvoidmain(){intj,s,sum=0;floatave;for(j=1;j=40;j++){scanf(“%d”,&s);sum=sum+s;}ave=sum/40;printf(“ave=%f”,ave);}这里只使用了一个变量s,虽然通过循环我们输入了40个学生的成绩,但循环结束后s中只是第40个学生的成绩,前面39个学生的成绩都没有保存下来如果要求保存这40名学生的成绩,最后再输出,应该怎么办?3因为现在要保存每个学生的成绩,那就不能只使用一个变量s了,而需要40个变量,这样一来输入、输出、计算都会变得繁琐。在这种情况下,我们希望能有一种数据类型可以保存一组数据,并且可以方便的对这组数据进行输入、输出、计算等操作,因此引出了数组类型。说明一个含有40个元素的数组,每个数组元素存放一个成绩,成绩的输入、输出、计算都可以通过循环来实现例:求某班成绩的平均分,并输出所有学生的成绩#includestdio.hvoidmain(){intj,sum=0,s[40];floatave;for(j=0;j=39;j++){scanf(“%d”,&s[j]);sum=sum+s[j];}ave=sum/40;printf(“ave=%f”,ave);for(j=0;j40;j++)printf(“%d,”,s[j]);}7.1一维数组的引出及使用4二、数组的概念1.数组:由具有相同类型的固定数量的元素组成的集合2.数组元素:每一个数组元素都是一个变量,为了与一般的变量相区别,我们称数组元素为下标变量3.下标变量在数组中的位置序号称下标下标变量的数据类型称为下标类型(或元素类型)7.1一维数组的引出及使用5三、一维数组的定义1.格式:类型标识符数组名[常量表达式];例:inta[10];2.说明(1)数组的类型实际上是指数组元素的取值类型。对于同一个数组,所有元素的数据类型都是相同的。84:668095101010121014:1028a[0]a[1]a[2]:a[9](2)数组名是用户定义的标识符,数组名表示了一个存储区的首地址(即第一个数组元素的地址)例:一个变量x的地址可以用&x来表示一个数组a的地址就用数组名a来表示,a等价于&a[0]7.1一维数组的引出及使用62.说明(3)数组长度:指数组中元素的个数(4)数组元素的下标由零开始例:inta[10]中a有10个元素,所以数组长度为10,数组元素分别是:a[0],a[1]…a[8],a[9](5)常量表达式中不能包含变量,其值也不能是实数intn;scanf(%d,&n);inta[n];intn=6;inta[n];intb[8.5];#defineSIZE8…inta[2+3];floatb[SIZE];对错7.1一维数组的引出及使用7四、数组元素的引用1.引用形式:数组名[下标]注意:如果出现a[5]=72;编译时不会指出错误,系统会将a[4]后下一个存储单元赋值为72,但这样可能会破坏数组以外其他变量的值847566809510101012101410161018a[0]a[1]a[2]a[3]a[4]72a[5]1020假设这个存储空间是变量x的,实际上a[5]是不存在的,如果执行了a[5]=72,会将x原有的正确数据覆盖掉2.说明(1)下标可以是整型常量或整型表达式如:a[1],a[2*3](2)数组定义为inta[5],数组长度为5而下标在0--4之内,即a[0]--a[4]7.1一维数组的引出及使用8五、一维数组的初始化1.概念:在定义一维数组时对各元素指定初始值称为数组的初始化inta[5]={1,3,5,7,9};2.说明(1)对数组的全体元素指定初值,初值用{}括起来,数据之间用逗号分开。这种情况下,可以不指明数组的长度,系统会根据{}内数据的个数确定数组的长度inta[]={1,3,5,7,9};(2)对数组中部分元素指定初值(这时不能省略数组长度)inta[5]={1,3,5};(3)使数组中的全部元素初始值都为0inta[5]={0,0,0,0,0};简单的写法:inta[5]={0};7.1一维数组的引出及使用13579135009逆序#includestdio.h#defineN10voidmain(){inti,t;inta[N]={5,8,0,1,9,2,6,3,7,4}for(i=0;iN/2;i++){t=a[i];a[i]=a[N-1-i];a[N-1-i]=t;}for(i=0;i=9;i++)printf(%3d,a[i]);}例:使数组元素a[0]~a[9]的值逆序再输出7.1一维数组的引出及使用5801926374a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]a[0]a[9]457830a[1]a[8]a[2]a[7]10例:用数组求fibonacci数列的前20个数#includestdio.hvoidmain(){inti,f[20]={1,1};for(i=2;i20;i++)f[i]=f[i-2]+f[i-1];for(i=0;i20;i++){if(i%4==0)printf(“\n”);printf(“%6d”,f[i]);}}110000:0f[0]f[1]f[2]f[3]f[4]f[5]:f[19]23586765i=2f[2]=f[0]+f[1]i=3f[3]=f[1]+f[2]i=4f[4]=f[2]+f[3]7.1一维数组的引出及使用117.1一维数组的引出及使用例:用筛选法求1—100间的素数0123456789101112131415161718…0023456789101112131415161718…00030507090110130150170…0000050700011013000170…第1步:先将1筛掉第2步:将2的倍数都筛掉第3步:将3的倍数都筛掉逐步将4、5…10的倍数都筛掉,最后数组中的非零数就是素数12#includestdio.h#includemath.hvoidmain(){inti,j,n,a[101];for(i=1;i=100;i++)a[i]=i;a[1]=0;for(i=2;i=sqrt(100);i++)for(j=i+1;j=100;j++){if(a[i]!=0&&a[j]!=0)if(a[j]%a[i]==0)a[j]=0;}…(见下页)7.1一维数组的引出及使用第1步:将1筛掉每次循环,筛掉i的倍数j从i+1开始逐渐变化到100,依次判断j是否是i的倍数对数组a的每个元素赋值,其值恰好等于其下标值13…n=0;for(i=1;i=100;i++){if(a[i]!=0){printf(%4d,a[i]);n++;}if(n%10==0)printf(\n);}}n是计数器,统计素数的个数i从1变化到100,判断数组元素a[i]是否等于0每输出10个换行7.1一维数组的引出及使用14找到x后结束循环例:输入一个数据,在已知数组中查找是否有该数据5801926374x9a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]#includestdio.hvoidmain(){inti,x;inta[10]={5,8,0,1,9,2,6,3,7,4};scanf(“%d”,&x);for(i=0;i10;i++)if(x==a[i]){printf(“find!a[%d]=x\n”,i);break;}if(i==10)printf(“nofind!\n”);}7.1一维数组的引出及使用15例:用冒泡排序法对6个数进行排序(从小到大)972541a[0]a[1]a[2]a[3]a[4]a[5]725419277547125417945152415792145791412冒泡排序方法:依次比较相邻的两个数,将小数放前面,大数放后面.n个数排序需要进行n-1轮比较,从第1轮到第n-1轮,各轮的比较次数依次为:n-1次、n-2次…1次9725419999972541初始状态第1轮第2轮第3轮第4轮第5轮77.1一维数组的引出及使用16#includestdio.h#defineN6voidmain(){inta[N],i,j,t;for(i=0;iN;i++)scanf(“%d”,&a[i]);for(i=0;iN-1;i++)for(j=0;jN-1-i;j++)if(a[j]a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}for(i=0;iN;i++)printf(“%3d”,a[i]);}输入6个数据用嵌套的for循环实现排序外层循环控制进行几轮比较内层循环控制每一轮的比较次数若前面的数大于后面的数,则进行交换输出排序后的6个数据7.1一维数组的引出及使用17例:用选择排序法对6个数进行排序(从小到大)972541a[0]a[1]a[2]a[3]a[4]a[5]选择排序方法:第1轮比较时,用a[0]依次与a[1]到a[5]进行比较,如果a[0]较大则进行交换,第1轮结束后,a[0]中为最小数.以后各轮比较过程与第1论类似.19754212975479574524124975124597795745972541729712初始状态第1轮第2轮第3轮第4轮第5轮7957797.1一维数组的引出及使用18#includestdio.h#defineN6voidmain(){inta[N],i,j,t;for(i=0;iN;i++)scanf(“%d”,&a[i]);for(i=0;iN-1;i++)for(j=i+1;jN;j++)if(a[i]a[j]){t=a[i];a[i]=a[j];a[j]=t;}for(i=0;iN;i++)printf(“%3d”,a[i]);}i=0时,进行5次比较,a[0]与a[1]比,a[0]与a[2]比,……a[0]与a[5]比,最后a[0]中为最小数i=1时,进行4次比较,a[1]与a[2]比,a[1]与a[3]比,……a[1]与a[5]比,最后a[1]中为第2小的数i=2时,进行3次比较,a[2]与a[3]比,a[2]与a[4]比,a[2]与a[5]比,最后a[2]中为第3小的数7.1一维数组的引出及使用19冒泡排序的改进方法971245a[0]a[1]a[2]a[3]a[4]a[5]712459124579124579124579第1轮第2轮第3轮第4轮第5轮124579从这道例题中我们发现,在进行完第二轮后,数据就排好序了,在第三轮中数据没有进行一次交换,说明排序已经完成了,第四、五轮的比较都是多余的,这种情况下应该终止排序过程初始状态20为了解决问题,在程序中设置一个变量flag,用它记录在每一轮比较中是否进行了交换在每轮比较开始前flag=0,如果在此轮比较中进行了交换,则flag=1,在一轮比较结束后,判断flag的值是否为1,如果值为1,则继续进行排序;如果值为0,说明在此轮比较中没有进行交换(即已经完成排序了),此时可终止循环(即结束排序)#includestdio.hvoidmain(){inta[6],i,j,t,flag;for(i=0;i6;i++)scanf(“%d”,&a[i]);i=0;do{flag=0;for(j=0;j5-i;j++)if(a[j]a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;flag=1;}i++;}while(flag);for(i=0;i6;i++)printf(“%3d”,a[i]);}冒泡排序的改进方法21分析选择排序过程发现,在每一轮的