C++ 【STL容器系列(一)】vector的使用

1.介绍

vector是STL中的容器之一( STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。),STL的容器有非常多,但是他们的使用都是一样了,所以在后续学习STL的时候,使用部分就不会再讲解了。

因为讲完vector的使用就等于讲了所有容器的使用方式(STL的容器有:vector,list,deque,map,set等等)
在这里插入图片描述

2. vector的使用

vector是代表数组的序列容器,并且可以改变数组大小。

vector学习时一定要学会查看文档:vector的文档介绍,vector在实际中非常的重要,在实际中我们熟悉常见的接口就可以,下面列出了哪些接口是要重点掌握的

2.1 vector的定义

(Construct)构造函数接口说明
vector()无参构造
vector (size_type n, const value_type& val = value_type())构造并且用n个val初始化
vector(const vector& x)(重点)拷贝构造
vector (InputIterator first, InputIterator last)用迭代器来初始化构造
vector (initializer_list<value_type> il)列表初始化构造(C++11引入)

为了方便观察,我们先定义一个打印函数,这个函数用范围for实现,这个函数会在后面讲解中频繁使用。

//使用模板来实现,因为vector本身也是一个模板类
template<class T>
void print_vector(const vector<T>& v)
{
//利用范围for来打印vfor (auto& e : v){cout << e << ' ';}cout << endl;
}

测试代码:

void test_vector1()
{vector<int> v1;									// 无参构造cout << "v1:";print_vector(v1);vector<int> v2(10, 1);							// 用n个val初始化构造cout << "v2:";print_vector(v2);vector<int> v3(v2);								// 拷贝构造cout << "v3:";print_vector(v3);vector<int> v4(v2.begin() + 2, v2.end() - 3);   // 迭代器构造cout << "v4:";print_vector(v4);vector<int> v5{ 1,2,3,4,5 };					// 列表构造cout << "v5:";print_vector(v5);
}

在这里插入图片描述

2.2 vector iterator 的使用

iterator的使用接口说明
begin + end (重点)begin:获取第一个元素位置的iterator / const_iterator;end:获取最后一个元素位置的iterator / const_iterator
rbegin + rendrbegin:获取最后一个元素位置的reverse_iterator / const_reverse_iterator ;rend:获取第一个元素位置的reverse_iterator / const_reverse_iterator

在这里插入图片描述
测试代码:

void test_vector2()
{vector<int> v{1,2,3,4,5};cout << "正着打印:";for (vector<int>::iterator it = v.begin(); it != v.end(); ++it){cout << *it << ' ';}cout << endl;cout << "倒着打印:";for (vector<int>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit){cout << *rit << ' ';}cout << endl;
}

在这里插入图片描述

2.3 vector 空间函数

容量空间接口说明
size获取元素个数
capacity获取容量大小
empty判断是否为空
resize改变vector的size
reserve改变vector的capacity
  • capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
  • reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。

reserve的使用和string的reserve是一样的,在vs环境下只扩容不缩容

  • resize在开空间的同时还会进行初始化,影响size。

resize如果小于原来的size,会缩容,如果大于原来的size,会增加元素(如果给了增加的元素,多出来的空间会用给的元素填充,如果没给,那就要默认值填充)

测试代码:

void test_vector3()
{vector<int> v1(10,1);//cout << v1.max_size() << endl;cout << v1.size() << endl;cout << v1.capacity() << endl <<endl;//reservev1.reserve(15);cout << v1.size() << endl;cout << v1.capacity() << endl << endl;v1.reserve(12);cout << v1.size() << endl;cout << v1.capacity() << endl << endl;v1.reserve(5);cout << v1.size() << endl;cout << v1.capacity() << endl << endl;//resizev1.resize(20);cout << "v1.resize(20):";print_vector(v1);cout << endl;cout << v1.size() << endl;cout << v1.capacity() << endl << endl;v1.resize(30,3);cout << "v1.resize(30):";print_vector(v1);cout << endl;cout << v1.size() << endl; cout << v1.capacity() << endl << endl;v1.resize(5);cout << "v1.resize(5):";print_vector(v1);cout << endl;cout << v1.size() << endl;cout << v1.capacity() << endl << endl;
}

2.4 vector的增删查改

vector的增删查改接口说明
push_back尾插
pop_back尾删
find查找(注意:这个函数是算法模块实现,不是vector的成员接口)
insert在position之前插入val
erase删除position位置的数据
swap交换两个vector的数据
operator[]像数组一样访问

所有需要指定位置的函数的位置参数只支持迭代器。

测试代码:

void test_vector4()
{vector<int> v1(10, 1);v1.push_back(2);cout << "v1.push_back(2)" << endl;cout << "v1:";print_vector(v1);cout << endl;v1.pop_back();cout << "v1.pop_back()" << endl;cout << "v1:";print_vector(v1);cout << endl;v1.insert(v1.begin(), 0);cout << "v1.insert(v1.begin(), 0)" << endl;cout << "v1:";print_vector(v1);cout << endl;v1.insert(v1.begin() + 3, 2, 3);cout << "v1.insert(v1.begin() + 3, 2, 3)" << endl;cout << "v1:";print_vector(v1);cout << endl;v1.erase(v1.begin());cout << "v1.erase(v1.begin())" << endl;cout << "v1:";print_vector(v1);cout << endl;v1.erase(v1.begin(), v1.end() - 5);cout << "v1.erase(v1.begin(), v1.end() - 5)" << endl;cout << "v1:";print_vector(v1);cout << endl;v1.clear();cout << "v1.clear()" << endl;cout << "v1:";print_vector(v1);cout << endl;vector<int>v2(3, 3);v1.swap(v2);cout <<"v1.swap(v2)" << endl;cout << "v1:";print_vector(v1);cout << endl;cout << "v2:";print_vector(v2);cout << endl;
}

在这里插入图片描述

2.5 vector 迭代器失效(重点)

迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如:vector的迭代器就是原生态指针T* 。因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)。

对vector可能会导致迭代器失效的操作有:

  1. 会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、assign、push_back等。
void test_vector5()
{vector<int> v{ 1,2,3,4,5,6 };auto it = v.begin();将有效元素个数增加到100个,多出的位置使用8填充,操作期间底层会扩容// v.resize(100, 8);reserve的作用就是改变扩容大小但不改变有效元素个数,操作期间可能会引起底层容量改变// v.reserve(100);插入元素期间,可能会引起扩容,而导致原空间被释放// v.insert(v.begin(), 0);// v.push_back(8);给vector重新赋值,可能会引起底层容量改变v.assign(100, 8);while (it != v.end()){cout << *it << " ";++it;}cout << endl;
}

出错原因:以上操作,都有可能会导致vector扩容,也就是说vector底层原理旧空间被释放掉,而在打印时,it还使用的是释放之间的旧空间,在对it迭代器操作时,实际操作的是一块已经被释放的空间,而引起代码运行时崩溃

解决方式:在以上操作完成之后,如果想要继续通过迭代器操作vector中的元素,只需给it重新赋值即可。

  1. 指定位置元素的删除操作–erase
void test_vector6()
{int a[] = { 1, 2, 3, 4 };vector<int> v(a, a + sizeof(a) / sizeof(int));// 使用find查找3所在位置的iteratorvector<int>::iterator pos = find(v.begin(), v.end(), 3);// 删除pos位置的数据,导致pos迭代器失效。v.erase(pos);cout << *pos << endl; // 此处会导致非法访问
}

erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了。

3. 结语

vector的使用还是比较简单的,学会使用vector就相当于会使用STL的所有容器了。

那么这次的分享就到这里结束了~
最后感谢您能阅读完此片文章~
如果您认为这篇文章对你有帮助的话,可以用你们的手点一个免费的赞并收藏起来哟~
如果有任何建议或纠正欢迎在评论区留言~
也可以前往我的主页看更多好文哦(点击此处跳转到主页)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/468541.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习5_支持向量机_原问题和对偶问题——MOOC

目录 原问题与对偶问题的定义 定义该原问题的对偶问题如下 在定义了函数 的基础上&#xff0c;对偶问题如下&#xff1a; 综合原问题和对偶问题的定义得到&#xff1a; 定理一 对偶差距&#xff08;Duality Gap&#xff09; 强对偶定理&#xff08;Strong Duality Theo…

华为eNSP:mux-vlan

一、什么是mux-vlan&#xff1f; Mux-vlan 是一种多路复用的虚拟局域网&#xff08;Virtual Local Area Network&#xff09;技术。它将多个不同的VLAN流量转发到同一个物理端口&#xff0c;从而实现VLAN间的互通。 在传统的以太网环境中&#xff0c;每个VLAN通常都有一个独立…

YOLOPv2论文翻译

YOLOPv2: Better, Faster, Stronger for Panoptic Driving Perception 摘要 在过去的十年中&#xff0c;多任务学习方法在解决全景驾驶感知问题方面取得了令人鼓舞的成果&#xff0c;既提供了高精度又具备高效能的性能。在设计用于实时实际自动驾驶系统的网络时&#xff0c;这…

【C/C++】memcpy函数的使用

零.导言 当我们学习了strcpy和strncpy函数后&#xff0c;也许会疑惑整形数组要如何拷贝&#xff0c;而今天我将讲解的memcpy函数便可以拷贝整形数组。 一.memcpy函数的使用 memcpy函数是一种C语言内存函数&#xff0c;可以按字节拷贝任意类型的数组&#xff0c;比如整形数组。 …

Matlab轻松烟雾检测

小编经验分享&#xff1a;如何使用Matlab进行烟雾检测 烟雾检测是一项重要的安全技术&#xff0c;它可以帮助我们及时发现火灾风险并采取相应的措施。在这篇文章中&#xff0c;小编将和大家分享如何使用Matlab进行烟雾检测的经验。希望这些经验对大家在实际应用中能够有所帮助…

【Linux系统编程】基础IO--内存文件

目录 前言&#xff1a; stdin&& stdout && stderr Linux文件操作之系统调用 打开文件 关闭文件 写入文件 读取文件 文件描述符fd fd的分配规则与重定向原理 理解用户级缓冲区 前言&#xff1a; 在往期博客《Linux基础概念》中&#xff0c;我们聊…

Python urllib

Python urllib 库用于操作网页 URL&#xff0c;并对网页的内容进行抓取处理。 本文主要介绍 Python3 的 urllib。 urllib 包 包含以下几个模块&#xff1a; urllib.request - 打开和读取 URL。urllib.error - 包含 urllib.request 抛出的异常。urllib.parse - 解析 URL。url…

数据结构 —— 红黑树

目录 1. 初识红黑树 1.1 红黑树的概念 1.2 红⿊树的规则 1.3 红黑树如何确保最长路径不超过最短路径的2倍 1.4 红黑树的效率:O(logN) 2. 红黑树的实现 2.1 红黑树的基础结构框架 2.2 红黑树的插⼊ 2.2.1 情况1&#xff1a;变色 2.2.2 情况2&#xff1a;单旋变色 2.2…

丹摩征文活动|AIGC实践-基于丹摩算力和CogVideoX-2b实现文生视频

一、CogVideoX简介 CogVideoX 是由智谱AI开源的新一代视频生成模型&#xff0c;属于大型语言模型在多模态应用中的重要突破。CogVideoX-2b 版本在参数规模和推理速度上进行了优化&#xff0c;支持视频从文本描述生成&#xff0c;并进一步提升了视频的分辨率和流畅度。相比于上…

麦当劳自助点餐机——实现

餐厅自助点餐优点 1. 降低服务成本&#xff1a; - 减少了对服务员数量的需求&#xff0c;降低了人力成本。 - 减轻了服务员的工作负担&#xff0c;使其能够更专注于提供优质的服务&#xff0c;如解决顾客的特殊需求和处理复杂问题。 2. 提升点餐效率和准确性&#xf…

Linux【基础篇】T

如何安装Linux操作系统&#xff1f; 1.直接把笔记本的Windows干掉&#xff0c;单独安装Linux系统&#xff08;初学者对于Linux使用还是比较苦难&#xff09;。 2.可以安装双系统&#xff08;开机也是命令行&#xff09;&#xff0c;电脑配置要高。 3.可以安装虚拟机。 --如果…

Linux操作系统之软件安装与包管理器工具

一、实验目的 1、掌握常用的软件包管理器RPM、YUM的使用&#xff1b; 2、掌握内网YUM源的配置方法。 二、实验环境 1台PC、VMware虚拟机、2个CentOS7操作系统 三、实验步骤及内容 1、使用RPM软件包管理器安装软件 (1)从阿里云https://mirrors.aliyun.com/下载CentOS7操作…

贯穿式学习MySQL

注&#xff1a;MySQL版本众多&#xff0c;本次讲述的内容以MySQL8.0.34版本为准 范式化设计 范式具体是用来干嘛的&#xff1f; 我们在设计关系数据库时&#xff0c;要遵从不同的规范要求&#xff0c;设计出合理的关系型数据库&#xff0c;这些不同的规范要求被称为不同的范式…

web——[SUCTF 2019]EasySQL1——堆叠注入

这个题主要是讲述了堆叠注入的用法&#xff0c;来复现一下 什么是堆叠注入 堆叠注入&#xff1a;将多条SQL语句放在一起&#xff0c;并用分号;隔开。 1.查看数据库的名称 查看数据库名称 1;show databases; 发现有名称为ctftraining的数据库 2.对表进行查询 1;show tabl…

「Mac畅玩鸿蒙与硬件31」UI互动应用篇8 - 自定义评分星级组件

本篇将带你实现一个自定义评分星级组件&#xff0c;用户可以通过点击星星进行评分&#xff0c;并实时显示评分结果。为了让界面更具吸引力&#xff0c;我们还将添加一只小猫图片作为评分的背景装饰。 关键词 UI互动应用评分系统自定义星级组件状态管理用户交互 一、功能说明 …

发布 VectorTraits v3.0(支持 X86架构的Avx512系列指令集,支持 Wasm架构及PackedSimd指令集等)

文章目录 支持 X86架构的Avx512系列指令集支持Avx512时的输出信息 支持 Wasm架构及PackedSimd指令集支持PackedSimd时的输出信息VectorTraits.Benchmarks.Wasm 使用说明 新增了向量方法支持 .NET 8.0 新增的向量方法提供交织与解交织的向量方法YGroup3Unzip的范例代码 提供重新…

分布式数据库中间件mycat

MyCat MyCat是一个开源的分布式数据库系统&#xff0c;它实现了MySQL协议&#xff0c;可以作为数据库代理使用。 MyCat(中间件)的核心功能是分库分表&#xff0c;即将一个大表水平分割为多个小表&#xff0c;存储在后端的MySQL服务器或其他数据库中。 它不仅支持MySQL&#xff…

操作系统学习笔记-3.2虚拟内存

文章目录 虚拟内存请求分页管理方式页面置换算法最佳置换算法工作原理OPT 算法的示例最佳置换算法的优点和缺点 先进先出置换算法最近最久未使用时钟置换算法时钟置换算法的工作原理&#xff1a;算法的步骤&#xff1a; 改进型时钟置换算法改进型时钟置换算法的特点&#xff1a…

【计网】物理层学习笔记

【计网】物理层 物理层概述 物理层要实现的功能 在各种传输媒体上传输比特0和1&#xff0c;进而为上面的数据链路层提供透明传输比特流的作用。 物理层接口特性 物理层之下的传输媒体 传输媒体是计网设备之间的物理通路&#xff0c;也称为传输介质。 传输媒体并不包含在…

python机器人Agent编程——实现一个本地大模型和爬虫结合的手机号归属地天气查询Agent

目录 一、前言二、准备工作三、Agent结构四、python模块实现4.1 实现手机号归属地查询工具4.2实现天气查询工具4.3定义创建Agent主体4.4创建聊天界面 五、小结PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源ps3.wifi小车控制相关…