yc's profileyc1229PhotosBlogLists Tools Help

Blog


    August 15

    第三章 标准库类型

    3.1命名空间的using声明
        使用using可以不需要加前缀namespace_name::的情况下访问命名空间中的名字。using声明的形式如下:
        using namespace::name;
        1.每个名字都需要一个using声明
        2.使用标准库存类型的类定义
        如果在头文件中放置using声明,就相当于包含该头文件的每个程序中都放置了同一using声明,不论该程序是否需要using声明。
        通常,头文件中应该只定义确实必要的东西。需要养成这个好习惯。
        3.2标准库string类型
        使用前需包含
        #include <string>
        using std::string;
        3.2.1string对象的定义和初始化
        几种初始string对象的方式
        string s1; 默认构造函数,s1为空串
        string s2(s1); 将s2初始化为s1的副本
        string s3("value"); 将s3初始化为一个字符串字面值副本
        string s4(n,'c'); 将s4初始化为字符'c'的n个副本
        3.2.2string对象的读写
        可以用iostream和string标准库,使用标准输入输出操作符来读写string对象:
        int main()
        {
            string s;
            cin>>s;
            cout<<s<<endl;
            return 0;
        }
        读取并忽略开关所有空白字符(如空格,换行符,制表符)
        读取字符直至再次遇到空白字符。
        1.读入未知数目的string对象
        string的输入操作符也会返回所读的数据流,可以把输入操作作为判断条件:
        string word;
        while(cin>>word)
        2.用getline读取整行文本
        这个函数接受两个参数:一个输入流对象和一个string对象。getline不保存换行符,getline并不忽略行开头的换行符,只要getline遇到换行符,即使它是输入的第一个字符,getline也将停止读入并返回。
        string line;
        while(getline(cin,line))
        3.2.3string对象的操作
       
        常用的string操作
        s.empty() 如果s为空串,则返回true,否则返回false
        s.size() 返回s中字符的个数
        s[n] 返回s中位置为n的字符,位置从0开始计数
        s1+s2 把s1和s2连接成一个新字符串,返回新生成的字符串
        s1=s2 把s1内容替换成s2的副本
        v1==v2 比较v1与v2的内容,相等则返回true,否则返回false
        !=,<,<= 保持这些操作符惯有的含义
        >,>=
        2.string::size_type类型
        size操作返回的是string::size_type类型的值。
        string类类型和许多其他库类型都定义了一些配套类型。通过这些配套类型,库类型的使用就能与机器无关。
        任何存储string的size操作结果的变量必须为string::size_type类型。特别重要的是,不要把size的返回值赋给一个int变量。
        int类型最大值 32767
        3.string关系操作符
        如果两个string对象长度不同,且短的string对象与长的string对象的前面部分相匹配,则短的string对象小于长的string对象。
        如果两个string对象的字符不同,则比较第一个不匹配的字符。
        4.string对象的赋值
        size()不算\0 算\n
        大多数string库类型的赋值等操作的实现都会遇到一些效率上的问题,但值得注意的是,从概念上讲,赋值操作确实需要做一些工作。
        6.和字符串字面值的连接
        当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的。
        9.计算下标值
        string对象的索引变量最好也用string::size_type类型。
        3.2.4string对象中字符的处理
        cctype定义的函数
        isalnum(c) 如果c是字母或数字,则为true
        isalpha(c) 如果c是字母,则为true
        iscntrl(c) 如果c是控制字符,则为true
        isdigit(c) 如果c是数字,则为true
        isgraph(c) 如果c不是空格,但可打印,则为true
        islower(c) 如果c是小写字母,则为true
        isprint(c) 如果c是可打印的字符,则为true
        ispunct(c) 如果c是标点符号,则为true
        isspace(c) 如果c是空白字符,则为true
        isupper(c) 如果c是大写字母,则为true
        isxdigit(c) 如果c是十六进制数,则为true
        tolower(c) 如果c是大写字母,则返回其小写字母形式,否则直接返回c
        toupper(c) 如果c是小写字母,则返回其大写字母形式,否则直接返回c
        可打印的字符是指那些可以显式表示的字符,空白字符则空格、制表符、垂直制表符、回车符、换行符和进纸符中的任意一种;标点符号则是除了数字、字母或(可打印的)空白字符(如空格)以外的其他字符。
        cname头文件中定义的名字都定义在命名空间std内,而.h版本中的名字却不是这样。
        3.3标准库vector类型
        #include <vector>
        using std::vector;
        必须说明vector保存何种对象的类型,通过将类型放在类模板名称后面的尖括号中来指定类型:
        vector<int> ivec;
        3.3.1vector对象的定义和初始化
        几种初始化vector对象的方式
        vector<T> v1; vector保存类型为T的对象,默认构造函数v1为空
        vector<T> v2(v1); v2是v1的一个副本
        vector<T> v3(n,i); v3包含n个为i的元素
        vector<T> v4(n); v4含有值初始化的元素的n个副本
        1.创建确定个数的元素
        当把一个vector对象复制到另一个vector对象时,这两个对象必须保存同一种元素类型。
        虽然可以对给定元素个数的vector对象预先分配内存,但更有效的方法是先初始化一个空vector对象,然后再动态地增加元素。
        2.值初始化
        如果vector保存内置类型(如int类型)的元素,那么标准库将用0值创建元素初始式。
        如果vector保存的是含有构造函数的类类型(如string)的元素,标准库将用该类型的默认构造函数创建元素初始化式。
        3.3.2vector对象的操作
        vector操作
        v.empty() 如果v为空,则返回true,否则返回false
        v.size() 返回v中元素的个数
        v.push_back(t) 在v的末尾增加一个值为t的元素
        v[n] 返回v位置为n的元素
        v1=v2 把v1的元素替换为v2元素的副本
        v1==v2 如果v1与v2相等,则返回true
        !=,<,<=,>,>= 保持这些操作符惯有的含义
        1.vector对象的size
        使用size_type类型时,必须指出该类型是在哪定义的。vector类型总是包括vector的元素类型:
        vector<int>::size_type //ok
        vector::size_type //error
        3.vector的下标操作
        for (vector<int>::size_type ix=0;ix!=ivec.size();++ix)
            ivec[ix]=0;
        安全的泛型编程
        for循环的判断条件用!=而不用<来测试vector下标值是否越界。上例中没有在for循环之前就调用size成员函数并保存其返回的值,而是在for语句头中调用size成员函数。
        调用size成员函数而不保存它返回的值,在这个例子中同样不是必需的,但这反映了一种良好的编程习惯。在C++中,有些数据结构(如vector)可以动态增长。
        4.下标操作不添加元素
        所谓的“缓冲区溢出”错误就是对不存在的元素进行下标操作的结果。
        3.4迭代器简介
        所有标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。
        1.容器的iterator类型
        每个标准库容器类型都定义了一个名为iterator的成员(迭代器)
        2.begin和end操作
        每种容器都定义了一对命名为begin和end的函数,用于返回迭代器。如果容器中有元素的话,由begin返回的迭代器指向第一个元素:
        vector<int>::iterator iter=ivec.begin();
        由end操作返回的迭代器指向vector的“末端元素的下一个”。通常称为超出末端迭代器。如果vector为空,begin返回的迭代器与end返回的迭代器相同。
        由end操作返回的迭代器并不指向vector中任何实际的元素。
        3.vector迭代器的自增和解引用运算
        迭代器类型可使用解引用操作符(*操作符)来访问迭代器所指向的元素:
        *iter=0;
        如果iter指向第一个元素,则++iter指向第二个元素。
        由于end操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作(可以进行自减操作,可以使指向end的迭代器指向最后一个元素)。
        4.迭代器的其他操作
        用==或!=操作符来比较两个迭代器,如果两个迭代器对象指向同一个元素,则它们相等,否则就不相等。
        6.const_iterator 可以改变指向的元素,不能改变指向元素的值。
        const vector<int>::iterator cit=num.begin() 可以改变元素值,不能改变指向的元素。
        当对const_iterator类型解引用时,返回的一个const值。不允许用const_iterator进行赋值。
        声明一个const迭代器时,必须初始化迭代器。
        const vector<int>::iterator cit=nums.begin()
        迭代器的算术操作
        iter+n
        iter-n
        加上或减去的值的类型应该是vector的size_type或difference_type类型(一种由vector类型定义的singed类型,用于存储任意两个迭代器间的距离)。
        iter1-iter2
        该表达式用来计算两个迭代器对象的距离,该距离是名为difference_type的signed类型的值。iter1与iter2两者必须都指向同一vector中的元素,或者指向vector末端之后的下一个元素。
        下面语句直接定位于vector的中间元素:
        vector<int>::iterator mid=vi.begin()+vi.size()/2;
        任何改变vector长度的操作都会使已存在的迭代器失效。例如,在调用push_back之后,就不能再依赖指向vector的迭代器的值了。
        3.5标准库bitset类型
        #include <bitset>
        using std::bitset;
        3.5.1bitset对象的定义和初始化
        在定义bitset时,要明确bitset含有多少位,须在尖括号内给出这的长度值。
        bitset<32> bitvec;
        初始化bitset对象的方法
        bitset<n> b; b有n位,每位都为0
        bitset<n> b(u); b是unsigned long型u的一个副本
        bitset<n> b(s); b是string对象s中含有的位串的副本
        bitset<n> b(s,pos,n); b是s中从位置pos开始的n个位的副本
        1.用unsigned值初始化bitset对象
        如果bitset类型长度大于unsigned long值的二进制位数,则其余的高阶位将置为0;如果bitset类型长度小于unsigned long值的二进制位数,则只使用unsigned值中的低阶位,超过bitset类型长度的高阶位将被丢弃。
        可以用0xfff初始化bitset对象。
        2.用string对象初始化bitset对象
        当用string对象初始化bitset对象时,string对象直接表示为位模式。从string对象读入位集的顺序是从右向左。
        string str("1111111000000011001101");
        bitset<32> bitvec5(str,5,4); //1100 从str[5]开始取
        bitset<32> bitvec6(str,str.size()-4); //use last 4 characters
        如果省略第三参数则意味着取从开始位置一直到string末尾的所有字符。
        3.5.2bitset对象上的操作
        bitset操作
        b.any() b中是否存在置为1的二进制位?
        b.none() b中不存在置为1的二进制位吗?
        b.count() b中置为1的二进制位的个数
        b.size() b中二进制位的个数
        b[pos] 访问b中在pos处的二进制位
        b.test(pos) b中在pos处的二进制位是否为1?
        b.set() 把b中所有二进制位都置为1
        b.set(pos) 把b中在pos处的二进制位置为1
        b.reset() 把b中所有二进制位都置为0
        b.reset(pos) 把b中在pos处的二进制位置为0
        b.filp() 把b中所有二进制位逐位取反
        b.filp(pos) 把b中在pos处的二进制位取反
        b.to_ulong() 用b中同样的二进制位返回一个unsigned long值
        os<<b 把b中的位集输出到os流
        1.测试整个bitset对象
        count操作的返回类型是标准中命名为size_t的类型。size_t类型定义在cstddef头文件中。它是一个与机器相关的unsigned类型,其大小足以保证存储内存中对象的大小。
        bitset和size操作返回值的类型是size_t。
        3.对整个bitset对象进行设置
        flip操作可以对bitset对象的所有位或个别位取反:
        bitvec.flip(0);
        bitvec[0].flip();
        bitvec.flip();
        4.获取bitset对象的值
        仅当bitset类型的长度小于或等于unsigned long的长度时,才可以使用to_ulong操作。

    Comments

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    Trackbacks

    The trackback URL for this entry is:
    http://yc1229.spaces.live.com/blog/cns!C863EF037BDFF0CE!115.trak
    Weblogs that reference this entry
    • None