• C++Primer_2021.11.2


    标准库就是武器库、功法招式。
    第三章:字符串、向量和数组
    标准库类型:
    string
    vector
    迭代器:它是string和vector的配套类型,常被用于访问string中的字符或vector中的元素。

    标准库类型vector
    vector表示对象的集合,其中所有对象的类型相同。集合中的每个对象都有一个与之对应的索引,用于访问对象。因为vector“容纳着”其它对象,所以常被称为容器(container)。

    C++语言既有类模板也有函数模板,vector是一个类模板。只有对C++有相对深入的理解才能写出模板。

    模板可看作为编译器生成类或函数编写的一份说明。编译器以此创建类或函数的过程称为实例化。

    对于类模板来说,通过提供一些额外信息来指定模板到底实例化成什么样的类,需要提供哪些信息由模板决定。方法:在模板名字后面跟一对尖括号,在括号内放上信息。
    这样就说明了vector内所存放对象的类型。

    vector是模板而非类型,由vector生成的类型必须包含vector中元素的类型,如:vector,这是一个类型。

    vector能容纳绝大多数类型的对象作为其元素,但因为引用不是对象,所以不存在包含引用的vector。

    $定义和初始化vector对象
    1 vector v1; 通用初始化
    2 vector v2(v1); 通用初始化
    2 vector v2 = v1; 通用初始化
    3 vector v3(n, val); 创建指定数量的元素
    3 vector v4(n); 值初始化 v4包含了n个重复地执行了值初始化的对象,此时T必须提供默认初始值,如int,string都有默认初始值。
    如:vector ivec(10);
    vector svec(10);
    4 vector v5{a,b,c...}; 列表初始化
    4 vector v5={a,b,c...}; 与上者等价,列表初始化

    123为直接初始化方式,4位列表初始化

    最常见的用法:先定义一个空的vector,然后当运行时获取到的元素的值后再逐一添加。还有就是:
    vector ivec;
    vector ivec2(ivec); 将ivec的元素拷贝给ivec2

    $列表初始化vector对象
    C++11新标准提供“列表初始化”方法。上面的等价式,在花括号里进行列表初始化。

    列表初始值还是元素数量。前者使用花括号,用来列表初始化;后者使用括号,是用来构造。注意:若使用花括号所提供的值不能用来列表初始化,就会将这样的值来构造vector对象,对话为圆括号。如:
    vector v5{"hi"};
    vector v6("hi"); 错误
    vector v7{10}; 编译器尝试使用()
    vector v8{10,"hi"}; 编译器尝试使用()

    $向vector对象中添加元素
    对于vector直接初始化的方法有三种。
    初始值已知且数量少、初始值是另一个vector对象的副本、所有元素的初始值都一样。

    还有就是列表初始化,数量少还可以,若是多了,就需要用push_back来添加元素。压入(push) - 尾端(back)

    c++标准要求vector应该能高效快速地添加元素。若直接设定大小,性能可能更差,除非所有元素的值一样,才会设定大小。
    注意:先创建空的vector,然后才动态添加push_back(),性能高。

    warning:当循环体内含有向vector对象添加元素的语句,则不能使用范围for循环。

    $其它vector操作
    v.empty() 是否包含元素
    v.size() 返回元素个数 vector::size_type,由vector定义的size_type类型,可以使用auto来替代?!不行,只能通过上述方式,或用decltype(v.size())来指定它的类型。

    v.push_back(t)
    v[n]
    v1 = v2
    v1 = {a, b, c, ...}
    v1 == v2
    v1 != v2
    <, <=, >, >=

    $计算vector内对象的索引
    只要vector对象不是一个常量,就能向下标运算符返回的元素赋值。也可通过计算得到vector内对象的索引,然后直接获取索引位置上的元素。

    一般性方法:cin通过while语句负责读入数据,在循环体内部首先检查读入数据是否合法,然后才执行之后的逻辑。使用下标的时候,必须清楚地知道它是否在合理范围内。

    $不能用下标形式添加元素
    vector ivect; ivec是一个空vector,根本不包含任何元素,当然也就不能通过下标去访问任何元素!正确的方法是使用push_back

    vector(string)对象的下标运算符可用于访问已存在的元素,而不能用于添加元素。只能对已知存在的元素执行下标操作!

    越界访问导致缓冲区溢出(buffer overflow)是导致PC以及其它设备上应用程序出现安全问题的一个重要原因。

    确保下标合法的一种有效手段是尽可能使用范围for语句

    3.4 迭代器介绍
    可使用下标运算符来访问string对象的字符或vector对象的元素,还可以用迭代器(iterator)。
    所有标准库容器都可以使用迭代器。类似指针类型,其对象是容器中的元素或string对象中的字符。

    end成员返回“尾元素的下一个位置”,仅是一个标记而已,表示我们已处理完容器中的所有元素,没什么实际含义(即不代表容器元素)。

    若容器为空,begin和end返回的是同一个迭代器,都是尾后迭代器。

    使用==和!=来比较两个合法的迭代器是否相同。
    标准容器迭代器的运算符:
    *iter 返回迭代器iter所指元素的引用,注意是引用;
    iter->mem 解引用iter并获取该元素的名为mem的成员;
    ++iter 令iter指示容器中的下一个元素;
    --iter 令iter指示容器中的上一个元素;
    iter1 == iter2 判断两个迭代器是否相同(同时为尾后迭代器或同一个元素);
    iter1 != iter2

    将第一个字符改为大写
    string s("some string");
    if (s.begin() != s.end()) {
    auto it = s.being(); // it表示s的第一个字符
    it = toupper(it); // 将当前字符改为大写形式
    }

    将迭代器从一个元素移动到另外一个元素:++
    for (auto it = s.begin(); it != s.end() && !isspace(it); ++it)
    it = toupper(it); //
    it解引用

    关键概念:泛型编程
    使用迭代器而非下标的原因,是因为这种编程风格在标准库提供的所有容器上都有效,都定义==和!=。

    只有string和vector等一些标准库类型由下标运算符,而并非全部如此。

    迭代器类型:拥有迭代器的标准库类型使用iterator和const_iterator来表示迭代器的类型。前者可以读写vector或string中的元素,后缀只能读取,和常量指针差不多。若vector或string对象不是常量,两者都可以用。

    每个容器类定义了一个名为iterator的类型,该类型支持迭代器概念所规定的一套操作。

    begin和end运算符:
    具体返回类型由对象是否是常量决定,若对象是常量,返回const_iterator,否则返回iterator。

    若对象只需读操作而无须写操作的话,最好使用const_iterator。C++11引入两个新函数cbegin和cend来表示返回值为const_iterator。
    auto it3 = v.cbegin(); it3的类型为:vector::const_iterator

    结合解引用和成员访问操作:
    解引用迭代器可获得迭代器所指的对象,若该对象是类,就可能希望进一步访问他的成员。或用箭头运算符(->)

    某些对vector对象的操作会使迭代器失效:
    1.不能在for循环中向vector对象添加元素;
    2.任何一个可能改变vector对象容器的操作,如push_back,都会使该vector对象的迭代器失效。记住:凡是使用了迭代器的循环体,都不要想迭代器所属的容器添加元素

    page:111

  • 相关阅读:
    yum源
    存储计量单位排序
    博客园代码高亮
    磁盘配置
    软件包安装
    网络配置
    用户、组及权限控制
    Android开发项目中常用到的开源库
    使用百度地图时,Application类的onCreate执行两次的解决方案
    计算从1到n中,出现某位数字的次数
  • 原文地址:https://www.cnblogs.com/gwzz/p/15500548.html
Copyright © 2020-2023  润新知