“C++学习笔记“ STL2_容器

目录

1. 容器的分类与基本函数

顺序容器

关联容器

容器适配器

成员函数

2. 容器定义的类型与构造函数参数

interator、const_iterator 

reverse_interator、const_reverse_interator

begin()、end()、cbegin()、cend()

rbegin()、rend()、crbegin()、crend()

reference, const_reference

引用(Reference)

常引用(Const Reference)

3. 容器内的函数

通用容器函数

顺序容器特有函数

关联容器特有函数

4. 容器内的常规操作

插入删除元素

反向迭代器


二、容器

定义:容器(container)用于存放数据的类模板。可变长数组、链表、平衡二叉树等数据结构在 STL 中都被实现为容器。

程序员使用容器时,即将容器类模板实例化为容器类时,会指明容器中存放的元素是什么类型的。

容器中可以存放基本类型的变量,也可以存放对象。对象或基本类型的变量被插入容器中时,实际插入的是对象或变量的一个复制品。

STL 中的许多算法(即函数模板),如排序、查找等算法,在执行过程中会对容器中的元素进行比较。这些算法在比较元素是否相等时通常用运算符进行,比较大小通常用<运算符进行,因此,被放入容器的对象所属的类最好重载==<运算符,以使得两个对象用==<进行比较是有定义的。

1. 容器的分类与基本函数

STL 对定义的通用容器分三类:顺序性容器、关联式容器和容器适配器。

顺序容器

顺序容器有以下三种:可变长动态数组 vector、双端队列 deque、双向链表 list。

它们之所以被称为顺序容器,是因为元素在容器中的位置同元素的值无关,即容器不是排序的。将元素插入容器时,指定在什么位置(尾部、头部或中间某处)插入,元素就会位于什么位置。

关联容器

关联容器有以下四种:set、multiset、map、multimap。关联容器内的元素是排序的。插入元素时,容器会按一定的排序规则将元素放到适当的位置上,因此插入元素时不能指定位置。

默认情况下,关联容器中的元素是从小到大排序(或按关键字从小到大排序)的,而且用<运算符比较元素或关键字大小。因为是排好序的,所以关联容器在查找时具有非常好的性能。

容器适配器

除了以上两类容器外,STL 还在两类容器的基础上屏蔽一部分功能,突出或增加另一部分功能,实现了三种容器适配器:栈 stack、队列 queue、优先级队列 priority_queue。

容器都是类模板。它们实例化后就成为容器类。用容器类定义的对象称为容器对象。

例如,vector<int>是一个容器类的名字,vector<int> a;就定义了一个容器对象 a,a 代表一个长度可变的数组,数组中的每个元素都是 int 类型的变量;vector<double> b;定义了另一个容器对象 b,a 和 b 的类型是不同的。本教程后文所说的“容器”,有时也指“容器对象”,读者需要根据上下文自行判别。

任何两个容器对象,只要它们的类型相同,就可以用 <、<=、>、>=、==、!= 进行词典式的比较运算。假设 a、b 是两个类型相同的容器对象,这些运算符的运算规则如下。

  • a == b:若 a 和 b 中的元素个数相同,且对应元素均相等,则a == b的值为 true,否则值为 false。元素是否相等是用==运算符进行判断的。
  • a<b:规则类似于词典中两个单词比较大小,从头到尾依次比较每个元素,如果发生 a 中的元素小于 b 中的元素的情况,则a<b的值为 true;如果没有发生 b 中的元素小于 a 中的元素的情况,且 a 中的元素个数比 b 少,a<b的值也为 true;其他情况下值为 false。元素比较大小是通过<运算符进行的。
  • a != b:等价于 !(a == b)。
  • a > b:等价于 b < a。
  • a <= b:等价于 !(b < a)。
  • a >= b:等价于 !(a < b)。

成员函数

所有容器都有以下两个成员函数:

  • int size():返回容器对象中元素的个数。
  • bool empty():判断容器对象是否为空。


顺序容器和关联容器还有以下成员函数:

  • begin():返回指向容器中第一个元素的迭代器。
  • end():返回指向容器中最后一个元素后面的位置的迭代器。
  • rbegin():返回指向容器中最后一个元素的反向迭代器。
  • rend():返回指向容器中第一个元素前面的位置的反向迭代器。
  • erase(...):从容器中删除一个或几个元素。该函数参数较复杂,此处省略。
  • clear():从容器中删除所有元素。


如果一个容器是空的,则 begin() 和 end() 的返回值相等,rbegin() 和 rend() 的返回值也相等。

顺序容器还有以下常用成员函数:

  • front():返回容器中第一个元素的引用。
  • back():返回容器中最后一个元素的引用。
  • push_back():在容器末尾增加新元素。
  • pop_back():删除容器末尾的元素。
  • insert(...):插入一个或多个元素。该函数参数较复杂,此处省略。

2. 容器定义的类型与构造函数参数

interator、const_iterator 

  • interator:当我们需要对容器元素进行修改、删除等操作时或者对象是非常量时使用
  • const_iterator:当我们只是遍历容器元素,而不更改容器元素时或者对象是常量时使用

注意:上面所说的常量是指常量容器,而不是容器内的元素为常量

建议:如果我们只是简单的遍历容器元素或者对象是常量时,一般使用const_iterator比较合适

C++11引进了两个新函数,分别为cbegin()、cend(),其两者的功能类似于begin()、end()

C++11标准之前,iterator与const_iterator都使用begin()、end()两个辅助函数遍历容器。

C++11标准之后,const_iterator既可以使用可以使用begin()、end(),也可以使用cbegin()、cend()。但是iterator还是只能使用begin()、end()

1

2

3

4

vector<int> v;

const vector<int> v2;

auto it1=v.begin(); //v1是vector<int>::iterator类型

auto it2=v2.cbegin();//v2是vector<int>::const_iterator类型

reverse_interator、const_reverse_interator

功能与interator、const_iterator均相同,但是用法不一样

  • reverse_interator:与interator相同,改变容器内部元素时使用。只能使用rbegin()、rend()
  • const_reverse_interator:与const_iterator相同,只是单纯遍历容器内部元素时使用。能使用rbegin()、rend()、crbegin()、crend()

用法的原理与interator、const_iterator是相同的

但是rbegin()、rend()分别指向容器元素的最后一个位置与第一个元素的前一个位置

1

2

3

4

5

6

7

8

9

//for循环打印的是3、2、1

  

vector<int> v;

vector<int>::const_reverse_iterator iter;

v.push_back(1);

v.push_back(2);

v.push_back(3);

for (iter = v.rbegin(); iter != v.rend(); iter++)

    printf("%d\t", *iter);

begin()、end()、cbegin()、cend()

4者都是容器的成员函数

begin()、end()代表容器的特殊位置,分别为元素的第一个位置与最后一个元素的下一个位置

下面比如是vector的一个模型,则begin()、end()分别代表一下位置

  • begin():我们在遍历容器的元素的时候,一般要获取该元素的首元素,因此设计bengin()
  • end():当我们用迭代器遍历容器的时候,一般需要结束条件(如遍历到最后一个元素),但是遍历到最后一个元素时又不能舍弃它,因此将最后一个元素的下一位置作为结束标志

rbegin()、rend()、crbegin()、crend()

这四者的原理与begin()、end()、cbegin()、cend()是相同的,也都是容器的成员函数

  • cbegin();cend()分别返回const类型的指向容器头的迭代器、指向容器尾的迭代器。

但是rbegin()、rend()分别代表最后一个元素与第一个元素的前一个位置

reference, const_reference

引用(Reference)

C语言中,使用指针(Pointer)可以间接获取、修改某个变量的值,C++中,使用引用可以起到跟指针类似的功能。
  引用相当于是变量的别名(基本数据类型、枚举、结构体、类、指针、数组等,都可以有引用)。
  在定义的时候就必须初始化,一旦指向了某个变量,就不可以再改变。
  对引用做计算相当于对引用所指向的变量做计算。
  可以利用引用初始化另一个引用,相当于某个变量的多个别名。
  引用的价值:比指针更安全、函数返回值可以被赋值。
  不存在:引用的引用、指向引用的指针、引用数组
  引用的本质就是指针,只是编译器削弱了它的功能,所以引用就是弱化了的指针;一个引用占一个指针的大小。

int main() {
 
    int age = 10;
    int height = 20;
    int &ref = age;//引用在定义的时候就必须初始化
    //int &ref = height;//错误 一旦指向某个变量就不可以改变
    int &ref1 = ref;
    co
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值