【C++】SLT——Vector详解

这篇具有很好参考价值的文章主要介绍了【C++】SLT——Vector详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本片要分享的是关于STL中Vector的内容,Vector的内容于string非常相似,只要会使用string那么学习Vector时会非常流畅。

目录

1.vector介绍 

2.vector的简单实用

2.1.简单的无参构造

 ​编辑2.2.简单带参构造

2.3.迭代器区间初始化

2.4.vector的遍历

2.5.vector插入数据

2.6.扩容机制 

不同平台扩容机制

reverse

resize


1.vector介绍 

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 官方的简介是vector是由一个动态增长数组实现的顺序容器,其实再简称一点就是顺序表。

以下是vector的组件

默认成员函数

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 迭代器

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

与容量相关的函数

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器 与访问数据相关的函数

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 与修改容器数据相关的

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 可以看到上面有我们在string中就接触过的一些函数,比如push_back,下标访问时的operator[],测量长度的size,等等

所以这也是我们学习vector比较容易的原因,同时vector在设计上也基于string有了一些改进,在内部函数的设计方面也更加合理了一些;

2.vector的简单实用

2.1.简单的无参构造

我们上代码来观察,先从最最简单的初始化构造来开始

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

如上是一个vector的无参构造 

 首先我们需要包含vector的头文件【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

其次我们在定义的时候需要将容器实例化, 就是规定我们的数据类型;

  2.2.简单带参构造

#include<iostream>
#include<vector>
using namespace std;
void test_vector1()
{
	vector<int> v1; 
	vector<int> v2(10,0); 
}
int main()
{

}

观察我们构造的v2,其中有两个参数,那这样的带参构造就是开辟是个空间,并且都初始化为0。

对比C语言我们不仅需要开一个数组,还需要memset,非常的麻烦;

2.3.迭代器区间初始化

#include<iostream>
#include<vector>
using namespace std;
void test_vector1()
{
	vector<int> v1; 
	vector<int> v2(10,0); 
	vector<int> v3(v2.begin(), v2.end());
 }
int main()
{
	test_vector1();
	return 0;
}

观察v3的初始化方式,我们使用了v2的迭代器的起始位置和末尾的位置

以上是相同容器的迭代器区间的初始化构造,那不同容器之间的初始化构造呢;

#include<iostream>
#include<vector>
using namespace std;
void test_vector1()
{
	vector<int> v1; 
	vector<int> v2(10,0); 
	vector<int> v3(v2.begin(), v2.end());
	string s("hello world");
	vector<int> v4(s.begin(), s.end());

 }
int main()
{
	test_vector1();
	return 0;
}

那当然也是可以的,可以看到我们在初始化v4的时候使用了字符串s的区间,也能完成初始化,但是我们需要注意的是这里的底层涉及到隐式类型转换,所以才能初始化成功。

2.4.vector的遍历

我们在上面的介绍中就可以看到vector读取数据时可以采用[],我们不妨将初始化后的v3进行遍历

void test_vector2()
{
	vector<int> v2(10, 0);
	vector<int> v3(v2.begin(), v2.end());
	for (size_t i = 0; i < v3.size(); i++)
	{
		cout << v3[i] << ' ';
	}
	cout << endl;
}
int main()
{
	test_vector2();
	return 0;
}

以下 是输出结果

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 可以看到我们使用v2迭代器区间初始化的v3输出的结果和我们想要的结果相同。

这里使用了for循环和[ ]对数据进行读取,还可以使用迭代器进行访问。

void test_vector2()
{
	vector<int> v2(10, 0);
	vector<int> v3(v2.begin(), v2.end());
	for (size_t i = 0; i < v3.size(); i++)
	{
		cout << v3[i] << ' ';
	}
	cout << endl;

	vector<int>::iterator it = v3.begin();
	while (it != v3.end())
	{
		cout << *it << ' ';
		++it;
	}
	cout << endl;
}

同样的我们首先要在vector类中声明并定义迭代器it,将v3的begin的位置给it,在while循环中依次将it解引用并输出,再对it进行++迭代,此时就完成了迭代器的遍历;

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 第一行的输出结果为for循环;第二行的结果为迭代器,他们都可以进行遍历;

在这里需要提醒大家的是迭代器中的begin或是end等等是指向数据的位置

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 所以这里我们可以将迭代器的功能理解为指针,遍历时将其解引用即可得到数据。

2.5.vector插入数据

如下是涉及到修改内容的函数

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

首先是尾插(push_back)

void test_vector8()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	for (auto e : v)
	{
		cout << e << ' ';
	}
	cout << endl;
}
int main()
{
	test_vector8();
	return 0;
}

 【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

结果不出所料,和我们在string中学到的插入方式相同;

同样的也有中间插入的方式insert, 

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

可以看到有很多种插入的方式,这里简单使用

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 可以看到在begin 的位置之前插入了0;

那如何在以上数据的3的前面插入想要的数呢?

auto it = find(v.begin(), v.end(), 3);
	if (it != v.end());
	{
		v.insert(it, 30);
	}
	for (auto e : v)
	{
		cout << e << ' ';
	}
	cout << endl;

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

这里我们就需要通过find来配合使用insert函数来查找并插入,结果如上;

2.6.扩容机制 

 

不同平台扩容机制

接下来是有关容量的函数

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器我们首先来研究vector的扩容机制;

在string中我们了解到可以插入很多数据时,系统会自动扩容,在vector中也同样如此;我们用代码来了解一下vector的扩容机制

void test_vector5()
{
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	for (size_t i = 0; i < 100; i++)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed" << sz << endl;
		}
	}
}

可以看到我我们在循环中给v插入数据,如果v的最大容量和插满数据时相同,系统就会自动扩容,此时我们再改变容量,并且标识出容量已经改变,那此时运行结果会是怎样呢?

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 我们可以看到大概是以原先容量的1.5倍进行扩容。

同样的代码我们在Linux系统下使用g++编译会有什么效果

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 可以看到对比vs环境下的1.5倍扩容,g++使用的是二倍扩容

reverse

其中还有reserve函数,他的作用是开辟空间,还是如上代码,我们使用reserve尝试一下

void test_vector6()
{
	size_t sz;
	vector<int> v;
	v.reserve(100);
	sz = v.capacity();
	for (size_t i = 0; i < 100; i++)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed" << sz << endl;
		}
	}
}

我们在它扩容之前使用reserve函数提前开好空间,运行结果如下

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 可以看到之前的扩容过程都不见了,原因是我们在扩容之前使用了reverse提前开了空间,将capacity修改成我们想要的,即可跳过在for循环中一边插入数据一边扩容的情况。

resize

resize不同于reserve的是,resize不仅可以改变capacity的大小,同时也可以改变size的大小,还是上段同样的代码,这里将reserve修改为resize来观察结果,

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器resize不仅可以修改容量的大小,还可以修改其本身的长度,这里的运行结果是在resize后的数据再进行插入,也就是说将两端数据接到一起。

还需要注意的一种情况如下

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

我们使用reserve直接开辟空间,然后直接去访问(利用for循环插入数据) reserve开辟的空间并打印是否可行呢?

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

结果是不行的,原因是这里访问v使用的是[ ],而在[ ]之前的模拟实现中,也就是它的底层逻辑是有assert断言的,条件是访问的下标必须小于size,而reserve只能修改capacity,不能修改size,所以就会报错。 

那使用resize即修改size也修改capacity会怎样呢?

【C++】SLT——Vector详解,c++,算法,开发语言,vector,容器

 可以看到这样操作就很丝滑了。

以上就是本次要分享的内容,在vector中还有一些不常用的函数在这里没有深入分析到,还请感兴趣的同学们自行尝试,如果对你有所帮助还请多多三连支持,感谢您的阅读。文章来源地址https://www.toymoban.com/news/detail-685352.html

到了这里,关于【C++】SLT——Vector详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Day 23 C++ vector容器

    定义 C++的vector容器是一个动态数组,提供了存储和操作元素的功能。它是标准模板库(STL)的一部分,在头文件中定义。 vector数据结构和 数组非常相似 ,也称为 单端数组 ( 动态数组 )( 也被称为向量 ) 使用vector容器前,需要引入头文件: vector容器的迭代器——支持随

    2024年02月14日
    浏览(23)
  • 【C++第三阶段】vector容器

    以下内容仅为当前认识,可能有不足之处,欢迎讨论! vector函数是常用数据结构,见于刷题网站。 它是单端数组,与普通数组区别在于可以动态扩展。 动态扩展是编译器自动的,不是在原空间之后续接新空间,而是找更大的内存空间,将原数据拷贝新空间,释放原空间。

    2024年04月10日
    浏览(31)
  • C++ —— STL容器【vector】模拟实现

    本章代码gitee仓库:vector模拟实现、vector源码 看源码发现 vector 是类模板定义的,成员是采用迭代器进行管理 当涉及到容器类时,通常有一些关键函数,如构造函数、析构函数和拷贝构造函数,它们负责初始化容器对象、销毁对象和进行对象的拷贝等 这里注意拷贝构造要实现

    2024年02月16日
    浏览(34)
  • C++提高编程——STL:string容器、vector容器

    本专栏记录C++学习过程包括C++基础以及数据结构和算法,其中第一部分计划时间一个月,主要跟着黑马视频教程,学习路线如下, 不定时更新,欢迎关注 。 当前章节处于: ---------第1阶段-C++基础入门 ---------第2阶段实战-通讯录管理系统, ---------第3阶段-C++核心编程, -----

    2024年01月23日
    浏览(34)
  • 【C++庖丁解牛】STL之vector容器的介绍及使用 | vector迭代器的使用 | vector空间增长问题

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 vector的文档介绍 vector是表示可变大小数组的序列容器。 就像数组一样,vector也采用的连续存储空间来存

    2024年03月14日
    浏览(62)
  • 详解c++STL—容器vector

    功能: vector数据结构和 数组非常相似 ,也称为 单端数组 vector与普通数组的区别: 不同之处在于数组是静态空间,而vector可以 动态扩展 动态扩展: 并不是在原空间之后续接新空间,而是 找更大的内存空间,将原数据拷贝到新空间,释放原空间 功能描述: 创建vector容器

    2024年02月05日
    浏览(31)
  • C++容器(vector、deque、list、map)

    数组尾部添加或删除元素非常迅速。但在中部或头部就比较费时。 *代码演示:* 取: at在下标越界时会抛出异常,我们能捕获异常进行处理;而[]下标越界会让程序直接终止; 构造函数: cbegin, cend, crbegin, crend返回的是常量迭代器,不能通过迭代器修改vector元素的值。 插入(

    2024年02月02日
    浏览(43)
  • C++ stl容器vector的底层模拟实现

    目录 前言:   1.成员变量,容量与大小 2.构造函数 无参构造: 带参的使用值进行构造:  使用迭代器区间进行构造: 3.交换 4.拷贝构造 5.赋值重载 6.迭代器 7.扩容 reserve: resize: 8.插入与删除 insert: erase: insert迭代器失效问题: erase迭代器失效问题: 9.头插头删 10.[]重载

    2024年04月15日
    浏览(31)
  • 【C++】:C++中的STL序列式容器vector源码剖析

    vector定于与stl_vector.h头文件中 例如: vector的数据结构非常简单:一个线性连续空间 下面介绍vector的3个数据结构: start:表示目前使用空间的头 finish:表示目前使用空间的尾 end_of_storage:表示目前可用空间的尾 说明:为了降低空间配置时的速度成本,vector实际配置的大小可

    2024年01月22日
    浏览(36)
  • 【C++】容器篇(一)—— vector 的基本概述以及模拟实现

    前言: 在之前,我们已经对 string类进行了基本的概述,并且手动的实现了string类中常用的接口函数。本期,我将带领大家学习的是STL库中的一个容器 -- vector 的学习。相比于之前的string类,本期的 vector 相对来说实现起来略微难一点,难点就在于要考虑关于 “ 迭代器失效 ”

    2024年02月07日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包