【C++】vector的使用

news/2024/4/24 17:40:19/

文章目录

  • 1. 主要结构
  • 2. 构造函数与复制重载
  • 3. 迭代器
  • 4. 容量相关
    • 1.容量读取
    • 2.容量修改
  • 5. 数据访问
  • 6. 数据修改
    • 1. 尾插尾删
    • 2.任意位置的插入删除
  • 7.其他接口

在之前我们学习了string的使用与模拟实现,在参考文档中可以发现,vector和string以及其他的容器的接口基本都相同,所以这里也就简要的介绍一下。

同样的,在这里还是要说一下,对于STL库的学习,不可能在一朝一夕之间学完,要学会去查看文档和多练习vector参考文档

1. 主要结构

image-20230418154326704

vector没有像string一样进行类型重定义typedef basic_string<char> string,所以在使用vector的时候要指定模板参数类型例如vector<int>

2. 构造函数与复制重载

image-20230418160501765

可以看到vector的构造函数实现相较于string就简化了很多,一共分为四个,分别是默认构造,指定长度和值的构造,迭代器区间构造,拷贝构造

void Test_Construct()
{vector<int> v1;//默认构造vector<int> v2(10, 3);//指定长度和值的构造string s("aaaaaaaaaaaaaa");vector<char> v3(s.begin(), s.end());//迭代器区间构造vector<char> v4(v3);//拷贝构造
}

image-20230418213255290

通过监视查看四个对象的值如上。

3. 迭代器

由于vector也是通过动态数组实现的,所以原生指针就能很好的支持迭代器行为,所以在vector中的迭代器本质也是指针。

image-20230419080950623

可以看到和string一样,vector的迭代器也分为普通迭代器,反向迭代器,const迭代器,const反向迭代器。

image-20230419081331230

对于迭代器和反向迭代器的工作方式如上图。

4. 容量相关

1.容量读取

1. size

image-20230419081458467

返回一个size_t类型的vector中数据个数

2. capacity

image-20230419081623104

返回一个size_t类型的vector的容量。

使用范例:

void Test_Capacity()
{vector<int> v;v.reserve(10);for (size_t i = 0; i < 5; ++i){v.push_back(i);}cout << "size:" << v.size() << endl;cout << "capacity:" << v.capacity() << endl;
}

运行结果为:

image-20230419082018970

2.容量修改

1. reserve

image-20230419082143747

扩大vector的容量到n,如果原来vector的容量大于等于n,不做任何操作

void Test_Capacity2()
{vector<int> v(5, 1);cout << "before reserve capacity:" << v.capacity() << endl;v.reserve(10);cout << "after reserve capacity:" << v.capacity() << endl;
}

image-20230419082505632

2. resize

image-20230419082619237

修改vector中的数据个数,如果n小于size,那就修改size;如果n大于size但是小于capacity,那就尾插数据直到size==n,如果n大于capacity,那就先扩容到n,再填充数据。

void Test_Capacity3()
{vector<int> v(5, 1);cout << "before resize capacity:" << v.size() << endl;v.resize(10);cout << "after resize capacity:" << v.size() << endl;for (auto e : v){cout << e << " ";}cout << endl;
}

image-20230419083020574

5. 数据访问

与string类似,在数据访问中也有很多接口,但是最常用的还是[]的重载,其余基本不常用,这里我们就不过多赘述

image-20230419083205192

[]实际上是一个运算符重载,使vector也具有类似下标访问的能力,返回值是vector中存放元素类型的引用

对于[]的重载,在库里面支持了两种重载,分别是普通类型的和const类型的用于支持多样化的使用环境

怎么判断需要实现const或者非const版本?

  1. 对于只读接口,只实现const版本即可
  2. 对于只写接口,只实现非const版本即可
  3. 对于可读可写的接口,需要同时实现const版本和非const版本
void Test_Access()
{vector<int> v(10);for (size_t i = 0; i < v.size(); ++i){v[i] = i;}for (size_t i = 0; i < v.size(); ++i){cout << v[i] << " ";}cout << endl;
}

image-20230419083716301

6. 数据修改

1. 尾插尾删

1. push_back

image-20230419085534437

尾插数据,插入前会进行扩容操作,每次扩容的大小取决于编译器的实现

2. pop_back

image-20230419085728462

如果vector中有数据的话,尾删一个数据,否则会由assert中断程序或者抛出异常,具体情况取决于编译器的实现

void Test_Modifity()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);v.pop_back();v.pop_back();v.pop_back();v.pop_back();v.pop_back();v.pop_back();
}

image-20230419090506991

2.任意位置的插入删除

1. insert

image-20230419090827948

在传入的任意位置插入一个数据或者迭代器区间的数据

2. erase

image-20230419091215741

删除任意位置的值或者任意一个迭代器区间的值

void Test_Modifity2()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);v.insert(v.begin() + 3, 30);v.erase(v.begin());for (auto e : v){cout << e << " ";}cout << endl;
}

image-20230419092501957

这里注意一下,vector中会出现迭代器失效的问题

❗❗==vector中的迭代器失效问题==❗❗

第一个问题:迭代器的出现原因是什么?

迭代器的设计模式,为了不暴露底层实现细节,提供统一的方式来访问容器,对于vector,其迭代器本质上就是原生指针T*,所以对vector来说,迭代器失效的原因就是原迭代器指向的空间被销毁,导致出现野指针。

第二个问题:导致迭代器失效的操作有哪些?

✅迭代器失效的原理是底层空间改变,导致产生野指针,所以所有的底层空间的改变都有可能使迭代器失效,例如:reserve,resize,push_back,insert等。

✅除了对底层空间的改变之外,erase也会导致迭代器失效。

第三个问题:按照我们上一个问题的逻辑,erase没有使底层空间发生改变啊,为什么也会使迭代器失效?

✅虽然erase没有改变底层空间,但是,如果erase删除的是vector中最后一个元素,刚好删除完之后pos位置是end指向的位置,那么迭代器就失效了。

✅就算删除的不是最后一个元素,那么迭代器指向的位置的值也是改变了的,严格意义上来说,也是不能实现我们所需要的功能的,所以也可以认为是迭代器失效了。

第四个问题:只有vector会遇到迭代器失效的的情况吗,string有没有迭代器失效的情况?

✅不只是vector有,string和其他的容器都有迭代器失效的情况。

第五个问题:迭代器失效的问题怎么解决呢?

✅在上文中,我们讲解了vector的主要接口,可以注意到,能够引起迭代器失效的接口函数的返回值都是迭代器,这里返回的迭代器就是我们所需要的有效的迭代器。所以,在使用前对迭代器进行重新赋值即可解决

//关于迭代器失效解决的例题:
//对于使用vector存储的数组{0,1,2,3,4,5,6,7,8,9},删除其中所有的偶数元素
int main()
{vector<int> v(10);for (size_t i = 0; i < 10; ++i){v[i] = i;}vector<int>::iterator it = v.begin();while (it != v.end()){if (*it % 2 == 0){it = v.erase(it);}else{++it;}}for (auto e : v){cout << e << " ";}cout << endl;return 0;
}

7.其他接口

1. clear

image-20230419092648474

删除vector内部所有数据(本质上做的操作就是将vector的size置为0)

2. swap

image-20230419092900368

vector内部实现的一个交换函数,提升效率。


http://www.ppmy.cn/news/48100.html

相关文章

ElasticJob

官网 :: ElasticJob ElasticJob 是面向互联网生态和海量任务的分布式调度解决方案&#xff0c;由两个相互独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成。 它通过弹性调度、资源管控、以及作业治理的功能&#xff0c;打造一个适用于互联网场景的分布式调度解决方案&…

​破除“内卷”,什么才是高阶智能座舱更优方案?

下一代智能座舱雏形已现。 从多屏互动到舱内全场景交互&#xff0c;从中控娱乐快速延伸到更多元化的车内娱乐平台&#xff1b;越来越多元化功能集中上车&#xff0c;座舱空间的营造&#xff08;包括氛围灯、香氛等&#xff09;以及AR技术的应用等等&#xff0c;开始深刻影响着…

[渗透测试笔记] 56.日薪2k的蓝队hw中级定级必备笔记系列篇4之面试必备web中间件漏洞汇总

文章目录 1.Weblogic1.1 任意文件上传漏洞(CVE-2018-2894)1.2 XML远程代码执行RCE漏洞(CVE-2020-14882)1.3 SSRF漏洞(CVE-2014-4210)1.4 Java反序列化漏洞(CVE-2018-2628)2.Nginx2.1 解析漏洞2.2 Nginx文件名逻辑漏洞(CVE-2013-4547)2.3 Nginx越界读取缓存漏洞(CVE-2017-752…

代码随想录刷题笔记2

文章目录 二叉树递归遍历统一迭代形式层序遍历迭代形式——队列 题型删除普通二叉树目标节点两棵树比较 递归模板深度、高度问题完全二叉树判断完全二叉树 平衡二叉树左叶子最大树二叉搜索树最近公共祖先 二叉树 递归遍历 递归三部曲 确定递归函数的 参数 与 返回值。确定终止…

【Vue全家桶】Pinia状态管理

【Vue全家桶】Pinia状态管理 文章目录 【Vue全家桶】Pinia状态管理写在前面一、认识Pinia1.1 认识Pinia1.2 为什么使用Pinia&#xff1f; 二、 Store2.1 定义Store2.2 Option对象2.3 setup函数2.4 使用定义的Store 三、Pinia核心概念State3.1 定义State3.2 操作State3.3 使用选…

为何MySQL 8.0开始取消了查询缓存

官方文档说明&#xff1a;MySQL :: MySQL 8.0: Retiring Support for the Query Cache MySQL查询缓存是查询结果缓存。它将以SEL开头的查询与哈希表进行比较&#xff0c;如果匹配&#xff0c;则返回上一次查询的结果。 进行匹配时&#xff0c;查询必须逐字节匹配&#xff0c;例…

Android:usb转232串口通信

准备工作 首先得adb进入盒子root模式&#xff0c;将/dev/ttys1这个文件改为777&#xff0c;使得所有用户可操作 adb root adb remount adb shell 进入设备的root模式&#xff0c;执行 chmod 777 /dev/ttys1 执行完成后退出 exit 再执行 adb shell chmod 666 /dev/ttyS1 如…

比较运算符、关键字子查询MySQL数据库 (头歌实践教学平台)

文章目的初衷是希望学习笔记分享给更多的伙伴&#xff0c;并无盈利目的&#xff0c;尊重版权&#xff0c;如有侵犯&#xff0c;请官方工作人员联系博主谢谢。 目录 第1关&#xff1a;带比较运算符的子查询 任务描述 相关知识 子查询 带比较运算符的子查询 编程要求 第2关…

第二章 法的内容与形式

目录 第一节 法的内容与形式的概念 一、法的内容与形式的含义 二、法的内容和形式的关系 第二节 法律权利与法律义务 一、权利和义务的概念 二、权利和义务的分类 三、权利与义务的联系 第三节 法的成文形式与不成文形式 一、历史上各种法的表现形式 二、成文法与不成文…

Vue中组件传值

Vue官网链接-向子组件传递数据 Vue官网-Prop 父组件将值传递给子组件 父组件中的值可以通过v-bind与子组件中的props属性将值传递给子组件&#xff0c;也可以通过v-on与this.$emit()间接被子组件中的函数调用 1、使用v-bind将父组件中data中的键与子组件中的props键进行绑定 …

【SpringBoot】一:SpringBoot的基础(下)

文章目录 1.外部化的配置1.1 配置文件基础1.1.1 配置文件格式1.1.2 application文件1.1.3 application.properties1.1.4 application.yml1.1.5 environment1.1.6 组织多文件1.1.7多环境配置 1.2 绑定Bean1.2.1 简单的属性绑定1.2.2 嵌套Bean1.2.3 扫描注解1.2.4 处理第三方库对…

Vue中mixins(混入)的介绍和使用

什么是Mixin&#xff1f; 想要使用一个事物或者工具&#xff0c;我们首要先了解它是什么&#xff0c;这样我们才好对症下药。 其实Mixin不是Vue专属的&#xff0c;可以说它是一种思想&#xff0c;也可以说它就是混入的意思&#xff0c;在很多开发框架中都实现了Mixin(混入)&a…

异常(throwable)

异常 异常分类 &#xff08;1&#xff09;Throwable类 所有的异常类型都是它的子类&#xff0c;它派生两个子类Error、Exception。 &#xff08;2&#xff09;Error类 表示仅靠程序本身无法恢复的严重错误&#xff08;内存溢出动态链接失败、虚拟机错误&#xff09;&#…

Seata强一致性事务模式XA的设计理念

承接上文分布式事务Seata-AT模式 XA规范是什么? 是分布式事务处理DTP&#xff08;Distributed Transaction Processing&#xff09;的标准。是描述全局的事务管理器和局部的资源管理器之间的接口规范。允许多个资源&#xff08;如数据库、应用服务、消息队列&#xff09;在同…

class与typename的异同

一、class与typename的相同点 typename关键字常用于函数模板&#xff0c;这里首先引入函数模板的概念&#xff1a;函数模板代表了一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用时被参数化&#xff0c;根据实参类型产生函数的特定 类型版本 //函数模板格式…

idea 配置docker 进行上传镜像,部署启动容器

前言 在我们开发测试过程中&#xff0c;需要频繁的更新docker镜像&#xff0c;然而默认情况下&#xff0c;docker的2375端口是关闭的&#xff0c;下面介绍如何打开端口。 修改docker配置文件 操作步骤&#xff1a; 1.1、修改配置 登录docker所在服务器&#xff0c;修改docker…

深入浅出剖析JAVA多线程原理

1. 线程基础知识 1.1 线程与进程 1.1.1 进程 ●程序由指令和数据组成&#xff0c;但这些指令要运行&#xff0c;数据要读写&#xff0c;就必须将指令加载至 CPU&#xff0c;数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理…

聚观早报|马斯克将TruthGPT挑战ChatGPT;腾讯披露自研芯片新进展

今日要闻&#xff1a;马斯克将TruthGPT挑战ChatGPT&#xff1b;苹果在印度年销售额近60亿美元&#xff1b;腾讯披露自研芯片沧海最新进展&#xff1b;特斯拉中国工厂普通工人月薪约1万元&#xff1b;飞猪将直接向阿里CEO张勇汇报 马斯克将TruthGPT挑战ChatGPT 4 月 18 日消息&…

【大厂直通车】哔哩哔哩日常实习_测开面经

📑哈喽,大家好,我是小浪;本篇博客更新的是最新B站测开面经,本专栏非常适合目前准备找实习,或者准备冲秋招测试,测开方向的同学阅读订阅,持续更新各大厂真题面经,带你成为offer收割机!! 🧃对于订阅本专栏的同学们,博主在努力更新,只需要一杯奶茶钱,订阅本专栏,…

数据结构(三)—— 哈希表

文章目录 一、哈希表积累1.1 哈希map1.2 哈希set 二、哈希表基础三、题3.1 242 有效的字母异位词3.2 349 两个数组的交集3.3 202 快乐数3.4 1 两数之和3.5 54 四数相加II 一、哈希表积累 什么时候想到用哈希法&#xff1a;当要需要查询一个元素是否出现过、判断一个元素是否出…