std::vector
std::vector是C++标准库中一个非常强大的容器类,它提供了动态数组的功能。std::vector可以自动调整大小,提供了随机访问的能力,同时还支持在序列的尾部高效地添加和删除元素。
当创建一个空的std::vector对象时,它不分配任何内存,大小是0。当开始添加元素时,std::vector会动态分配内存。通常情况下,第一次分配的内存大小由具体的实现决定,但通常是一个小的初始值,比如16或32个元素大小的内存块。
当元素数量超过当前内存容量时,std::vector将重新分配内存,并将元素从旧的内存块复制到新的内存块中。新的内存块的大小通常是当前元素数量的两倍或更多,具体取决于具体的实现和策略。重新分配内存时,可能会有一些额外的内存开销,因为需要考虑到内存对齐和内存管理的一些细节。
std::vector的特性:
- 动态大小:std::vector的大小可以动态变化,能够根据需要自动扩容
- 连续存储:像静态数组一样,内部使用连续的内存存储元素,这使得元素访问速度很快
- 模板类:std::vector是一个模板类,可以存储任何类型的数据
std::vector提供了一系列成员函数来操作和管理动态数组:
-
构造函数和析构函数
-
std::vector():构造一个空的向量
-
std::vector(size_type n, const T& value = T()):构造一个包含n个具有value值的元素的向量
-
std::vector(const std::vector& other):拷贝构造函数,深拷贝,会复制other中的元素,并存储到新的向量中
-
std::vector(std::vector&& other) noexcept:移动构造函数,将另一个已存在的vector对象的资源移动到新创建的vector中,而不是进行深拷贝
-
~std::vector():析构函数,释放向量所占用的内存
std::vector<int> vec; // 创建vec向量std::vector<std::string> vec(5, "A"); // 创建一个向量,该向量有5个元素,每个元素的值都是"A"std::vector<int> vec = {1, 2, 3, 4, 5}; // 创建向量vec,并进行初始化 std::vector<int> new_vec(vec); // 创建新的向量new_vec,并深拷贝vec中的元素std::vector<int> vec = {1, 2, 3, 4, 5}; std::vector<int> new_vec(std::move(vec)); // 创建新的向量new_vec,并将vec的资源移动到new_vec在C++标准库中,std::vector的析构函数是隐式生成的,如果用户没有自定义,将会使用编译器默认生成的析构函数。默认情况下,析构函数会按顺序释放元素,然后释放分配的内存。因此,std::vector在其生命周期结束时会自动执行析构函数,确保动态分配的内存被正确释放,从而避免内存泄漏。
-
-
元素访问
-
operator[]:通过索引访问向量的元素
-
at(value):通过索引访问向量的元素,带边界检查
-
front():访问向量的第一个元素
-
back():访问向量的最后一个元素
-
data():返回一个指向向量第一个元素的指针
std::vector<int> vec{0, 1, 2, 3, 4, 5}; // 创建向量vec,并进行初始化std::cout << vec[3] << std::endl; // 3 std::cout<< vec.at(3) << std::endl; // 3 std::cout<< vec.front() << std::endl; // 0 std::cout<< vec.back() << std::endl; // 5 int* ptr = vec.data(); for (size_t i = 0; i < vec.size(); ++i) {std::cout << *(ptr + i) << " "; // 0 1 2 3 4 5std::cout << ptr[i] << " "; // 0 1 2 3 4 5 }
-
-
修改器
-
push_back(const T& value):在向量的末尾添加一个元素
-
pop_back():移除向量的最后一个元素
-
emplace_back(Args&&… args):就地构造一个元素,避免额外的复制或移动
-
insert(const_iterator pos, const T& value):在指定位置插入一个元素
-
erase(const_iterator pos):删除指定位置或指定范围内的元素
-
resize():调整向量的大小
-
clear():清除向量中的所有元素
std::vector<std::string> vec{"A", "B", "C"}; for (auto value : vec) {std::cout << value << std::endl; // A B C }vec.push_back("D"); // 在向量末尾添加一个元素 for (auto value : vec) {std::cout << value << std::endl; // A B C D }vec.pop_back(); // 移除向量的最后一个元素 for (auto value : vec) {std::cout << value << std::endl; // A B C }vec.emplace_back("E"); // 在向量末尾添加一个元素 for (auto value : vec) {std::cout << value << std::endl; // A B C E }vec.insert(vec.begin() + 1, "F"); // 在索引为1的位置插入元素"F" for (auto value : vec) {std::cout << value << std::endl; // A F B C E }std::string values[] = {"X", "Y", "Z"}; vec.insert(vec.end(), std::begin(values), std::end(values)); // 在向量末尾插入一系列元素 for (auto value : vec) {std::cout << value << std::endl; // A F B C E X Y Z }vec.erase(vec.begin() + 1); // 删除索引为1的元素 for (auto value : vec) {std::cout << value << std::endl; // A B C E X Y Z }vec.erase(vec.begin() + 4, vec.end()); // 删除一系列元素,范围包括索引为4的元素到最后一个元素;范围是左闭右开,vec.end()指向末尾元素的后一位,因此囊括了末尾元素 for (auto value : vec) {std::cout << value << std::endl; // A B C E }vec.resize(3); // 调整向量大小,新的向量变小了,会删除多余的元素;A B C vec.resize(5); // 调整向量大小,新的向量变大了,会添加新的元素,默认构造;A B C 空值 空值 vec.resize(7, "E"); // 调整向量大小,新的向量变大了,会添加指定了值的元素;A B C 空值 空值 E Evec.clear(); // 清除向量中的所有元素;向量变为空,但分配的内存不会被释放 std::cout << vec.size() << std::endl; // 0/* push_back函数用于在向量的末尾添加一个元素,这个元素可以是值,也可以是另一个向量中元素的引用或指针。 emplace_back函数用于在向量的末尾就地构造一个元素,它可以避免临时对象的创建,而是直接将参数传递给构造函数,从而提高效率。 emplace_back通常比push_back更高效,因为它避免了复制或移动操作,直接在向量的末尾就地构造元素。 如果需要构造一个对象并将其添加到向量的末尾,emplace_back是更好的选择;如果需要添加一个已经存在的对象,push_back是合适的。 */
-
-
容量
-
empty():判断向量是否为空,返回一个布尔值
-
size():返回向量中元素的数量
-
max_size():返回向量能容纳的最大元素数量
-
capacity():返回向量当前的容量
-
reserve(size_type new_cap):改变向量的容量
-
shrink_to_fit():减小向量的容量以适应其大小
std::vector<int> vec = {1, 2, 3, 4, 5}; bool is_empty = vec.empty(); // 如果向量为空,返回1;如果向量不为空,返回0 std::cout << is_empty << std::endl; // 输出0vec.pop_back(); // 移除末尾元素 std::cout << vec.size() << std::endl; // 输出4,向量中还有4个元素 std::cout << vec.capacity() << std::endl; // 输出5,虽然移除了一个元素,但占用的内存空间并没有释放,因此容量为5 std::cout << vec.max_size() << std::endl; // 4611686018427387903,向量能容纳的最大元素数量vec.reserve(10); // 将vec的容量改为10 std::cout << vec.capacity() << std::endl; // 输出10vec.shrink_to_fit(); // 改变容量以适应向量的大小 std::cout << vec.capacity() << std::endl; // 输出4,因为向量中有4个元素,因此容量会自动适应向量的大小
-
-
迭代器
-
begin():返回指向向量第一个元素的迭代器
-
end():返回指向向量尾后一位的迭代器
-
cbegin():返回指向向量第一个元素的const迭代器
-
cend():返回指向向量尾后一位的const迭代器
-
rbegin():返回指向向量最后一个元素的反向迭代器
-
rend():返回指向向量首前一位的反向迭代器
-
crbegin():返回指向向量最后一个元素的const反向迭代器
-
crend(): 返回指向向量首前一位的const反向迭代器
std::vector<int> vec{1, 2, 3, 4, 5}; for (auto it = vec.begin(); it != vec.end(); it++) {std::cout << *it << std::endl; // 1 2 3 4 5 }for (auto it = vec.cbegin(); it != vec.cend(); it++) {std::cout << *it << std::endl; // 1 2 3 4 5 }for (auto it = vec.rbegin(); it != vec.rend(); it++) {std::cout << *it << std::endl; // 5 4 3 2 1 }for (auto it = vec.crbegin(); it != vec.crend(); it++) {std::cout << *it << std::endl; // 5 4 3 2 1 }
-
-
数据操作/赋值操作
-
assign(size_type n, const T& value):替换向量的内容为n个value元素
-
swap(std::vector& other):交换向量的内容
std::vector<int> vec = {1, 2, 3, 4, 5}; std::vector<int> new_vec = {6, 7, 8, 9};vec.assign(new_vec.begin(), new_vec.end()); // 将new_vec的全部元素赋给vec for (auto value : vec) {std::cout << value << std::endl; // 6 7 8 9 }vec.assign(5, 10); // 将5个10赋给vec for (auto value : vec) {std::cout << value << std::endl; // 10 10 10 10 10 }
std::vector<int> vec = {1, 2, 3, 4, 5}; std::vector<int> new_vec = {6, 7, 8, 9};vec.swap(new_vec); // 将vec与new_vec的元素互相交换 for (auto value : vec) {std::cout << value << std::endl; // 6 7 8 9 }for (auto value : new_vec) {std::cout << value << std::endl; // 1 2 3 4 5 }
-
-
查找操作
-
find(const T& value):查找第一个等于value的元素
-
lower_bound(const T& value):查找第一个不小于value的元素
-
upper_bound(const T& value):查找第一个大于value的元素
std::vector<int> vec{3, 2, 1, 4, 5};auto it = std::find(vec.begin(), vec.end(), 3); // std::find函数用于在向量中查找特定值,并返回指向找到的元素的迭代器,如果未找到,则返回尾后迭代器 std::cout << *it << std::endl; // 输出3auto it = std::find(vec.begin(), vec.end(), 0); // 要查找的0不在向量中,因此返回尾后迭代器,即指向向量尾后一位的迭代器 std::cout << *(it - 1) << std::endl; // 输出5,尾后迭代器前一个元素就是向量的末尾元素
std::vector<int> vec{3, 2, 1, 4, 5};std::sort(vec.begin(), vec.end()); // 对向量进行排序,默认为升序 for (auto value : vec) {std::cout << value << std::endl; // 1 2 3 4 5 }std::sort(vec.begin(), vec.end(), std::greater<int>()); // 对向量进行降序排序 for (auto value : vec) {std::cout << value << std::endl; // 5 4 3 2 1 }std::sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; }); // 使用lambda表达式实现降序排序 for (auto value : vec) {std::cout << value << std::endl; // 5 4 3 2 1 }/* std::sort是一个非常强大的标准库算法,用于对序列进行排序。它可以对数组、向量(std::vector)、字符串(std::string)等容器进行排序。std::sort函数定义在<algorithm>头文件中。 */
std::vector<int> vec{3, 4, 6, 7, 8};auto it = std::lower_bound(vec.begin(), vec.end(), 4); // 找出第一个不小于4的元素,并返回指向该元素的迭代器 std::cout << *it << std::endl; // 输出4auto it = std::lower_bound(vec.begin(), vec.end(), 5); // 找出第一个不小于5的元素,并返回指向该元素的迭代器 std::cout << *it << std::endl; // 输出6auto it = std::upper_bound(vec.begin(), vec.end(), 4); // 找出第一个大于4的元素,并返回指向该元素的迭代器 std::cout << *it << std::endl; // 输出6
-
-
运算符重载
-
赋值运算符 =:用于将一个向量的内容赋值给另一个向量
-
比较运算符 ==、!=、<、>、<=、>=:用于比较两个向量的内容
std::vector<int> vec1 = {1, 2, 3}; std::vector<int> vec2; vec2 = vec1; // 将vec1的内容赋给vec2 for (auto value : vec2) {std::cout << value << std::endl; // 1 2 3 }
std::vector<int> vec1 = {1, 2, 3}; std::vector<int> vec2 = {1, 2, 4}; bool res = vec1 <= vec2; std::cout << res << std::endl; // 输出1
-
-
特殊操作
-
emplace(const_iterator pos, Args&&… args):在指定位置就地构造一个元素,它可以直接将参数传给构造函数,而不需要提前创建一个对象
std::vector<int> vec = {1, 2, 3, 4, 5};vec.emplace(vec.begin(), 0); // 在vec的第一个位置就地插入一个元素0 for (auto value : vec) {std::cout << value << std::endl; // 0 1 2 3 4 5 }
-
相关文章:
std::vector
std::vector是C标准库中一个非常强大的容器类,它提供了动态数组的功能。std::vector可以自动调整大小,提供了随机访问的能力,同时还支持在序列的尾部高效地添加和删除元素。 当创建一个空的std::vector对象时,它不分配任何内存&a…...
Java Web 之 Cookie 详解
在 JavaWeb 开发中,Cookie 就像网站给浏览器贴的小纸条,用于记录一些用户信息或状态,方便下次访问时识别用户身份或进行个性化服务。 也可以这么理解: 场景一:想象一下,你去一家咖啡店,店员认…...
linux系统下让.py文件开机自启动
一 创建服务文件 1、打开终端 2、切换到root用户 sudo su3、创建一个新的systemd服务文件 nano /etc/systemd/system/total_test0619.service 4、在服务文件中添加以下内容 [Unit] DescriptionRun total_test0619.py at startup[Service] Typesimple ExecStart/usr/bin/n…...
linux远程桌面:xrdp 安装失败
window 如何远程 Linux 桌面 安装xrdp yum install xrdpsystemctl start xrdp 如果找不到软件包,就安装epel源,最好改成国内镜像的 在 /etc/yum.repos.d/ 下创建epel.repo,内容如下 [epel] nameExtra Packages for Enterprise Linux 7 - $basearch …...
9.30Python基础-元组(补充)、字典、集合
Python元组(tuple)补充 1、元组的不可变性 元组(tuple)是Python中的一种内置数据类型,用于存储不可变的序列。虽然元组本身不可变,但元组内的元素如果是可变对象(如列表)ÿ…...
桥接模式和NET模式的区别
桥接模式和NET模式的区别 NAT模式: NAT:网络地址转换(模式):借助宿主机来上网,没桥接那么麻烦,只用配置DNS即可。 缺点:扎根于宿主机,不能和局域网内其它真实的主机进行…...
Pigar:Python 项目的依赖管理利器
🌟 引言 在Python项目开发过程中,依赖管理是一个不可忽视的环节。一个精确且易于维护的requirements.txt文件对于项目的部署和协作至关重要。今天,我们将介绍一款名为Pigar的自动生成requirements.txt文件的依赖管理工具,它通过一…...
泰勒图 ——基于相关性与标准差的多模型评价指标可视化比较-XGBoost、sklearn
1、基于相关性与标准差的多模型评价指标可视化比较 # 数据读取并分割 import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split plt.rcParams[font.family] = Times New Roman plt.rcParams[axes.unic…...
记录|Modbus-TCP产品使用记录【摩通传动】
目录 前言一、摩通传动实验图1.1 配置软件 IO_Studio1.2 测试软件Modbus Poll1.2.1 读写设置测试1.2.2 AI信号的读取 1.3 对应的C#连接Modbus的测试代码如下【自制,仅供参考】1.4 最终实验图 更新时间 前言 参考文章: 自己需要了解和对比某些产品的Modbu…...
工业交换机的RMON
工业交换机在现代网络中扮演着至关重要的角色,它不仅负责数据的高效传输,还具备强大的监控和管理能力。其中,RMON(远程监控)功能使得交换机的性能得以进一步提升,成为网络管理的重要工具。RMON提供了一种先…...
生态遥感数据下载分享
中国土壤湿度/土壤水分数据集(2000-2020) 下载网站:https://poles.tpdc.ac.cn/zh-hans/data/49b22de9-5d85-44f2-a7d5-a1ccd17086d2/#:~:text%E6%88%91%E4%BB%AC%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%AD%E5%9B%BD%E8%8C%83 note: The data can …...
ECharts 快速使用
最终效果 使用介绍 echarts图表的绘制,大体分为三步: 根据 DOM实例,通过 echarts.init方法,生成 echarts实例构建 options配置对象,整个echarts的样式,皆有该对象决定最后通过实例.setOption方法…...
进程--消息队列和共享内存
目录 消息队列 创建消息队列 删除消息队列 发送消息和接收 消息队列 消息队列就是一个消息的列表,进程可以在消息队列中添加消息和的读取消息 消息队列具有FIFO的特性,具有无名管道与有名管道各自的优势,可以支持任意两个进程的进程间通讯…...
useCallback()
官网直达:https://zh-hans.react.dev/reference/react/useCallback 点击按钮,子组件会重新渲染 import { memo, useState, useCallback } from react;const Child (props) > {console.log(我是子组件!我在渲染呢!࿰…...
Python面试题精选及解析--第二篇
在Python的面试中,除了基础语法和常用库的知识外,面试官往往还会通过一系列的问题来考察应聘者的逻辑思维、问题解决能力以及项目经验。以下是一些精心挑选的Python面试题及其详细答案,旨在帮助求职者更好地准备面试。 面试题一:…...
Linux操作常用问题
目录 Ubuntu操作问题vi编辑方向键键盘乱码回退键不能使用的问题解决问题的方法 Ubuntu操作问题 vi编辑方向键键盘乱码回退键不能使用的问题 编辑/etc/systemd/resolved.conf文件来修改DNS,结果编辑时键盘乱码,按下方向键会出现ABCD,且回退键…...
汽车发动机系统(ems)详细解析
汽车发动机系统EMS,即Engine-Management-System(发动机管理系统),是现代汽车电子控制技术的重要组成部分。以下是对汽车发动机系统EMS的详细解析,内容将涵盖其定义、工作原理、主要组成、功能特点、技术发展以及市场应…...
对比学习训练是如何进行的
对比学习(Contrastive Learning)是一种自监督学习的方法,旨在通过拉近相似样本的表示、拉远不相似样本的表示来学习特征表示。在训练过程中,模型并不依赖标签,而是通过样本之间的相似性进行学习。以下是对比学习的基本…...
React 生命周期 - useEffect 介绍
在 React 中,useEffect 钩子可以被看作是函数组件中的一种副作用管理工具,它的行为可以模拟类组件中的不同生命周期方法。useEffect 的执行时机取决于其依赖项数组(第二个参数)的设置方式。 根据 useEffect 的使用方式,…...
OpenCV-指纹识别
文章目录 一、意义二、代码实现1.计算匹配点2.获取编号3.获取姓名4.主函数 三、总结 一、意义 使用OpenCV进行指纹识别是一个复杂且挑战性的任务,因为指纹识别通常需要高精度的特征提取和匹配算法。虽然OpenCV提供了多种图像处理和计算机视觉的工具,但直…...
IPD的核心思想
IPD是一套领先的、成熟的研发管理思想、模式和方法。它是根据大量成功的研发管理实践总结出来的,并被大量实践证明的高效的产品研发模式。 那么,按照IPD来开展产品研发与产品管理工作,应该基于哪些基本思想或原则?市场导向、客户…...
如何在算家云搭建MVSEP-MDX23(音频分离)
一、MVSEP-MDX23简介 模型GitHub网址:MVSEP-MDX23-music-separation-model/README.md 在 main ZFTurbo/MVSEP-MDX23-音乐分离模型 GitHub 上 在音视频领域,把已经发布的混音歌曲或者音频文件逆向分离一直是世界性的课题。音波混合的物理特性导致在没有…...
常用的Java安全框架
Spring Security: 就像Java安全领域的“瑞士军刀”,功能全面且强大。 支持认证、授权、加密、会话管理等安全功能。 与Spring框架无缝集成,使用起来特别方便。 社区活跃,文档丰富,遇到问题容易找到解决方案。 Apach…...
使用 PHP 的 strip_tags函数保护您的应用安全
在现代 web 开发中,处理用户输入是一项常见的任务。然而,用户输入的内容往往包含 HTML 或 PHP 标签,这可能会导致安全漏洞,如跨站脚本攻击(XSS)。为了解决这个问题,PHP 提供了一个非常有用的函数…...
您的计算机已被Lockbit3.0勒索病毒感染?恢复您的数据的方法在这里!
导言 在数字化时代,互联网已成为我们生活、工作和学习中不可或缺的一部分。然而,随着网络技术的飞速发展,网络安全威胁也日益严峻。其中,勒索病毒作为一种极具破坏性的网络攻击手段,正逐渐成为企业和个人面临的重大挑…...
经典sql题(十二)UDTF之Explode炸裂函数
1. EXPLODE: UDTF 函数 1.1 功能说明 EXPLODE 函数 是Hive 中的一种用户定义的表函数(UDTF),用于将数组或映射结构中的复杂的数据结构每个元素拆分为单独的行。这在处理复杂数据时非常有用,尤其是在需要将嵌套数据“打散”以便更…...
【AIGC】ChatGPT提示词解析:如何打造个人IP、CSDN爆款技术文案与高效教案设计
博客主页: [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯打造个人IP爆款文案提示词使用方法 💯CSDN爆款技术文案提示词使用方法 💯高效教案设计提示词使用方法 💯小结 💯前言 在这…...
【Ubuntu】Ubuntu常用命令
文章目录 网卡路由常用命令:编辑文件echo 权限设置gcc编译器: 重启网络服务 sudo service network-manager restart 网卡 #查看网卡信息 ip a #区分光网卡电网卡 sudo lshw -class network -businfo ifconfig ifconfig eth1 192.168.1.12/24 #重启网卡…...
架构设计笔记-5-软件工程基础知识-2
知识要点 构件组装是将库中的构件经适当修改后相互连接,或者将它们与当前开发项目中的软件元素连接,最终构成新的目标软件。 构件组装技术大体可分为: 1. 基于功能的组装技术:基于功能的组装技术采用子程序调用和参数传递的方式将构件组装起来。它要求库中的构件以子程序…...
[网络]抓包工具介绍 tcpdump
一、tcpdump tcpdump是一款基于命令行的网络抓包工具,可以捕获并分析传输到和从网络接口流入和流出的数据包。 1.1 安装 tcpdump 通常已经预装在大多数 Linux 发行版中。如果没有安装,可以使用包管理器 进行安装。例如 Ubuntu,可以使用以下…...
自己有网站怎么优化/如何推广一个网站
当前,新一轮科技革命和产业革命蓬勃兴起,大数据、云计算、人工智能等现代信息技术与经济社会深度融合,给各行各业带来了深刻的变革。 在2018(第三届)中国大数据产业生态大会上,工业和信息化部党组成员、总…...
网站建设 东八区/企业网站建设的重要性
部分代码(完整包见资源下载链接) 注:资源上传时默认付费,可以私信我,我看到会回复的 <!doctype html> <html><head><meta charset"utf-8"><meta http-equiv"X-UA-Compatib…...
广州网站推广奋/百度seo刷排名软件
安装到最后一步出错,求解...
个人备案 可以做企业网站吗/新闻发布的网站
影任有料,总有一款是你想要影任J作为一个不资深且跑路的程序猿,今天要跟大家讲的算是一个行业小技巧,请各位搬好小板凳仔细听吧!F12作为一个多功能按键,在职场有着特殊的运用,比如说扒图、改网页上的内容、…...
做兼职网站赚钱吗/百度一下百度搜索官网
从接触thinkphp到今天,填完此坑,必有其他的坑有会冒出来。哎!这个填坑之路我想是没有尽头的了。 最近,需要使用ajax完成一些操作,一开始想Ajax简单啊,不过是一种提交数据的方式,不过是害苦了我。…...
html编辑器中文版/搜索引擎优化方法总结
如图所示:打开file-->setting-->Editor-->General,搜索show,然后勾选上Show quick documentation on mouse move(将信息在鼠标移动到方法上时进行提示)转载于:https://www.cnblogs.com/alisande/p/10713388.html...