C++ vector容器

一、基本概念

  1. vector是表示可变大小的数组的容器
  2. vector是连续存储空间来存储元素的,并且是动态的(如果需要扩容/缩容的话,不是在原来空间的后面增加空间,而是找另一块空间,将原来空间的内容拷贝回去,释放原来的空间)
  3. vector容器在头文件 < vector >中

二、成员变量

vector是用三个指针来维护的

start:指向空间的开头
finish:指向有效数据的尾
endOfStorage:指向存储空间的尾

在这里插入图片描述

三、重要接口

3.1 构造函数

默认构造vector ()
构造并初始化n个valuevector(n,value)
拷贝构造vector(const vector& v)
迭代器区间构造vector(InputIterator first,InputIterator last)

代码演示

void printVector(vector<int>& v)
{	//利用迭代器打印 v
	for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}

int main()
{
	vector<int> v; //默认构造
	vector<int> v1(10, 1);  //构造10个1
	vector<int> v2(v1.begin(), v1.end());  //利用v1的迭代器区间构造
	vector<int> v3(v2);  //拷贝构造
	printVector(v);
	printVector(v1);
	printVector(v2);
	printVector(v3);
	return 0;
}

在这里插入图片描述

3.2 iterator

vector的iterator可以简单的理解成指针。

begin()返回第一个数据位置的iterator
end()返回最后一个数据位置的后一个 的iterator
rbegin()返回最后一个数据位置的iterator
rend()返回第一个数据位置的前一个的iterator
void PrintVector(const vector<int>& v)
{
	// const对象使用const迭代器进行遍历打印
	vector<int>::const_iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

void main()
{
	// 使用push_back插入4个数据
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	// 使用迭代器进行遍历打印
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	// 使用迭代器进行修改
	it = v.begin();
	while (it != v.end())
	{
		*it *= 2;
		++it;
	}

	// 使用反向迭代器进行遍历再打印
	// vector<int>::reverse_iterator rit = v.rbegin();
	auto rit = v.rbegin();
	while (rit != v.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

	PrintVector(v);
}

在这里插入图片描述

3.3 容量和大小

size返回数据元素的个数
capacity返回容量的大小
empty返回是否为空
resize(n)改变容器的size
reserve(n)改变容器的capacity

注:

  1. resize第二个参数是缺省参数,如果没传,就默认调用构造函数
  2. 如果resize的n大于size的大小,那么后面的位置会填充你传的数据,如果没传就填充默认数据
  3. 如果resize的n小于size的大小,发生截断
  4. reserve扩容规则在不同编译器下是不同的,vs下capacity是按1.5倍增长的,g++是按2倍增长的

代码演示

int main()
{
	vector<int> v;

	// set some initial content:
	for (int i = 1; i < 10; i++)
		v.push_back(i);

	v.resize(5);
	v.resize(8, 100);
	v.resize(12);

	cout << "v contains:";
	for (size_t i = 0; i < v.size(); i++)
		cout << ' ' << v[i];
	cout << '\n';
	return 0;
}

在这里插入图片描述

3.4 增删查改

push_back(num)尾插数据
pop_back()尾删数据
insert(pos,num)在pos位置前插入数据
insert(pos,size,num)在pos位置前插入size个数据
erase(pos)删除pos位置的数据
erase (begin,end)删除begin~end区间的数据
clear()清理所有数据
operator[ ]像数组一样访问数据
int main()
{

	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	auto it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	v.pop_back();
	v.pop_back();

	it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

在这里插入图片描述

四、迭代器失效

迭代器失效的本质就是指向了一块已经被释放的空间(野指针),那什么情况会导致这个问题呢?很明显就是在扩容和缩容的时候,一些接口比如:resize、reserve、insert、assign、push_back都会导致底层空间的改变,导致迭代器失效。
代码演示

int main()
{
	int a[] = { 1, 2, 3, 4 };
	vector<int> v(a, a + sizeof(a) / sizeof(int));
	
	// 使用find查找3所在位置的iterator
	vector<int>::iterator pos = find(v.begin(), v.end(), 3);
	// 删除pos位置的数据,导致pos迭代器失效。
	v.erase(pos);
	
	cout << *pos << endl; // 此处会导致非法访问
	return 0;
}

erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了。

  • 22
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值