【C++】STL标准库之vector

vector是C++STL中的一个动态数组,支持各种操作如构造、遍历、访问、增删查改。它允许存储任意类型的数据,并能自动调整容量。在插入元素时,vector通常会预先分配额外空间以优化性能。然而,某些操作如resize和erase可能导致迭代器失效,需谨慎处理。
摘要由CSDN通过智能技术生成

vector类的简介

vector是大小可变数组的序列容器,与string相比,vector中可以存任何类型的数据,而string中存储的只能是字符类型。
因为vector采用的是连续存储空间,因此它也可以通过下标对vector中的元素进行访问,而它比数组的优势在于,它的大小是可以动态改变的,它的大小会被容器自动处理。
在插入新元素的时候,并没有使用常规的开辟新数组,拷贝元素,释放旧空间,而是会以空间换取时间的方式,事先多分配一部分空间,以便于未来可能会增加的元素

常用的vector类的接口

构造

函数名称功能
vector()无参构造
vector(size_t n, const value_t& val = val_type())构造并初始化n个val
vector(const vector& v)拷贝构造
vector(InputIterator first, InputIterator last)使用迭代器进行构造

对应写法

vector<int> v();
vector<int> v1(5, 10);
vector<int> v2(v);
vector<int> v3(v1.begin(), v1.begin()+5);

注意:vector是一个类模板,需要在构造时进行类型定义。
而在c++11中,还可以用数组直接进行构造 vector v(1,2,3,4,5);

容量

函数名称功能
size获取元素个数
capacity获取当前容量大小
empty判断当前vector是否为空
resize改变vector中有效元素的个数
reserve改变容量大小(只增不减)

当前的容量部分的函数实际上和string的非常相似,但是string在resize中由于内部存在的数组,与vector稍微不同
我们在扩容时,vs下是以1.5倍来扩容的,g++是按2倍来扩容的。如果事先知道vector中大概要存放多少个元素,可以先对其进行扩容,这样就能够避免边插入边扩容的问题了。

遍历及访问

函数名称功能
operator[]访问元素
at访问元素
front访问第一个元素
back访问最后一个元素

请注意:访问元素有以下几种访问方式

//auto遍历
for(auto : e : v2)
{
	cout << e << " ";
}
cout << endl;
//下标遍历
for (size_t i = 0; i < v1.size(); ++i)
{
	cout << v1[i] << " ";
}
cout << endl;
//正向迭代器遍历
auto it = v1.begin();
while (it != v1.end())
{
	cout << *(it) << " ";
	++it;
}
cout << endl;
//反向迭代器遍历
auto rit = v1.rbegin();
while(rit != v..rend())
{
	cout << *(rit) << " ";
	++rit;
}
cout << endl;

增删查改

函数名称功能
push_back尾插
pop_back尾删
find查找(是算法模块实现的,不是vector的成员函数)
insert在pos前插入val
erase删除pos位置的数据
swap交换两个vector的数据空间
operator[]像数组一样通过下标访问

迭代器

在这里插入图片描述
如当前图片所示:begin是在当前vector中的第一个元素的位置,end在当前vector最后一个元素的下一个位置,而反向迭代器正好相反。

迭代器失效问题

如果我们写这样一个代码

在这里插入图片描述

当程序执行到第14行时,直接奔溃了。这是什么原因呢?

实际上和当前这个迭代器有关,当前迭代器我们可以将其理解为是一个指针,当前指针本来指向的是vector的第一个元素的位置,而我们将其扩容后,实际上在底层经历了开辟新空间,拷贝元素,释放旧空间三个步骤,当这三个步骤结束后,原本指向第一个元素的指针已经失去了意义,成为了野指针,我们要访问这个野指针程序就会奔溃。因为我们使用的是一块已经被释放的空间。

如果总结下来:有以下几种情况可能会导致迭代器失效
1.会引起底层空间发生改变的操作:resize,reserve,insert,assign,push_back
2.指定位置删除元素

int main()
{
	vector<int> v{1,2,3,4,5,6};

	auto pos = find(v.begin(), v.end(), 5);
	v.erase(pos);
	cout << *(pos) << endl;
	return 0;
}

针对上述迭代器失效的解决办法,第一种情况,我们要在使用迭代器之前再次对迭代器进行赋值
第二种情况,我们要在使用erase时去接收返回值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值