C++ vector
前言:
vector的部分源码:
(做过删除,留下关键信息)
vector的使用
构造函数:

1 无参构造
vector<int> v1;

2 构造并初始化n个val
vector<int> v2(5,1);

3 拷贝构造
vector<int> v3(v2);

4 使用迭代器进行初始化构造
迭代器可以是任意容器的迭代器
vector<int> v3(v2.begin(), v2.end());

string s("hello");vector<int> v3(s.begin(), s.end());

vector的 iterator 的使用
1 begin+end (顺序)
获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator

string s("hello");vector<int> v2(s.begin(),s.end());vector<int>::iterator it = v2.begin();//auto it = v2.begin();while (it != v2.end()){cout << *it << " ";it++;}cout << endl;

有迭代器,就可以使用范围for遍历数组
for (auto e : v2){cout << e << " ";}cout << endl;

const对象使用const迭代器进行遍历打印:
const vector<int> v(5,3);vector<int>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;

2 rbegin+rend(逆序)
获取最后一个数据位置的reverse_iterator/const_reverse_iterator,获取第一个数据前一个位置的
reverse_iterator/const_reverse_iterator

string s("hello");vector<int> v2(s.begin(),s.end());vector<int>::reverse_iterator rit = v2.rbegin();//auto rit = v2.rbegin();while (rit != v2.rend()){cout << *rit << " ";rit++;}cout << endl;

vector的容量空间
size:获取数据个数
capacity:获取容量大小
empty:判断是否为空
1 resize
改变vector的size
![]()
reisze(size_t n, const T& data = T())
n<size 删除作用
size<n<capacitty 插入作用
n>capacity 扩容+插入
传参给val,就用传过来的值,若没有传参,则用缺省值:匿名对象(先调用构造完成初始化)拷贝构造val
可完成开空间+初始化
vector<int> v;v.resize(4);

2 reserve
改变vector的capacity
reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题
vector<int> v;//v.reserve(100);size_t sz = v.capacity();for (size_t i = 0; i < 100; i++){v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << "扩容:" << sz << endl;}}

使用reserve,没有发生扩容
vector<int> v;v.reserve(100);size_t sz = v.capacity();for (size_t i = 0; i < 100; i++){v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << "扩容:" << sz << endl;}}

如果已经确定vector中要存储元素大概个数,可以提前将空间设置足够,就可以避免边插入边扩容导致效率低下的问题了
vector 增删查改
1 push_back(尾插)
2 pop_back(尾删)
vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);vector<int>::iterator it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;v.pop_back();v.pop_back();it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;
3 find
find不是vector自身提供的方法,是STL提供的算法,是算法模块实现,不是vector的成员接口

4 insert
在指定位置前插入值为val的元素,比如:3之前插入30,如果没有则不插入
5 erase

vector<int> v{ 1,2,3 ,4};// 使用列表方式初始化,C++11新语法vector<int>::iterator pos= find(v.begin(), v.end(), 3);//1. 先使用find查找3所在位置if (pos != v.end()){v.insert(pos, 20);// 2. 在pos位置之前插入30}auto it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;pos = find(v.begin(), v.end(), 3);v.erase(pos);it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;

insert和erase以后迭代器都失效了,不能在访问,所以以上代码中的迭代器pos在insert以后失效,重新赋值后,才可以使用
vector 迭代器失效问题
迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如:vector的迭代器就是原生态指针T*
迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)
迭代器失效解决办法:在使用前,对迭代器重新赋值即可
对于vector可能会导致其迭代器失效的操作有:
1. 会引起其底层空间改变的操作,都有可能使迭代器失效
比如:resize、reserve、insert、assign、push_back等
vector<int> v{ 1,2,3,4,5,6 };auto it = v.begin();v.resize(100, 8);//扩容了,旧空间被释放掉//v.reserve(100)//扩容了//v.insert(v.begin(), 0);//扩容了//v.push_back(0);//扩容了//v.assign(100, 8);//扩容了while (it != v.end())//操作的是已经释放掉的旧空间,程序崩溃{cout << *it << " ";it++;}cout << endl;
程序崩溃原因:以上操作,都有可能会导致vector扩容,一旦扩容,vector底层原理旧空间被释放掉,而在打印时,it使用的是已经释放掉的旧空间,在对it迭代器操作时,实际操作的是一块已经被释放的空间,而引起代码运行时崩溃
解决方案:给it重新赋值即可
vector<int> v{ 1,2,3,4,5,6 };auto it = v.begin();v.resize(100, 8);it = v.begin();//重新赋值while (it != v.end()){cout << *it << " ";it++;}cout << endl;
2. 指定位置元素的删除操作--erase
vector<int> v{ 1,2,3,4,5,6 };auto pos = find(v.begin(), v.end(), 5);v.erase(pos); 删除pos位置的数据,导致pos迭代器失效cout << *pos << endl;//非法访问
erase删除pos位置元素后,pos位置之后的元素会全部往前移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了
下面来看实例:
删除vector中所有的偶数
错误代码:
vector<int> v{ 1, 2, 3, 4 };auto it = v.begin();while (it != v.end()){if (*it % 2 == 0)v.erase(it);//erase以后,it迭代器失效++it;//报错}
正确代码:
vector<int> v{ 1, 2, 3, 4 };auto it = v.begin();while (it != v.end()){if (*it % 2 == 0){it = v.erase(it);//it失效,重新赋值,it成为下一个要判断的数据的迭代器}else{it++;}}for (auto e : v){cout << e << " ";}cout << endl;

3 注意
Linux下,g++编译器对迭代器失效的检测并不是非常严格,处理也没有vs下极端
1. 扩容之后,迭代器已经失效了,程序虽然可以运行,但是运行结果已经不对了
2. erase删除任意位置代码后,linux下迭代器并没有失效,因为空间还是原来的空间,it的位置还是有效的
3 erase删除的迭代器如果是最后一个元素,it已经等于end,失效了,++it导致程序崩溃
4 与vector类似,string在插入+扩容操作+erase之后,迭代器也会失效
vector的遍历
1 operator[]
vector<int> v{ 1,2,3,4 };for (size_t i = 0; i < v.size(); i++){v[i] *= 10;//写cout << v[i]<<" ";//读}

2 迭代器遍历
vector<int> v{ 1,2,3,4 };vector<int>::iterator it = v.begin();//auto it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;

3 范围for遍历
for (auto e : v){cout << e << " ";}cout << endl;相关文章:
C++ vector
前言: vector的部分源码: (做过删除,留下关键信息) vector的使用 构造函数: 1 无参构造 vector<int> v1; 2 构造并初始化n个val vector<int> v2(5,1);3 拷贝构造 vector<int> v3…...
Spring+redis集成redis缓存
1、引入maven依赖 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.7.0</version></dependency><dependency><groupId>org.springframework.data</groupId><art…...
聊聊springboot的启动事件
序 本文主要研究一下springboot的启动事件 SpringApplicationEvent org/springframework/boot/context/event/SpringApplicationEvent.java public abstract class SpringApplicationEvent extends ApplicationEvent {private final String[] args;public SpringApplicatio…...
jmeter HTTP请求默认值
首先,打开JMeter并创建一个新的测试计划。 右键单击测试计划,选择"添加" > “配置元件” > “HTTP请求默认值”。 在HTTP请求默认值中,您可以设置全局的HTTP请求属性,例如: 服务器地址:…...
CSS选择器-CSS3属性
CSS选择器-CSS3属性 持续更新… 1、CSS3的概念和优势 css3概念:是css的升级版本,新增加了一些模块 css3优点:完全向后兼容,可使用新的选择器和属性,能实现新的设计效果CSS3是CSS技术的升级版本,CSS3语言开发是朝着模块化发展的。以前的规范作为一个模块实在是太庞…...
线性代数的学习和整理8:行列式相关
目录 1 从2元一次方程组求解说起 1.1 直接用方程组消元法求解 1.2 有没有其他方法呢?有:比如2阶行列式方法 1.3 3阶行列式 2 行列式的定义 2.1 矩阵里的方阵 2.2 行列式定义:返回值为标量的一个函数 2.3 行列式的计算公式 2.4 克拉…...
java+springboot+mysql农业园区管理系统
项目介绍: 使用javaspringbootmysql开发的农业园区管理系统,系统包含超级管理员、管理员、用户角色,功能如下: 超级管理员:管理员管理;用户管理;土地管理(租赁)&#x…...
IDEA远程开发
IDEA远程开发 前期准备 IDEA的远程开发是在本地去操昨远程服务器上的代码,所以我们先需要准备一台服务器,在此我使用vmware虚拟出ubuntu-20.04.6的Server版本,以便后面演示。 Ubuntu的Java环境配置 JDK8 sudo apt install openjdk-8-jdkmaven sudo apt instal…...
Redis 工作总结
1.Redis是什么 Redis是互联网技术领域使用最为广泛的存储中间件,它是Remote Dictionary Service的首字母缩写,也就是远程字典服务。 2.Redis的用途? 2.1 计数器 2.2 缓存 2.3 分布式锁 2.4 消息中间件 3.Redis的数据类型 3.1 string&am…...
GO学习之 数据库(Redis)
GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…...
谈一谈浏览器与Node.js中的JavaScript事件循环,宏任务与微任务机制
JavaScript中的异步代码 JavaScript是一个单线程非阻塞的脚本语言。这代表代码是执行在一个主线程上面的。但是JavaScript中有很多耗时的异步操作,例如AJAX,setTimeout等等;也有很多事件,例如用户触发的点击事件,鼠标…...
User Java bean的命名规范
Java Bean 是一种用于表示简单的、可重用的组件的规范。它是一个符合特定命名和约定的 Java 类,通常用于封装数据和提供访问方法。以下是关于 Java Bean 命名规范的一些准则: 类名: 类名应该使用驼峰命名法(Camel Case)…...
ajax和fetch的区别
ajax 和 fetch的相同点和区别是什么? 以前我们都用ajax去做请求, 但是原生的ajax不好用,我们会用$.ajax或者axios插件去请求,他们都是ajax的封装 最近出来个fetch是什么? 问到这里的时候,你就已经入坑了&am…...
java+springboot+mysql村务档案管理系统
项目介绍: 使用javaspringbootmysql开发的村务档案管理系统,系统包含超级管理员、工作人员角色,功能如下: 超级管理员:系统用户管理(工作人员管理);公开资料;会议记录&…...
windows查看/删除DNS缓存
一、查看DNS缓存 打开CMD,输入ipconfig/displaydns 二、删除DNS缓存 打开CMD,输入ipconfig/flushdns...
自动化测试之Junit
Junit引入注解参数化单参数多参数方法传参 测试用例执行顺序断言测试套件 Junit引入 Junit来编写和组织自动化测试用例,使用Selenium来实际模拟用户与Web应用程序的交互。也就是使用JUnit的测试功能来管理和运行Selenium测试。常见的做法是,使用JUnit作…...
Spring Boot 整合MyBatis-Plus
😀前言 本篇博文是关于Spring Boot 整合MyBatis-Plus的,希望你能够喜欢😊 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的…...
CC++ 常用技巧
C 中的C C 是面向过程的是把整个大程序分为一个个的子函数;C 是面向对象的是把整个程序划分为一个个的类。C 是完全兼容C 的,C 是C 的子集,C 是C 的超集。C 又对C 做了很多补充和提升,因此使用C 会比使用纯C 更方便。混用C和C&am…...
【AndroidStudio】屏蔽小米打印
使用小米手机调试时,会一直有notifyQueue load error的打印 在过滤器重添加过滤条件即可 -message:notifyQueue...
Tomcat的安装与介绍
首先我们先了解一下什么是服务器?什么是服务器软件? 什么是服务器?安装了服务器软件的计算机。 什么是服务器软件? 服务器软件是一种运行在服务器操作系统上,用于接收和处理客户端请求,并提供相应服务和资…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
UE5 音效系统
一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类,将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix,将上述三个类翻入其中,通过它管理每个音乐…...
欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!
多连接 BLE 怎么设计服务不会乱?分层思维来救场! 作者按: 你是不是也遇到过 BLE 多连接时,调试现场像网吧“掉线风暴”? 温度传感器连上了,心率带丢了;一边 OTA 更新,一边通知卡壳。…...


