C++vector容器

目录

1、vector介绍

2、常用接口介绍

vector的定义

vector迭代器的使用

vector空间操作

vector的增删查改

vector的迭代器失效问题


1、vector介绍

vector文档介绍

1、vector能够像容器一样存储各种类型的对象,使用时加上#include头文件

2、vector是一个动态数组,能够增加和减少容器容量

3、与其他容器相比,vector在末尾增上和删除元素相对高效。

2、常用接口介绍

vector的定义

constructor

C++vector容器_第1张图片

 (1)vector():无参构造

vector v1;

(2)构造并初始化值为 n 个 val

vector v1(10, 5);

(3)拷贝构造,利用现有的vector构造一个同类型的vector

vector v1(10, 5);
vector v2(v1);

(4)利用迭代器进行初始化构造

vector v1(10, 5);
vector v2(v1.begin(), v1.end());

vector迭代器的使用

begin  end :begin获取vector第一个有效数据位置的迭代器,end获取vector最后一个数据的后一个位置的迭代器

vector v1(10, 5);
auto it = v1.begin();
while (it != v1.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;

rbegin  rend :rbegin获取vector最后一个有效数据位置的迭代器,rend获取第一个数据的前一个位置的迭代器。

//C++11新增可以使用{}初始化数据
vector v1{ 1,2,3,4,5 };
auto it = v1.rbegin();
while (it != v1.rend())
{
	cout << *it << " ";
	//5  4  3  2  1
	++it;
}
cout << endl;

vector空间操作

size :获取数据个数

vector v1{ 1,2,3,4,5 };
cout << v1.size() << endl;//5

capacity :获取容量大小

vector v1{ 1,2,3,4,5 };
cout << v1.capacity() << endl;//5

empty :判断vector是否为空,空返回true,否则false

vector v1{ 1,2,3,4,5 };
if (v1.empty())
	cout << "空" << endl;
else
	cout << "非空" << endl;

resize :开辟空间并初始化,实际上就是改变vector的size

当开辟的空间小于vector原来的空间时,会发生截断;

等于不做操作;

大于就会用指定数据填充。

vector v1{1,2,3,4,5};
//让v1的size增长到10,数据不够用5填充
v1.resize(10, 5);

reserve :改变vector的容量capacity

vector v1{1,2,3,4,5};
//将容量增加到20,有效数据个数不变
v1.reserve(20);

vector的增删查改

push_back :在vector最后一个有效数据后插入数据

vector v1{ 1,2,3,4,5 };
//在5后面插入6
v1.push_back(6);

pop_back :删除最后一个有效数据

vector v1{ 1,2,3,4,5 };
//将最后一个数据5删除
v1.pop_back();

operator[] :访问vector中位置为pos的数据,就和C语言的数组访问一样。

vector v1{ 1,2,3,4,5 };
cout << v1[3] << endl;//4

find :vector没有这个接口,这个是算法的接口,返回值是一个迭代器

vector v1{ 1,2,3,4,5 };
//从v1的起始到结束的位置中去找3
//找到就会返回该位置迭代器,否则返回v1.end()
auto pos = find(v1.begin(), v1.end(), 3);
if (pos != v1.end())
{
	cout << *pos << endl;
}

insert :在pos位置之前插入数据,返回值是新插入数据的迭代器

vector v1{ 1,2,3,4,5 };
auto pos = find(v1.begin(), v1.end(), 3);
//在3之前插入6
v1.insert(pos, 6);

erase :删除pos位置的数据,返回值是被删除数据的后一个数据的迭代器

vector v1{ 1,2,3,4,5 };
auto pos = find(v1.begin(), v1.end(), 3);
//删除3,删除后pos迭代器失效,得重新接收
pos = v1.erase(pos);
//此时pos是3后面一个数据的迭代器
cout << *pos << endl;//4

swap:交换两个vector的数据

vector v1{ 1,2,3 };
vector v2{ 4,5,6,7 };
v1.swap(v2);

vector的迭代器失效问题

vector v1{ 1,2,3,4,5 };
auto pos = find(v1.begin(), v1.end(), 3);
v1.reserve(100);
cout << *pos << endl;//err

上面这段代码,在增容之前pos定位的是3的位置;但是增容后如果后面连续空间不足,就会在内存中型开辟一块连续空间使用,将数据拷贝到新空间,然后释放原空间;经过一系列操作,迭代器pos就会失效,不再指向3,如果再去访问就会失效。所以必须重新再找一次。

只要发生增容导致空间变更,就导致迭代器失效的操作有很多,例如:insert、resize、reserve等。

vector v1{ 1,2,3,4,5 };
auto pos = find(v1.begin(), v1.end(), 3);
v1.erase(pos);
cout << *pos << endl;//err

上面的erase操作同样会导致迭代器失效,理论上讲,删除pos位置元素,后面数据会往前填充,但是如果删除的是最后一个数据,pos就等于end了。因此,删除任意位置的数后,vs都会认为该位置的迭代器失效了。

C++vector容器_第2张图片

 而g++中,删除3后读取pos就是4;如果是删除最后一个数据,读取pos还是最后一个数据。

C++vector容器_第3张图片

 所以在vs中解决这样的问题只需要用pos重新接收一下erase的返回值即可。

vector v1{ 1,2,3,4,5 };
auto pos = find(v1.begin(), v1.end(), 3);
//如果删除的是最后一个数据,就没必要再去接收了
//因为返回值是v1.end()
pos = v1.erase(pos);
cout << *pos << endl;//4

你可能感兴趣的:(c++,容器)