12第9章-字符串课件_第1页
12第9章-字符串课件_第2页
12第9章-字符串课件_第3页
12第9章-字符串课件_第4页
12第9章-字符串课件_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第9章字符串字符串是C语言中另一种常用的数值对象,可以用来表示若干个字符的集合。在C语言的实现中,字符串与字符数组有着紧密的联系。读者在学习字符串的时候要注意两者的异同点。在第8章中已经介绍了数组,并且涉及了字符数组的一些简单使用。本章将详细讨论字符数组和字符串的使用,同时还将介绍字符串的格式化输入输出函数的使用。第9章字符串通过本章的学习,需要掌握以下知识点:字符数组的使用;字符串和字符数组的关系;字符串常量和字符串变量的使用;字符串终止符’\0’的作用;使用printf函数和scanf函数处理字符串。9.1字符数组字符数组,即char型数组,是用以存放char型数据的数组容器。它的定义和使用与其他类型的数组基本相似。本小节将先介绍如何字符数组的定义和赋值,再讨论初始化数组的方法,并在此基础上介绍二维字符数组的使用,最后通过几个范例来演示字符数组的使用。9.1.1定义和赋值字符数组字符数组的定义与其他数据类型的数组定义类似,需要首先指定数组容量。标准形式如下:char数组名[数组容量];其中,为了提高程序可维护性,一般使用具名常量作为数组容量。在数组定义后对数组赋值,只能通过对其中的每个元素挨个赋值的方式进行。例如:01 chararray_ch[6];02 03 array_ch[0]=‘S’;04 array_ch[1]=‘u’;05 array_ch[2]=‘n’;06 array_ch[3]=‘d’;07 array_ch[4]=‘a’;08 array_ch[5]=‘y’;9.1.1定义和赋值字符数组以上语句将array_ch定义为字符数组,并对其中的元素挨个赋值,如果数组内的元素具有某种规律性,还可以使用循环语句来为字符数组赋值。这种赋值方式比较简洁。例如,要把一个数组赋值为’a’到’z’,可以使用如下代码:01 #defineMAX_CHAR2602 …03 inti=0;04 chararray_ch[MAX_CHAR];05 06 for(i=0;i<MAX_CHAR;++i){07 array_ch[i]=‘a’+i;08 }9.1.1定义和赋值字符数组上述语句将数组array_ch的元素挨个赋值为’a’~’z’。注意:定义字符数组时,同样要求指定数组容量大小,并且必须使用常量来表示。由于char型可以视为字长为1个字节的整数,所以也可以使用整型数组来存储字符。但是,由于int型数据类型占用4个字节,而char型数据类型只占用1个字节,因此使用int型数组会浪费空间。范例9-1展示了如何使用字符数组和int型数组来存储字符。9.1.2字符数组的初始化与其他变量一样,使用字符型数组也应当对其初始化。字符型数组的初始化方法与上一章介绍的数组的初始化一样,有3种方法:1.初始化所有元素在数组定义语句中为所有数组元素赋值,如下:chararray[6]={‘S’,‘u’,‘n’,‘d’,‘a’,‘y’};charstr[4]={‘g’,‘o’,‘o’,‘d’};上述两个语句将数组array和str的全部元素初始化。9.1.2字符数组的初始化2.初始化部分元素初始化值序列只给数组的前一部分值。如下:chararray[6]={‘S’};charstr[4]={‘g’,‘o’};上述两个语句虽然只将数组的前一部分元素显式初始化,但是编译器会将其它部分自动初始化为0。其中,array[1]、array[2]、array[3]、array[4]和array[5]全为0,str[2]和str[3]全为0。9.1.2字符数组的初始化3.不指定数组容量初始化数组时还可以不指定数组容量,而只给出初始化值序列,由初始值序列的个数决定数组容量,例如:chararray[]={‘S’};charstr[]={‘g’,‘o’};上述初始化语句执行后,字符数组array的容量被设为1,只含一个元素’S’;字符数组str的容量被设为2,元素分别为’g’和’o’。9.1.3二维字符数组1.二维字符数组的定义二维字符数组就是数组元素为字符的二维数组。与定义其他类型的二维数组一样,定义二维字符数组也必须指定各个维数的容量,其标准形式如下:char数组名[容量1][容量2];例如:charq[3][4];变量q被定义为字符数组,并占用3×4的数组空间。9.1.3二维字符数组2.二维字符数组的赋值同样二维字符数组的赋值也必须通过访问其中的每个元素来进行。例如:q[2][3]=‘a’;q[1][1]=‘b’;其中,二维字符数组q的第2排第3列元素(均从0开始编号)被设为字符’a’,数组中的第1排第1列元素被设为’b’。9.1.3二维字符数组3.二维字符数组的初始化二维字符数组的初始化与一维数组初始化类似,也可以通过三种方式进行初始化。例如:01 charq[2][2]={{‘a’,‘b’},{‘c’,‘d’}}; /*方式一:初始化所有元素*/02 charp[4][4]={ /*方式二:初始化所有一维数组的部分元素*/03 {‘a’,‘b’,‘c’},04 {‘e’,‘f’,},05 {‘g’},06 {}};07 charw[][]={ /*方式三:初始化部分一维数组*/08 {‘a’,‘b’,‘o’,‘u’,‘t’},09 {‘!’}};9.1.4字符数组使用举例下面通过两个字符数组的案例来讨论如何在C语言中有效地使用字符数组。1.翻转单词本案例要求使用一个字符串数组实现将一个单词的字符翻转的功能,并要求将结果存储在原来的字符数组中。例如,如果一个单词为“GoodBye”,翻转后为“eyBdooG”。对于这个问题,方法之一是引入一个临时数组,可以分两个步骤来解决问题:9.1.4字符数组使用举例(1)借助一个临时字符数组,将原字符数组的内容按相反的顺序存储在该临时字符中。该步完成后,两个数组的内容如下图所示。9.1.4字符数组使用举例(2)将该临时数组的内容顺序复制回原数组中。该步骤完成后,两个数组的内容如下图所示。9.1.4字符数组使用举例2.翻转单词的另一种实现由于上一种方法引入了一个临时数组,因此会占用额外的内存空间。这里将介绍另一种不需要借助其他数组,只在原数组上进行操作而实现翻转单词功能的方法。9.1.4字符数组使用举例由于单词顺序存储在一个数组内,对其进行翻转实际上等效于,将其前后调换:第一个字符和倒数一个交换,第二个字符和倒数第二个字符交换,第三个字符和倒数第三个字符交换……直到字符数组的中间,假设为第n个字符。如果该字符数为奇数,则正好只剩一个字符;如果为偶数,则剩为两个字符。但是不论哪种情况,都可以照样将第n个字符和倒数第n个字符交换,如果是只有一个字符,就是自己和自己交换,不会影响功能。9.1.4字符数组使用举例该方法的实现过程如下图所示。9.2字符串常量与字符串变量为了更方便地对字符数据集合进行处理,C语言引入了字符串类型。本节将讨论字符串与字符数组的关系,首先依次介绍了字符串常量和字符串变量的使用,并通过几个范例来演示如何字符串的格式化输入输出。9.2.1字符串常量C语言中的字符串常量是指用以表示字符串数据的常量,是包含在引号里的字符的集合。在前面的程序中,已经接触到很多的字符串常量,例如:“Hello,world!\n”“a=%d”“Thisisaprogram.”这三个都是字符串常量。字符串常量在C语言中被处理为一维字符数组存储在内存中一块连续的区域内。9.2.1字符串常量例如,上面的“Hello,world!\n”(中间无空格)在内存中的存储形式如图9-7所示。9.2.1字符串常量而有以下定义的字符数组在内存中的存储形式如下图所示。charstr[]={‘H’,‘e’,‘l’,‘l’,‘o’,‘,’,‘w’,‘o’,‘r’,‘l’,‘d’,‘!’,‘\n’};9.2.1字符串常量C语言定义了’\0’作为字符串常量在内存中结束的标志。对于任何一个字符串常量,C语言存储其有效内容的同时,还会在它后面加上一个’\0’。例如,字符串“Hello”的有效内容为5个字符,将其存储在内存中时,末尾会自动追加一个’\0’,变为6个字符。其在内存中的空间为6字节。9.2.2字符串变量字符串变量实际上就是一维字符数组。使用字符串常量初始化一维数组,便可以得到一个字符串变量。例如:charstr[13]={“GoodDay!”};该语句会将字符串“GoodDay!”的内容赋值给字符数组str中前几个相应的内存空间,即’G’、’o’、’o’、’d’、’’、’D’、’a’、’y’、’!’和’\0’被相应赋值给字符数组str的前10个字符空间,未被明确赋值的空间被初始化为0,即’\0’。初始化后str的内存空间如下图所示。9.2.2字符串变量注意:字符串变量在内存中以一维字符数组的形式存储。上述初始化语句也可以省略花括号,如下所示:charstr[13]=“GoodDay!”;也可以不指定数组容量,如下所示:charstr[]=“GoodDay!”;这种方式下,字符数组str的数组容量由字符串常量的字节数决定。因为“GoodDay!”所占空间为10个char型,所以str的容量大小为10。上述初始化语句,与以下初始化语句等效:charstr[]={‘G’,’o’,’o’,’d’,’’,’D’,’a’,’’y,’!’,’\0’};9.2.2字符串变量而以下缺少最后一个’\0’的初始化语句得到的字符数组str是不一样的:charstr[]={‘G’,’o’,’o’,’d’,’’,’D’,’a’,’’y,’!’};该语句只能得到一个内存空间为9个字节的字符数组。提示:字符串必须包含’\0’,其最后一个字符肯定是’\0’;而字符数组可以不要’\0’。要将字符数组初始化为全0,可以使用如下简单形式:chararray[20]=“\0”;因为字符串“\0”的存储在内存中为两个’\0’,所以执行该语句后array的前两个字符赋值\0,剩余18个字符会自动初始化为’\0’。9.2.3格式化输出字符串使用printf函数可以实现字符串的格式化输出,其为字符串输出提供了专门的格式符:%s。使用printf函数输出字符数组的形式如下:printf(“%s”,str);该语句会将从地址str(数组名也是数组首地址)开始的字符依次输出,直到遇到’\0’字符。范例9-6演示了如何使用printf函数输出字符数组。9.2.4字符终止符的作用在前面的讨论中,已经知道’\0’符号在字符串中的作用。范例9-7进一步演示了’\0’在使用printf函数格式化输出字符串中的作用。9.2.5格式化输入字符串使用scanf函数可以实现字符串的格式化输入,实现从标准输入为字符串变量赋值。与printf函数一样,scanf函数提供的格式字符也为‘s’,该函数调用形式如下:scanf(“%s”,str);由于数组名就代表数组的首地址,因此该语句中不需要再对str取地址。如下形式是错误的:scanf(“%s”,&str);9.2.5格式化输入字符串该语句会以字符串的形式从标准输入读取数值,直到遇到空白符(包括空格符、回车符、制表符和字符串终止符)。读取的值将会依次赋值给从地址str(变量名str也是数组首地址)开始的若干个字符空间。例如,若有输入为:hello,world!则字符串变量(字符数组)str只能得到空格前的6个字符,而系统会在其有效字符后自动增加字符串终结符’\0’。赋值的结果如右图所示。9.2.5格式化输入字符串也可以在一个scanf函数中给多个字符数组赋值,如下所示:scanf(“%s%s%s”,s1,s2,s3);如果输入为:Itistimefordinner!(回车)那么,字符数组s1被赋值为“It”,字符数组s2被赋值为“is”,字符数组s3被赋值为“time”,同样每个字符数组末尾都会自动增加一个’\0’。9.3字符串应用举例字符串处理是C语言程序中十分频繁的处理任务。为了熟悉C语言中的字符串处理方式,本小节将通过几个字符串处理的典型范例来演示C语言中对字符串的基本操作方法。同时,还介绍了字符串处理时最常用的辅助函数之一:strlen函数。9.3.1使用strlen函数strlen函数在字符串处理中是十分常用的,其功能为得到一个字符串的有效长度,即从第一个字符开始到第一个字符串终止符的字符个数(不包括字符串终止符)。其调用形式如下:a=strlen(str);执行该语句后,strlen函数会计算字符串str的有效长度,并将该值作为函数值赋值给a。然后通过访问a,即可获得字符串str的有效长度。9.3.2统计单词数本案例要求实现统计字符串中单词数的功能。假定单词之间使用空格隔开。如果输入字符串为“dogcatwoftant”,则输入为4个单词。基本算法描述如下:使用一个游标i从首字符向后遍历字符串{如果i指向字符!=空格,说明这是一个单词的开始{单词数connt增加1;将i向后移到该单词结束的位置,即使i指向遇到的第一个空格或字符串终止符;}i自增1;}9.3.3颠倒单词顺序本范例要求实现颠倒字符串中的单词顺序的功能。例如:如果输入为“Howdoyoudo?”,则输出“do?youdoHow”;如果输入为“Whatagoodday!!!”,输出为“day!!!goodaWhat”。其中,单词之间只考虑出现空格符。一种比较容易想到的方法就是引入一个临时字符数组。将逆序输出的字符串先拷到临时数组,再从临时数组复制会原数组。具体步骤如下:9.3.3颠倒单词顺序(1)使用游标从字符结尾向前搜索,每找到一个单词都将其整个复制到临时数组,并在每个单词后增加一个空格(最后一个单词加字符串终止符’\0’)。这一步骤执行后,原数组与临时数组的内容状况如下图所示。9.3.3颠倒单词顺序(2)将临时数组的内容逐个字符复制到原数组。这一步骤执行完后,两个数组在内存中的内容如下图所示。9.3.4颠倒单词顺序-改进范例9-10的方法有两个缺点:由于引入了一个临时字符串,空间复杂度高。执行了两次复制(从原字串到临时字串,从临时字串到原字串),时间复杂度高。另外一种比较灵巧且较节约空间的做法是在本数组内实现单词顺序的颠倒。该方法也需要两部来实现。9.3

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论