您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 公司方案 > C++Primer第三章
制作人:左玉俊制作日期:2012-5-11部门:研发部标准库类型C++Primer第三章前言除第2章介绍的基本数据类型外,C++还定义了一个内容丰富的抽象数据类型标准库。其中最重要的标准库类型是string和vector,它们分别定义了大小可变的字符串和和集合。string和vector往往将迭代器用作配套类型,用于访问string中的字符串,或者vector中的元素。这些标准库类型是语言组成部分中更基本的那些数据类型(如数组和指针)的抽象。另一种标准库类型是bitset,提供了一种抽象方法来操作位的集合。与整型值上的内置位操作相比,bitset类类型提供了一种更方便的处理位的方式。本章将介绍标准库中的vector、string和bitset类型。3.1命名空间using的声明在本章之前看到的程序,都是通过直接说明名字来自std命名空间,来引用标准库中的名字。例如,需要从标准输入读取数据时,就用std::cin。这些名字都用了::操作符,该操作符是作用域操作符。它的含义是右操作数的名字可以在左操作数的作用域中找到。因此,std::cin的意思是说所需名字cin是在命名空间std中定义的。显然,通过这种符号引用标准库名字的方式是非常麻烦的。幸运的是,C++提供了更简洁的方式来使用命名空间成员。本节将介绍一种最安全的机制:using声明。使用using声明可以在不需要加前缀namespace_name::的情况下访问命名空间中的名字。3.1命名空间using的声明(续)using声明的形式如下:usingnamespace::name;一旦使用了using声明,我们就可以直接引用名字,而不需要再引用该名字的命名空间:#includestring#includeiostreamusingstd::cin;usingstd::string;intmain(){strings;//okcins;//ok3.1命名空间using的声明(续)couts;//errorstd::couts;//ok}1.每个名字都需要一个using声明一个using声明一次只能作用于一个命名空间成员。using声明可用来明确指定在程序中用到的命名空间中的名字,如果希望使用std(或其他的命名空间)中的几个名字,则必须为要用到的每个名字都提供一个using声明。例如,利用using声明可以这样重新编写第1.2.2节中的加法程序:3.1命名空间using的声明(续)#includeiostream//usingdeclarationsfornamesfromthestandardlibraryusingstd::cin;usingstd::cout;usingstd::endl;intmain(){coutEntertwonumbers:endl;intv1,v2;cinv1v2;3.1命名空间using的声明(续)coutThesumofv1andv2isv1+v2endl;return0;}对cin,cout和endl进行using声明,就意味着以后可以省前缀std::,直接使用命名空间中的名字,这样代码可以更易读。从这里开始,假定本书所有例子中所用到的标准库中的名字都已提供了using声明。注意:在编译我们提供的实例程序前,读者一定要注意在程序中添加适当的#include和using声明。3.1命名空间using的声明(续)2.使用标准库类型的类定义有一种情况下,必须总是使用完全限定的标准库名字:在头文件中。理由是文件的内容会被预处理器复制到程序中。用#include包含文件时,相当于头文件中的文本将成为我们编写的文件的一部分。如果在头文件中放置using声明,就相当于在包含该头文件using的每个程序中都放置了同一using声明,不论该程序是否需要using声明。通常,头文件中应该只定义确实必要的东西。请养成这个好习惯。3.2标准库string类型string类型支持长度可变的字符串,C++标准库将负责管理与存储字符相关的内存,以及提供各种有用的操作。与其他的标准库类型一样,用户程序要使用string类型对象,必须包含相关头文件。#includestringusingstd::string;3.2.1string对象的定义和初始化表3-1列出了几个string类型常用的构造函数。表3-1几种初始化string对象的方式strings1;默认构造函数,s1为空串strings2(s1);将s2初始化为s1的一个副本strings3(value);初始化为一个字符串字面值副本strings4(n,'c');将s4初始化为字符'c'的n个副本3.2.2string对象的读写我们已在第1章学习了用iostream标准库来读写内置类型的值,如int,double等。同样地,也可以用iostream和string标准库,使用标准库输入输出操作符来读写string对象:intmain(){strings;cins;//readstringintoscoutsendl;//writestoouputreturn0;}注意的是,string类型的输入操作符:3.2.2string对象的读写(续)●读取并忽略开头所有的空白字符(如空格、换行符、制表符)。●读取字符直至再次遇到空白字符,读取终止。因此,如果输入到程序的是Helloworld!(注意开头和结尾的空格),则屏幕上将输出Hello,而不含有任何空格。输入和输出的行为与内置类型操作符基本类似。尤其是,这些操作符返回左操作数作为运算结果。因此,我们可以把多个读操作或多个写操作放在一起:strings1,s2;cins1s2;couts1s2endl;3.2.2string对象的读写(续)如果给定输入Helloworld!,则输出结果将是:Helloworld!注意:对于上例,编译时必须加上#include来标示iostream和string标准库,以及给出用到的所有标准库中的名字的using声明。从本例开始的程序均假设程序中所有必须的#include和using声明已给出。1.读入未知数目的string对象和内置类型的输入操作符一样,string的输入操作符也会返回所读的数据流。因此,可以把输入操作作为判断条件。下面程序从标准输入读取一组string对象,然后在标准输出上逐行输出:3.2.2string对象的读写(续)intmain(){stringword;//readuntilend-of-file,writeeachwordtoanewlinewhile(cinword)coutwordendl;return0;}上例中,用输入操作符来读取string对象。该操作符返回所读取的istream对象,并在读取结束后,作为while的判断条件。如果输入时有效的,即未到文件尾且未3.2.2string对象的读写(续)遇到无效输入,则执行while循环体,并将读取到的字符串输出到标准输出。2.用getline读取整行文本getline函数接受两个参数:一个输入流对象和一个string对象。getline函数从输入流的下一行读取,并保存读取的内容到string中,但不包括换行符。和输入操作符不一样的是,getline并不忽略行开头的换行符。只要getline遇到换行符,即使它是输入的第一个字符,getline也将停止输入并返回。如果第一个字符就是换行符,string参数将被置为空string。getline函数将istream参数作为返回值,和输入操作符一样也把它作为判断条件。例如:3.2.2string对象的读写(续)intmain(){stringline;while(getline(cin,line))coutlineendl;return0;}由于line不含换行符,若要逐行输出需要自行添加,照常,我们用endl来输出一个换行符并刷新输出缓冲区。注意:由于getline函数返回时丢弃换行符,换行符将不会存储在string对象中。3.2.3string对象的操作表3-2列出了常用的string操作。表3-2string操作s.empty()如果s为空串,则返回true,否则返回falses.size()返回s中字符的个数s[n]返回s中位置为n的字符,位置从0计数s1+s2把s1和s2连接成一个新字符串s1=s2把s1的内容替换成s2的副本v1==v2比较s1与s2的内容,相等返回true!=,,=保持这些操作符惯有的含义和=3.2.3string对象的操作(续)1.string的size和empty操作string对象的长度指的是string对象中字符的个数,可以通过size操作获取。如果想判断string对象是否为空,有两种方法:if(st.size()==0)//ok:emptyif(st.empty())//ok:empty2.string::size_type类型从逻辑上讲,size()成员函数似乎应该返回整型数值,或无符号整数。但是事实上,size操作返回的是size_type类型的值。3.2.3string对象的操作(续)string类类型和许多其他库类型都定义了一些配套类型。通过这些配套类型,库类型的使用就能与机器无关。size_type就是这些配套类型的一种。它定义为与unsigned型(unsignedint或unsignedlong)具有相同的含义,而且可以保证足够大可以存储任意string对象的长度。注意:任何存储string的size操作结果的变量必须为string::size_type类型。特别重要的是,不要把size的返回值赋给一个int变量。虽然我们不知道string::size_type的确切类型,但可以知道它是unsigned型。对于任意一种给定的数据类型,它的unsigned型所能表示的最大正数值比对应的signed型要大一倍。这个事实表明size_type存储的string长度是int所能存储的两倍。3.2.3string对象的操作(续)使用int变量的另一个问题是,有些机器上int变量的表示范围太小,甚至无法存储实际并不长的string对象。如在16的机器上,int类型变量最大只能表示32767个字符的string对象。而能容纳一个文件内容的string对象轻易就会超过这个数字。因此,为了避免溢出,保存一个string对象size的最安全的方法就是使用标准库类型string::size_type。3.string关系操作符string类定义了几种关系操作符用来比较两个string值的大小。string对象比较操作是区分大小写的。stringbig=big,small=small;strings1=big;3.2.3string对象的操作(续)if(big==small)//false//...if(big=s1)//truetheyareequal//...关系操作符比较两个string对象时采用了和字典排序相同的策略:●如果两个string对象长度不同,且短的string对象与长的string对象的前面部分相匹配,则短的string对象小于长的string对象。●如果两个string对象的字符不同,则比较第一个不匹配的字符。举例来说,给定string对象:3.2.3string对象的操作(续)stringsubstr=Hello;stringphrase=HelloWorld;stringslang=Hiya;则substr小于phrase,而slang则大于phrase。4.string对象的赋值对string对象来说,可以把一个string对象赋值给
本文标题:C++Primer第三章
链接地址:https://www.777doc.com/doc-2904176 .html