STL vector基本用法

vector介绍

  • vector是可变大小数组的序列容器。
  • 像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。

思考一个问题:可以用vector<char>替代string吗?
答案是不能:原因有二
1.结构不同,string要求最后又'\0',为了更好的兼容C,string的函数都会对'\0'处理,但是vector的函数不会
2.string中又许多独特的接口函数

vector的使用

vector的定义

template < class T, class Alloc = allocator<T> > class vector;

vector的定义是模板的形式,因为会有不同类型的模板
有2个模板参数,
class T指的是元素的类型,在类中有别名为value_type,因为类中进行了typedef T value_type
class Alloc = allocator<T>是空间配置器(内存池),有缺省值,通常我们不用传这个参数


vector接口函数

构造函数和赋值重载

构造函数 说明
vector() 无参构造
vector(size_type n,const value_type& val = value_type()) 构造并初始化n个val
vector (const vector& x); 拷贝构造
vector (InputIterator first, InputIterator last); 使用迭代器进行初始化构造

vector()无参构造我们不必多说

vector(size_type n,const value_type& val = value_type())value_type就是T,是typedef出来的
val的缺省值value_type()其实就是容器中元素类型的构造函数,以无参构造出的值为缺省值

这里T的类型假如是自定义类型Date,那么缺省值是Date(),就是默认构造函数,我们都可以理解
如果T类型 为内置类型,比如int,那么int()是什么意思呢?
这里其实是C++中的优化,int()其实会就是0

void test1()
{
    
    
	vector<int> v(5, 2); //22222
}

vector (const vector& x);拷贝构造,也没什么多说的

vector (InputIterator first, InputIterator last);,这里的迭代器可以是自己容器的,也可以是其他容器的,甚至可以是数组的

void test1()
{
    
    
	vector<int> v1(5, 98); 

	vector<int> v2(v1.begin(), v1.end());//相同类型的迭代器
	for (auto e : v2)
	{
    
    
		cout << e << " ";  
		e++;
	}//输出98 98 98 98 98
	cout << endl;

	vector<char> v3(v1.begin(), v1.end());//相同容器不同元素类型的迭代器
	for (auto e : v3)
	{
    
    
		cout << e << " ";
		e++;
	}//输出b b b b b
	cout << endl;

	int nums[] = {
    
     1,2,3,4,5,6 };
	vector<int> v4(nums, nums + sizeof(nums) / sizeof(int));//数组
	for (auto e : v4)
	{
    
    
		cout << e << " ";
		e++;
	}//输出1 2 3 4 5 6 
	cout << endl;
}

赋值重载

vector& operator= (const vector& x);
void test2()
{
    
    
	vector<char> v1(10, 'x');
	vector<char> v2;
	v1 = v2;//xxxxxxxxxx
}

迭代器

这里的迭代器也是指针
用法和前面的string的迭代器类似

void test2()
{
    
    
	int nums[] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	vector<int> v(nums, nums + 10);
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
    
    
		cout << *it << " ";
		it++;
	}//1 2 3 4 5 6 7 8 9 10
	cout << endl;

	vector<int>::reverse_iterator rit = v.rbegin();
	while (rit != v.rend())
	{
    
    
		cout << *rit << " ";
		rit++;
	}//10 9 8 7 6 5 4 3 2 1
	cout << endl;

	const vector<int> cv(nums, nums + 10);
	vector<int>::const_iterator cit = cv.cbegin();
	while (cit != cv.cend())
	{
    
    
		cout << *cit << " ";
		cit++;
	}//1 2 3 4 5 6 7 8 9 10
	cout << endl;

	vector<int>::const_reverse_iterator crit = cv.crbegin();
	while (crit != cv.crend())
	{
    
    
		cout << *crit << " ";
		crit++;
	}//10 9 8 7 6 5 4 3 2 1
	cout << endl;
}


元素访问

operator[]
vector中也重载了[]

reference operator[] (size_type n);//读写
const_reference operator[] (size_type n) const;//只读

用法和string::operator[]一样
还是会assert断言判断是否下标越界

at

 reference at (size_type n);
const_reference at (size_type n) const;

用法和at相似
如果下标越界,就会抛出异常


front和back

front返回第一个元素
back返回最后一个元素
这两个函数不常用,完全可以用[]替代:   v.front()–>v[0]   v.back()–>v[v.size()-1]



data

value_type* data() noexcept;
const value_type* data() const noexcept;

返回指向内存数组的直接指针


vector容量相关函数

函数 说明
size 获取数据个数
max_size 获取最大数据个数
capacity 获取容量大小
empty 判空
shrink_to_fit 缩减至适合容量
resize 调整size
reserve 调整capacity

这几个函数在string也都有,用法都相似

这里只有reserve 函数和string中略有区别
如果 n 大于当前的矢量容量,函数会使容器重新分配存储空间,将容量增加到 n(或更大)。
在所有其他情况下,函数调用不会导致重新分配,向量容量也不会受到影响。

这里与string中的reserve不同,如果n<capacity(),string中的reserve可能会减少,取决于编译器
但是vector中的n<capacity()也不会减少capacity

capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。
但是也不要固化的认为,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。

reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。

resize会影响size()和capacity()

下面有一个情况,我们先用无参构造出一个vector<int>类型对象,再用reserve函数开出空间,如果我们用[]去赋值会发生什么呢?

void test3()
{
    
    
	vector<int> v;
	v.reserve(20);
	v[0] = 1;
	v[1] = 2;
}

答案是,程序会报错
在这里插入图片描述
原因是,虽然用reserve(20)开辟了20个空间,但是此时size()为0
然后我们再通过[]去赋值,operator[]函数内部有assert断言,这里就会报错

所以像上面的那个情况,需要使用resize函数,resize既可以改变size也可以改变capacity

void test3()
{
    
    
	vector<int> v;
	v.resize(20);
	v[0] = 1;
	v[1] = 2;
}

vector增加 删除 修改操作


push_back

void push_back (const value_type& val);

作用:尾插一个元素

pop_back

void pop_back();

作用:删除最后一个元素


insert

iterator insert (iterator position, const value_type& val);

void insert (iterator position, size_type n, const value_type& val);

template <class InputIterator>
    void insert (iterator position, InputIterator first, InputIterator last);

前面string类型的insert函数,都是在size_t类型的pos位置插入
而vector中的insert都是在迭代器position位置处插入

  • iterator insert (iterator position, const value_type& val),在position迭代器位置处插入val
  • void insert (iterator position, size_type n, const value_type& val),在position迭代器位置处插入nval
  • template <class InputIterator> void insert (iterator position, InputIterator first, InputIterator last);在迭代器position位置处插入[frist,last)迭代器区间中的内容
void test4()
{
    
    
	vector<int> v;
	v.push_back(0);
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);
	v.push_back(7);

	v.insert(v.begin() + 3,100);//0 1 2 (100) 3 4 5 6 7
	v.insert(v.begin(), 2, 10);//(10 10) 0 1 2 100 3 4 5 6 7

	int num[] = {
    
     12,13,14,15 };
	v.insert(v.begin() + 1, num, num + 4);//10 (12 13 14 15) 10 0 1 2 100 3 4 5 6 7

	for (auto e : v)
	{
    
    
		cout << e<<" ";
		e++;

	}
}


erase

iterator erase (iterator position);
iterator erase (iterator first, iterator last);

iterator erase (iterator position)删除迭代器position位置处元素
iterator erase (iterator first, iterator last)删除[first,last)迭代器区间中的内容

void test5()
{
    
    
	vector<int> v;
	v.push_back(0);
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);
	v.push_back(7);

	//0 1 2 3 4 5 6 7
	v.erase(v.begin()); //1 2 3 4 5 6 7

	v.erase(v.begin() + 2, v.end());//1 2
}

上面的eraseinsert会涉及到迭代器失效,迭代器失效我们之后会进行了解



swap

void swap (vector& x);

交换两个vector的数据空间



clear

void clear();

清除内容
使size()值变为0,不改变capacity()的值


关系操作符

vector中也支持各种关系操作符的重载,这些函数为非成员函数重载
在这里插入图片描述

关系操作符对于string很实用,但是关系操作符对于vector用处不大

猜你喜欢

转载自blog.csdn.net/weixin_64116522/article/details/132391309
今日推荐