C++必修:STL之vector的了解与使用
✨✨ 欢迎大家来到贝蒂大讲堂✨✨
🎈🎈养成好习惯,先赞后看哦~🎈🎈
所属专栏:C++学习
贝蒂的主页:Betty’s blog
1. C/C++中的数组
1.1. C语言中的数组
在 C 语言中,数组是一组相同类型元素的有序集合。与字符串类似,它的大小在编译时就已经确定,不可更改。
//大小为5的整型数组
int arr1[5] = { 1,2,3,4,5 };
//大小为5的浮点型数组
double arr2[5] = {0.0};
1.2. C++中的数组
同样与string
类似,C++为了更加方便就引入了一个支持可动态大小数组的序列容器vecotr
。其特点如下:
vector
是可变大小的序列容器,采用连续存储空间存储元素,可通过下标高效访问。- 与数组不同,
vector
大小可动态改变,由容器自动处理。vector
本质上用动态分配数组存储元素,插入新元素时可能重新分配空间,即分配新数组并移动全部元素,此操作时间代价高,但不是每次插入都重新分配。vector
会分配额外空间适应增长,不同库策略不同,但重新分配通常是对数增长间隔,使末尾插入元素能在常数时间完成。- 与
deque
、list
和forward_list
相比,vector
访问元素及末尾添加和删除元素更高效,非末尾的删除和插入操作效率低,且统一的迭代器和引用更好。
//整型数组
vector<int> v1;
//浮点型数组
vector<double> v2;
并且注意每次使用vector
都需要包含头文件#include<vector>
。并且vector
是一个模版类,所以在使用时需要显示实例化。
2. vector的接口
接下来我们将介绍一些vector
的常见接口,因为很多接口的作用都与string
的接口非常类似,所以很多就不在详细说明,大家具体也可以参考vector的使用。
2.1. vector的迭代器
同样的vector
中也存在迭代器iterator
,因为定义在vector
类中,所以其需要通过域作用限定符访问——vector<类型>::iterator
下面将介绍的begin()
,end()
,rbeign()
,rend()
的使用访问方法与string
中的几乎一摸一样,我们直接上实例演示:
void Test1()
{vector<int> v = {1,2,3,4,5,6,7,8};vector<int>::iterator it = v.begin();cout << "顺序遍历:";while (it != v.end()){cout << *it << " ";++it;}cout << endl;cout << "逆序遍历:";vector<int>::reverse_iterator rit = v.rbegin();while (rit != v.rend()){cout << *rit << " ";++rit;}
}
当然vector
也支持const_iterator
,用法也类似,这里就不在赘述。
2.2. vector的初始化与销毁
同样的vector
也支持多种构造函数,拷贝构造以及赋值运算符重载。
void Test2()
{//1.默认构造函数初始化vector<int> v1;//2.n个val初始化vector<int> v2(3, 2);string s("abcd");//3.利用迭代器区间初始化vector<int> v3(s.begin(), s.end());//4.拷贝构造vector<int> v4(v3);//5.赋值重载v2 = v3;//6.可变参数列表初始化vector<int> v5 = { 1,2,3,4,5 };vector<char> v6 = v4;//error 不同类型不能赋值
}
其中需要注意的是可变参数列表初始化,这是在C++11之后支持的新语法,具体讲解我们之后再谈。
2.3. vector的容量操作
函数名称 | 功能 |
---|---|
size | 返回数组的有效长度 |
capacity | 返回数组的容量大小 |
clear | 清空数组 |
empty | 检查是否为空数组,是则返回ture,否则返回false |
reserve | 请求改变数组的容量 |
resize | 重新设置有效元素的数量,超过原来有效长度则用c字符填充 |
2.3.1. 有效长度与容量大小
在vector
类中,我们同样可以通过size()
容器的有效长度;capacity()
返回容器的容量大小。
void Test3()
{vector<int> v = { 1,2,3,4,5 };cout << v.size() << endl;cout << v.capacity() << endl;
}
在初始化时,vecotr
中的size
与capacity
一般相同。这时我们也可以通过以下程序探究一下其扩容机制:
void TestExpand()
{size_t sz;vector<int> v;sz = v.capacity();cout << "making v grow:"<<endl;for (int i = 0; i < 100; ++i){v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << "capacity changed: " << sz << endl;}}
}
在VS环境下,vector
一般是以1.5倍扩容。但是在Linux环境下一般就以2倍扩容。
至于clear()
与empty()
两个函数用法就十分简单,这里就不在赘述了。
2.3.2. 有效长度与容量操作
接下来我们来使用一下vector
中的resize()
与reserve()
。其实他们的用法与特点也是与string
类中的相同,我们直接上手即可
- 当
n<sz
时,reserve
并不会发生任何改变,resize
会删除有效字符到指定大小。- 当
sz<n<capcity
时,reserve
并不会发生任何改变,resize
会补充有效字符(默认为0)到指定大小。- 当
n>capacity
时,reserve
会发生扩容,resize
会补充有效字符(默认为0)到指定大小。
void Test4()
{vector<int> v1 = { 1,2,3,4,5 };cout << "v1的有效长度为:" << v1.size() << endl;cout << "v1的容量大小为:" << v1.capacity() << endl;v1.reserve(10);cout << "v1的有效长度为:" << v1.size() << endl;cout << "v1的容量大小为:" << v1.capacity() << endl;v1.resize(8, 10);for (auto& e : v1){cout << e << " ";}
}
在这里我们需要注意一个经典错误,如下列代码:
void Test5()
{vector<int> v;v.reserve(10);for (int i = 0; i < 10; i++){v[i] = i;}for (auto& e : v){cout << e << " ";}
}
一旦运行就会发生如上错误,这是为什么呢?因为reserve
只是改变了容量capacity
并没有改变size
,而operator[]
访问时元素时是禁止访问下标size
以后的元素的,一旦访问就会直接报错。
2.4. vector的访问操作
函数名称 | 功能 |
---|---|
operator[] | 返回指定位置的元素,越界则报错 |
at | 返回指定位置的元素,越界则抛异常 |
back | 返回字符串最后一个元素 |
front | 返回字符串第一个元素 |
这四个函数的用法也与string
中的函数用法相同,我们就直接上手示例
void Test6()
{vector<int> v = { 1,2,3,4,5 };for (int i=0;i<v.size();i++){cout << v[i] << " ";}cout << endl;for (int i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;cout << "front:" << v.front() << endl;cout << "back:" << v.back() << endl;
}
2.4. vector的修改操作
函数名称 | 功能 |
---|---|
push_back | 在数组后追加元素 |
insert | 在指定位置追加元素 |
assign | 使用指定数组替换原数组 |
pop_back | 删除数组最后一个元素 |
erase | 删除数组指定部分区间 |
swap | 交换两个数组 |
我们首先先介绍最简单的四个函数push_back()
,pop_back()
,assign()
,swap()
。
void Test7()
{vector<int> v = { 1,2,3,4,5,6 };cout << "back:" << v.back() << endl;//尾插v.push_back(7);//尾删cout << "back:" << v.back() << endl;v.pop_back();cout << "back:" << v.back() << endl;vector<int> vv = { 6,5,4,3,2,1 };//n个val赋值给原数组vv.assign(3, 2);for (int i = 0; i < vv.size(); i++){cout << vv[i] << " ";}cout << endl;vv.swap(v);for (int i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;for (int i = 0; i < vv.size(); i++){cout << vv[i] << " ";}
}
然后我们来介绍insert()
与·earse()
的用法,这两个函数的用法就与string
中的有所不同。首先是insert()
函数:
void Test8()
{vector<int> myvector(3, 100);vector<int>::iterator it = myvector.begin();//1.向指定位置插入一个元素it = myvector.insert(it, 200);cout << "myvector contains:";for (it = myvector.begin(); it < myvector.end(); it++)cout << ' ' << *it;cout << endl;//2.向指定位置插入n个元素myvector.insert(it, 2, 300);cout << "myvector contains:";for (it = myvector.begin(); it < myvector.end(); it++)cout << ' ' << *it;cout << endl;//3.向指定位置插入一段迭代器区间it = myvector.begin();vector<int> anothervector(2, 400);cout << "myvector contains:";for (it = myvector.begin(); it < myvector.end(); it++)cout << ' ' << *it;cout << endl;it = myvector.begin();myvector.insert(it + 2, anothervector.begin(), anothervector.end());//4.向指定位置插入一段迭代器区间int myarray[] = { 501,502,503 };myvector.insert(myvector.begin(), myarray, myarray + 3);cout << "myvector contains:";for (it = myvector.begin(); it < myvector.end(); it++)cout << ' ' << *it;cout << endl;
}
接下来我们继续来使用erase()
函数
void Test9()
{//1.删除迭代器所指元素vector<int> myvector;for (int i = 1; i <= 10; i++) myvector.push_back(i);vector<int>::iterator it = myvector.erase(myvector.begin() + 5);it = myvector.erase(it);//2.删除一段迭代器区间it = myvector.erase(myvector.begin(), myvector.begin() + 3);cout << "myvector contains:";for (int i = 0; i < myvector.size(); ++i)cout << ' ' << myvector[i];cout << endl;
}
虽然看起来vector
的insert()
和erase()
与string
的没有什么区别,但是仔细观察就可以发现我们每次使用完迭代器之后都会更新,这是为什么呢?
主要还是因为我们每次插入数组都可能发生扩容,而扩容分为就地扩容与异地扩容。如果发生的异地扩容,这时的迭代器就不在指向原来的空间,而就指向一块释放的内存,我们一旦继续访问就会报错,这种现象我们称为迭代器失效。为了避免出现这种情况,所以我们在使用完迭代器之后需要更新。
相关文章:
C++必修:STL之vector的了解与使用
✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C学习 贝蒂的主页:Betty’s blog 1. C/C中的数组 1.1. C语言中的数组 在 C 语言中,数组是一组相同类型…...
【MySQL】索引 【上】 {没有索引的查询/磁盘/mysql与磁盘IO/初识索引}
文章目录 1.没有索引存在的问题2. 认识磁盘MySQL与存储MySQL与磁盘交互基本单位建立共识图解IO认识索引 在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物…...
GO goroutine状态流转
Gidle -> Grunnable newproc获取新的goroutine,并放置到P运行队列中 这也是go关键字之后实际编译调用的方法 func newproc(fn *funcval) {// 获取当前正在运行中的goroutinegp : getg()// 获取调用者的程序计数器地址,用于调试和跟踪pc : getcallerp…...
DLMS/COSEM中的信息安全:DLMS/COSEM安全概念(上)
DLMS/COSEM中的信息安全描述并规定: ——DLMS/COSEM安全概念; ——选择加密算法; ——安全密钥; ——使用加密算法进行实体认证、xDLMS APDU保护和COSEM数据保护。 1.综述 DLMS/COSEM服务器的资源(COSEM对象属性和方法)可以由在应用连接内的DLMS/COSEM客户机访问。 在AA…...
C语言第九天笔记
数组的概念 什 么是数组 数组是 相同类型, 有序数据的集合。 数 组的特征 数组中的数据被称为数组的 元素,是同构的 数组中的元素存放在内存空间里 (char player_name[6]:申请在内存中开辟6块连续的基于char类 型的变量空间) 衍生概念&…...
智慧环卫可视化:科技赋能城市清洁管理
图扑智慧环卫可视化通过实时监控、数据分析和智能调度,提高环卫作业效率,优化资源配置,提升城市清洁水平,实现城市管理的精细化和现代化。...
【力扣】SQL题库练习5
高级查询和连接 1341.电影评分 表:Movies ------------------------ | Column Name | Type | ------------------------ | movie_id | int | | title | varchar | ------------------------ movie_id 是这个表的主键(具有唯一值的列)。 ti…...
永结无间Ⅸ--你不需要LLM Agent
人们将目光锁定在下一个闪亮的事物上。FOMO 是人性的一部分。这也适用于企业。就像数据科学成为每个企业分析功能的热潮一样,Agentic Architecture 是大多数 AI 雷达上的热门目标。 但您是否考虑过您是否真的需要它? 实际情况是,您不需要 A…...
Simulink|基于粒子群算法的永磁同步电机多参数辨识
目录 主要内容 模型研究 结果一览 下载链接 主要内容 仿真程序参考文献《改进粒子群算法的永磁同步电机多参数辨识》,采用粒子群算法与simulink模型结合的方式,对永磁同步电机进行多参数辨识。程序以定子绕组电阻、d轴电感、q轴电感和永磁…...
程序如何自动点击亚马逊商户后台的“邀请评论”按钮
要在亚马逊上自动点击“邀请评论”按钮,可以使用自动化脚本来实现。由于你希望自动化操作,我提供一个示例代码,使用 Selenium WebDriver 来执行这个任务。Selenium 是一个流行的浏览器自动化工具,能够模拟用户操作,例如…...
大模型算法面试题(十八)
本系列收纳各种大模型面试题及答案。 1、P-tuning v2 思路、优缺点是什么 P-tuning v2是清华大学自然语言处理实验室(THUDM)等研究机构提出的一种新的预训练模型优化方法,主要关注如何通过动态构建任务相关的提示序列来引导预训练模型进行更…...
手机在网状态接口如何对接?(二)
一、什么是手机在网状态? 传入手机号码,查询该手机号的在网状态,返回内容有正常使用、停机、在网但不可用、不在网(销号/未启用/异常)、预销户等多种状态。 二、手机在网状态使用场景? 1.用户验证与联系…...
力扣-3232. 判断是否可以赢得数字游戏
给你一个 正整数 数组 nums。 Alice 和 Bob 正在玩游戏。在游戏中,Alice 可以从 nums 中选择所有个位数 或 所有两位数,剩余的数字归 Bob 所有。如果 Alice 所选数字之和 严格大于 Bob 的数字之和,则 Alice 获胜。 如果 Alice 能赢得这场游…...
Table SQL connectors以及FileSystem、JDBC connector
目录 Flink支持的连接器 如何使用连接器 FileSystem SQL Connector 文件格式 分区文件 Source 目录监控 元数据 Streaming Sink 滚动策略 文件合并 JDBC SQL Connector 依赖 如何创建JDBC表 连接器配置 案例 pom依赖 代码 测试 Flink的Table API和SQL…...
Animate软件基础:“分散到图层”创建的新图层
FlashASer:AdobeAnimate2021软件零基础入门教程https://zhuanlan.zhihu.com/p/633230084 FlashASer:实用的各种Adobe Animate软件教程https://zhuanlan.zhihu.com/p/675680471 FlashASer:Animate教程及作品源文件https://zhuanlan.zhihu.co…...
ffmpeg命令-Windows下常用最全
查询命令 参数 说明 -version 显示版本。 -formats 显示可用的格式(包括设备)。 -demuxers 显示可用的demuxers。 -muxers 显示可用的muxers。 -devices 显示可用的设备。 -codecs 显示libavcodec已知的所有编解码器。 -decoders 显示可用…...
反序列化漏洞靶机实战-serial
一.安装靶机 下载地址为https://download.vulnhub.com/serial/serial.zip,安装好后开启靶机,这里并不需要我们去登录,直接扫描虚拟机nat模式下c网段的ip,看看哪个的80端口开放,然后直接去访问 二.查找cookie 访问靶…...
医疗器械产品没有互联网连接,就不适用于网络安全要求吗?
医疗器械产品是否不适用于网络安全要求,需要考虑产品是否具有网络连接功能以进行电子数据交换或远程控制,以及是否采用储存媒介进行电子数据交换。详细解析如下: 一、医疗器械的网络安全要求不仅限于互联网连接 数据交换接口:医疗…...
可视掏耳勺安全吗?独家揭示六大风险弊病!
很多人习惯在洗漱完顺手拿一根棉签掏耳朵,但是棉签的表面直径大且粗糙,不易将耳朵深处的耳垢挖出,耳垢堆积在耳道深处长时间不清理会导致堵塞耳道,引起耳鸣甚至感染。而可视掏耳勺作为一种新型的挖耳工具,它的安全性也…...
JavaScript 变量声明var、let、const
在 JavaScript 中,var、let和const是用于声明变量的关键字。 let和const是JavaScript里相对较新的变量声明方式。 let用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。 const声明一个只读的常量。一旦声明,常量的…...
ipvlan: operation not supported 导致的POD不断重启
情况描述 接到反馈有一台虚拟机HA迁移了,需要检查一下上面业务是否正常,由于是K8S node节点,正常情况下重启会自动恢复的,不过抱着严谨的态度,上去看了一眼。 问题:发现docker运行正常,但是业…...
组蛋白乳酸化和RNA甲基化如何联动?请大数据把这个思路推给科研人
在细胞生物学中,基因表达调控是决定细胞功能与命运的核心过程之一。组蛋白作为修饰性蛋白,在调控基因转录中起着至关重要的作用。近年来,科学家们发现,组蛋白的多种化学修饰(如甲基化、乙酰化、磷酸化等)影…...
操作文件-Path
Java操作文件-Path Paths 参数说明 first:必选参数,表示路径的第一个组件。more:可选参数,表示路径的其他组件,可以传入多个。 创建路径对象 // 创建一个表示当前工作目录的Path对象 Path currentPath Paths.get…...
RAC(Teamcenter )开发,Bom行解包和打包的方法
1、打包 UnpackAllAction allAction new UnpackAllAction((AbstractBOMLineViewerApplication) currentApplication, "packAllAction"); new Thread(allAction).start();2、解包 UnpackCommand command new UnpackCommand(bomLine); command.executeModal();3、注…...
log4j2漏洞练习
log4j2 是Apache的一个java日志框架,我们借助它进行日志相关操作管理,然而在2021年末log4j2爆出了远程代码执行漏洞,属于严重等级的漏洞。apache log4j通过定义每一条日志信息的级别能够更加细致地控制日志生成地过程,受影响的版本…...
OpenEuler安装部署教程
目录 OpenEuler安装部署教程 MobaXterm一款全能的远程工具 yum安装软件 vim编辑器(了解) 防火墙 常用命令 网络工具netstat & telnet 进程管理工具top ps 磁盘free、fdisk 用户、组(了解) 权限(了解&am…...
Canto - hackmyvm
简介 靶机名称:Canto 难度:简单 靶场地址:https://hackmyvm.eu/machines/machine.php?vmCanto 本地环境 虚拟机:vitual box 靶场IP(Canto):192.168.130.53 windows_IP:192.1…...
【数据结构进阶】手撕红黑树
🔥个人主页: Forcible Bug Maker 🔥专栏: C || 数据结构 目录 🌈前言🔥红黑树的概念🔥手撕红黑树红黑树结点的定义红黑树主体需要实现的成员函数红黑树的插入findEmpty和Size拷贝构造析构函数和…...
【C++从小白到大牛】类和对象
目录 一、面向过程和面向对象初步认识 二、类的引入 三、类的定义 类的成员函数两种定义方式: 1. 声明和定义全部放在类体中 2. 类声明放在.h文件中,成员函数定义放在.cpp文件中 成员变量命名规则的建议: 四、类的访问限定符 【访问限…...
Kafka 为什么这么快的七大秘诀,涨知识了
我们都知道 Kafka 是基于磁盘进行存储的,但 Kafka 官方又称其具有高性能、高吞吐、低延时的特点,其吞吐量动辄几十上百万。 在座的靓仔和靓女们是不是有点困惑了,一般认为在磁盘上读写数据是会降低性能的,因为寻址会比较消耗时间。…...
开发动态网站有哪些技术/必应搜索网站
while 1:try:t = input()p = input()if p in t:_ = t.split(p)print(len(_[...
企业服务建设网站/想做游戏推广怎么找游戏公司
9月1日,全球3D设计、3D数字样机和产品全生命周期管理(PLM)解决方案、3D体验解决方案领导者达索系统和欧洲领先的工程企业Assystem(巴黎欧洲证券)宣布扩大核工程领域的合作,通过数字技术将彻底改进复杂工程项…...
登封做网站优化/一站式发稿平台
1、出现如下错误 解决办法: ①确保你有该文件夹的完全控制权。文件夹点右键->属性->安全->高级->所有者->改为自己->编辑自己的权限为完全控制。 ②将setup.exe的兼容性改为windows server 2003(server pack 1)。右键属性-〉兼容性-〉兼容模式…...
广东省医院建设协会网站首页/百度商家版下载
解决办法: window --> preferences --> Team --> SVN --> Client选项选择: SVNKit x.x.x.xxx 转载于:https://www.cnblogs.com/zheh/p/4199400.html...
wordpress 下载短代码/全国十大教育机构
期货交易服务市场的企业竞争态势 该报告涉及的主要国际市场参与者有Daniels Trading、Saxo、Tradovate、NinjaTrader、AGT Futures、CQG、Gain Capital Group、ABLWSYS、SmartQuant、E-Futures、TransAct Futures、Trade Navigator、MultiCharts等。这些参与者的市场份额、收入…...
台山网站建设公司/网页设计个人主页
文章目录c六大组件包括:容器,迭代器,算法,适配器,函数对象和分配器容器分为序列式容器(vector,list,deque)和关联式容器(set,multiset,map, multimap) 适配器讲解 分配器讲解1 分配器讲解2 函数对象又称为仿函数,其实是在类中重载运算符()...