C++vector的使用

vector的使用

1.vector的介绍

1.vector是表示可变大小数组的序列容器.
2.vector也采用连续空间存储元素,所以vector可以采用下标的方法对元素进行访问,但是又不想数组,它的大小是可以动态改变的。
3.vector动态分配数组来存储它的元素,当新元素插入时,可能需要重新分配空间,把全部元素移到这个数组。就时间而言,这是一个比较大的开销,但是并不是每次插入元素,vector都会扩容。
4.vector会分配额外多的空间以适应可能的增长,所以存储空间要比实际需要的存储空间更大。不同库采用不同的方法来进行空间的分配。
5.与其他动态系列容器相比(deques,lists...),vector访问元素时更加高效,在末尾插入和删除也更高效,对于不在末尾插入和删除的操作,效率更低。

2.vector的使用

学习容器一定要学会查看文档,vector的文档介绍,下面我们介绍一些重点掌握的接口

3.Member functions

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

3.1构造函数


3.2拷贝构造

cpp 复制代码
	vector<int> v3(v2);

	for (auto e : v3)
	{
		cout << e << " ";
	}
	cout << endl;

3.3赋值运算符重载

4.iterator

iterator的使用 接口说明
begin(重点) 获取第一个数据位置的iterator/const_iterator
end (重点) 获取最后一个数据的下一个位置的iterator/const_iterator
rbegin 获取最后一个数据位置的reverse_iterator
rend 获取第一个数据前一个位置的reverse_iterator
cpp 复制代码
void test2()
{
	//先拷贝构造函数的隐式类型转换,然后再走拷贝构造函数
	vector<int> v = {1,2,3,4,5,6,7,8,9,10};

	//iterator通用的访问方式
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

//范围for底层被替换成迭代器,这里不再叙述

到这里可能会觉得vector ,string看似相似;其实vector并不能替代string

1.接口不一样

2.string以\0结尾,vector不一定

3.如比较大小,vector不一定是字符

5.capacity

补充知识:

cpp 复制代码
int main()
{
	//请问这里i和k是说明结果呢?
	int i = int();
	int k = int(10);

	return 0;
}

发现内置类型,有了构造。这是因为有了模板之后,为了兼容模板,不知道T到底是自定义类型还是内置类型,如果是内置类型难道就报错吗?

所以有了模板之后,内置类型有了构造。

容量空间 接口说明
size 获取数据个数
capacity 获取容量大小
empty 判断是否为空
resize(重点) 改变vector的size
reserve (重点) 改变vector的capacity

看不懂上面的形参,可以参照下面的

cpp 复制代码
void test3()
{
	vector<int> v;
	//改变v的size大小,并且初始化
	v.resize(10);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}

这里就可以把刚才补充的知识点解释清楚,为什么要有内置类型构造?

不可能T都是自定义类型,T如果是内置类型就报错吗?

所以有了模板之后内置类型构造有了意义。

resize有三种情况

1.n<size

删除数据
2.size<n<capacity

插入数据
3.n>capacity

扩容+插入数据

cpp 复制代码
void test3()
{
	//测试vs下vector扩容机制
	size_t capacity = v.capacity();
	cout << "capacity:" << capacity << endl;
	for (int i = 0; i < 1000; ++i)
	{
		v.push_back(i);
		if (capacity != v.capacity())
		{
			capacity = v.capacity();
			cout << "capacity changed:" << capacity << endl;
		}
	}
}

我们知道频繁扩容,会有时间开销,如果我们提前知道要开辟空间大小,这样就减少了扩容的时间开销。

不同编译器扩容机制是不一样的。和string一样,在Linux下每次扩容2倍。

注意:

resize,reserve比当前容量小时,都不会缩容。

这里以时间换空间。

如何就想缩容,使用下面这个函数

把空间缩到size;

6.Element access

访问 接口说明
operator[] (重点) 像数组一样访问
cpp 复制代码
void test4()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	for (size_t i = 0; i < v.size(); ++i)
	{
		cout << v[i] << " ";
	}
	cout << endl;

}

const和非const函数在string详细说明,这里不再叙述。

这里其实有一个问题,如果不小心真的很容易犯错误。

v.[i]是报断言错误,v.at(i)抛异常。
所以这样的去访问一定要注意。

解决方法

pusk_back没有那种检查机制,就没问题。

设置size大小

7.增删查改

vector增删查改 接口说明
push_back(重点) 尾插
pop_back (重点) 尾删
find 查找。(注意这个是算法模块实现,不是vector的成员接口)
insert 在position之前插入val
erase 删除position位置的数据
swap 交换两个vector的数据空间

7.1增

push_back


push_back 不直接头插(需要挪动数据,效率低,建议少用)

insert




7.2删

pop_back

erase



7.3查

vector没有实现find成员函数,因为vector,list等等都是找到返回位置,所以算法库里实现了模板,可以使用。

cpp 复制代码
void test6()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);

	auto it = find(v.begin(), v.end(), 3);
	if (it != v.end())
	{
		v.insert(it, 30);
	}
}

7.4改

改的话就用迭代器+[ ]就可以了。

关于vector接口的使用就说到这里,下一篇来模拟实现vector。喜欢的点赞,评论,收藏加关注哦。

相关推荐
超浪的晨2 分钟前
Java List 集合详解:从基础到实战,掌握 Java 列表操作全貌
java·开发语言·后端·学习·个人开发
盛夏绽放4 分钟前
Excel导出实战:从入门到精通 - 构建专业级数据报表的完整指南
开发语言·javascript·excel·有问必答
我命由我123454 分钟前
嵌入式单片机开发 - HAL 库 STM32F1 外设的时钟使能(时钟使能宏、时钟禁用宏)
c语言·c++·stm32·单片机·嵌入式硬件·嵌入式·嵌入式软件
超浪的晨7 分钟前
Java Set 集合详解:从基础语法到实战应用,彻底掌握去重与唯一性集合
java·开发语言·后端·学习·个人开发
workflower23 分钟前
活动图描述场景
开发语言·软件工程·需求分析·软件需求·敏捷流程
梦想的初衷~25 分钟前
基于现代R语言【Tidyverse、Tidymodel】的机器学习方法
开发语言·机器学习·r语言
liliangcsdn25 分钟前
mac mlx大模型框架的安装和使用
java·前端·人工智能·python·macos
香蕉可乐荷包蛋28 分钟前
Python学习之路(十三)-常用函数的使用,及优化
开发语言·python·学习
chian-ocean32 分钟前
零基础入门:用C++从零实现TCP Socket网络小工具
网络·c++·tcp/ip
惜.己36 分钟前
使用python的读取xml文件,简单的处理成元组数组
xml·开发语言·python·测试工具