vector【1】介绍与使用(超详解哦)

vector

  • 引言
  • vector介绍
  • 接口使用
    • 默认成员函数
    • 迭代器
    • 容量
    • 元素访问
    • 数据修改
  • 总结

引言

在string部分,我们详细的介绍了各个接口的使用,虽然其不属于STL的一部分,但是接口与STL中的容器相似,所以我们在学习使用vector等STL容器的使用时,就会简单许多:
戳我康string的使用详解哦

vector介绍

vector是可变大小数组序列容器
vector的底层是一块动态申请连续的空间,与数组类似,vector可以通过下标高效的访问数组中的元素;同时由于是动态申请的空间,可以根据需求扩容,弥补了数组大小固定的缺陷;
但是,在进行插入时,vector会根据需要自动扩容,这个过程中需要重新申请一块空间并拷贝数据,会十分影响效率。所以库中的vector会在申请空间时预先多申请一些空间,并以2倍或1.5倍的扩容规则来以减少拷贝行为的发生
vector尾插与尾删的效率非常高,但是其在任意位置插入与删除时,尤其是头插与头删时,就需要挪动数据,效率相对会低很多。所以vector的接口就直接没有支持push_frontpop_front所以vector更适合多次尾插尾删,并且需要经常随机访问其中元素的数据的存储
vector是一个类模板,可以支持存储任意类型的数据:
在这里插入图片描述

接口使用

与string类似,vector也有默认成员函数、迭代器、容量、元素访问、数据修改等接口(使用库vector时需要包含头文件#include

默认成员函数

构造
构造函数部分重载有,无参构造、n个指定元素构造、迭代器区间构造以及拷贝构造
vector【1】介绍与使用(超详解哦)_第1张图片
由于vector是一个类模板,所以在使用vector来实例化对象是,就需要显式指定模板参数,如vector

#include
#include
using namespace std;

int main()
{
	vector<int> v1; //无参初始化
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<int> v2(10, 6);  //使用10个6初始化
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<int> v3(v2.begin(), v2.end());  //使用迭代器区间初始化
	for (auto e : v3)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<int> v4(v3); //拷贝构造
	for (auto e : v4)
	{
		cout << e << " ";
	}
	cout << endl;
}

vector【1】介绍与使用(超详解哦)_第2张图片

析构
析构函数在该对象生命周期结束时由编译器自动调用
vector【1】介绍与使用(超详解哦)_第3张图片
赋值重载
vector【1】介绍与使用(超详解哦)_第4张图片
v2赋值给v1

int main()
{
	vector<int> v1;
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<int> v2(10, 6);
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;

	v1 = v2;
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

vector【1】介绍与使用(超详解哦)_第5张图片

迭代器

vector【1】介绍与使用(超详解哦)_第6张图片
vector的迭代器用法与string相同,并且他们的底层都是原生指针。我们可以使用迭代器访问容器中的元素,也可以使用范围for遍历容器中的元素。
begin返回首元素位置的迭代器,end返回尾元素下一个位置的迭代器、rbegin返回尾元素的反向迭代器、rend返回首元素前一个位置的反向迭代器。后面的cbegincendcrbegincrend都是返回其对应的const迭代器,但是前面的函数都有重载const版本。

int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	v1.push_back(6);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << *v1.begin() << endl;
	cout << *(v1.end() - 1) << endl;
	cout << *v1.rbegin() << endl;
	cout << *(v1.rend() - 1) << endl;

	return 0;
}

vector【1】介绍与使用(超详解哦)_第7张图片

容量

vector【1】介绍与使用(超详解哦)_第8张图片
与string类似,size返回容器中元素的个数;resize用于修改容器中元素的个数;capacity返回容器的容量;empty判断容器是否为空;reserve用于修改容器的容量(关于C++11新增的接口先暂时不做介绍):

int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	v1.push_back(6);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << "size:" << v1.size() << " ";
	cout << "capacity:" << v1.capacity() << " ";
	cout << endl;

	v1.reserve(25);//使用reserve修改容量
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << "size:" << v1.size() << " ";
	cout << "capacity:" << v1.capacity() << " ";
	cout << endl;

	v1.resize(3);//使用resize修改数据数量
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << "size:" << v1.size() << " ";
	cout << "capacity:" << v1.capacity() << " ";
	cout << endl;

	v1.resize(10, 6);//使用reserve增大数据数量,并使用6补足
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << "size:" << v1.size() << " ";
	cout << "capacity:" << v1.capacity() << " ";
	cout << endl;
	return 0;
}

vector【1】介绍与使用(超详解哦)_第9张图片

元素访问

vector【1】介绍与使用(超详解哦)_第10张图片
operator[]at都可以通过下标访问对应位置的元素,不同的是:operator[]当传递的下标越界时,就会崩溃并直接终止程序;当at传递的下标越界时,会抛异常,可以被try-catch捕获,而不会导致程序终止
front会返回首元素的引用、back会返回尾元素的引用。

正常访问:

//正常访问时
int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	v1.push_back(6);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << v1[3] << endl;
	cout << v1.at(3) << endl;
	cout << v1.front() << endl;
	cout << v1.back() << endl;

	return 0;
}

vector【1】介绍与使用(超详解哦)_第11张图片
越界访问:

//越界访问
int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	v1.push_back(6);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	//at越界访问
	try
	{
		cout << v1.at(6) << endl;
	}
	catch(const exception& e)
	{
		cout << e.what() << endl;
	}
	cout << "访问继续" << endl;
	//operator[]越界访问
	try
	{
		cout << v1[6] << endl;
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}
	cout << "访问继续" << endl;

	return 0;
}

vector【1】介绍与使用(超详解哦)_第12张图片

数据修改

vector【1】介绍与使用(超详解哦)_第13张图片
对于数据修改,与string类似:
push_back用于在序列尾插入一个元素;
pop_back用于在序列尾删除一个元素(由于vector中头插与头删的效率过低,所以不提供接口):

int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	v1.push_back(6);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	v1.pop_back();
	v1.pop_back();
	v1.pop_back();
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

vector【1】介绍与使用(超详解哦)_第14张图片

insert用于在序列中的任一位置(迭代器)插入一个元素、n个指定元素或一段迭代器区间中的元素;
vector【1】介绍与使用(超详解哦)_第15张图片

int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	v1.push_back(6);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<int> v2;
	v2.insert(v2.begin(), 6); //相当于头插6
	v2.insert(v2.end(), 7);  //相当于尾插7
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;

	v2.insert(v2.end(), 5, 0);  //尾插5个0
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;

	v2.insert(v2.end(), v1.begin(), v1.end());  //尾插一个v1
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

vector【1】介绍与使用(超详解哦)_第16张图片

erase用于在序列的任一位置删除一个元素,或删除一段迭代器区间中的元素;
在这里插入图片描述

int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	v1.push_back(6);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	v1.erase(v1.begin() + 1); //删除第二个元素
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	
	v1.erase(v1.begin() + 1, v1.end() - 1); //删除一个迭代器区间
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	
	return 0;
}

vector【1】介绍与使用(超详解哦)_第17张图片

swap用于交换两个vector中的数据;
clear用于清理vector中的数据(不改变容量):

int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	v1.push_back(6);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<int> v2(6, 6);
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;

	//交换两个vector的数据
	v1.swap(v2);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;

	//清除两个vector中的数据
	v1.clear();
	v2.clear();
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

vector【1】介绍与使用(超详解哦)_第18张图片

总结

到此,关于vector的介绍以及接口的使用就介绍完了
STL的容器接口在使用时都有很多相似之处,在后面了解到更多的容器后就会体会到

如果大家认为我对某一部分没有介绍清楚或者某一部分出了问题,欢迎大家在评论区提出

如果本文对你有帮助,希望一键三连哦

希望与大家共同进步哦

你可能感兴趣的:(C++初阶,c++,stl,数据结构)