Bootstrap

【c++】vector的使用

前言

前面我们学习了c++管理字符串的string类,较c语言管理字符串方便了不少。但是在处理其他数据(非字符串)时显得力不从心。这时,c++为我们提供了一个强大的容器——vector。vector底层是一个动态开辟的数组,它为我们提供了许多的接口来管理数据。

一、vector的默认成员函数

构造函数(constructor) 

 一共有六个构造函数,在这里只介绍常用的几个。

无参构造,用n个val值构造,拷贝构造,迭代器区间构造。

代码示例:


#include <vector>
#include <iostream>
using namespace std;


void print(vector<int>& v)
{
	for (auto e : v)
	{
		cout << e;
	}
	cout << endl;
}

int main()
{
	vector<int> v1;//无参构造
	vector<int> v2(6,5);//用n个val构造
	vector<int> v3(v2);//拷贝构造
	vector<int> v4(v3.begin(), v3.end());//迭代器区间构造
	print(v1);
	print(v2);
	print(v3);
	print(v4);

	return 0;
}

析构函数(destructor)

在对象生命周期结束时自动释放动态开辟的内存。

二、vector的迭代器接口

图示:

 正向迭代器:

begin()

返回指向首元素的迭代器。 

 end()

返回指向最后一位元素的下一个位置。

反向迭代器与正向迭代器恰恰相反。

代码示例:


#include <vector>
#include <iostream>
using namespace std;


void print(vector<int>& v)
{
	for (auto e : v)
	{
		cout << e;
	}
	cout << endl;
}

int main()
{
	vector<int> v1({ 1,2,3,4 });
	vector<int> v2(v1.begin(), v1.end());//正向迭代器
	vector<int> v3(v1.rbegin(), v1.rend());//反向迭代器
	cout << "正向迭代器构造" << endl;
	print(v2);
	cout << "反向迭代器构造" << endl;
	print(v3);


	return 0;
}

三、vector的容量接口 

 一共有七个接口,这里我们只介绍常用的几个:

size()

返回容器中元素的个数。

capacity()

返回容器的储存容量。在任何情况下,size都小于等于capacity。

代码示例:


#include <vector>
#include <iostream>
using namespace std;


int main()
{
	vector<int> v1({ 1,2,3,4 });
	v1.pop_back();
	vector<int> v2(5,3);
	vector<int> v3;
	
	cout << "size:" << v1.size() << "capacity:" << v1.capacity() << endl;
	cout << "size:" << v2.size() << "capacity:" << v2.capacity() << endl;
	cout << "size:" << v3.size() << "capacity:" << v3.capacity() << endl;


	return 0;
}

 v1删除了一个元素,但是没有缩容,这是vs编译器下的结果,不同的编译器可能不同,一些比较激进的编译器可能会缩容。

empty()

返回一个布尔值,容器为空返回1,反之返回0;

resize()

 它可以增加或减少的vectorr容器元素数量。如果调整后的大小大于当前大小,则会根据提供的默认值或指定的值填充新添加的元素;如果调整后的大小小于当前大小,则会丢弃多余的元素。

代码示例:


#include <vector>
#include <iostream>
using namespace std;

void print(vector<int>& v)
{
	for (auto e : v)
	{
		cout << e;
	}
	cout << endl;
}
int main()
{
	vector<int> v1({ 1,2,3,4 });
	
	print(v1);
	v1.resize(6,5);
	print(v1);
	v1.resize(2);
	print(v1);
	return 0;
}

reserve()

用于提前为容器开辟空间,从而避免在添加元素时进行多次内存重分配,提高程序的效率。

代码示例:

#include <vector>
#include <iostream>
using namespace std;

int main()
{
	vector<int> v1({ 1,2,3,4 });
	cout << "size:" << v1.size() << "capacity:" << v1.capacity() << endl;
	v1.reserve(8);
	cout << "size:" << v1.size() << "capacity:" << v1.capacity() << endl;
	v1.push_back(2);
	cout << "size:" << v1.size() << "capacity:" << v1.capacity() << endl;
	return 0;
}

四、vector的元素访问接口

容器的访问接口方便我们直接访问与修改容器指定的元素。

operator[] 

代码示例:


#include <vector>
#include <iostream>
using namespace std;

void print(vector<int>& v)
{
	for (auto e : v)
	{
		cout << e;
	}
	cout << endl;
}
int main()
{
	vector<int> v1;
	v1.resize(10);

	for (size_t i = 0; i < 10; i++)
	{
		v1[i] = i;
		
	}
	print(v1);
	return 0;
}

如果operator[]中的n超出范围,会导致未定义的行为。

五、vector的修改器接口

push_back()

在容器的尾元素后插入一个元素。

pop_back()

删除容器的最后一个元素。 

insert()

在指定位置之前插入元素。 

erase()

释放指定位置的内存空间。 

clear()

清除容器的全部元素,将size置零。 

代码示例:


#include <vector>
#include <iostream>
using namespace std;

void print(vector<int>& v)
{
	for (auto e : v)
	{
		cout << e;
	}
	cout << endl;
}
int main()
{
	vector<int> v1(3,8);
	v1.resize(10);
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	print(v1);
	v1.pop_back();
	v1.insert(v1.begin(),9);
	print(v1);
	v1.erase(v1.begin(), v1.begin() + 3);

	print(v1);
	v1.clear();
	print(v1);

	return 0;
}

 

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;