C++里的vector详细讲解

在C++的标准模板库(STL)中,vector是一个非常有用的动态数组容器。它允许我们存储可变大小的同类型元素序列,并且能够动态地增长和缩小。由于其灵活性和易用性,vector在C++编程中得到了广泛的应用。

一、vector的基本操作

1. 包含头文件

要使用vector,首先需要包含相应的头文件:

#include <vector>
2. 创建vector对象

创建一个空的int类型的vector

std::vector<int> v;

创建一个包含10个整数的vector,并初始化为0:

std::vector<int> v(10, 0);
3. 添加元素

使用push_back()函数向vector的末尾添加一个元素:

v.push_back(1);
v.push_back(2);
4. 访问元素

使用下标运算符[]来访问vector中的元素:

int first_element = v[0];  // 访问第一个元素
v[1] = 3;  // 修改第二个元素的值为3
5. 删除元素

使用erase()函数删除指定位置的元素:

v.erase(v.begin() + 1);  // 删除第二个元素
6. 遍历元素

使用迭代器或范围for循环遍历vector中的元素:

// 使用迭代器遍历
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {std::cout << *it << " ";
}
std::cout << std::endl;// 使用范围for循环遍历
for (const auto& element : v) {std::cout << element << " ";
}
std::cout << std::endl;
7. 获取vector的大小和容量

使用size()函数获取vector中元素的数量,使用capacity()函数获取vector当前分配的内存空间能够容纳的元素数量:

std::cout << "Size: " << v.size() << std::endl;
std::cout << "Capacity: " << v.capacity() << std::endl;

二、vector的特点和优势

  1. 动态扩展:当向vector中添加元素时,如果当前分配的内存空间不足以容纳新元素,vector会自动重新分配更大的内存空间,并复制或移动原有元素到新的内存空间。这个过程对用户是透明的,无需手动管理内存。
  2. 连续存储vector中的元素在内存中是连续存储的,这使得访问和操作元素非常高效。同时,连续存储也方便了元素的遍历和查找。
  3. 类型安全vector是模板类,可以存储任意类型的元素(包括基本数据类型、自定义类型等),并且保证了类型安全。在编译时会检查元素的类型,避免了运行时类型错误的风险。
  4. 易于使用vector提供了丰富的成员函数和操作符重载,使得对容器的操作更加直观和方便。例如,可以使用==运算符比较两个vector是否相等,使用+=运算符向vector中添加元素等。

三、示例代码

下面是一个简单的示例代码,演示了如何使用vector进行基本的操作:

#include <iostream>
#include <vector>int main() {// 创建一个空的int类型的vectorstd::vector<int> v;// 向vector中添加元素v.push_back(1);v.push_back(2);v.push_back(3);// 访问和修改元素std::cout << "First element: " << v[0] << std::endl;  // 输出:First element: 1v[1] = 4;  // 修改第二个元素的值为4// 遍历元素并输出std::cout << "Elements in vector: ";for (const auto& element : v) {std::cout << element << " ";}std::cout << std::endl;  // 输出:Elements in vector: 1 4 3 // 删除第二个元素(现在的值为4的元素)v.erase(v.begin() + 1);// 再次遍历元素并输出std::cout << "Elements after deletion: ";for (const auto& element : v) {std::cout << element << " ";}std::cout << std::endl;  // 输出:Elements after deletion: 1 3 return 0;
}

四、vector的性能考虑

虽然vector提供了很多便利,但在某些情况下,其性能可能并不是最优的。这主要源于vector在动态扩展时可能涉及大量的内存分配和数据复制。以下是一些使用vector时需要考虑的性能因素:

  1. 内存分配和复制:当vector需要增长时,它通常会分配一个更大的内存块,并将旧元素复制到新位置。这个过程可能很耗时,特别是对于大型vector。因此,如果你知道将要存储的元素数量,最好提前使用reserve()函数预留足够的空间。

  2. 连续内存访问:由于vector的元素在内存中是连续存储的,因此访问它们的性能通常很好。然而,插入或删除元素(特别是在vector的中间)可能会导致大量元素的移动,从而影响性能。在这种情况下,使用其他数据结构(如listdeque)可能更为合适。

  3. 缓存友好性:由于vector的元素是连续存储的,因此它们更容易被CPU缓存,从而提高访问速度。但是,当vector变得非常大时,它可能无法完全适应缓存,导致性能下降。

五、高级用法和注意事项

1. 使用emplace_back()避免不必要的复制或移动

当你想在vector的末尾添加一个元素时,如果元素类型是一个复杂的对象,使用emplace_back()而不是push_back()可以避免不必要的复制或移动操作。emplace_back()允许你在容器内直接构造元素,而无需先创建一个临时对象再将其复制或移动到容器中。

std::vector<std::string> strVec;
strVec.emplace_back("Hello");  // 直接在vector中构造std::string对象
2. 使用reserve()优化性能

如果你知道将要添加到vector中的元素数量,可以使用reserve()函数提前分配足够的内存空间。这样可以避免多次重新分配内存和数据复制,从而提高性能。

std::vector<int> intVec;
intVec.reserve(1000);  // 预留空间以存储1000个整数
for (int i = 0; i < 1000; ++i) {intVec.push_back(i);
}
3. 使用shrink_to_fit()释放未使用的内存

在删除大量元素后,vector可能不会立即释放未使用的内存。你可以调用shrink_to_fit()来请求容器减小其容量以匹配当前的大小。但请注意,这只是一个请求,标准库并不保证一定会释放内存。

std::vector<int> intVec(1000);
// ... 使用intVec ...
intVec.clear();  // 清除所有元素
intVec.shrink_to_fit();  // 请求释放未使用的内存
4. 避免在循环中多次调用size()

在循环中多次调用size()函数可能会导致不必要的性能开销,特别是当循环体很大且迭代次数很多时。最好将size()的结果存储在一个变量中,并在循环中使用该变量。

std::vector<int> intVec = {1, 2, 3, 4, 5};
size_t size = intVec.size();
for (size_t i = 0; i < size; ++i) {// ... 使用intVec[i] ...
}

六、总结

vector是C++ STL中非常强大且易于使用的动态数组容器。它提供了灵活的内存管理、高效的元素访问和丰富的操作函数。然而,在使用vector时,我们也应该注意其性能特点和最佳实践,以确保代码的高效运行。通过合理使用vector的成员函数和注意避免一些常见陷阱,我们可以充分利用这个容器的优势来编写高效且可靠的C++代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/14846.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java异常处理:最佳实践与常见模式

在Java编程中&#xff0c;异常处理是保证程序健壁性和稳定性的重要方面。良好的异常处理不仅可以帮助程序在面对错误情况时恢复到正常状态&#xff0c;还可以提供错误诊断的信息&#xff0c;辅助开发者快速定位问题。本文将探讨Java中的异常处理机制&#xff0c;包括异常的分类…

esp32 Micropython 长按按键动作一次代码

1. 长按按键&#xff0c;松手后动作 from machine import Pin import timeEnter_key Pin(15, Pin.IN, Pin.PULL_UP) Enter_key_flag 0 Enter_key_flag_temp 0while True:if Enter_key.value() 0:time.sleep_ms(10)while Enter_key.value() 0:Enter_key_flag_temp not En…

System.Collections.Generic 中的接口和类型区分

System.Collections.Generic 命名空间包含了许多与泛型集合相关的接口和类。这些接口定义了一组通用的集合行为&#xff0c;而具体的实现&#xff08;如 List、Dictionary<TKey, TValue> 等&#xff09;则遵循这些接口&#xff0c;从而提供具体的集合功能。以下是 System…

前后端开发入门全攻略:零基础学起

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、前后端开发概览 二、后端开发基础&#xff1a;Flask框架入门 代码案例&#xff1a;Hel…

vue3之使用图片实现类似于 el-radio 的单选框功能,并且可实现选中和取消选中

背景 我们在工作中常用的一般都是使用类似于 element-plus 中的 el-radio 或者是 el-checkbox 来实现单选或者多选 若有一天我们遇到了一个新的业务需求,需要使用 图片 来实现类似于 el-radio 的功能,并且要求实现第一次点击时处于选中状态,当我们再次点击时处于非选中状态…

谈恋爱没经验?那就来刷谈恋爱经验宝宝吧

❤️作者主页&#xff1a;小虚竹 ❤️作者简介&#xff1a;大家好,我是小虚竹。2022年度博客之星评选TOP 10&#x1f3c6;&#xff0c;Java领域优质创作者&#x1f3c6;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;掘金年度人气作…

自动驾驶---Tesla的自动驾驶技术进化史(PerceptionPlanning)

1 前言 笔者在专栏《自动驾驶Planning模块》中已经详细讲解了传统自动驾驶Planning模块的内容&#xff1a;包括行车的Behavior Planning和Motion Planning&#xff0c;以及低速记忆泊车的Planning&#xff08;最开始有15篇&#xff0c;目前逐渐更新到17篇&#xff09;。读者对整…

【Spring】SSM介绍_SSM整合

1、SSM介绍 1.1简介 SSM&#xff08;Spring SpringMVC MyBatis&#xff09;整合是一种流行的Java Web应用程序框架组合&#xff0c;它将Spring框架的核心特性、SpringMVC作为Web层框架和MyBatis作为数据访问层框架结合在一起。这种整合方式提供了从数据访问到业务逻辑处理再…

5.18 TCP机械臂模拟

#include <netinet/tcp.h>//包含TCP选项的头文件 #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/input.h>//读取输入事件 #include <sys/types.h> #include <sys/stat.h&…

对于mybatis和mybatisplus的选择

对于mybatis和mybatisplus的选择 1. 问题2. MP单表操作2.1 单表普通查询2.2 单表分页查询 3. mybatis多表操作3.1 多表普通查询3.2 多表分页查询 1. 问题 mybatis 和 mybatisplus作为当下主流的持久层框架&#xff0c;各有优劣势。依据个人经验&#xff1a;mybatis可以定制化输…

一文详解逻辑越权漏洞

1. 逻辑越权 1.1. 漏洞原理 逻辑越权漏洞就是当用户跳过自己的权限限制&#xff0c;去操作同等级用户或者上级用户。正常的情况下&#xff0c;当一个用户去访问某个资源的时候&#xff0c;首先需要去登录验证自己的权限&#xff0c;其次是对数据的查询&#xff0c;最后返回数…

gateway基本配置,如何配置?

文章推荐 1 作为程序员&#xff0c;开发用过最好用的AI工具有哪些&#xff1f; 2 Github Copilot正版的激活成功&#xff0c;终于可以chat了 3 idea,pycharm等的ai assistant已成功激活 4 新手如何拿捏 Github Copilot AI助手&#xff0c;帮助你提高写代码效率 5 Jetbrains的a…

linux命令中arpd的使用

arpd 收集免费ARP信息 补充说明 arpd命令 是用来收集免费arp信息的一个守护进程&#xff0c;它将收集到的信息保存在磁盘上或者在需要时&#xff0c;提供给内核用户用于避免多余广播。 语法 arpd(选项)(参数)选项 -l&#xff1a;将arp数据库输出到标准输出设备显示并退出…

【云原生】Kubernetes----POD基本管理

目录 引言 一、Pod基础概念 &#xff08;一&#xff09;Pod简介 &#xff08;二&#xff09;Pod的分类 1.自主式Pod 2.控制器管理的Pod &#xff08;三&#xff09;Pod使用方式 1.单容器pod 2.多容器Pod 3. 注意事项 二、Pod容器的分类 &#xff08;一&#xff09;…

C#中的惰性对象你使用过吗?

概述&#xff1a;本文深入探讨了 C# 中 Lazy Objects 的概念。惰性对象是高效资源配置和初始化的非常有益的工具&#xff0c;尤其是在这些过程成本高昂或耗时的情况下。它全面研究了 Lazy Objects 的功能、其目的和最佳用例&#xff0c;以及实际的实现策略。延迟加载简介什么是…

【Unity】免费的高亮插件——QuickOutline

除了常见的HighLightSystem来实现的高亮功能&#xff0c;其实还有很多的方法实现物体的高亮。 在 Unity资源商店 搜索OutLine&#xff0c;就会有很多免费好用的高亮插件。 下面介绍一下 QuickOutline这个插件&#xff0c;在 Unity资源商店 搜索到后&#xff0c;点击进去就可以…

推荐几款新手学习编程的网站

免费在线开发平台 介绍一款编程平台&#xff0c;专为学生和开发者量身打造&#xff01;平台拥有近4000道编程题目&#xff0c;支持多种编程语言&#xff08;包括C、C、JavaScript、TypeScript、Go、Rust、PHP、Java、Ruby、Python3和C#&#xff09;&#xff0c;为您提供全面的学…

Tomcat端口配置

Tomcat是开源免费的服务器&#xff0c;其默认的端口为8080&#xff0c;本文讲述一下如何配置端口。 最后在浏览器中输入localhost:8888即可打开Tomcat界面

python判断字符串是否为回文串的详细解析与实现

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;回文串的定义与背景 二、判断回文串的基本思路 示例解析 三、代码实…

三维场景感知之三维目标检测方向入门

三维目标检测入门 1 文档需知2 基础知识深度学习基础必上手项目科研研究必知道的论文门户深度学习必看论文 3 目标检测入门知识二维目标检测必看论文 4 三维目标检测入门知识三维目标检测必熟悉数据集三维目标检测点云分类分割预备知识三维目标检测必熟悉&#xff0c;必跑通&am…