《C语言程序设计(谭浩强编)第七章数组.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计(谭浩强编)第七章数组.ppt(42页珍藏版)》请在三一办公上搜索。
1、第七章 数 组,在本章节前给大家讲的都是基本类型的数据,c语言还提供了构造类型的数据(数组类型、结构体类型、共用体类型)。数组是有序数据的集合,数组中的每个元素都属于同一个数据类型。7.1 一位数组的定义和引用7.1.1一维数组的定义定义方式:类型说明符 数组名 常量表达式;例:int a10;它表示数组名为a,此数组有10个元素。,说明:(1)数组名定义规则和变量名相同;(2)数组名的常量表达式用方括弧括起来(3)常量表达式表示元素的个数,即数组长度。例如:a10表示a数组共有10个元素,下标从0开始分别为:a0,a1,a2,a3,a4,a5,a6,a7,a8,a9 注意:没有a10。(4)
2、常量表达式中可以包括常量和符号常量,即数组的大小不能依赖于程序过程中变量的值。例如:int n;scanf(“%d”,是不合法的。,c语言中是先扫描全篇分配空间,因此先int an后scanf(.)。,7.1.2 一维数组元素的引用 C语言规定,只能逐个引用数组元素而不能一次引用整个数组。数组元素的表示形式为:数组名下标 其中下标可以是整型常量或整型表达式。例如:a0=a5+a7-a2*3例7.1 数组元素的引用#main()int i,a10;for(i=0;i=0;i-)printf(“%d”,ai);,一维数组的初始化,(1)在定义数组时对数组元素赋以初值。例如:int a10=0,1,
3、2,3,4,5,6,7,8,9 其中:a0=0,a1=1,a2=2,a3=3,a4=4,a5=5,a6=6,a7=7,a8=8,a9=9(2)可以只给一部分元素赋值。例如:int a10=0,1,2,3,4;其中:a0=0,a1=1,a2=2,a3=3,a4=4,a5=0,a6=0,a7=0,a8=0,a9=0(3)如果想使一个数组中全部元素值为0,可以写成:int a10=0,0,0,0,0,0,0,0,0,0不能写成:int a10=0*10,(4)在对全部数组元素赋初值时,可以不指定数组长度。例如:int a5=0,1,2,3,4可以写成:int a=0,1,2,3,4例如:int a1
4、0=0,1,2,3,4;只初始化了前5个元素,后5个元素为0。,7.1.4 一维数组程序举例,*例7.2 用数组来处理求Fibonacci数列问题。main()int i;int f20=1,1;for(i=2;i20;i+)fi=fi-2+fi-1;for(i=0;i20;i+)if(i%5=0)printf(“n”);printf(“%12d”,fi);,例7.3 用冒泡法对10个数排序(由小到大)。冒泡法:对将进行排序的数,两两比较,如果不满足次序要求,则交换位置;,第一次比较,第二次比较,第三次比较,第四次比较,第五次比较,第一次冒泡排序的结果,n个数经过一次冒泡排序后,最大数(最小数
5、)将被交换到确定位置,但前面n-1数仍然无序。,第0趟冒泡排序,从上述我们可以得出:如果n个数参加冒泡排序,则共要进行n-1趟排序。在第j趟比较中有n-j个数参加排序,要进行n-j-1次两两比较。本例中第1趟有5个数参加排序,进行了4次比较。,第一次比较,第二次比较,第三次比较,第四次比较,第二次冒泡排序的结果,第1趟冒泡排序,程序的结构:main(),1、定义相关的数组和相关变量,3、按冒泡算法对其升序排序 由于在排序中涉及到总共所 需的趟次和每一趟中具体比 较的次数,因此可用循环嵌 套控制语句来完成。,4、输出经排序后的十个数,2、输入待排序的十个数,*main()int a10;int
6、i,j,t;printf(“input 10 numbers:n”);for(i=0;iai+1)t=ai;ai=ai+1;ai+1=t;printf(“the sorted numbers:n”);for(i=0;i10;i+)printf(“%d”,ai);,6.2 二维数组的定义和引用 一、定义 格式:类型说明符数组名常量表达式常量表达式 如:int a34;float b56;说明:1.多维数组的下标仍从0计起。例如:a23其元素个数为 6个,即:a00,a01,a02 a10,a11,a12 2.C 语言中,二维(或高维)数组中的元素是按行 存放。如:a34 数组 a00 a01 a
7、02 a03 a10 a11 a12 a13 a20 a21 a22 a23,3.对二维或高维数组可看成其元素也是数组的数组。如:a34可看成由三个元素 a0,a1,a2组成。而每个元素又是一个包含4个元素的一维数组。即 a0 a00 a01 a02 a03 a1 a10 a11 a12 a13 a2 a20 a21 a22 a23 二、二维数组元素的引用 格式:数组名下标下标 注意:下标值同数组大小的匹配。如:int a34;.a34=3;(是错误的),a34,1.分行赋初值(即按行赋值)如:int a34=1,2,3,4,5,6,7,8,9,10,11,12;2.按数组排列的顺序对各元素赋
8、值 如:int a34=1,2,3,4,5,6,7,8,9,10,11,12;3.部分赋值(1)int a34=1,5,9;1 0 0 0 5 0 0 0 9 0 0 0(2)int a34=1,0,6,0,0,11;1 0 0 0 0 6 0 0 0 0 11 0,(3)int a34=1,5,6;1 0 0 0 5 6 0 0 0 0 0 0(4)int a34=1,9;1 0 0 0 0 0 0 0 9 0 0 0 4.int a34=1,2,3,12;int a 4=1,2,3,12;但不能写成:int a3=1,2,3,12;5.int a34=0,0,3,0,10;int a 4=
9、0,0,3,0,10;,运行结果示意,四、二维数组程序举列(p86)例 6.4 将一个二维数组行和列元素互换,存到 一个二 维数组中。如:1 2 3 1 4 a=b=2 5 4 5 6 3 6,算法:bji=aij,源程序,main()int a23=1,2,3,4,5,6;int b32,i,j;for(i=0;i=1;i+)for(j=0;j=2;j+)printf(“%5d”,aij);bji=aij;printf(“n”);printf(“narray b:n”);for(i=0;i=2;i+)for(j=0;j=1;j+)printf(“%5d”,bij);printf(“n”);,
10、行列互换结果 array a:1 2 3 4 5 6 array b:1 42 53 6,例 6.5 求一个 3 4 的的矩阵中最大的那个元素的 值,以及其所在的行号和列号。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;i max)max=aij;row=i;colum=j;printf(“max=%d,row=%d,colum=%d n”,max,row,colum);结果:max=10,row=2,colum=1,6.3 字符数组 一、定义 格式:一维:char 数组名常量
11、表达式 二维:char 数组名常量表达式常量表达式 如:char c10;char a56;二、初始化 例如:char c8=,H,e,l,l,o,w,!;c0,c1 H,.c7!说明:1.所赋的字符个数不能超过数组长度。2.如所赋的字符个数小于数组长度,则 其余元素自动赋为空字符(0)。如:char c9=,H,e,l,l,o,w,!;c0,c1H,.c7!,c80,3.如字符个数与数组长度相等,则可省略数组长度。由系统自动确定数组长度。如:char c=,H,e,l,l,o,w,!;4.二维字符数组的初始化与上述一维字符数组的初 始化相同。如:char diamond55=,*,*,*,*
12、,*,*,*,*;,*,三、字符数组的引用 格式:数组名下标 例 6.6 输出一个字符串。main()char c10=I,a,m,a,b,o,y;int i;for(i=0;i 10;i+)printf(“%c”,ci);printf(“n”);,例 6.7 输出一个钻石 图形。main()char diamond55=,*,*,*,*,*,*,*,*;int i,j;for(i=0;i 5;i+)for(j=0;j 5;j+)printf(“%c”,diamondij);printf(“n”);,*,四、字符串和字符串的结束标志 C语言中规定了一个“字符串结束标志”,用 0表示。例如:pr
13、intf(“Hellow!n”);遇到 0 就停止输出。可以用字符串常量来初始化字符数组。如:char c=“I am happy”;char c=“Iamhappy”;上述初始化等效于:char c=I,a,m,h,a,p,p,y,0;(11个字符)又如:char c10=“China”;,C h i n a 0 0 0 0 0,说明:1.逐个字符赋值时,并不要求最后字符为 0,但采用字符串常量赋值时,则会有 0。如:char c5=C,h,i,n,a;如:char c6=“China”;2.字符型数据和整型数据在一定范围内是互 相通用的。可用整型数组来处理字符数据。例如:int c=C,h
14、,i,n,a;但不能用字符串常量来初始化整型数组。例如:int c=“China”;int c=“China”;,7.3.5 字符数组的输入输出,字符数组的输入输出可以有两种方法:(1)逐个字符输入输出。用格式符“%c”输入或输出一个字符。如:main()char c10I,a,m,a,b,o,y;int i;for(i=0;i10;i+)printf(“%c”,ci);printf(“n”);(2)将整个字符串一次输入或输出。用“%s”格式符。如:char c=“china”;printf(“%s”,c);,注意:1.输出字符不包括结束符0;2.用“%s”格式符输出字符串时,printf函数
15、中的输出项是字符数组名,而不是字符元素名。不能写成:printf(“%s”,c0);3.如果数组长度大于字符串实际长度,也只输出到遇0结束。4.如果一个字符数组中含一个以上的0,则遇到第一个0 输出就结束。,用scanf函数输入一个字符串。例如:scanf(“%s”,c);从键盘输入:China 系统自动在后面加一个0结束符。注意:scanf函数中的输入项是字符数组名。输入项为字符数组名时,不要再加地址符&,因为在c语言中数组名代表该数组的起始地址。这样写法不对:scanf(“%s”,&c),利用scanf函数输入多个字符串时,则以空格分隔。例如:char str15,str25,str35;
16、scanf(“%s%s%s”,str1,str2,str3);键盘输入:How are you?如果改为:char str13;scanf(“%s”,str);输入这样12个字符:How are you?,7.3.6 字符串处理函数,在C的函数库中提供了一些用来处理字符串的函数,使用方便。下面是几种常用的函数。1.puts(字符数组)作用:将一个字符串(以0结束的字符序列)输出到终端。例如:char str=“China”;puts(str);输出:China 由于可以用printf函数输出字符串,因此puts函数用的不多。用puts函数输出的字符串中可以包含转义字符。,2.gets(字符数组
17、)作用:从终端输入一个字符串到字符数组,并且得到一个函数值。该函数值是字符数组的起始地址。如执行下面的函数:gets(str)从键盘输入:Computer 将输入的字符串”Computer”送给字符数组str(请注意送给数组的共有9个字符,而不是8个字符),函数值为字符数组str的起始地址。一般利用gets函数的目的是向字符数组输入一个字符串,而不大关心其函数值。注意:用puts和gets函数只能输入或输出一个字符串。,3.strcat(字符数组1,字符数组2)作用是:连接两个字符数组中的字符串,把字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值字符数组1的地址。例如
18、:chat str130=“Peoples Repubnic of”;chat=“China”;printf(%s,strcat(str1,str2);输出:Peoples Republic of China 连接前后的状况见下图所示。,str1:str2:,说明:(1)字符数组1必须足够大,以便容纳连接后的新字符串。上例中定义str1的长度为30,是足够大的。(2)连接前两个字符串的后面都有一个0,连接时将字符串1后面的0取消,只在新串最后保留一个0。4.strcpy(字符数组1,字符串2)作用:将字符串2复制到字符数组1中去,例如:char str110,str2=“China”);str
19、cpy(strl,str2);执行后,str1的状态下图所示。,说明:(1)字符数组1必须定义得足够大,以便容纳被复制的字符串。字符数组1的长度不应小于字符串2的长度;(2)“字符数组1”必须写成数组名形式(如str1),“字符串2”可以是字符数组名,也可以是一个字符串常量。如:strcpy(str1,“China”);(3)复制时连同字符串后面的0一起复制到字符数组1中。(4)不能用赋值语句将一个字符串常量或字符数组直接给一个字符数组。下面两行都是不合法的:str1=“China”;str1=str2;而只能用strcpy函数处理。用赋值语句只能将一个字符赋给一个字符型变量或字符数组元素。,
20、5.strcmp(字符串1,字符串2)作用:比较字符串1和字符串2。例如:strcmp(str1,str2);strcmp(”China”,”Korea”);strcmp(str1,“Beijing”);字符串比较的规则与其他语言中的规则相同,即对两个字符串自左至右逐个字符相比,按ASCII码值大小比较,直到出现不同的字符或遇到“0”为止。如全部字符相同,则认为相等;若出现不相同的字符,则以第一个不相同的字符的比较结果为准。例如:“A”“B”,“computer”“compare”,“CHINA”“CANADA”,比较的结果由函数值带回。(1)如果字符串1字符串2,函数值为0.(2)如果字符串
21、1字符串2,函数值为一正整数。(3)如果字符串1字符串2,函数值为一负整数。注意:对两个字符串比较,不能用以下形式 if(str1=str2)printf(“yes”);而只能用 if(strcmp(str1,str2)=0)printf(“yes”);,6.strlen(字符数组)作用:测试字符串长度的函数。函数的值为字符串中的实际长度,不包括0在内。如:char str10=“china”;printf(“%d”,strlen(str);输出结果不是10也不是6,而是5。也可以直接测字符串常过的长度,如 strlen(“china”);7.strlwr(字符串)作用是将字符串中的大写字母换
22、成小写字母。8.strupr(字符串)作用是将字符串中的小写字母换成大写字母。,强调:库函数并非C语言本身的组成部分,而是人们为使用方便而编写、提供大家使用的公共函数。每个系统捉供的函数数量和函数名、函数功能都不尽相同,使用时要小心,心要时查一下库函数手册。当然,有一些基本的函数(包括函数名和函数功能)不同的系统所提供的是相同的,这就为程序的通用性提供了基础。,七、字符数组应用举列 补例:下列程序是否有错。如有,请改正。main()char c1=“CHINA”;int c2=“Hellow”;printf(“%sn”,c1i);printf(“%s”,c2);main()int i;char
23、 c1=“CHINA”;int c2=H,e,l,l,o,w;printf(“%sn”,c1);for(i=0;i 6;i+)printf(“%c”,c2i);,7.3.7 字符数组应用举例,*例7.8 输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。解题的思路:单词间的数目可由空格出现的次数决定(连续的空格做为出现一次空格;开头的空格不统计在内)如果测出某一个字符为非空格,而它的前面的字符是空格,则表示“新的单词开始”,此时使num(单词数)累加1。如果当前字符为非空格而其前面的字符也是非空格,则意味着仍然是原来那个单词的继续,num不应再累加1。前面一个字符是否空格可以从一个标志
24、变量word的值看出,若word0,则表示前一个字符是空格;如果word=1,则意味前一个字符为非空格。,判断当前字符为空格吗?,未出现新单词,使 word=0,num不累加,前一字符为空格(由 word=0可判断),新单词出现,num 加 1,word=1,前一字符为非空格(由 word=1可判断),未出现新单词,num 不加 1。,Y,N,#include“stdio.h”main()char string80;int i,num=0,word=0;char c;gets(string);for(i=0;(c=stringi)!=0;i+)if(c=)word=0;else if(word
25、=0)word=1;num+;printf(“%d words in the line n”,num);输入:I am a boy.输出:There are 4 words in the line,作标志。word=0 表示未 出现单词。如出现单词,则 word 置 1。,分析:第一次:i=0,c=I,执行 word=1;num+;第二次:i=1,c=执行 word=0;此时 num=1 第三次:i=2,c=a,执行 word=1;num+;即num=2 第四次:i=3,c=m,不执行 word=1;num+;语句.第五次:i=4,c=执行 word=0;第六次:i=5,c=a,执行 word
26、=1;num+;即 num=3,例7.9 有3个字符串,要求找出其中最大者。今设一个1二维的字符数组str,大小为3X20,即有3行20列,每一行可以容纳20个.可以把str0,str1,str2看作3个一维字符数组,可以把它们如同一维数组那样进行处理,可以用gets函数分别读入。经过二次比较,可以得到最大者,把它放入一维数组string中。,str0:str1:str2:,main()char string20;char str320;int i;for(i=0;i0)strcpy(string,str0);else strcpy(string,str1);if(strcmp(str2,string)0)strcpy(string,str2);printf(“n the largest string is:n%sn”,string);,*,