头文件:#include <vector>
1.vector容器的内存开辟方式
vector容器和数组比较相似,但是开辟空间的方式不同。
(1)当vector对象的容量满了之后,在插入一个数据时,并不一定是再开辟一个空间,可能是会一次性多开辟几个空间,避免了下次再插入数据的时候需要频繁开辟空间的消耗。
(2)当vector对象声明后在物理内存上会固定存放在一段内存上,如果再插入一些数据后该物理空间满了,这时候后就需要将数据迁移到一段更大的内存地址上,他会复制原vector中的数据到新的内存地址上,并且释放掉原来的对象。所以如果你之前声明了变量指向了原vector中数据的地址,此时就会失效了。
2.vector的迭代器
std::vector<int> vec{1,2,3};
std::vector<int>::iterator it = vec.begin();//这个迭代器指向vec的第一个元素的位置
std::vector<int>::iterator it = vec.end();//这个迭代器指向vec的最后一个元素的后一个位置
std::vector<int>::iterator it = vec.rbegin();//这个迭代器指向vec的最后一个元素的位置
std::vector<int>::iterator it = vec.rend();//这个迭代器指向vec的第一个元素的前一个位置
rbegin和rend一般用于从后往前遍历vector
3.vector的构造函数
(1)直接用类型声明一个空的vector
std::vector<int> vec;
(2)将begin迭代器和end迭代器之间的数据拷贝到vector中构造一个vector对象
std::vector<int> vec{1,2,3,4};
std::vector<int> vec1(vec.begin(),vec.end());
注意这里复制的begin迭代器到end迭代器之间的数据,包括begin迭代器指向的数据,不包括end迭代器指向的数据
(3)使用n个相同的元素m构造vector对象
int n =10;
int m =100;
std::vector<int> vec(10,100);
(4)使用一个vector对象来构造另一个vector对象
std::vector<int> vec{1,2,3,4};
std::vector<int> vec1(vec);
4.vector的赋值操作
(1)使用‘=’赋值
std::vector<int> vec{1,2,3,4};
std::vector<int> vec1 = vec;
(2)使用assign用begin迭代器和end迭代器之间的数据进行赋值
std::vector<int> vec{1,2,3,4};
std::vector<int> vec1;
vec1.assign(vec.begin(),vec.end());
(3)使用assign用n个m给vector容器赋值
std::vector<int> vec{1,2,3,4};
std::vector<int> vec1;
int n =10;
int m = 100;
vec1.assign(n,m);
(4)使用swap交换两个vector对象中的数据
std::vector<int> vec{1,2,3,4};
std::vector<int> vec1{5,6,7,8};
vec.swap(vec1);
5.vector容器大小相关的操作
(1)用size获取vector对象中元素的个数
std::vector<int> vec{1,2,3,4};
int count = vec.size();
(2)用empty判断vector对象是否为空
std::vector<int> vec;
bool isEmpty = vec.empty();
(3)重新指定vector容器的长度,如果长度变短则,则删除超出长度的元素;如果元素变长则用元素m来填充
std::vector<int> vec{1,2,3,4};
int m = 10;
vec.resize(8,m);
(4)用capacity获取vector对象的容量,容量是指开辟出来给存储数据的个数,它大于等于size
std::vector<int> vec{1,2,3,4};
int count = vec.capacity();
(5)使用reserve为vector对象预留n个长度的元素。由于在向vector中插入数据的时候,如果插入的数量所需的内存超过了vector对象声明时所在的内存块的上限,那么系统会先将原vector对象里的数据赋值到一个更大的内存块上,再释放掉原vector对象。调用reserve方法,相当于告诉系统我vector对象即将插入多少个数据,系统就会按照这个数据量去找到适合的内存块上创建该对象,就避免了上面说的插到一般发现内存块不够用再换去其他地方所产生的开销。
std::vector<int> vec;
vec.reserve(100000);
for(int i = 0;i<100000;i++){
vec.push_back(i);
}
6.对vector中元素的操作
(1)使用at访问vector容器中的元素
std::vector<int> vec{1,2,3,4};
for(int i = 0;i<vec.size();i++){
std::cout<<vec.at(i)<<std::endl;
}
(2)使用[]访问vector容器中的元素
std::vector<int> vec{1,2,3,4};
for(int i = 0;i<vec.size();i++){
std::cout<<vec.[i]<<std::endl;
}
(3)front获取vector容器的第一个元素,back获取vector容器的最后一个元素
std::vector<int> vec{1,2,3,4};
int firstEle = vec.font();
int lastEle = vec.back();
(4)用push_back向vector容器的尾部插入一个数据
std::vector<int> vec{1,2,3,4};
vec.push_back(5);
(5)用pop_back删除vector容器的最后一个元素
std::vector<int> vec{1,2,3,4};
vec.pop_back();
(6)用insert向迭代器指向的位置插入n个m元素
std::vector<int> vec{1,2,3,4};
int n =10;
int m =100;
vec.insert(vec.begin(),10,100);
(7)用erase删除迭代器指向的元素
std::vector<int> vec{1,2,3,4};
vec.erase(vec.begin());
(8)用erase删除两个迭代器之间的全部元素
std::vector<int> vec{1,2,3,4};
vec.erase(vec.begin(),vec.begin()+2);
(9)使用clear删除vector容器中的全部元素
std::vector<int> vec{1,2,3,4};
vec.clear();
tips1:在使用迭代器构造和赋值vector对象的时候,可以使用数组指针代替迭代器
int arr[] = {1,2,3,4,5};
vector<int> vec(arr,arr+sizeof(arr)/sizeof(int));
tips2:在使用at和[]访问vector容器中的元素的区别和string容器中at和[]使用区别一致,at访问越界会抛出异常,[]访问越界不会抛出异常直接报错中断程序
tips3:在使用resize对vector进行长度重置的时候,它的容量capacity是不会改变的。
例如:vector<int> vec;
for(int i = 0;i<10000;1++){
vec.push_back(i);
}
vec.resize(3);
上面的代码vec的长度size的确变为了3,但是它的capacity还是大于10000的,也就是说它占用的内存还是和以前一样大。
可以使用下面的这段代码来清除多余的容量:
vector<int>(v).swap(v);
这段代码的意思是先用v作为参数构造一个新的匿名vector对象,该对象构造时是按照长度size来新建一个新的匿名vector对象,所以新的匿名vector对象长度和capacity都是3。然后调用新创建的匿名vector对象的swap方法与原对象vec进行交换,之后原对象vec就执行了新建的这个匿名vector对象,长度和容量都是3。而原来的vec对象则变成了一个匿名对象,该对象在使用后会被系统自己回收释放。这样就完成了对vector对象的多余容量的释放。