💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
在本节中介绍**STL**标准库类型的**vector**容器。容器(**container**),顾名思义表示对象的集合,这些对象的类型都相同,每个对象都有一个自己的索引,用这个索引我们就可以方便的访问该对象了。 实际上,**STL**中的**vector**容器就是动态大小数组。我们先来看看**vector**的一些操作,最后再做一个实例。首先,要使用**vector**,需要包含头文件,以及做**using**申明。 ~~~ #include <vector> //头文件包含 using namespace std; //或者using std::vector; ~~~ 其次,再看**vector**的定义和初始化,这里以**int**类型举例。 ~~~ vector<int>v1; //空的vector,元素类型为int,执行的是默认初始化 vector<int>v2(v1); //拷贝覆盖,v2与v1中元素个数、值都相同 vector<int>v3=v1; //同上 vector<int>v4(5,3); //v4包含了5个重复元素,元素值为3 vector<int>v5(10); //v5包含10个重复元素,执行的是默认初始化 //列表初始化,是C++11提供的新标准 vector<int>v6{1,2,3,4}; //v6包含4个元素,其值为{...}中的元素 vector<int>v7={1,2,3,4}; //同上 ~~~ 了解了一些基础知识后,我们来看看**vector**有哪些常用的操作方法。 **vector的member functions** | push_back() | 在容器尾部添加元素 | crbegin() |   | |-----|-----|-----|-----| | pop_back() | 删除容器的最后一个元素 | crend() |   | | size() | 返回容器中实际元素的个数 | clear() | 清除容器中所有元素 | | resize() | 重新设定容器的大小 | capacity() | 返回需要重新分配容量的元素个数 | | at() | 返回索引位置的元素 | reserve() | 设定重新分配容量的元素个数 | | begin() | 返回第一个元素的迭代器 | data() |   | | end() | 返回最后一个元素后面位置的迭代器 | assign() | 赋值 | | front() | 返回第一个元素 | insert() | 插入 | | back() | 返回最后一个元素 | max_size() | 返回最大数据量 | | empty() | 返回1为空,0为非空 | get_allocator() | 使用构造函数,返回一个拷贝 | | swap() | 交换两容器 | shrink_to_fit() |   | | cbegin() |   | emplace_back() |   | | cend() |   | erase() | 擦除元素 | | rbegin() | 返回逆向容器中的第一个元素的迭代器 | emplace() |   | | rend() | 返回逆向容器中的最后一个元素后面位置的迭代器 |   |   | 接下来,对**vector**的成员方法进行逐一阐述: ~~~ vector<int>c; //定义vector容器c,数据类型为int ~~~ **1、push_back(val)** 将元素val添加到容器尾部,同时c.size()会增加。 ~~~ c.push_back(val); ~~~ 需要说明的是:**c.push_back(val)**先将容器c中的元素拷贝到新的内存空间中,然后在将**val**值拷贝到新空间的末尾,最后析构掉原始空间。当**push_back**检测到空间不足时,将自动以**2**倍的方式扩展空间。对于大量数据来说,这是一个弊端,可以使用**vector::reserve**方法来改善。 其定义如下,调用的方法**vector::insert**,在容器尾部**insert**来实现的。 ~~~ void push_back(_Elem _Ch) { // insert element at end insert(end(), _Ch); } ~~~ **2、pop_back()** 删除容器尾部元素,同时**c.size()**会减少。 ~~~ c.pop_back(); //删除尾部元素 ~~~ 其定义如下,调用的方法**vector::earse**,擦除最后一个位置元素来实现的。 ~~~ void pop_back() { // erase element at end erase(this->_Mysize - 1); // throws if _Mysize == 0 } ~~~ **3、size()** 容器实际大小,返回容器中元素的个数。 ~~~ c.size(); ~~~ 其定义如下: ~~~ size_type size() const { // return length of sequence return (this->_Mysize); } ~~~ **4、resize()** 重新设定容器大小,**c.size()**会发生改变。 ~~~ //c.size()<n时,扩大容器,多余的元素追加在末尾,执行默认初始化;反之,则将容器截断,保留前面n个元素 c.reize(n); //c.size()<n时,扩大容器,多余的元素追加在末尾,其值都为val;反之,则将容器截断,保留前面n个元素 c.resize(n,val); ~~~ 注意:**resize()**改变了容器大小,且创建了对象,可以使用操作符operator[]或迭代器进行元素的访问。 **5、at()** 访问某个位置元素,返回元素值。 ~~~ c.at(index); //返回index处的元素值 ~~~ 注意:**index**的范围在**[0,c.size()]**之间,**at()**方法,对索引有越界判断,若**index**越界,则会抛出**out_of_range**异常。 **6、begin()** 返回容器第一个元素的迭代器。(迭代器可理解为指针的加强版) ~~~ vector<int>::iterator it = c.begin(); ~~~ **7、end()** 返回容器末尾元素后面位置的迭代器。 ~~~ vector<int>::iterator it = c.end(); ~~~ **8、front()** 返回容器的第一个元素。 ~~~ c.front() ~~~ 其定义如下: ~~~ reference front() { // return first element of mutable sequence return (*begin()); } ~~~ **9、back()** 返回容器的最后一个元素。 ~~~ c.back() ~~~ 其定义如下: ~~~ reference back() { // return last element of mutable sequence return (*(end() - 1)); } ~~~ **10、empty()** 判断容器是否为空。返回**0**表示非空,返回**1**表示空。 ~~~ c.empty() ~~~ **11、swap()** 两容器相互交换,对象类型必须相同才能交换。 ~~~ vector<int>c(5,1); //5个元素,值均为1 vector<nt>a(10,2); //10个元素,值均为2 c.swap(a); //交换两容器,下同 swap(c,a); swap(a,c); ~~~ 经过一次交换后,**a**容器有**10**个元素,值均为**2**;**c**容器有**5**个元素,值均为**1**。 **12、cbegin()** 同**begin()**,返回的是**const**类型的迭代器。 其定义如下: ~~~ const_iterator cbegin() const { // return iterator for beginning of nonmutable sequence return (((const _Myt *)this)->begin()); } ~~~ **13、cend()** 同**end()**,返回的是**const**类型的迭代器。 ~~~ const_iterator cend() const { // return iterator for end of nonmutable sequence return (((const _Myt *)this)->end()); } ~~~ **14、rbegin()** 返回逆向容器中第一个元素的迭代器。 ~~~ vector<int>::reverse_iterator it = rbegin();//++it则表示正向的倒数第二个元素的迭代器 ~~~ 注:实际上,是正向的最后一个元素后面位置的迭代器。 **15、rend()** 返回逆向容器中最后一个元素后面位置的迭代器。 ~~~ vector<int>::reverse_iterator it = rend(); ~~~ 注:实际上,是正向第一个元素的迭代器。 **16、crbegin()** 同**cbegin()**,只不过是逆向的。 ~~~ c.crbegin(); ~~~ **17、crend()** 同**crbegin()**; ~~~ c.crend(); ~~~ **18、clear()** 清除容器中所有元素,被还原成一个空的容器。 ~~~ c.clear(); ~~~ **19、capacity()** 返回需要重新分配容量的元素个数。 ~~~ c.capacity(); ~~~ 注:不一定是按2的指数增长的哦,下面是我在**xp vs2010**上测试得到的值。且**c.capacity()**至少是**大于等于****c.size()**的。 ![](https://box.kancloud.cn/2016-03-09_56dfc9eca5e9b.jpg)  ![](https://box.kancloud.cn/2016-03-09_56dfc9ecb9d33.jpg)  ![](https://box.kancloud.cn/2016-03-09_56dfc9ecca2e4.jpg)  ![](https://box.kancloud.cn/2016-03-09_56dfc9ecdaa17.jpg)  ![](https://box.kancloud.cn/2016-03-09_56dfc9eceb979.jpg) **20、reserve()** ~~~ c.reserve(length); ~~~ 注意:若**length<=c.capacity()**,则不会发生任何改变;因此**length>c.capacity()**才有意义。 **21、data()** **22、assign()** 赋值,相当于将容器**c**中的所有元素的清除,然后重新生成一个**n**个元素值均为**val**的容器。**c.size()**为**n**。 ~~~ c.assign(n,val); ~~~ **23、insert()** 在某个位置插入或连续插入元素。 ~~~ //在第一个位置插入一个元素 c.insert(c.begin(), val); //从第二个位置开始,连续插入两个元素 c.insert(c.begin()+1, 2, vla); //从第三个位置开始,连续插入第一个位置到最后一个位置之间的元素 c.insert(c.begin()+2, c.begin(), c.end() - 1); ~~~ **24、max_size()** 返回容器最多能容纳元素的个数。数据类型所占字节相同的容器,其返回值相同。如**vector<int>a**、**vector<float>b**,容器**a**与**b**的**max_size**就相同。 ~~~ c.max_size(); ~~~ **25、get_allocator()** **26、shrink_to_fit()** **27、emplace_back()** **28、emplace()** **29、erase()** 擦除某个位置或某个连续位置的元素。**c.size()**发生改变,**c.capacity()**不会发生改变。 ~~~ //擦除倒数第二个元素 c.erase(c.end() - 2); //擦除第二个元素到最后一个元素之间的所有元素(闭集合,包含本身) c.erase(c.begin() + 1, c.end() - 1); ~~~ 未完待续。。。 **参考:** **[https://msdn.microsoft.com/en-us/library/9xd04bzs.aspx](https://msdn.microsoft.com/en-us/library/9xd04bzs.aspx)** [**https://msdn.microsoft.com/zh-cn/cn-us/library/9xd04bzs.aspx**](https://msdn.microsoft.com/zh-cn/cn-us/library/9xd04bzs.aspx)