【C++】vector容器的基本使用
一、vector是什么
vector是STL第一个正式的容器,它的底层其实就是动态数组,插入数据时当容量满了会自动扩容,它和string差不多,不同的之处之一在于vector本身是一个模板,它这个容器中可以存放各种各样的类型的数据,而string已经是模板实例化之后的结果。
vector类模板的第一个参数是T,其实就是你要放进容器中数据的类型,第二个参数我们暂且不管,它是一个空间配置器,主要是提高效率的,我们在实例化时暂且不传第二个参数,用它的默认缺省值,我们暂且只传第一个参数即可。
在本篇中涉及到allocator空间配置器的我们暂且不用管,可以先忽略。
vector大多数接口和string的功能用法上没有什么太大的区别,这篇文章不会细讲,所以建议大家先去看一下这篇文章 -> string类的基本实现
二、基本使用
1、构造函数
C++98版本下有4个构造函数,我们这里只说C++98,不谈论其它版本。
我们来看一下它的使用:
void test_vector1()
{vector<int> v1; //(1)默认构造vector<int> v2(10,1); //(2)带参构造,int类型的10个1vector<int> v3(v2.begin(),v2.end()); //(3)迭代器区间构造vector<int> v4(v3); //(4)拷贝构造
}
带有空间配置器的构造函数,我们用它的缺省值。
value_type就是模板的第一个参数T,即容器中存放数据的类型。
通过调试,我们可以看到各个容器中的内容:
2、析构函数
析构函数就不用多说了,我们创建容器添加数据,要在堆上开辟动态空间,析构函数就是要来对这些开辟的空间进行释放的,从而销毁容器对象。编译器会自动调用析构函数,我们可以不用单独处理。
我们可以通过调试简单演示一下:
程序结束前:
程序结束后:
程序结束自动调用析构,销毁容器对象。
3、赋值重载
它的作用就是将 x 中的所有元素复制到容器中。
我们用代码来理解一下:
void test_vector2()
{vector<int> v1(2,6);vector<int> v2(3,1);v2 = v1;
}
调试结果:
赋值前:
赋值后:
从这两张图可以看出,当v2的size大小取决于v1,如果v2在赋值前容量比v1大,则赋值后保持不变,否则会扩容,保证能存放完v1的数据。
4、重载[]
因为vector的底层是动态数组,所以它也支持用[]来访问指定下标的元素。
void test_vector3()
{vector<int> v(6, 6);cout << v[0] << endl;cout << v[2] << endl;
}
在主函数中调用test_vector3()结果如下:
如果越界访问就会报错。
这里也有3种遍历容器的方法,和string差不多一样:
void test_vector4()
{vector<int> v1;vector<int> v2(10, 1);vector<int> v3(++v2.begin(), --v2.end());//1、重载[]for (size_t i = 0; i < v3.size(); i++){cout << v3[i] << " ";}cout << endl;//2、迭代器vector<int>::iterator it = v3.begin();while (it != v3.end()){cout << *it << " ";++it;}cout << endl;//3、范围forfor (auto e : v3){cout << e << " ";}cout << endl;
}
在主函数中调用test_vector4()结果如下:
这3种迭代方法,我们在string篇幅都已详细讲解了,大家如果不懂,可以看一下那篇文章。
5、扩容规律
我们可以看一下vector在添加元素时,自动扩容的规律:
void TestVectorExpand()
{size_t sz;vector<int> v;sz = v.capacity();cout << "capacity changed: " << sz << '\n';cout << "making v grow:\n";for (int i = 0; i < 100; ++i){v.push_back(i); //尾插if (sz != v.capacity()){sz = v.capacity();cout << "capacity changed: " << sz << '\n';}}
}
在主函数中调用TestVectorExpand()结果如下:
不难发现,它是从0开始扩的,这与string是不同的,它是严格的1.5倍扩容。
6、成员函数
成员函数中大多和string用法和功能一样,这里只说一些特殊的。
(1)reserve()
它的功能是也是预留容量的,也就是改变capacity的大小,它可以避免频繁扩容。
size_type是一个无符号整形,它和string中的reserve()成员函数相似,但有一点不同,我们先往下看,假设参数是n(就是改变后的容量大小),分3种情况:
1、n < size
明确不会缩容。(这是和string不同的)
也不会改变size的大小,就是不会破坏原有内容。
2、size < n < capacity
明确不会缩容。(这是和string不同的)
3、n > capacity
会扩容,至少扩到n,也可能更多,这是不确定的。
我们写一段代码验证一下:
void test_vector5()
{vector<int> v(10, 1);cout << v.size() << endl;cout << v.capacity() << endl;//1、 n > capacityv.reserve(20); cout << v.size() << endl;cout << v.capacity() << endl;//2、size < n < capacityv.reserve(15);cout << v.size() << endl;cout << v.capacity() << endl;//3、n < sizev.reserve(5);cout << v.size() << endl;cout << v.capacity() << endl;
}
在主函数中调用test_vector5()结果如下:
根据结果显示,当n < capacity时,它是不会缩容的,这是明确的。
(2)resize()
它是将size设置为n,也分3种情况:
1、n < size
size的大小会变为n,其余的size - n个元素被删除(摧毁),但capacity通常不变。
2、size < n < capacity
size的大小会变为n,插入n - capacity个数据,如果不给第二个参数,那就用给的缺省值来初始化这n - capacity个数据,如果value_type是自定义类型,就调用它的默认构造,如果想自己初始化这n - capacity个数据,那么就手动给第二个参数赋值。
3、n > capacity
会扩容,至少扩到n,也可能更多,这是不确定的。在vs下通常会扩的更多一些。
对于前两点,缩不缩容不一定,这个需要看平台的处理。
我们写一段代码验证一下:
void test_vector6()
{vector<int> v(3, 1);v.reserve(8); //提前预留8字节空间cout << v.size() << endl;cout << v.capacity() << endl;//1、n < sizev.resize(1);cout << v.size() << endl;cout << v.capacity() << endl;//2、size < n < capacityv.resize(5, 3); //多余的n - size个数的数据初始化为3cout << v.size() << endl;cout << v.capacity() << endl;//3、size > capacityv.resize(10,100);//多余的n - size个数的数据初始化为100cout << v.size() << endl;cout << v.capacity() << endl;
}
在主函数中调用test_vector6()结果如下:
大家对比上面的3点进行理解。
(3)insert()
这里的insert比string当中的insert简洁了许多。
它在这不支持下标了,只支持迭代器。
void test_vector7()
{ vector<int> v2(2, 0);vector<int> v1(5, 1);for (auto e : v1)cout << e << " ";cout << endl;v1.insert(v1.begin(), 0); //(1)在v1头部位置插入0for (auto e : v1)cout << e << " ";cout << endl;v1.insert(v1.begin() + 3, 3, 100); //(2)在v1下标为3的位置上插入3个100for (auto e : v1)cout << e << " ";cout << endl;v1.insert(v1.end(), v2.begin(), v2.end());//(3)在v1的末尾,插入一段迭代区间for (auto e : v1)cout << e << " ";cout << endl;
}
在主函数中调用test_vector7()结果如下:
它不直接支持下标,但间接却是支持的,因为用迭代器就可以实现下标的问题,假设你要在下标为3的位置插入数据,那迭代器 v.begin() + 3就可以实现。这里没有用下标更多的原因是和后面的容器进行兼容,像list,它的底层不是动态数组,用下标访问就是不合适的。所以我们在容器这一部分,统一都用迭代器。
(4)erase()
同时,它也是只支持用迭代器来进行相应位置数据删除。
7、其他
vector不支持流插入和流提取,因为它的打印形式是多样的,不像string那样是固定的,遇到'\0'就终止打印,vector不支持流插入和流提取方便了我们对打印形式的控制,更自由和灵活。
vector底层是动态数组,string底层也是动态数组,那vector<char> 可以等同于string吗?
答案是不能。
首先,string定义的对象后面默认有'\0',vector<char>没有,其次,string定义的对象可以用字符串进行初始化,vector<char>不能,接着,string有很多针对字符串具有特定功能的接口,vector却没有,最后,string可以进行一些接口的传参,如果换用vector<char>则会麻烦许多。
所以vector<char> 是不可以取代string的。
三、结语
以上就是本篇的全部内容了,主要讲了vector的基本使用,希望大家有所收获,祝大家天天开心!
相关文章:

【C++】vector容器的基本使用
一、vector是什么 vector是STL第一个正式的容器,它的底层其实就是动态数组,插入数据时当容量满了会自动扩容,它和string差不多,不同的之处之一在于vector本身是一个模板,它这个容器中可以存放各种各样的类型的数据&am…...

【强化学习系列】Gym库使用——创建自己的强化学习环境2:拆解官方标准模型源码/规范自定义类+打包自定义环境
目录 一、 官方标准环境的获取与理解 二、根据官方环境源码修改自定义 1.初始化__init__() 2.重置环境 reset() 三、打包环境 1.注册与创建自定义环境 2.环境规范化 在本文的早些时候,曾尝试按照自己的想法搭建自定义的基于gym强化学习环境。 【强化学习系列】Gy…...
PyQt5实现按钮选择文件夹及文件夹
目录 1、选择文件夹并显示 2、选择文件 3、选择多个文件 4、设置保存文件路径 1、选择文件夹并显示 from PyQt5 import QtWidgetsdirectory QtWidgets.QFileDialog.getExistingDirectory(None, "选取文件夹", "./") # 起始路径 print(directory) 2…...

Gin渲染
HTML渲染 【示例1】 首先定义一个存放模板文件的 templates文件夹,然后在其内部按照业务分别定义一个 posts 文件夹和一个 users 文件夹。 posts/index.tmpl {{define "posts/index.tmpl"}} <!DOCTYPE html> <html lang"en">&…...
前端——JS基础
定义变量:let / var 字符串 字符串拼接: 字符串和数字拼:您.... 25 ; 这个25会转成字符串再拼接 字符串和数组拼:10以内的质数有: [2,3,5,7] > 10以内的质数有:2,3,5,7 字符串长度:leng…...

MATLAB入门教程
MATLAB安装教程可参考链接:matlab怎么安装 matlab安装教程-电脑软件-PHP中文网 1.MATLAB的工作环境 (1)命令窗(command window) 是对MATLAB进行操作的主要载体。默认情况下,启动MATLAB时就打开命令窗。MATLAB的所有所数…...

muduo - 概要简述
作者:陈硕 编程语言:C 架构模式:Reactor 代码链接:GitHub - chenshuo/muduo: Event-driven network library for multi-threaded Linux server in C11 设计自述:https://www.cnblogs.com/Solstice/archive/2010/08…...
Selenium点击元素的方法
前言 点击方法在web自动化测试中经常用到,下面就来介绍一下selenium常用和不常用的点击方法; 1、常用方法 1.1、使用 click() 方法: 这是最简单和最常用的方法。通过选中要点击的元素,然后使用 click() 方法来触发点击事件。 示例代码: element = self.driver.find_e…...

kali里面搭建docker容器
注意事项:kali版本,镜像源 (1)权限为管理员: sudo su (2) 更新软件包列表并升级已安装的软件包 apt-get update apt-get upgrade 出错了,应该是更新源出问题了。 (3)更换镜像源&am…...

WebGL系列教程八(GLSL着色器基础语法)
目录 1 前言2 基本原则3 基本数据类型4 顶点着色器和片元着色器4.1 声明4.2 初始化项目4.3 赋值 5 结构体5.1 声明5.2 赋值 6 函数6.1 基本结构6.2 自定义函数6.3 常用内置函数 7 精度8 其他9 总结 1 前言 通过前七讲,我们已经见过了WebGL中的部分基础语法ÿ…...

go多线程
1、简单使用(这个执行完成,如果进程执行比较久,这里不会等待它们结束) package mainimport "time"func main() {go func() {println("Hello, World!")}()time.Sleep(1 * time.Second) }2、wg.Add(数量)使用&…...
【话题】如何看待IBM中国研发部裁员?
(一)背景 在全球化的大趋势下,跨国公司的业务布局一直处于动态调整之中。IBM 作为全球知名的 IT 企业,在中国市场已经运营多年,其在中国的研发中心曾经为公司的全球业务发展做出了重要贡献。近年来,全球经…...

【C/C++】涉及string类的经典OJ编程题
【C/C】涉及string类的经典OJ编程题 一. 把字符串转化成整数(atoi)解法一:(不用long)完整代码:解法二:(用long) 二.字符串相加代码实现(含注释)&a…...
淘系等电商平台API接口系列:商品详情数据解析,json数据返回参考
——在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦! 在淘系(如淘宝、天猫)等电商平台中,商品详情数据…...
vue组件之间的数据共享
一、组件之间的关系 1.父子关系 2.兄弟关系 3.后代关系 二、父子组件之间的数据共享 1.父-->子共享数据 父组件通过v-bind属性绑定向子组件共享数据,子组件需要使用props接受数据。 <template><p>父组件</p><Son :msg"msg"…...
LangChain:构建强大的LLM应用的全方位框架
LangChain:构建强大的LLM应用的全方位框架 引言 在人工智能和大语言模型(LLMs)快速发展的今天,开发者们迫切需要一个强大而灵活的框架来简化LLM应用的开发过程。LangChain应运而生,它不仅提供了丰富的工具和组件&…...

自有平台自有品牌如何利用电商API接口做定价参考(多平台商品详情数据接口)
如今,多数自有商城自有品牌在为产品做定价时都会参考淘宝|天猫|京东等主流电商平台的商品价格以做参考,这一行为的好处主要有以下几点: 通过参考主流平台价格,用户更能了解目标市场中消费者对产品的接受度,从而制定出符…...

三万字长文Java面试题——基础篇(注:该篇博客将会一直维护 最新维护时间:2024年9月18日)
🧸本篇博客重在讲解Java基础的面试题,将会实时更新,欢迎大家添加作者文末联系方式交流 📜JAVA面试题专栏:JAVA崭新面试题——2024版_dream_ready的博客-CSDN博客 📜作者首页: dream_ready-CSDN博…...
数学建模——熵权+TOPSIS+肘部法则+系统聚类
文章目录 一、起因二、代码展示 一、起因 我本科的数学建模队长找上我,让我帮她写下matlab代码,当然用的模型还是曾经打比赛的模型,所以虽然代码量多,但是写的很快,也是正逢中秋,有点时间。 当然我也没想到…...

Java | Leetcode Java题解之第403题青蛙过河
题目: 题解: class Solution {public boolean canCross(int[] stones) {int n stones.length;boolean[][] dp new boolean[n][n];dp[0][0] true;for (int i 1; i < n; i) {if (stones[i] - stones[i - 1] > i) {return false;}}for (int i 1…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...