C++ Primer学习笔记(第9章第11章)

const使用总结

  1. const修饰变量,表示该变量为常量,必须在定义是初始化,且不能修改它的值。

  2. const修饰指针:

    • const int *ip = &valip是指向const对象(int)的指针,即不能通过(*ip)修改val的值(如果val不是const常量,可以通过其他方式修改val的值);

    • int *const ip = &valip是指向int对象的const指针,即不能修改ip的值,但(*ip)的值可以修改;

    • const int *const ip=&valip是指向const对象的const指针。

  3. Const修饰函数:const int& op(const int) const

    • const修饰返回值,表示返回值不能修改,只有在返回引用类型时才有效(不能返回局部对象的引用);

    • const修饰参数,表示该参数不能在函数中修改。需要注意的是参数是指针的情况,到底是const指针还是指向const对象的指针;

    • const修饰函数:const修饰类的成员函数时,表示该函数不能修改类的成员变量。

  4.  

9章 顺序容器

  1. 关联容器和顺序容器的本质区别在于:关联容器通过键(key)存储和读取元素,而顺序容器的元素排列次序与元素值无关,是由元素添加到容器里的次序决定。

  2. 标准库定义了三种顺序容器类型:vector, list dequevector是连续存储的,能支持快速随机访问;list不需要连续存储,所以能在中间快速插入和删除;deque是双端队列。标准库还提供了三种容器适配器:后进先出的stack、先进先出的queue和有优先级管理的priority_queuestack可以建立在vectorlistdeque上,queue要能提供push_front操作,不能建立在vector上,priority_queue要求提供随机访问能力,只能建立在vectordeque上。

  3. 定义元素是容器的容器时,必须用空格隔开两个相邻的>符号,以示这是两个分开的符号,否则,系统会认为>>是单个符号,为右移操作符,并结果导致编译时错误;

             examplevector< vector<string> > lines;

  1. 容器元素类型必须满足两个约束:

    • 元素类型必须支持赋值运算

    • 元素类型的对象必须可以复制

引用不支持一般意义的赋值运算,IO标准库类型不支持赋值和复制操作,所以不能创建存储他们的容器。

  1. 顺序容器上的操作

    • 初始化(适用于关联容器)

      1. C<T> c默认初始化,创建一个空的容器

      2. C c(c2) 创建容器c2的副本c,两个容器的类型和元素类型都必须相同

      3. C c(b,e) 创建c,其元素是迭代器bc标示的范围内元素的副本,只要迭代器存储的值能转化为容器的元素即可,不需要容器类型相同。

      4. C c(n,t) / C c(n) 创建有n个值为t(或默认值)的容器c,只适用于顺序容器。

    • 向容器内添加元素

                       有三类函数push_back()push_front()insert(),用insert()在指定位置插入单个元素时,返回指向新元素的迭代器,其他的都返回void

    • 容器大小操作

                             size(), max_size(), empty() resize()resize()能删除多出来的元素。

    • 访问元素

                      用迭代器迭代容器或者使用下标操作(list不支持下标操作)

    • 删除元素

                            erase()(返回指向删除元素后的迭代器), clear(), pop_back(), pop_front() (pop_操作只删除元素,不返回删除的元素值,返回void

    • assign赋值操作 , swap 交换容器操作(不会破坏迭代器)

  1. list vs vector deque

    • list的元素不是连续存储,所以不支持随机访问,所以不支持下标操作([])和at()操作,其上的迭代器不支持 +n 操作和大小比较操作(进支持等于,不等操作)

    • vector不支持前端操作(push_front() pop_front()

  2. 修改容器时,会使容器上的迭代器失效。vectordeque连续存储,在中间插入删除元素时,会重组织存储。

  3. string类型不支持以栈方式操纵容器;string支持的其他操作:substr append replace find compare

10章 关联容器

  1. 标准库提供的关联容器有:mapsetmultimapmultisetmap存储键值对,set存储单个键,multi支持同一个见多次出现。

  2. pair类型和make_pair函数:对map上的迭代器解引用是pair<cont T1, T2>对象。

  3. mapset上的键类型,唯一的约束就是必须支持<操作符,至于是否支持其他的关系或相等运算,则不做要求。

  4. mapsetmultimapmultiset

    • 都支持insertcountfinderase操作以及lower_boundupper_boundequal_range操作(注意他们的返回值),初始化见顺序容器;

    • 只有map支持下标操作,而且与下标访问数组或vector的行为截然不同:用下标访问不存在的元素将导致在map容器中添加一个新元素,它的键即为该下标值,值为值类型的默认初始化值。

11章 泛型算法

  1. 泛型算法中,所谓“泛型“指的是两个方面:这些算法可作用与各种不同的容器类型,而这些容器又可以容纳多种不同的元素。泛型算法必须包含<algorithm>头文件,算术算法还必须包含<numerc>头文件。插入器(inserter)包含在<interator>头文件中。

  2. 泛型算法的形参模式: alg (beg, end, beg2, end2, other parms)

beg,end标记第一个范围,这两个参数泛型算法都有;beg2,end2标记第二个范围,可能没有这个两个参数;parms表示其他算法需要的值或谓词。

  1. 算法不直接修改容器的大小,如果需要添加和删除元素,则必须使用容器操作。

  2. 泛型算法的分类

    • 只读算法:只读输入范围内的元素,而不会写这些元素。find(), accumulate(), find_first_of()是只读算法;

    • 写容器元素算法:将数据写入第一或第二输入范围。find(), find_n(), copy(), replace() 都是这类算法。直接将元素写入目标很危险,因为泛型算法不会调用容器提供的操作(如insert)(相当于用下标读vector的内容,再修改),所以很类算法一般要和插入迭代器配合使用。有三种插入迭代器:back_inserter,创建使用push_back实现插入的迭代器;front_inserter,使用push_front实现插入(不能用在vector上);inserter,使用insert实现插入。

                         vector<int> ivec;

                          replace_copy(ilist.begin(), ilist.end(), inserter(ivec,ivec.begin), 0, 42);

  • 对容器元素重新排序的算法:sort(), unique()

  1. 五种迭代器

    • 输入迭代器:读,不能写;只支持自增运算。istream_iterator是输入迭代器

    • 输出迭代器:写,不能读;只支持自增运算。ostream_iterator是输出迭代器

    • 前向迭代器:读和写,只支持自增运算。replace算法需要前向迭代器

    • 双向迭代器:读和写,支持自增和自减运算,mapsetlist提供双向迭代器。Reverse算法需要双向迭代器

    • 随机访问迭代器:读和写,支持完整的迭代器算术运算,stringvectordeque提供双向迭代器。

  2. list容器特有的算法

list上提供双向迭代器,故很多需要随机访问迭代器的算法不能在其上运行,故标准库为list容器定义了更精细的操作集合,如merge(), remove(), sort(), reverse(), splice(), unique()

原文地址:https://www.cnblogs.com/little_ask/p/2656853.html