《C语言第8章-数组和字符串.ppt》由会员分享,可在线阅读,更多相关《C语言第8章-数组和字符串.ppt(77页珍藏版)》请在三一办公上搜索。
1、1,第8章 数组与字符串,苏州市职业大学 计算机工程系,C 语言程序设计,2,第8章 数组与字符串,本章重点介绍:8.1 一维数组8.2 二维数组8.3 字符数组与字符串8.4动态分配与void类型指针,3,4,引言,简单变量:如a,b2,x3,day,sum,如同一个姓名代表一个人一样,变量间没有任何联系。有一些变量可以归结为同一类型,如s1,s2,s3,s4,s5,s10代表同一个班中10个学生每个学生的成绩。这些变量都用相同的名字,只是下角标有所区别,即用相同的名字不同的下标代表同一类型的一组数据,这种变量称为下标变量。C语言中同样也可以用下标变量,只是把下标用方括号括起来。即s1,s2
2、,s10,这就是数组类型变量。,5,什么构造类型?所谓构造类型是指由基本类型数据按一定的规则组成的,是用户自己按规则定义的。数组是构造类型之一。在数学中我们学过数列、矩阵的概念,数列通常表示为:a1、a2、a3、.、an 矩阵通常表示为:,6,在C语言中表示数组和矩阵的方法是:数组:a0、a1、a2、a3、a4、a5其中 a:称为数组名。方括号中的数:称为下标 下标是一个数时,也就是数列,称为一维数组。下标是两个数时,也就是矩阵,称为二维数组。还有三维数组、四维数组等。,7,第8章 数组与字符串,一个人N门课的成绩怎样存储和处理?一个班N门课的成绩怎样存储和处理?.,这些数据的特点:具有相同的
3、数据类型。为了方便地使用这些数据,C语言提供了一种构造数据类型:数组。例如:存储学生成绩用实型数组 score5其中:score是数组名。该数组可以存放5个成绩,分别用下标变量表示:score0,score1,score4。下标变量也称为数组元素。,8,引言,数组的特点:1、数组是有序数据的集合;2、数组中的每一个元素都属于同一个数据类型;3、用一个统一的数组名和下标来唯一的确定数组中的元素。,9,8.1 一维数组,例如:int a10;float score5;“数据类型”:是数组元素的数据类型。“数组名”:遵循C语言标识符规则。“常量表达式”:表示数组中有多少个元素,即数组的长度。它可以是
4、整型常量、整型常量表达式或符号常量。,8.1.1 一维数组的定义,数据类型 数组名常量表达式;,10,以下数组定义是正确的:#define N 10float score1N,score2N;int num10+N;char c26;,以下数组定义是不正确的:int array(10);int n;float scoren;double ba.d;char str;,8.1.1 一维数组的定义(续),11,数组在内存的存放,数组下标从0开始。一维数组的数组元素在内存里按顺序存放。数组名代表数组的首地址,即score的值与score0 的地址值相同。,score数组,12,8.1.2 数组元素的
5、引用,格式:,例如:输入学生成绩 for(i=0;i5;i+)scanf(%f,例如:fibn=fibn-1+fibn-2;,下标表达式的值必须是整型表达式。,数组名下标表达式,13,8.1.2 数组元素的引用(续),说明:下标从0开始(下界为0),数组的最大下标(上界)是数组长度减1。例如:int a10;scanf(%d,/*下标越界*/,C编译系统不做越界检查,如果引用的数组元素超出数组范围会破坏其他变量的值。,14,8.1.2 数组元素的引用(续),是下标运算符,引用数组元素时,根据数组的首地址和下标数,计算出该元素的实际地址,取出该地址的内容进行操作。,如引用 score2:(1)计
6、算 2000+2*4=2008(2)取出2008的内容,15,合法标识符,表示元素个数引用时下标从0开始,:数组运算符单目运算符,例 int a6;,编译时分配连续内存内存字节数=数组大小*sizeof(元素数据类型),数组名表示内存首地址,是地址常量,一维数组的定义定义方式:类型说明符 数组名常量表达式;,返回,16,main()int i,a10;for(i=0;i=0;i-)printf(“%d”,ai);,一维数组的引用数组必须先定义,后使用只能逐个引用数组元素,不能一次引用整个数组数组元素表示形式:数组名下标其中:下标可以是常量或整型表达式例8.1 数组元素的引用,运行结果:9 8
7、7 6 5 4 3 2 1 0,17,8.1.3 一维数组的初始化,初始化:在定义数组时给数组元素赋初值。,1在定义数组时,对全部数组元素赋初值 例如:int a5=0,1,2,3,4;此时可以省略数组长度,例如:int a=0,1,2,3,4;2在定义数组时,对部分数组元素赋初值 例如:int a5=1,2,3;系统为其余元素赋 0。3当初值的个数多于数组元素的个数时,编译出错 例如:int a5=0,1,2,3,4,5;,18,8.1.4 一维数组应用举例,【例8.1】将10个人的成绩输入计算机后按逆序显示。#define N 10main()int i;float scoreN;for(
8、i=0;i=0;i-)printf(%8.1f,scorei);,运行情况如下:67 74 89 92 34 67 83 95 73 78 78.0 73.0 95.0 83.0 67.0 34.0 92.0 89.0 74.0 67.0,19,【例8.2】用数组求Fibonacci数列前20个数,分析:定义一个含有20个元素的数组f,即 int f20;其中 f0=1,f1=1,fn=fn-1+fn-2(n2)用一个循环结构:让循环变量n从 2到 20,循环体为 fn=fn-1+fn-2 程序如面所示:,lt16,20,f0,f1,f2,f3,f4,f5,f19,.,1,1,f19,0,1,
9、4,5,2,3,19,#include 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);,21,【例8.4】冒泡法排序(从小到大)。,排序过程:(1)比较第一个数与第二个数,若为逆序a0a1,则交换;然后比较第二个数与第三个数;依次类推,直至第n-1个数和第n个数比较为止第一趟起泡排序,结果最大的数被安置在最后一个元素位置上(2)对前n-1个数进行第二趟起泡排序,结果使次大的数被安置在第n-1个元素位置(3)重复上述过程,共经过n-1趟起泡
10、排序后,排序结束,22,例,38 49 65 76 13 27 30 97,第一趟,38 49 65 13 27 30 76,第二趟,38 49 13 27 30 65,第三趟,38 13 27 30 49,第四趟,13 27 30 38,第五趟,13 27 30,第六趟,49 38 65 97 76 13 27 30,初始关键字,n=8,13,76,76,76,27,30,13,65,27,65,30,65,13,13,49,49,30,49,27,38,27,38,30,38,13 27,第七趟,38,49,76,97,97,97,97,27,13,27,30,23,冒泡法排序(续),从上
11、述过程可以看到:n个数要比较n-1趟,而在第j趟比较中,要进行n-j次两两比较。,24,#include main()int a11,i,j,t;printf(Input 10 numbers:n);for(i=1;iai+1)t=ai;ai=ai+1;ai+1=t;printf(The sorted numbers:n);for(i=1;i11;i+)printf(%d,ai);,25,以6个数:3、7、5、6、8、0为例。思路:第一趟:将第一个数依次和后面的数比较,如果后面的某数小于第一个数,则两个数交换,比较结束后,第一个数则是最小的数。第二趟:将第二个数依次和后面的数比较,如果后面的某
12、数小于第二个数,则两个数交换,比较结束后,第二个数则是次小的数;。,【例8.5】选择法排序(从小到大)。,26,【例8.5】选择法排序(续),27,#define N 5main()int aN;int i,j,t;for(i=0;iai)t=aj;aj=ai;ai=t;printf(The sorted numbers:n);,程序运行情况如下:96 78 65 86 40The sorted numbers:40 65 78 86 96,28,8.2 二维数组,数据类型 数组名常量表达式1常量表达式2;,例如:float x23;,8.2.1 二维数组的定义,int a3,4,b(3,4)
13、,c,d(3)(4);,29,地址 值 数组元素,二维数组元素在内存中的排列顺序:按行存放,30,例 int a34;,二维数组理解,每个元素ai由包含4个元素的一维数组组成,二维数组a是由3个元素组成,31,x0是数组名,是元素x00的地址,x1是数组名,是元素x10的地址,二维数组可看作是一种特殊的一维数组,x0-x00,x01,x02,x1-x10,x11,x12,例如,可以把x数组看作是包含二个元素的一维数组,每个元素又是一个含有三个元素一维数组。,32,a34=3;/*下标越界*/a1,2=1;/*应写成 a12=1;*/,8.2.2 二维数组元素的引用,例:int a34;a00=
14、3;a01=a00+10;,数组名行下标表达式列下标表达式,数组元素的表示形式:,33,8.2.3 二维数组的初始化,例:int a23=1,2,3,4,5,6;,1按行赋初值,例:int a23=1,2,3,4,5,6;初始化后结果:1 2 3 4 5 6,2按数组元素在内存中排列的顺序对各元素赋初值,3给部分元素赋初值,例:int a23=1,4;初始化后结果:1 0 0 4 0 0,34,8.2.3 二维数组的初始化(续),4数组初始化时,行长度可省,列长度不能省 例如:int a3=1,2,3,4,5,6,7;int b4=1,4,5;初始化结果:,a 结果:a0:1 2 3 a1:4
15、 5 6a2:7 0 0,b 结果:b0:1 0 0 0b1:4 5 0 0,35,下面对二维数组的定义都是错误的:,8.2.3 二维数组的初始化(续),float x3=1.0,2.0,3.0,4.0,5.0,8.0;,int a,b 2,c3;,int m24=1,2,3,4,5,6,7,8,9;/*编译出错,初值个数多于数组元素的个数*/,36,8.2.4 二维数组应用举例,【例8.6】给一个4行3列的二维数组输入/出数据。main()int a43,i,j,k;for(i=0;i4;i+)for(j=0;j3;j+)scanf(%d,程序运行情况如下:1 2 34 5 67 8 910
16、 11 121 2 34 5 67 8 910 11 12,37,二维数组元素的引用形式:数组名下标下标二维数组元素的初始化分行初始化:,按元素排列顺序初始化,38,程序举例,【例8.6】将二维数组行列元素互换,存到另一个数组中。,39,8.2.4 二维数组应用举例(续),【例8.7】有一个NM矩阵,编程序求出其中绝对值最大的那个元素的值及其所在的行、列位置。,图8.4 查找最大元素,40,#include math.h#define N 4#define M 5main()int i,j,row,colum,max,aNM;/*输入数据*/max=a00;row=colum=0;for(i=
17、0;imax)max=abs(aij);row=i;colum=j;/*输出数据*/,程序运行情况如下:34 56 12 67 2312 67 43 98 5465 45 66 16 2437 83 25 64 19max=98,row=1,colum=3,41,8.3 字符数组与字符串,字符数组:可以存放若干个字符,也可以存放字符串。,8.3.1 基本概念,字符串:字符串的末尾必须有0字符,它的ASCII码值为0。,不是字符串,是字符串,42,再例如:char a35;a数组是一个二维的字符数组,可以存放15个字符或3个长度不大于4的字符串。,8.3.2 字符数组的定义,例如:char s1
18、0;s数组是一维字符数组,它可以存放10个字符或一个长度不大于9的字符串。,注意:字符串只能存放在字符数组中。,43,8.3.3 字符数组的初始化,1用字符常量赋初值例如:char c5=C,h,i,n,a;,再例如:char c6=C,h,i,n,a,0;,是字符串,不是字符串,44,8.3.3 字符数组的初始化(续),再例如:char a310=basic,pascal,c;,2用字符串常量赋初值,例如:char str10=a string;或char str10=a string;,是字符串吗?,45,8.3.3 字符数组的初始化(续),例如:char s37=s,t,r,i,n,g;
19、,3初始化时长度的省略,例如:char s1=Good morning!;,b0,b13,例如:char s2=s,t,r,i,n,g;,思考:哪个数组存放的是字符串,?,46,8.3.4 字符数组的引用,【例8.8】对字符数组c1赋 09,对字符数组c2赋 AZ,然后输出c1和c2数组中的数据。,1对字符数组元素的引用,可以为数组元素赋值,也可以输入/输出元素的值。,47,程序如下:,main()char c110,c226;int i;for(i=0;i10;i+)c1i=i+48;for(i=0;i26;i+)c2i=i+A;for(i=0;i10;i+)printf(%c,c1i);p
20、rintf(n);for(i=0;i26;i+)printf(%c,c2i);printf(n);,48,2对字符数组的整体引用,输出字符串例如:char c=China;printf(%s,c);输出结果为:China,C是数组首地址,输出时遇 0 为止,再例如:char c=pascal0basic;printf(%s,c);输出结果为:pascal,49,2对字符数组的整体引用(续),输入字符串例如:char c10;scanf(%s,c);输入:beijing,三个字符串用空格隔开,分别赋给str1、str2、str3三个数组。,再例如:char str110,str210,str31
21、0;scanf(%s%s%s,str1,str2,str3);输入:pascal basic c,注意:不可以为数组整体赋值,例如:char c10;c=beijing;因为c是数组首地址,是常量!,50,8.3.5 字符串处理函数,说明:程序中如果调用下面介绍的8个字符串处理函数,在程序的开始应该写:#include stdio.h 或#include string.h 预处理命令,但在Turbo C中可以省略。在字符串处理函数中,凡是用数组名或字符串首地址作参数的地方,都可以用指针变量作参数。指针变量的概念在第8章介绍。,51,1字符串输出函数puts(),调用格式:puts(str)功能
22、:输出一个字符串,输出后自动换行。说明:str可以是字符数组名或字符串常量。,例如:char str1=China;char str2=Beijing;puts(str1);puts(str2);输出结果:China Beijing,52,2字符串输入函数gets(),调用格式:gets(str)功能:从键盘读入一个字符串存入str数组中,并且得到一个函数值,该函数值是str数组的首地址。说明:str是数组名。,程序运行情况如下:How are you?Fine thank you.How are you?Fine thank you.,例如:main()char c120,c220;gets
23、(c1);gets(c2);puts(c1);puts(c2);,53,3字符串连接函数 strcat(),调用格式:strcat(str1,str2)功能:把str2中的字符串连接到str1字符串的后面,结果放在str1数组中,函数值是str1的值。,必须足够大,输出结果:beijing and shanghai,例如:char str121=beijing and;char str2=shanghai;printf(%s,strcat(str1,str2);,54,4字符串复制函数 strcpy(),调用格式:strcpy(str1,str2)功能:将str2中的字符串复制到str1数组中
24、。,s1必须足够大,思考:这样赋值s1=Beijing;或 s1=s2;可以吗?为什么?,s1的结果,例如:char s110,s2=Beijing;strcpy(s1,s2);或:strcpy(s1,Beijing);,55,5字符串比较函数 strcmp(),调用格式:strcmp(str1,str2),str1,str2,str1,str2,str1,str2,strcmp(str1,str2)=0,strcmp(str1,str2)0,strcmp(str1,str2)0,56,例如:比较两个字符串的大小。,main()char s1=aBC,s2=abc;if(strcmp(s1,s
25、2)=0)printf(s1=s2);else if(strcmp(s1,s2)0)printf(s1s2);else printf(s1s2);,程序输出结果:s1s2,思考:若有语句if(s1=s2)printf(s1=s2);比较的是什么?,57,8.求字符串长度函数 strlen(),调用格式:strlen(str)功能:测试字符串长度。函数值就是str中字符的个数。,思考:字符串China和str数组在内存中各占几个字节?,输出结果:5,例如:char str10=China;printf(%d,strlen(str);或printf(%d,strlen(China);,58,7大写
26、字母转换成小写字母函数 strlwr(),调用格式:strlwr(str)功能:将str字符串中的大写字母转换成小写字母。,输出结果:micro soft word,输出结果:abcd,例如:char str=MICRO SOFT WORD;strlwr(str);puts(str);,例如:printf(%s,strlwr(AbCd);,59,8小写字母转换成大写字母函数 strupr(),调用格式:strupr(str)功能:将str字符串中的小写字母转换成大写字母。,输出结果:PASCAL,例如:char ch10=pascal;printf(%s,strupr(ch);,60,8.3.
27、6 字符数组应用举例,【例8.9】从标准输入设备上输入一个字符串,分别统计其中每个数字、空格、字母及其他字符出现的次数。,思路:用gets()函数读字符串,然后判断每一个字符是否是数字、空格、大小写字母或其他字符,用循环实现。注意:此题要求分别统计每个数字出现的次数,而不是统计数字出现的总次数。用一个一维整型数组存放每个数字出现的次数。,61,char s80;int i,sp=0,oth=0,lett=0;int dig10=0;gets(s);for(i=0;si!=0;i+)if(si=0,程序运行情况如下:0:4个 1:5个 2:2个 3:0个 4:1个 5:0个 6:0个 7:0个
28、8:0个 9:2个space:1 letter:5 other:5,62,8.3.6 字符数组应用举例(续),【例8.10】输入某月份的整数值112,输出该月份的英文名称。,思路:将12个英文月份以字符串的形式存放到month1315中,一行存放一个字符串。,63,main()char month 15=Illegal month.,January,February,March,April,May,June,July,August,September,October,Novenber,Decenmber;int m;printf(nInput month:);scanf(%d,程序运行情况如下
29、:Input month:1010:October,64,8.3.6 字符数组应用举例(续),【例8.11】将N个国家名按字母顺序排序后输出。思路:从键盘输入N个国家名称存放到一个二维字符数组中,然后用选择法对这N个字符串排序。,程序如下:#define N 5#define M 10#include stdio.hmain()char sNM,strM;int i,j;,65,8.3.6 字符数组应用举例(续),for(i=0;i0)strcpy(str,si);strcpy(si,sj);strcpy(sj,str);for(i=0;iN;i+)puts(si);,66,例3:输入一行字符
30、,统计有多少个单词,单词用空格分隔。如:I am a student.#include stdio.hmain()char string81,c;int i,num=0,word=0;gets(string);for(i=0;(c=stringi)!=0;i+)if(c=)word=0;else if(word=0)word=1;num+;printf(There are%d words in the linen,num);,67,第8章 习题,1.下面不能把字符串:Hello!赋给数组的语句是A)static char b110=H,e,l,l,o,!;B)static char b210;
31、b2=Hello!;C)static char b310;strcpy(b3,Hello!);D)static char b410=Hello!;,2、若二维数组a 有m列,则aIj前的元素个数为:A)j*m+I B)I*m+j C)I*m+j-1 D)I*m+j+1,3、下面程序段运行结果是:char c5=a,b,0,c,d,0;printf(“%s”,c);A)ab B)ab C)ab c D)ab0,68,4、以下对S的初始化,不正确的是:A)char s5=“abc”B)char s5=a,b,c;C)char s5=;D)char s5=“abcdef”;,5、有下面程序段:cha
32、r a3,b=“china”;a=b;printf(“%s”,a);则A)运行后输出china B)运行后输出chC)运行后输出chi D)编译出错,69,6、若定义二维数组 int a33=1,2,3,4,5,6,7,8,9;int k;则下列语句的输出结果是:for(k=0;k3;k+)printf(“%d”,ak,2-k);A)3 5 7 B)3 6 9 C)1 5 9 D)1 4 7,7、判断字符串a 和 b 是否相等,应当使用:A)if(a=b)B)if(a=b)C)if(strcpy(a,b)D)if(strcmp(a,b),70,读程序,写出正确结果:1、main()char a
33、5=*,*,*,*,*int i,j,k;char space=;for(i=0;i5;i+)printf(“n”);printf(“”);for(j=1;j=i;j+)printf(“%c”,space);for(k=0;k5;k+)printf(“%c”,ak);,*,71,读程序,写出正确结果:2、#include main()char a80=“AB”,b80=“LMNP”int I=0;strcat(a,b);while(aI+!=0)bI=aI;puts(b);,答案:LBLMNP注意:当b 赋值时,I的值已递增即 b1=a1,而b0仍保持原来的值L,72,程序填空:数组A包括10
34、个整型元素。下面程序是求出A中各相邻两个元素的和,并存入数组B中,按每行3 个元素的形式输出,请填空。main()int a10,b10,I;for(I=0;I10;I+)scanf(“%d”,73,8-1 main()int a11=1,3,5,7,9,10,13,14,35,98;int i,j,k,number;clrscr();for(i=0;inumber)k=i;break;for(i=10;ik;i-)/*依次后移一个位置*/ai=ai-1;ak=number;/*插入*/printf(nThe inserted numbers:n);for(i=0;i=10;i+)printf
35、(“%5d”,ai);,读程序,说明程序的功能,74,8-2#define N 11 main()int i,j,aNN;for(i=1;iN;i+)/*初值*/aii=1;ai1=1;for(i=3;iN;i+)for(j=2;j=i-1;j+)aij=ai-1j-1+ai-1j;for(i=1;iN;i+)/*输出*/for(j=1;j=i;j+)printf(%6d,aij);printf(n);printf(“n”);,75,8-3 main()int a34,i,j,x,k,max,maxi,maxj;for(i=0;i3;i+)for(j=0;j4;j+)scanf(“%d”,76
36、,#include stdio.h main()int i,j,upp,low,dig,spa,oth;char text380;upp=low=dig=spa=oth=0;printf(Please input the paper(3 line)n);for(i=0;i=A,printf(n);for(i=0;i3;i+)puts(texti);printf(upper case:%d,lower case:%d,digist:%d,space:%d,others:%d,upp,low,dig,spa,oth);,8-4,77,8-5 编一程序,将两字符串连接起来,不用strcat函数 main()static char s180,s280;int i=0,j=0;scanf(%s,s1);scanf(%s,s2);while(s1i!=0)i+;while(s2j!=0)s1i+=s2j+;s1i=0;printf(%sn,s1);,