版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第5章
数组理解数组概念及其在内存中的存储结构一维数组定义、初始化、引用二维数组定义、初始化、引用字符数组及字符串使用数组处理批量同类型数据问题应用所学知识灵活处理数据存储问题本章目标例5-1考试成绩统计,输入一组学生成绩以-1作为结束标记,计算所有成绩的平均分并统计高于平均分人数。分析:输入一组数据求平均分,使用循环就可以解决,读入数据累加,然后计算平均分(后读入数据覆盖先读入数据)若要统计高于平均分人数,就需要遍历之前所有输入的成绩数据,但是之前所学知识无法解决这个问题。使用数组存储读入的成绩数据,再求出平均分后,再遍历成绩数组,统计出高于平均分的人数。5.1初识数组
例5-1代码#include<stdio.h>intmain(){floatsum=0,ave;intscore;
intscores[100];intnum=0,count=0,i;printf("请输入学生成绩(以-1作为结束标记):\n");scanf("%d",&score);while(score!=-1){
scores[num]=score;sum+=score;num++;scanf("%d",&score);}if(num!=0){ave=sum/num;printf("学生平均成绩为:%.1f\n",ave);for(i=0;i<num;i++)if(scores[i]>ave)count++;printf("高于平均成绩的学生人数为%d\n",count);}elseprintf("没有输入有效成绩!\n");return0;}一维数组的定义形式:
类型名数组名[数组长度]说明:类型名确定每个数组元素的数据类型数组名是数组变量的名称,需要满足标识符命名原则数组长度,必须是确定的值5.1.2一维数组的定义及使用intnum[5];#defineM5......intnum[M];intn=5;intnum[n];
数组在内存中的存储数组初始化格式
类型名数组名[数组长度]={数组元素初值表};例如:intnum[5]={25,13,-12,36,54};intnum[]={25,13,-12,36,54};intnum[5]={25,13};说明:定义同时为数组元素赋值若对所有元素赋值,可以省略数组长度数组的初始化数组元素引用:数组名[下标]例如:num[i+1]=num[i]*2;说明:数组下标从0开始,可以使用的范围为0~数组长度-1注意数组下标不能越界数组定义完成后,只能通过下标对数组每个元素进行单独的使用,而不能单独使用数组名对整个数组进行访问数组元素的引用intnum[5];inti;for(i=0;i<5;i++)num[i]=i*2;1、遍历数组【例5-2】键盘输入一个班级人数n,以及n个学生《C语言程序设计》的分数,请编写程序对成绩进行分析,即统计最高分、最低分、平均分以及及格比例。分析n个学生成绩需要记录,所以使用数组分析时,需要遍历所有学生成绩,通过数组下标的变化实现对数组元素的遍历程序分为三部分设计:数据输入、找最大最小、输出结果使用一维数组解决问题
示例代码#include<stdio.h>intmain(){intscores[50],max,min,sum=0;intnum,i,count=0;doubleave,rate;printf("请输入学生人数:");scanf("%d",&num);printf("请输入学生成绩:\n");for(i=0;i<num;i++)scanf("%d",&scores[i]);max=scores[0];min=scores[0];for(i=0;i<num;i++){sum+=scores[i];if(max<scores[i])max=scores[i];if(min>scores[i])min=scores[i];if(scores[i]>=60)count++;}
/*平均分定义为double类型,计算时将sum强制类型转换为double*/ave=(double)sum/num;/*计算及格率时,需要将count强制类型转换为double类型*/rate=1.0*count/num;printf("******成绩分析*******\n");printf("最高分是:%d,最低分是:%d\n",max,min);/*输出使用格式控制符%0.1lf指明输出保留1位小数*/printf("平均分是:%0.1lf\n",ave);/*使用%%输出%,输出百分比结果因此输出内容为rate*100*/printf("及格率:%.1lf%%",rate*100);return0;}2、查找数组【例5-3】有一门课程的考试成绩,按照学号顺序存在数组中,现在输入一个成绩,想知道考这个成绩的学生学号,该如何实现呢?分析查找问题,遍历数组,找到后对应下标即为所求查找的两种情况:1、遍历数组,找到第一个就结束(从循环中break)2、遍历数组,要找到所有相等的数据(遍历所有元素,设置是否找到的标记)使用一维数组解决问题
示例代码#include<stdio.h>#defineM50intmain(){intiScore[M],input;intiNum,i,flag=0;/*flag标记是否查找到,0表示没有查找到*/printf("请输入班级人数:");scanf("%d",&iNum);printf("请输入%d个成绩:\n",iNum);for(i=0;i<iNum;i++)scanf("%d",&iScore[i]);printf("请输入待查询成绩:");scanf("%d",&input);
for(i=0;i<iNum;i++)if(input==iScore[i]){if(flag==0)printf("成绩为%d的学号为:%d",input,i+1);/*如果是第一次找到则输出*//*学号从1开始,而数组下标从0开始,所以返回i+1*/elseprintf("%d",i+1);flag=1;}if(flag==0)printf("没有找到成绩为%d的学生",input);return0;}3、数组中插入数据【例5-4】老师在录入成绩结束后核对发现,有一个同学的成绩落下了,导致从这个同学往后所有的同学成绩都向前串了一位。输入落下的同学的学号及对应的成绩,请编写程序帮助老师将成绩单整理正确。分析列表插入问题不能直接在对应位置赋值需要将后面的元素一次后移使用一维数组解决问题
示例代码#include<stdio.h>#defineM20intmain(){intiScore[M]={0,78,87,98,87,68,79,82,96,77};/*为使学号与下标对应,成绩从第1个数组元素开始存储*/intiId,i,input;printf("请输入插入成绩的学号:");scanf("%d",&iId);printf("请输入插入的成绩:");scanf("%d",&input);
if(iId<1||iId>10)printf("输入学号有误!\n");else{for(i=10;i>iId;i--)iScore[i]=iScore[i-1];iScore[i]=input;}printf("插入的成绩序列:");for(i=1;i<=10;i++)printf("%d",iScore[i]);return0;}4、借助数组计数【例5-5】一门课程期末考试成绩出来后,老师想了解得分情况,请你编写程序统计一下每个分数成绩都有多少人。分析要统计每个分数的人数,从第一个出现的成绩开始计数,会使程序十分复杂。百分制成绩数据范围一定在0~100之间,将成绩作为数组下标,数组元素值用来计数iCount[88]对应的值为分数为88的人数。使用一维数组解决问题
示例代码#include<stdio.h>#defineM50intmain(){intiScore[M],iNum,i;intiCount[101]={0};/*使用iCount[i]记录成绩为i的学生人数*/printf("请输入总人数:");scanf("%d",&iNum);printf("请输入%d个成绩:\n",iNum);for(i=0;i<iNum;i++)scanf("%d",&iScore[i]);for(i=0;i<iNum;i++)/*成绩iScore[i]对应下标的iCount数组元素累加*/iCount[iScore[i]]++;for(i=100;i>=0;i--)if(iCount[i]!=0)printf("%d分%d人\n",i,iCount[i]);return0;}5、排序问题【例5-6】期末考试结束后,若需要对一个班级学生的《C语言程序设计》成绩进行排序,应该如何完成呢?排序问题,先将问题进行分解:从第0个元素开始,找到数组的最大值的下标将最大值与第0个元素互换从第i个元素开始向后,找到最大值的下标,并且将最大值与第i个元素互换i从0到n-1,重复第3个步骤实现排序(选择法排序)使用一维数组解决问题从第0个元素开始,找到数组的最大值的下标
从第0个元素开始,找到数组的最大值的下标#include<stdio.h>#defineM50intmain(){intiScore[M],iNum,k,maxIndex;printf("请输入总人数:");scanf("%d",&iNum);printf("请输入%d个成绩:\n",iNum);for(k=0;k<iNum;k++)scanf("%d",&iScore[k]);/*使用maxIndex记录最大值下标,iScore[maxIndex]为当前最大值初始假设iScore[0]为最大值,因此初始时maxIndex=0*/maxIndex=0;for(k=1;k<iNum;k++)/*遍历数组,若记录的最大值比当前元素值小,则更新最大值下标*/if(iScore[maxIndex]<iScore[k])maxIndex=k;printf("成绩最大值为%d,下标为%d\n",iScore[maxIndex],maxIndex);return0;}
将最大值与第0个元素互换inttmp;tmp=iScore[0];iScore[0]=iScore[maxIndex];iScore[maxIndex]=tmp;
从第i个元素开始向后,找到最大值的下标,并且将最大值与第i个元素互换maxIndex=i;for(k=i+1;k<iNum;k++)
/*遍历数组,若记录的最大值比当前元素值小,则更新最大值下标*/if(iScore[maxIndex]<iScore[k])maxIndex=k;tmp=iScore[i];iScore[i]=iScore[maxIndex];iScore[maxIndex]=tmp;
i从0到n-1,重复第3个步骤实现排序(选择法排序)
i从0到n-1,重复第3个步骤实现排序(选择法排序)6、借助数组使程序易于维护【例5-7】学校每学期都会进行奖学金的评定,综合奖学金的评定成绩由以下几部分构成:学业平均成绩80%,竞赛获奖10%,班级贡献5%,活动参与5%,现在已知一位同学每部分百分制成绩,使用数组存储,请计算他的综合评定成绩。要考虑程序的可维护性。软件维护是指在软件产品发布后,因修正错误、提升性能或其他属性而进行的软件修改为了便于维护,将每个分项成绩的占比存放在数组中,将来修改更方便使用一维数组解决问题
示例代码#include<stdio.h>#defineM5intmain(){intiScore[M]={0};intiRate[M]={0,80,10,5,5};/*分项成绩存储在iScore[1]~iScore[4]中,综合成绩计算完成存入iScore[0]*/inti;printf("请输入学业平均成绩、竞赛获奖、班级贡献和活动参与成绩:\n");for(i=1;i<M;i++)scanf("%d",&iScore[i]);for(i=1;i<M;i++)iScore[0]+=iScore[i]*iRate[i];iScore[0]/=100;printf("该同学综合成绩是:%d\n",iScore[0]);return0;}【例5-8】输入一个专业所有学生的学业平均成绩、竞赛获奖成绩、班级贡献成绩、活动参与成绩,并且按照学业平均成绩80%,竞赛获奖10%,班级贡献5%,活动参与5%来计算每个学生的综合成绩,请编写程序完成这个任务。二维数组解决该问题每个学生有四项成绩,需要使用数组记录(一个维度)多个学生构成另一个维度5.2二维数组
#include<stdio.h>#defineMAXSTUNUM50#defineM5intmain(){
intiScore[MAXSTUNUM][M]={0};intiRate[5]={0,80,10,5,5};/*分项成绩存储在iScore[1]~iScore[4]中,综合成绩计算完成存入iScore[0]*/inti,j,iNum;printf("请输入学生人数:");scanf("%d",&iNum);printf("请输入每位学生的学业平均成绩、竞赛获奖、班级贡献和活动参与成绩:\n");for(j=0;j<iNum;j++)for(i=1;i<M;i++)scanf("%d",&iScore[j][i]);
for(j=0;j<iNum;j++){for(i=1;i<M;i++)iScore[j][0]+=iScore[j][i]*iRate[i];iScore[j][0]/=100;}for(j=0;j<iNum;j++)printf("第%d位同学的综合成绩是:%d\n",j+1,iScore[j][0]);return0;}二维数组定义形式:类型名
数组名[行长度][列长度]intnum[2][3];1、二维数组定义5.2.2二维及多维数组定义、初始化及引用2、二维数组初始化按行进行初始化intnum[2][3]={{1,2,3},{4,5,6}};顺序初始化intnum[2][3]={1,2,3,4,5,6};5.2.2二维及多维数组定义、初始化及引用3、二维数组引用二维数组引用形式:数组名[行下标][列下标]
行(列)下标取值范围[0,行(列)长度-1],可以是整型表达式。下列代码段以矩阵形式输出二维数组num。5.2.2二维及多维数组定义、初始化及引用inti,j,num[2][3]={1,2,3,4,5,6};for(i=0;i<2;i++){for(j=0;j<3;j++)printf(“%d“,num[i][j]);putchar(“\n”);}1、与矩阵相关操作【例5-9】给定一个n阶方阵,请编写程序判断这个矩阵是否为对称矩阵,所谓对称矩阵是指矩阵经过行列互换后得到的矩阵与原矩阵相等的矩阵。分析:使用二维数组记录方阵内容通过对行i和列j进行遍历,判断方阵特点5.2.3二维数组应用
示例代码#include<stdio.h>#defineM10intmain(){intn,i,j,iMatrix[M][M];printf("请输入矩阵的阶数:");scanf("%d",&n);printf("请输入矩阵:\n");for(i=0;i<n;i++)for(j=0;j<n;j++)scanf("%d",&iMatrix[i][j]);
for(i=0;i<n;i++){for(j=0;j<n;j++)if(iMatrix[i][j]!=iMatrix[j][i])break;if(j<n)break;}if(i>=n)printf("该矩阵是对称矩阵\n");elseprintf("该矩阵不是对称矩阵\n");return0;}2、二维数组的排序问题【例5-10】学校评奖学金,在求得一个专业每位同学的综合评定成绩后,请编写程序输出学生的学号排名。分析:需要存储的信息包括两部分:学号和成绩问题解决方案两种:学号信息使用一个数组,成绩使用另一个数组,对成绩数组排序,交换数据时同步交换学号信息学号和成绩作为数据的一个维度,所有数据存储在一个二维数组中,对二维数组进行排序对二维数组排序,分析排序依据和交换数据对象5.2.3二维数组应用
排序依据交换数据
关键代码/*对数组进行排序,排序依据是iScore[i][1]*/for(i=0;i<iNum-1;i++){index=i;for(j=i+1;j<iNum;j++)/*找到当前最大成绩行下标*/if(iScore[j][1]>iScore[index][1])index=j;/*将最大成绩行整体与最前面的行互换,因此需要遍历所有列*/for(k=0;k<2;k++){tmpScore[k]=iScore[i][k];iScore[i][k]=iScore[index][k];iScore[index][k]=tmpScore[k];}}
【例5-11】图灵在中学时代就对密码产生浓厚的兴趣,他与好朋友使用加密的内容传递小纸条。加密的规则是确定好一个秘钥key(绝对值10以内的数字),然后将消息中的字母使用字母表顺序该字母后key个字母替换。例如key是1,则消息中”A”用”B”替换,”B”用”C”替换,以此类推,最后”Z”用”A”替换。有一天图灵收到一条消息”WIICSYMEXASPSRKAIIOWHIEVIWXJVMIRH”已知秘钥是-4,请编写程序破译一下这条消息吧。分析:读入消息,将字符对应的ASCII码加秘钥后输出对应的字符批量的字符处理方式5.3字符串
示例代码#include<stdio.h>#defineM500intmain(){charstrCode[M];intkey;inti;printf("请输入秘钥:");scanf("%d",&key);getchar();
printf("请输入待解密的字符串以回车结束:\n");gets(strCode);for(i=0;strCode[i]!='\0';i++){/*小写字母的处理,将字符加秘钥*/if(strCode[i]>='a'&&strCode[i]<='z'){strCode[i]+=key;/*累加完超过字母范围处理*/if(strCode[i]>'z')strCode[i]-=26;elseif(strCode[i]<'a')strCode[i]+=26;}
/*大写字母的处理,将字符加秘钥*/elseif(strCode[i]>='A'&&strCode[i]<='Z'){strCode[i]+=key;if(strCode[i]>'Z')strCode[i]-=26;elseif(strCode[i]<'A')strCode[i]+=26;}}printf("解密后字符串为:\n");puts(strCode);return0;}字符串常量“IloveProgramming!”是一个字符串常量字符串特点字符串由字符序列和字符串结束符’\0’构成,字符串结束符’\0’对应ASCII表0,是不可见字符,占用存储空间。字符串“IloveProgramming!”由字符序列IloveProgramming!和不可见的’\0’构成。字符串中的字符序列称为字符串的有效字符。5.3.2使用字符数组存放字符串C语言没有字符串类型,字符串使用一维字符数组存储。charstr[20]=“LOVE”用字符串对字符数组初始化时,字符数组长度可以省略不写,但其真实长度是字符串长度+1。charstr1[]=“LOVE”charstr2[]={‘L’,‘O’,‘V’,‘E’}通过判断字符串结束符’\0’来判断字符串的结束for(length=0;str[length]!=‘\0’;length++);使用字符数组存放字符串的要点长度不一样!1、字符串输入输出函数1)使用格式控制符”%s”的scanf函数和printf函数scanf(“%s”,str); /*str为存放字符数组名*/printf(“%s”,str); /*str为存放字符数组名*/2)gets函数和puts函数<string.h>gets(str); /*str为存放字符串的字符数组*/puts(str); /*str为存放字符串的字符数组*/5.3.3与字符串相关的函数1、字符串输入输出函数注意两组函数的差别:1、scanf使用%s读取字符串时,遇到空格、回车或是制表符输入结束;gets函数从键盘读入字符串,遇到回车符输入结束2、printf使用%s直接输出字符串;puts函数将str中存储字符串输出到终端,并在字符串结尾出输出回车。5.3.3与字符串相关的函数【例5-12】从键盘读入一个单词,统计单词中每个字母出现的次数。分析:程序要求读入一个单词,因此中间没有空格,可以使用scanf语句读入。要统计每个字母出现的次数,字母的个数是有限的26个,结合一维数组中介绍的方法,可以使用一个长度为26的整型数组依次存储字母A(a)到Z(z)出现的次数,将每个字母的ASCII码转换为对应字母的下标,进行计数。字符串输入输出示例
代码示例#include<stdio.h>#defineM20intmain(){charstrWord[M];intiCount[26]={0},i;printf("请输入一个单词:\n");scanf("%s",strWord);for(i=0;strWord[i]!='\0';i++)if(strWord[i]>='a'&&strWord[i]<='z')/*找到字母strWord[i]对应下标累加*/iCount[strWord[i]-'a']++;elseif(strWord[i]>='A'&&strWord[i]<='Z')iCount[strWord[i]-'A']++;printf("%s中出现的字符为:\n");for(i=0;i<26;i++)if(iCount[i]!=0)printf("%c:%d\n",i+'A',iCount[i]);return0;}【例5-13】键盘输入一个段落,统计其中一共出现多少个单词。分析:要统计段落中出现的单词数,因此输入包括空格,字符串读入使用gets函数。统计单词个数就需要在每次遇到新单词时进行计数,如何才能确定当前字符是新单词的开始呢?设置一个标记位,在遇到非字母符号时标记为1,这样遇到字母符号当标记为为1就表示是新单词的开始。字符串输入输出示例
示例代码#include<stdio.h>#defineM500intmain(){charstrPara[M];intnewWflag=1,iWordCount=0,i;intisLetter;printf("请输入段落:\n");gets(strPara);for(i=0;strPara[i]!='\0';i++){isLetter=strPara[i]>='A'&&strPara[i]<='Z'||strPara[i]>='a'&&strPara[i]<='z';if(!isLetter)newWflag=1;elseif(isLetter&&newWflag==1){iWordCount++;newWflag=0;}}printf("文中出现了%d个单词\n",iWordCount);return0;}2、其他字符串函数头文件string.h中1、字符串长度函数strlen2、字符串复制函数strcpy3、字符串连接函数strcat4、字符串比较函数strcmp5.3.3与字符串相关的函数1、strlenstrlen(str); /*返回字符串有效字符长度*/例如:charstr[]=“LOVE”;printf(“%d”,strlen(str));输出为4,因为”LOVE”有效字符长度为4,但是需要注意这里str占用的字节数是5(有效字符长度+’\0’)。字符串函数2、strcpystrcpy(str1,str2); /*将字符串str2拷贝到str1中*/例如:charstr1[20],str2[]=“Programming”;/*参数str1必须定义为字符数组*/strcpy(str1,str2);puts(str1);将输出Programming。字符串函数2、strcpycharstr1[20]=“Love”,str2[]=“Programming”;strcpy(str2,str1);puts(str2);字符串函数3、strcatstrcat(str1,str2) /*将str2连接到str1后面,生成的新字符串存储在str1中*/例如:charstr1[20]=“Love”,str2[]=“Programming”;strcat(str1,str2);puts(str1);输出:LoveProgramming字符串函数4、strcmp例如:strcmp(“Love”,“Love”); /*返回0*/strcmp(“Love”,“Love“);/*返回负值,str2后面有空格*/strcmp(“Love”,“LOVE”);/*返回正值*/字符串函数字符串函数例题【例5-14】输入3个字符串,请按字符串长度从小到大对这三个字符串排序#include<stdio.h>#include<string.h>#defineM20intmain(){charstrA[M],strB[M],strC[M],strTmp[M];printf("请输入字符串A:");gets(strA);pri
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 互联网创业借款居间服务
- 剧院装修工程承包协议
- 抗病毒药品紧急空运协议
- 产业园翻新贷款模板
- 保健品运输服务合同样本
- 办公室翻新贷款合同模板
- 交通运输规划技术服务合同
- 医院教学设施改造范本
- 住宅区沥青运输协议样本
- 乳制品冷链运输分包协议
- 新教科版五年级上册科学 第三单元第5课《摆的快慢》教案
- 中南大学学位证书样本扫描件WORD
- 微机原理及单片机接口技术课后题答案_1-6章_
- 中国股票市场反向投资策略的实证研究
- 通灵蓝色火焰 柏林电影节事件营销方
- 多重中介模型及其应用
- 车位租赁合同电子版
- 化妆品行业标准操作程序《玻璃瓶检验标准》
- 可分离变量的微分方程(8)课件
- 苏J01-2005图集
- (精选)台阶和树木移除申请书
评论
0/150
提交评论