《c语言大学实用教程第6章数组-新.ppt》由会员分享,可在线阅读,更多相关《c语言大学实用教程第6章数组-新.ppt(95页珍藏版)》请在三一办公上搜索。
1、第6章 数组,C语言大学实用教程,如何计算一个班级学生的平均分数?如何记录直线上的整数点?比如(0,0)、(1、1)、(2、2)、(3、3)、(4、4)、(5、5)。,数组,问题:给一组数排序,这组 数该 如何存放呢,?这些数据如何存放才便于排序,1,8,8,8,8,8,8,8,8,8,8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,8,第6章 数组,数组,内容提要,数组类型;向函数传递一维数组和二维数组;常用算法:排序、查找、求最大最小值等;用字符数组存取字符串;使用字符串处理函数处理字符串,数组的用处,保存大量同类型的相关数据如矩阵运算,
2、表格数据等,构造数据类型之一 数组:有序数据的集合,用数组名标识 元素:属同一数据类型,用数组名和下标确定,6.1 一维数组一维数组的定义:数据类型 数组名常量或常量表达式;,合法标识符,表示元素个数下标从0开始,例 int a6;,编译时分配连续内存内存字节数=数组定义的元素个数*sizeof(元素数据类型),数组名表示内存首地址,是地址常量,一维数组的引用数组必须先定义,后使用只能逐个引用数组元素,不能一次引用整个数组数组元素表示形式:数组名下标其中:下标可以是整型常量或整型表达式 以0开始,到n-1结束,例 int a10;printf(“%d”,a);()必须 for(j=0;j10;
3、j+)printf(“%dt”,aj);(),例 int data5;data5=10;/C语言对数组不作越界检查,使用时要 注意下标越界是大忌!使用大于最大下标的下标,将访问数组以外的空间。那里的数据是未知的,可能带来严重后果,数组的定义与初始化,数组定义后的初值仍然是随机数,一般需要我们来初始化int a5=12,34,56,78,9;int a5=0;int a=11,22,33,44,55;数组大小最好用宏来定义,以适应未来可能的变化#define SIZE 10int aSIZE;数组大小定义好后,将永远不变,一维数组的初始化初始化方式,在定义数组时,为数组元素赋初值(在编译阶段使之
4、得到初值),int a5=1,2,3,4,5;等价于:a0=1;a1=2;a2=3;a3=4;a4=5;,说明:数组不初始化,其元素值为随机数对static数组元素不赋初值,系统会自动赋以0值,当全部数组元素赋初值时,可不指定数组长度,如 int a5=6,2,3;等价于:a0=6;a1=2;a2=3;a3=0;a4=0;如 int a3=6,2,3,5,1;(),static int a5;等价于:a0=0;a1=0;a2=0;a3=0;a4=0;,只给部分数组元素赋初值,int a=1,2,3,4,5,6;编译系统根据初值个数确定数组元素个数,float a0;/*数组大小为0没有意义*/
5、int b(2)(3);/*不能使用圆括号*/int k,ak;/*不能用变量说明数组大小*/,数组说明中其他常见的错误,数组的特点,快速地随机访问一旦定义,不能改变大小,只能逐个对数组元素进行操作(字符数组例外),输入方法:,int a10,i;,输入第i个数组元素:,scanf(%d,输入整个数组元素:,for(i=0;i10;i+)scanf(%d,输出方法:,输出第i个数组元素:,printf(%d,ai);,输出整个数组元素:,for(i=0;i10;i+)printf(%d,ai);,一维数组的输入和输出,程序举例,例 将10个整数存入数组,并打印输出。,#include#defi
6、ne SIZE 10main()int xSIZE=0,1,2,3,4,5,6,7,8,9;int i;for(i=0;iSIZE;i+)printf(%d,xi);,#include#define SIZE 10main()int xSIZE,i;printf(Enter 10 integers:n);for(i=0;iSIZE;i+)scanf(%d,程序举例,例 读10个整数存入数组,找出其中最大值和最小值,步骤:1.输入:for循环输入10个整数2.处理:(a)先令max=min=x0(b)依次用xi和max,min比较(循环)若maxxi,令min=xi3.输出:max和min,#i
7、nclude#define SIZE 10main()int xSIZE,i,max,min;printf(Enter 10 integers:n);for(i=0;ixi)min=xi;printf(Maximum value is%dn,max);printf(Minimum value is%dn,min);,文曲星猜数游戏,由计算机随机生成一个各位相异的4位数字,由人来猜,每次提示:xAxBA前面的数字表示有几个数字猜对位置也对了B前面的数字表示有几个数字猜对但位置不对提示用数组a存计算机随机生成的4位数用数组b存人猜的4位数对a和b的相同位置的元素进行比较,得到A前面的数字对a和b的
8、不同位置的元素进行比较,得到B前面的数字,文曲星猜数游戏,随机生成一个各位相异的4位数字 srand(time(NULL);a0=rand()%10;do a1=rand()%10;while(a0=a1);do a2=rand()%10;while(a0=a2|a1=a2);do a3=rand()%10;while(a0=a3|a1=a3|a2=a3);,文曲星猜数游戏,统计数字和位置都猜对的个数,对a和b的相同位置的元素进行比较,得到A前面的数字right=0;for(j=0;j4;j+)if(aj=bj)right=right+1;,j=0,j=1,j=2,j=3,a,b,文曲星猜数游
9、戏,统计人猜对的数字个数,对a和b的不同位置的元素进行比较,得到B前面的数字good=0;for(j=0;j4;j+)for(k=0;k4;k+)if(ak=bj)good=good+1;good=good-right;,k=0,k=1,k=2,k=3,j=0,a,b,j=1,餐饮服务质量调查打分,有40个学生被邀请给自助餐厅的食品和服务质量打分(110等级),统计调查结果,并用*打印如下形式的统计结果直方图 Grade CountHistogram 1 5*2 10*3 7*.,餐饮服务质量调查打分,提示定义数组score存放打的分数定义数组count为计数器(count0不用)计算统计结果
10、:设置一个循环,依次检查数组元素值scorei,是1则将数组元素count1加1,是2则将数组元素count2加1,依此类推for(i=0;iSTUDENTS;i+)countscorei+;打印统计结果,设置一个循环,按count数组元素的值,打印相应个数的符号*,例6.1,兔子繁殖问题打印每个月和年底时的总的兔子对数Fibonacci数列 123581321345589144233,,例6.1,#include#define YEAR_MONTH 12main()int fYEAR_MONTH+1=0,1,2;int month;for(month=3;month=YEAR_MONTH;m
11、onth+)fmonth=fmonth-1+fmonth-2;for(month=1;month=YEAR_MONTH;month+)printf(%dt,fmonth);printf(nsum=%dn,fYEAR_MONTH);,例6.2 打印出最高分及其学生序号,从键盘输入信管1班学生高数成绩(每班最多不超过45人,具体人数由键盘输入),试编程输出最高分及其学生序号。,max(i=0),max(i=2),max(i=3),计算最大值算法,Step1 从键盘输入学生人数n;Step2 从键盘输入所有学生的学号和成绩分别存入数组num和scoreStep3 假设其中的一个学生成绩为最高,同时记
12、录其学号,即令maxScore=score0maxNum=num0;Step4 对所有学生成绩进行比较,即 for(i=0;i maxScore,则修改maxScore值为scorei,并记录其学号maxNum=numi;Step5 打印最高分maxScore及其学号maxNum。,例6.2 算法,.main().for(i=0;i maxScore)maxScore=scorei;printf(maxScore=%.0fn,maxScore);,例6.2 打印最高分,.main().for(i=0;i maxScore)maxScore=scorei;maxNum=numi;printf(m
13、axScore=%.0f,maxNum=%ldn,maxScore,maxNum);,例6.2 打印最高分及其学生序号,用函数实现?,同时输出最高分和最低分及其学生序号,该如何改写程序呢?,#include#define ARR_SIZE 40float FindMax(float arr,int n);main()float scoreARR_SIZE,maxScore;int n,i;printf(Please enter total number:);scanf(%d,float FindMax(float arr,int n)float max;int i;max=arr0;for(i
14、=1;i max)max=arri;return max;,现场编程用函数实现打印最高分,数组名作函数参数 P174-6.3,传递整个数组到另一个函数内,可以将数组的首地址作为参数传过去用数组名作为函数参数只拷贝一个地址自然比拷贝全部数据效率高由于首地址相同,故实参数组与形参数组占用同一段内存在该函数内,不仅可以读这个数组的元素,还可以修改它们,简单变量和数组作函数参数的区别,用数组名作函数参数时,此时形参应当用数组名或用指针变量。,例-L函数地址传递.c有一个一维数组score,内放3个学生成绩,求平均成绩。,#include float average(float array3);/*函数
15、声明*/void main()float score3,aver;int i;printf(input 3 scores:n);for(i=0;i3;i+)scanf(%f,float average(float array3)int i;float aver,sum=0;for(i=0;i3;i+)sum=sum+arrayi;aver=sum/3.0;return aver;,运行情况如下:,长度可以不声明吗?P174-175,作业,P1986.4,现场演示排序算法,交换法排序选择法排序,交换法排序,第一轮后,交换法排序,第二轮后,第三轮后,交换法排序,交换法排序 for(i=0;i sc
16、orei)交换成绩scorej和scorei,交换学号numj和numi;,选择法排序,k=1,k=2,k=0,k=1,选择法排序,k=3,k=4,k=3,k=4,选择法排序,选择法排序 for(i=0;i scorek)记录此轮比较中最高分的元素下标 k=j;若k中记录的最大数不在位置i,则 交换成绩scorek和scorei,交换学号numk和numi;,现场演示查找算法,顺序查找折半查找,顺序查找,int Search(long a,int n,long x)int i;for(i=0;in;i+)if(ai=x)return(i);return(-1);,哈,找到了!,折半查找,哈,找
17、到了!,折半查找,唉,没找到!,int BinSearch(long a,int n,long x)int low,high,mid;low=0;high=n-1;while(low amid)low=mid+1;else if(x amid)high=mid-1;else return(mid);return(-1);,排序&查找作业,作业:1.请将从键盘输入的5个整数,从大到小排列后输出到屏幕。2.从键盘随便输入的5个整数存储到数组a中,将这5个数中最大数的下标输出到屏幕。,二维数组的定义和引用,二维数组定义的一般形式为类型说明符 数组名常量表达式常量表达式;例如:定义a为34(3行4列)
18、的数组,b为510(5行10列)的数组。如下:float a34,b510;,不能写成 float a3,4,b5,10;,二维数组的定义,二维数组中的元素在内存中的排列顺序是:按行存放,即先顺序存放第一行的元素,再存放第二行的元素,一维数组在内存中的存放,下图表示对a34数组存放的顺序,地址 值 数组元素,b00b01b02b10b11b12b20b21b22,3000H3002H3004H3006H3008H300AH300CH300EH3010H,例如:整型数组 b33=1,2,3,4,5,6,7,8,9;,123,456,789,二维数组元素的表示形式为:数组名下标下标 例如:a23下
19、标可以是整型表达式,如 a2-12*2-1,数组元素可以出现在表达式中,也可以被赋值,例如:b12=a23/2,二维数组的引用,常出现的错误有:int a34;/*定义a为34的数组*/a34=3;,在使用数组元素时,应该注意下标值应在已定义的数组大小的范围内。,可以用下面4种方法对二维数组初始化,数据类型 数组名 常量表达式1常量表达式2初始化数据;,(1)分行给二维数组赋初值。如:int a34=1,2,3,4,5,6,7,8,9,10,11,12;,(2)可以将所有数据写在一个花括弧内,按数组排列的顺序对各元素赋初值。如:int a34=1,2,3,4,5,6,7,8,9,10,11,1
20、2;,二维数组的引用,(3)可以对部分元素赋初值。如 int a34=1,5,9;,1 0 0 05 0 0 0 9 0 0 0,也可以对各行中的某一元素赋初值,如int a34=1,0,6,0,0,0,11;,1 0 0 00 6 0 00 0 0 11,1 0 0 05 6 0 0 0 0 0 0,也可以只对某几行元素赋初值。如:int a34=1,5,6;,(4)如果对全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省。如:int a34=1,2,3,4,5,6,7,8,9,10,11,12;它等价于:int a4=1,2,3,4,5,6,7,8,9,10,11
21、,12;,在定义时也可以只对部分元素赋初值而省略第一维的长度,但应分行赋初值。如:int a4=0,0,3,0,10;,0 0 3 00 0 0 00 10 0 0,二维数组的引用,二维数组的输入和输出,数组的输入和输出只能逐个对数组元素进行操作(字符数组例外),int b23,i,j;,二维数组程序举例,例kw1 将一个二维数组行和列元素互换,存到另一个 二维数组中。,#include void main()int a23=1,2,3,4,5,6;int b32,i,j;printf(array a:n);for(i=0;i=1;i+)for(j=0;j=2;j+)printf(%5d,ai
22、j);/*打印输出矩阵a的元素,先行后列*/bji=aij;/*给矩阵b赋值*/printf(n);/*下一行输出前,先换行*/,printf(array b:n);for(i=0;i=2;i+)for(j=0;j=1;j+)printf(%5d,bij);/*打印输出矩阵b的元素,先行后列*/printf(n);/*程序结束*/,运行结果如下:array a:1 2 3 4 5 6array b:1 4 2 5 3 6,例kw2:有一个34的矩阵,要求编程序求出其中值最大的那个元素的值,以及其所在的行号和列号。,先用N-S流程图表示算法,如下:,二维数组程序举例,+1,+1,#include
23、 void main()int i,j,row=0,colum=0,max;int a34=1,2,3,4,9,8,7,6,-10,10,-5,2;max=a00;for(i=0;imax)max=aij;/*最大值为当前值*/row=i+1;/*记录行、列号*/colum=j+1;printf(max=%d,row=%d,colum=%dn,max,row,colum);/*程序结束*/,6.4 向函数传递二维数组,实际传送的是指向数组第一个元素的地址在声明二维数组形参时,不能省略数组第二维的长度,为什么?,例6.8 计算每门课程的总分和平均分,void Total(int scoreCOU
24、RSE,int sum,float aver,int n)int i,j;for(j=0;jCOURSE;j+)sumj=0;for(i=0;in;i+)sumj=sumj+scoreij;averj=(float)sumj/n;,可以省略数组第一维的长度不能省略数组第二维的长度,6.5 字符数组,字符 char字符串,字符串(String)与字符数组,字符串一串以0结尾的字符在C语言中被看作字符串用双引号括起的一串字符是字符串常量,C语言自动为其添加0终结符C语言并没有为字符串提供任何专门的表示法,完全使用字符数组和字符指针来处理字符数组每个元素都是字符类型的数组char string80;
25、,字符数组的初始化 P188,用字符型数据对数组进行初始化 char str6=C,h,i,n,a,0;字符数组长度为6,但字符串实际长度为5 char str6=C,h,i,n,a;用字符串常量直接对数组初始化 char str6=China;char str6=China;char str=China;char str=China;char str5=China;长度不够,无法按照字符串来处理,结尾不是0不是字符串!,0作为字符串结束符的天生缺陷,假若交给这些字符串处理函数的字符串没有0会如何?0很关键,如果没有,那么这些处理函数会一直进行处理直到遇到一个0为止。此时可能已经把内存弄得乱七
26、八糟ANSI C定义了一些“n族”字符处理函数,包括strncpy、strncat、strncmp等,通过增加一个参数来限制处理的最大长度,例kw3 字符数组的输出,#include#include#define ARRA_SIZE 4/*字符串最大长度*/main(void)int n;char strARRA_SIZE=a,b,c,minARRA_SIZE;printf(“%sn,str);for(n=0;strn!=0;n+)printf(“%c”,strn);/*每次输出一个字符串*/printf(n);,把4改成3看看输出结果,字符数组,字符数组的输入输出,字符数组的输入输出可以有两
27、种方法:,逐个字符输入输出。用格式符“%c”输入或输出一个字符。将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串的输入输出。,在内存中数组c的状态,逐个输入输出,for(i=0;si!=0;i+)putchar(si);putchar(n);,一次性输入输出,scanf(%s,s);printf(%s,s);,char s10;,字符数组的输入输出,gets(%s,s);puts(%s,s);,如果利用一个scanf函数输入多个字符串,则在输入时以空格分隔(scanf函数遇空格、回车、制表符结束)。例如:char str15,str25,str35;scanf(%s%s%s,str
28、1,str2,str3);输入数据:How are you?数组中未被赋值的元素的值自动置0。,scanf(%s,str1);输入:How are you?数组str1中的字符串为“how”,而不是“How are you?”,str1:str2:str3:,puts()/gets()字符串处理函数,在C的函数库中提供了一些用来处理字符串的函数,使用方便。几乎所有版本的C编译系统都提供这些函数。下面介绍几种常用的函数。,1.puts函数其一般形式为:puts(字符数组)其作用是将一个字符串(以0结束的字符序列)输出到终端。假如已定义str是一个字符数组名,且该数组已被初始化为China。则执行
29、puts(str);其结果是在终端上输出China。由于可以用printf函数输出字符串,因此puts函数用的不多。,用puts函数输出的字符串中可以包含转义字符。例如:char str=ChinanBeijing;puts(str);输出结果:ChinaBeijing,同时,在输出时,将字符串结束标志0转换成n,即输出完字符串后换行。,2.gets函数其一般形式为:gets(字符数组)其作用是从终端输入一个字符串到字符数组,函数值返回值为字符串的首地址。该函数值是字符数组的起始地址。如执行下面的函数:gets(str);可以输入空格!从键盘输入:Computer,将输入的字符串Compute
30、r送给字符数组str(请注意送给数组的共有9个字符,而不是8个字符。注意:用puts和gets函数只能输入或输出一个字符串,不能写成 puts(str1,str2)或 gets(str1,str2),scanf(),int i;scanf(%d,不能读入带空格的字符串,gets()可以这种用法很不安全。当用户的输入多于10个(含10个),str数组将越界scanf被公认为最易遭到黑客攻击的函数之一,gets(),字符串输入函数gets()也没有提供限制输入字符串长度的方法,容易引起缓冲区溢出,给黑客攻击以可乘之机 对输入字符串长度有限制的函数调用fgets(buf,sizeof(buf),st
31、din);,字符串处理函数,在中定义了若干专门的字符串处理函数strcpy:string copy字符串2复制到字符数组1中,应确保字符串数组1足够大strlen:string length返回字符串的实际长度,不包括0strcat:string combination字符串2连接到字符数组1的字符串后面,结果存在字符串数组1中strcmp:string comparison当出现第一对不相等的字符时,就由这两个字符决定所在字符串的大小,赋值运算符“=”不能用于字符串赋值!,str1=str2/*错误*/,str1=str2/*错误*/,字符串不能用关系运算符比较大小!,if(str1str2
32、)/*错误*/,1.strcat函数其一般形式为:strcat(字符数组1,字符数组2)Strcat的作用是连接两个字符数组中的字符串,把字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值字符数组1的地址。,例如:char str130=Peoples Republic of;char str2=China;printf(%s,strcat(str1,str2);或printf(%s,str1);输出:Peoples Republic of China,2.strcpy函数 其一般形式为:strcpy(字符数组1,字符串2)strcpy是“字符串复制函数”。作用是将字符
33、串2复制到字符数组1中去。例如:char str110,str2=China;strcpy(str1,str2);,str1:,1.字符数组1必须定义得足够大,以便容纳被复制的字符串。字符数组1的长度不应小于字符串2的长度。,2.“字符数组1”必须写成数组名形式(如str1),“字符串2”可以是字符数组名,也可以是一个字符串常量。如strcpy(str1,China);,3.复制时连同字符串后面的0一起复制到字符数组1中。,4.可以用strcpy函数将字符串2中前面若干个字符复制到字符数组1中去。例如:strcpy(str1,str2,2);作用是将str2中前面2个字符复制到str1中去,然
34、后再加一个0。,5.不能用赋值语句将一个字符串常量或字符数组直接给一个字符数组。如下面两行都是不合法的:str1=China;str1=str2;而只能用strcpy函数将一个字符串复制到另一个字符数组中去。用赋值语句只能将一个字符赋给一个字符型变量或字符数组元素。如下面是合法的:char a5,c1,c2;c1=A;c2=B;a0=C;a1=h;a2=i;a3=n;a4=a;,3.strcmp函数 其一般形式为:strcmp(字符串1,字符串2)strcmp的作用是比较字符串1和字符串2。例如:strcmp(str1,str2);strcmp(China,Korea);strcmp(str1
35、,Beijing);,AA,computercompare,36+54!$,CHINACANADA,DOGcat,字符串比较的规则与其他语言中的规则相同,即对两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到0为止。如全部字符相同,则认为相等;若出现不相同的字符,则以第一个不相同的字符的比较结果为准。,例如,比较的结果由函数值带回(1)如果字符串1=字符串2,函数值为0。(2)如果字符串1字符串2,函数值为一正整数。(3)如果字符串1str2)printf(yes);而只能用if(strcmp(str1,str2)0)printf(yes);,4.strl
36、en函数 其一般形式为:strlen(字符数组)strlen是测试字符串长度的函数。函数的值为字符串中的实际长度(不包括0在内)。如:char str10=China;printf(%d,strlen(str);输出结果不是10,也不是6,而是5。也可以直接测试字符串常量的长度,如strlen(China);,例kw4 有3个字符串,要求找出其中最大者,#include#includevoid main()char string20;char str320;int i;for(i=0;i0)/*str0比str1大*/strcpy(string,str0);/*把str0赋值个字符串strin
37、g大*/else strcpy(string,str1);if(strcmp(str2,string)0)strcpy(string,str2);printf(nthe largest string is:%sn,string);,运行结果如下:CHINAHOLLANDAMERICA the largest string isHOLLAND,例6.9,从键盘任意输入5个学生的姓名,编程找出并输出按字典顺序排在最前面的学生姓名 等价于求最小字符串,#include#include#define ARRA_SIZE 80main()int n,num;char strARRA_SIZE,minARRA_SIZE;printf(Please enter five names:n);gets(str);strcpy(min,str);for(n=1;n5;n+)gets(str);if(strcmp(str,min)0)strcpy(min,str);printf(The min is:);puts(min);,这一章我们学习了,了解了在什么情况下使用数组这种数据类型 向函数传递一维数组和二维数组的方法 用数组名作为函数参数和用简单变量作为函数参数的不同之处 常用算法:求最大值,排序,查找,作业,P1941996.16.3 写在书上6.116.12,
链接地址:https://www.31ppt.com/p-6503828.html