版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C+面向对象程序设计,第八章 字符串和向量 葛勇,总览,字符串的一种数组类型 标准string类 向量,字符串的一种数组类型,C字符串值和C字符串变量 陷阱:为C字符串使用=和= 中的其他函数 C字符串输入和输出 C字符串到数字的转换和可靠输入,8.1.1 C字符串值和C字符串变量 在C语言中字符串是用字符数组的形式来表示的,如写一个字符串:”hello”,则可以分解为h,e,l,l,o这5个字符,另外每个字符串有个字符0来表示字符串的结束,为字符串结束符,因此要表示它,就需要长度为6的数组来保存这里字符,因此,可以这样: char str6=“hello”;,C字符串变量是一个字符数组,并且
2、可能是一个部分填充的数组。和其他数组一样,C字符串变量的下标索引也是从0开始的。C字符和一般数组之间的差别在于,C字符串作为一个函数形参时,不需要传一个参数来表示这个数组的大小,因为C字符串有一个结束符0,因此函数是可以知道这个字符串的实际大小的。,C字符串做函数形参,用C字符串做函数形参时,可这样来做: int fun(char str) coutstrendl; 就可以把字符串中所有字符输出来。从上面的使用方法中,我们还可以看出来,C字符串的输出与一般数组也不一样,一般数组输出,C字符串的输入与输出,时,需要使用一个循环一个一个元素进行输出,而C字符串只需要简单的输出这个字符串的名称,就可
3、以直接输出所有元素了。 C字符串的输入方式也与一般的数组不一样,如: cinstr; 可以将从键盘输入的字符逐个读入字符串变量str中,直到遇到空白字符为止。读取完毕后,会自动在后面添加0表示字符串结束。,C字符串的初始化,C字符串的初始化与一般数组也有所不同,如: char MyMessage20=“Hi there.”; 如果和一般数组一样的初始化方式应该是: char MyMessage20=H,i, , t,h,e,r,e,.,0; 这两种初始化方式是等价的。 与一般数组一样,C字符串变量在进行初始化时可省略长度,如:,char s=“abc”; 等价于, char s4=“abc”;
4、 但在MingW中,如果写如下代码: char s3=“abc”; 则会有长度不够的错误提示。 当进行部分填充时,C字符串也与一般数组有所不同,如:,int a10=1,2,3,5; char s6=“hi”; 则从a4开始以后的元素值都是0,而s中从s3开始后的元素是用不到,因为s2=0 当读字符串s时,遇到0就不再往后读了。 和一般数组一样,也可以为字符串数组某个元素赋值或输出一个元素的值,如: couts1;,则输出字符i,若: s1=e; 则s变成”He”。,8.1.2 陷阱:为C字符串使用=和=,对于C字符串不能使用=号进行赋值,如: char str6; str=“Hello”;
5、则是非法的,要为C字符串赋值,则需要使用函数strcpy,即是字符串copy函数,如: strcpy(str,”Hello”); 则是有效的,但这个函数不会检查第二个参数的长度是否超过第一个字符串变量的长度,如:,char str6; strcpy(str,”I am a teacher.”); 一样可以进行,当使用: coutstr; 时,输出结果为: I am a teacher. 比较安全的方式是,当要进行赋值时,使用函数strncpy,它具有三个参数,可如下使用:,char s6; strncpy(s,Iamateacher.,5); coutsendl; 则输出结果为: Iamat
6、但如果strncpy的第三个参数超过第一个参数字符串变量的长度,则结果可以不可预料,如:,char s6; strncpy(s,Iamateacher.,8); coutsendl; 测试的结果为: Iamateacv 另外关于C字符串操作的函数常用的还有strcat,strcmp等,strcat为两个C字符串拼接的函数,strcmp为两个C字符串比较大小的函数,如:,char s13=hi,s25=good; strcat(s1,s2); couts1endl; 则输出结果为: higood 从结果我们可以看出, 拼接的结果放在s1中 在拼接如不检查s1的长度是否足够,strcmp的使用可如
7、下进行: char s13=hi,s25=good; coutstrcmp(s1,s2)endl; 输出结果为: 1 再如: coutstrcmp(s1,s1)endl; 则输出,0 再如: coutstrcmp(hi,hi,you)endl; 则输出 -1 也就是strcmp(s1,s2)的结果是: 当s1位于s2的前面时(按各个字符的Ascii码来确定前后关系),则结果为-1,反之,则为1,如果s1与s2相等,则结果为0,但C字符串的相等关系不能使用如s1=s2来判定,练习,P.304(7版P.316) 18,C字符串到数字的转换和可靠输入,函数atoi可将一个字符串转换为整数,如: at
8、oi(“1234”) 则转换成整数1234。atoi函数放在头文件cstdlib中,但在MingW中可以不引入这个头文件,有了iostream与std名称空间即可。 但atoi(“s234”)则转换为: 0 因为s不是数字,另外关于字符串与数字之间的转换函数还有atof,如:atof(“3.25”)则转换为double类型的值3.25,8.2标准string类,string类实际上是从C字符串产生出来的,但它是一个类机制的产物,与C字符串相比较它有许多更人性化的操作,如,我们可以: string str; /无需指定长度 str=“student”; /赋值,无需关心长度 string s=“
9、Hi”; coutstr+s; /str与s拼接,更方便 另外,string类有一个构造函数,可以在声明,时将声明的对象自动初始化为空串,如上 string str; 则str自动初始化为”空串。 另外比较两个string类的对象可以使用, =,=等等关系运算符,从这点上看,string类比C字符串要优越得多,使用起来更为方便。 string类的赋值与初始化的方式也是多种多样的,如:,string noun(“ants”); string noun=“ants”; 是等价的。 另外还可以为string类与C字符串变量之间使用+等操作符,如: noun=noun+”, I love you.”;
10、 则noun变成了”ants, I love you.”。还可以: noun=I love you, +noun;,实际上,这些操作的背后,string类都做了大量的工作,也就是它把C字符串“I love you, ”转换成了string类的字符串,然后再与noun相加,string类的I/O,string类的对象输入可如下进行: string s1,s2; cins1 s2; 这种方式输入时,s1与s2不能读入空白字符,如输入如下句子: May I come in? 则s1读到的是”May”,而s2读到的是”I”,也就,是说,string类的对象在读入时一但遇到空白字符就停止读取,因此这样只
11、能是一个一个单词读取。 如果要希望读取整行或空格,则需要使用getline函数,如: string line; getline(cin,line); 但不可以这样使用:,cin.getline(line); 因为cin.getline(char*)要求参数是一个字符数组,而string类型的不等同于字符数组。,练习,P.315(7版P.328) 15、16,getline函数的另类用法,在getline函数中还可以停止字符,如: string line; getline(cin,line,?); 当遇到?时,则停止读取,这样就可以把换行符n读入变量line中。 此外,getline函数的返回值
12、是一个输入流的引用,实际是第一个参数,原型为: istream”和getline,当我们在程序中混合使用cin变量;和getline函数时,读取的结果可能与我们预期不符,如: int n; string line; cinn; getline(cin,line); 假如输入如下:,557 Hi. 可能我们希望n读入的值为557,line读入的值为”Hi.”,但是,实际上,这样line得到是却是”,即一个换行符,因为当cinn;运行结束时,紧跟后面的是一个空行,然后是n,所以getline(cin,line)读到的是空行.,string类的下标操作符,string类的对象可以具有类似于数组的行为
13、,如: string str=“Hello, world.”; coutstr4; 则输出字符o。但string类的下标操作符不会检查是否越界,如: coutstr30; 编译器并不会给出错误提示。,如: #include #include using namespace std; int main() string line(Hello, world.); coutline30endl; 的输出结果为: =,不过string类有个成员函数at可以解决下标越界的问题,可如下使用: coutline.at(5); 则输出: , 但如果 coutline.at(30); 会引起程序异常终止,Thi
14、s application has requested the Runtime to terminate it in an unusual way. Please contact the applications support team for more information.,我们也可以使用at成员函数为string对象的某个元素赋值,如: string str(“Mary”); str.at(2)=X; 等价于 str2=X; 此外,关于string类还有许多成员函数和一些非常方便的使用方法,如赋值号等。,str.substr(3,4); str1=str2; str.empty();
15、 str1+str2; str.insert(3,str2); str.remove(pos,length); str1=str2 str1!=str2,str1str2 str1=str2 str.find(str1); str.find(str1,pos); str.find_first_of(str1,pos); str.find_first_not_of(str1,pos);,replace成员函数,replace成员函数是将string类指定位置,指定长度的串用指定的字符串替换掉,如: string line(Hello, world.),str(me); line.replace(
16、1,6,str); 则将line中从下标为1开始,长度为6的串,即 “ello,w”替换成str,即”me”,替换后,line为”Hmeorld.” 更多成员函数请查询Msdn,练习,P.322(7版P.335) 17、18,string类向C字符串的转换,可使用string类的成员函数c_str()进行,如: string s(“Mary”); char Cs=“I am C String, come on.”; strcpy(Cs,s.c_str(); 但不可以使用: strcpy(Cs,s);,练习,P.330(7版P.345) 5 作业: P.330(7版P.344) 4、7 第7题假
17、设是从一行进行输入,可使用getline读取到一个string对象中,使用string类的find和replace函数来实现,更正,string s1=“I am a teacher.”,s2=“good”; s1.find(s2); /值为4294967295,实际上就是-1 s1.erase(3,2); 则s1变成I aa teacher.,8.3 向量,向量可理解为能自动更改长度的数组,在C+中,我们目前为止,数组声明后,在运行时,长度是不可改变的。而向量可根据需要在运行时随时改变长度,可像如下方式声明一个向量,如: vector vi; 这样就声明一个元素类型为int型的一个向量,基本
18、上相当于是: int vi;,当然后者在C+中是不合法的,如果我们要使得向量的元素是其他类型的,比如说是double类型,则可如下进行: vector vd; 使用向量需要头文件vector以及std名称空间的支持。 向量中分量的使用基本上和数组一个,如: vi3=10;,如上声明的向量,是一个空的向量,也就是没有任何元素的,可理解为一个长度为0的数组,可以使用push_back成员函数为向量添加元素,如: vi.push_back(3); 则可把向量vi添加一个元素,该元素的值为3,则vi的长度也增加1,可使用size()成员函数获取一个向量的长度,如: vi.size(),可以想像现在vi
19、的长度应该为1,可使用循环来遍历向量的所有元素,如: for(int i=0;ivi.size();i+) coutvii“ “; coutendl; vi.size()返回的是一个unsigned int类型的值,因此和i比较时,可将i声明为unsigned int,则,for(unsigned int i=0;ivi.size();i+) coutvii“ “; coutendl; 或者可将vi.size()转换为int,如: for(unsigned int i=0;i(int)vi.size();i+) coutvii“ “; coutendl;,使用向量示例,#include #in
20、clude using namespace std; int main() vector v; cout“请输入一列正数.n” “并用一个负数表示输入结束。n”;,int next; cinnext; while(next0) v.push_back(next); coutnext; cout“您输入了:n”;,for(unsigned int i=0;iv.size();i+) coutvi“ “; coutendl; ,运行结果,声明向量时,也可以指定一个向量的初始长度,如: vector vd(10); 这样向量vd的初始长度为10,以后当元素个数超过10时,会自动增加长度,vector
21、在声明时自动将所有元素初始化为0,不需要像数组那么要程序员手动的去初始化。另外,内可以是任意已经定义的数组类型,如: vector str(20); 则str的每一个元素为一个字符串,现在共20个元素。 vector matrix; 则matrix的每一个元素是一个向量,可用来表示数学上的矩阵的概念,当然,还可以是: vector matrix;,从而,我们做数学的关于矩阵的运算,如两个矩阵的、,一个方阵的逆、行列式等。,陷阱:下标越界的问题,当我们使用 : vi; 时,当下标i=v.size()时,编译器并不给出错误提示,并且当我们使用如下赋值语句时: vi=10; 系统也不给出错误提示,可
22、能赋值还比较正常地进行着,但,这一定会造成一种不可预料的结果。和数组下标越界时原理相同。,长度、容量与效率问题,可使用向量的capacity()成员函数得到一个向量的容量,注意容量与size()即向量的长度是两个概念,容量是当前编译器为向量预留的内在空间的大小,而size()得到的是向量实际存在的元素个数,一般地,capacity()size(),并且capacity()=size()是一定的。,如果往向量里添加元素当size()的值到了capacity(),则编译器自动增加capacity()的值,即再次为该向量分配内存空间。 我们可使用reserve()成员函数为向量手动预留一定的内存空间
23、,如: vector vd; vd.reserve(32); 则为向量vd预留了32个double类型的存储空间。这样一次为向量分配一定的存储空间,要比每添加一个元素再分配一次内存空间效率要高,我们也可以使用resize()成员函数来改变一个向量的长度,如: vector vi; vi.resize(24); 则将向量的长度改为24,有时也可以提高效率。,关于向量的其他操作,int n=10; int t5=1,2,3,4,5; vector a(n); /按需创建 vector b(10, 1); /元素赋全,灵活的初始化 vector c(b); / 整体拷贝创建 vector f(t, t+5); /异类拷贝创建 vector d(b.begin(), b.begin()+3);/局部拷贝创建d为b的前个元素 a.assign(100); /动态扩容至100个元素,a.assign(b.begin(), b.begin()+3); /b的前3个元素赋给a a.assign(4,2); / a向量含4个元素,全初始化为
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2026学年河南省洛阳市初中数学七年级期末下册点睛提升黑金考题附答案
- PCR混采检测专项考核试题及详细答案
- 铜冶炼吹炼工安全操作规程
- 2026年配电箱线路绝缘检测理论与实操模拟试卷及答案
- 2025-2026学年江苏省南通市初中历史七年级期末上册高分黑金试卷详细参考解析
- OUM运营管理岗位实操考核试题(含详细答案)
- 帕金森病吞咽障碍饮水安全照护规范共识
- 线上处方药学审核要点专家共识(2025版)
- 老旧厂区拆除及场地平整施工方案
- 中级刨工理论考试题库及答案
- 雨课堂学堂在线《人工智能安全与伦理(北京航空航天)》学堂云单元测试考核答案
- 《CPPC1080.1实验室智慧化建设和评价指南第1部分总则-》
- 人教版 二年级上册数学 第三单元《平均分-等分》课件
- 全国青少年科技辅导员专业水平认证笔试模拟试题(初级)(含参考答案)
- 2026年度全国大学生廉政知识问答完整题库及答案
- 广东省广州市2026年中考化学试题附答案
- 九年级道德与法治上册 8.3 推动高质量发展 教学设计
- 2026年现代自动化控制理论的研究进展
- 2026年合理用药知识培训课件
- 高考导数大题10种核心题型导学案(全真题详解)
- 2026年浙江省选调生笔试《综合能力测试》真题及答案解析
评论
0/150
提交评论