前言
前面我们学习了c++管理字符串的string类,较c语言管理字符串方便了不少。但是在处理其他数据(非字符串)时显得力不从心。这时,c++为我们提供了一个强大的容器------vector。vector底层是一个动态开辟的数组,它为我们提供了许多的接口来管理数据。
一、vector的默认成员函数
构造函数(constructor)
一共有六个构造函数,在这里只介绍常用的几个。
无参构造,用n个val值构造,拷贝构造,迭代器区间构造。
代码示例:
cpp
#include <vector>
#include <iostream>
using namespace std;
void print(vector<int>& v)
{
for (auto e : v)
{
cout << e;
}
cout << endl;
}
int main()
{
vector<int> v1;//无参构造
vector<int> v2(6,5);//用n个val构造
vector<int> v3(v2);//拷贝构造
vector<int> v4(v3.begin(), v3.end());//迭代器区间构造
print(v1);
print(v2);
print(v3);
print(v4);
return 0;
}
析构函数(destructor)
在对象生命周期结束时自动释放动态开辟的内存。
二、vector的迭代器接口
图示:
正向迭代器:
begin()
返回指向首元素的迭代器。
end()
返回指向最后一位元素的下一个位置。
反向迭代器与正向迭代器恰恰相反。
代码示例:
cpp
#include <vector>
#include <iostream>
using namespace std;
void print(vector<int>& v)
{
for (auto e : v)
{
cout << e;
}
cout << endl;
}
int main()
{
vector<int> v1({ 1,2,3,4 });
vector<int> v2(v1.begin(), v1.end());//正向迭代器
vector<int> v3(v1.rbegin(), v1.rend());//反向迭代器
cout << "正向迭代器构造" << endl;
print(v2);
cout << "反向迭代器构造" << endl;
print(v3);
return 0;
}
三、vector的容量接口
一共有七个接口,这里我们只介绍常用的几个:
size()
返回容器中元素的个数。
capacity()
返回容器的储存容量。在任何情况下,size都小于等于capacity。
代码示例:
cpp
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> v1({ 1,2,3,4 });
v1.pop_back();
vector<int> v2(5,3);
vector<int> v3;
cout << "size:" << v1.size() << "capacity:" << v1.capacity() << endl;
cout << "size:" << v2.size() << "capacity:" << v2.capacity() << endl;
cout << "size:" << v3.size() << "capacity:" << v3.capacity() << endl;
return 0;
}
v1删除了一个元素,但是没有缩容,这是vs编译器下的结果,不同的编译器可能不同,一些比较激进的编译器可能会缩容。
empty()
返回一个布尔值,容器为空返回1,反之返回0;
resize()
它可以增加或减少的vectorr容器元素数量。如果调整后的大小大于当前大小,则会根据提供的默认值或指定的值填充新添加的元素;如果调整后的大小小于当前大小,则会丢弃多余的元素。
代码示例:
cpp
#include <vector>
#include <iostream>
using namespace std;
void print(vector<int>& v)
{
for (auto e : v)
{
cout << e;
}
cout << endl;
}
int main()
{
vector<int> v1({ 1,2,3,4 });
print(v1);
v1.resize(6,5);
print(v1);
v1.resize(2);
print(v1);
return 0;
}
reserve()
用于提前为容器开辟空间,从而避免在添加元素时进行多次内存重分配,提高程序的效率。
代码示例:
cpp
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> v1({ 1,2,3,4 });
cout << "size:" << v1.size() << "capacity:" << v1.capacity() << endl;
v1.reserve(8);
cout << "size:" << v1.size() << "capacity:" << v1.capacity() << endl;
v1.push_back(2);
cout << "size:" << v1.size() << "capacity:" << v1.capacity() << endl;
return 0;
}
四、vector的元素访问接口
容器的访问接口方便我们直接访问与修改容器指定的元素。
operator[]
代码示例:
cpp
#include <vector>
#include <iostream>
using namespace std;
void print(vector<int>& v)
{
for (auto e : v)
{
cout << e;
}
cout << endl;
}
int main()
{
vector<int> v1;
v1.resize(10);
for (size_t i = 0; i < 10; i++)
{
v1[i] = i;
}
print(v1);
return 0;
}
如果operator[]中的n超出范围,会导致未定义的行为。
五、vector的修改器接口
push_back()
在容器的尾元素后插入一个元素。
pop_back()
删除容器的最后一个元素。
insert()
在指定位置之前插入元素。
erase()
释放指定位置的内存空间。
clear()
清除容器的全部元素,将size置零。
代码示例:
cpp
#include <vector>
#include <iostream>
using namespace std;
void print(vector<int>& v)
{
for (auto e : v)
{
cout << e;
}
cout << endl;
}
int main()
{
vector<int> v1(3,8);
v1.resize(10);
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
print(v1);
v1.pop_back();
v1.insert(v1.begin(),9);
print(v1);
v1.erase(v1.begin(), v1.begin() + 3);
print(v1);
v1.clear();
print(v1);
return 0;
}