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