C++ vector 核心知识:常用操作与示例详解
在C++编程中,
vector是标准模板库(STL)中最常用的容器之一。它以其动态数组的特性、高效的尾部操作和便捷的随机访问能力,成为处理动态数据的首选工具。无论是初学者还是经验丰富的开发者,掌握vector的使用方法和性能优化技巧,都是提升代码效率的关键。然而,
vector的强大功能背后也隐藏着一些需要注意的细节,例如动态扩容的开销、迭代器失效问题以及不同操作的性能差异。
一、vector 容器概述
-
定义:
vector是C++标准模板库(STL)中的动态数组,支持随机访问、动态扩容和高效尾部操作。 -
特点:
-
内存连续存储,支持快速随机访问(时间复杂度 O(1))。
-
尾部插入/删除高效(均摊 O(1)),中间或头部操作效率较低(O(n))。
-
自动管理内存,动态调整容量(通过
reserve可手动优化)。
-
二、vector 常用操作及示例
1. 构造函数与初始化
| 操作 | 功能说明 | 示例代码 |
|---|---|---|
| 默认构造 | 创建空 vector | vector<int> v1; |
| 指定大小和初始值 | 创建大小为 n 的 vector | vector<int> v2(5, 10); // 5个元素,值10 |
| 通过迭代器初始化 | 用其他容器的范围初始化 | vector<int> v3(v2.begin(), v2.end()); |
| 列表初始化(C++11) | 直接通过列表初始化 | vector<int> v4 = {1, 2, 3, 4}; |
2. 元素访问
| 操作 | 功能说明 | 示例代码 | 时间复杂度 |
|---|---|---|---|
v[i] | 访问第 i 个元素(不检查越界) | int x = v[2]; | O(1) |
v.at(i) | 访问第 i 个元素(检查越界) | int y = v.at(3); // 越界抛出异常 | O(1) |
v.front() | 访问第一个元素 | int first = v.front(); | O(1) |
v.back() | 访问最后一个元素 | int last = v.back(); | O(1) |
v.data() | 获取底层数组指针 | int* p = v.data(); | O(1) |
3. 容量操作
| 操作 | 功能说明 | 示例代码 | 时间复杂度 |
|---|---|---|---|
v.empty() | 判断容器是否为空 | if (v.empty()) { ... } | O(1) |
v.size() | 返回元素个数 | int n = v.size(); | O(1) |
v.capacity() | 返回当前分配的容量 | int cap = v.capacity(); | O(1) |
v.reserve(n) | 预分配容量(避免多次扩容) | v.reserve(100); | O(n) |
v.shrink_to_fit() | 请求释放未使用的内存 | v.shrink_to_fit(); | O(n) |
4. 修改操作
| 操作 | 功能说明 | 示例代码 | 时间复杂度 |
|---|---|---|---|
v.push_back(val) | 在尾部插入元素 | v.push_back(10); | 均摊 O(1) |
v.pop_back() | 删除尾部元素 | v.pop_back(); | O(1) |
v.insert(pos, val) | 在 pos 位置插入元素 | v.insert(v.begin() + 2, 20); | O(n) |
v.erase(pos) | 删除 pos 位置的元素 | v.erase(v.begin() + 1); | O(n) |
v.clear() | 清空所有元素 | v.clear(); | O(n) |
v.resize(n) | 调整容器大小为 n | v.resize(10); // 新元素默认初始化 | O(n) |
v.emplace_back(args) | 在尾部直接构造元素(避免拷贝) | v.emplace_back(10); | 均摊 O(1) |
5. 遍历操作
| 操作 | 功能说明 | 示例代码 |
|---|---|---|
| 范围for循环(C++11) | 遍历所有元素 | for (int x : v) { cout << x << " "; } |
| 迭代器遍历 | 使用迭代器遍历 | for (auto it = v.begin(); it != v.end(); ++it) { ... } |
三、代码示例
1. 基本操作示例
#include <iostream>
#include <vector>
using namespace std;int main() {// 初始化vector<int> vec = {1, 2, 3, 4, 5};// 尾部插入元素vec.push_back(6); // vec: {1, 2, 3, 4, 5, 6}// 访问元素cout << "Third element: " << vec[2] << endl; // 输出: 3cout << "Last element: " << vec.back() << endl; // 输出: 6// 删除尾部元素vec.pop_back(); // vec: {1, 2, 3, 4, 5}// 插入元素vec.insert(vec.begin() + 2, 10); // vec: {1, 2, 10, 3, 4, 5}// 删除元素vec.erase(vec.begin() + 3); // vec: {1, 2, 10, 4, 5}// 遍历输出for (int x : vec) {cout << x << " "; // 输出: 1 2 10 4 5}return 0;
}
2. 容量管理示例
#include <vector>
#include <iostream>
using namespace std;int main() {vector<int> vec;cout << "Initial capacity: " << vec.capacity() << endl; // 输出: 0vec.reserve(5); // 预分配容量为5for (int i = 0; i < 10; ++i) {vec.push_back(i);cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << endl;}// 容量会自动扩展(具体策略依赖实现,如翻倍扩容)vec.shrink_to_fit(); // 释放多余内存return 0;
}
3.更多例子
#include <bits/stdc++.h> // 包含标准库的所有头文件
using namespace std; // 使用标准命名空间int main() { // 主函数开始vector<int> a; // 初始化一个 size 为 0 的 vectora.insert(a.begin(), 4, 2); // 在 a 的开始位置插入 4 个值为 2 的元素// 下面的 4 个 for 是 4 种遍历方法for (int i = 0; i < a.size(); i++) // 通过下标访问,输出 2 2 2 2cout << a[i] << " "; cout << "\n"; // 输出每个元素for (vector<int>::iterator it = a.begin(); it != a.end(); ++it) // 通过迭代器访问cout << *it << " "; cout << "\n"; // 输出每个元素for (auto it = a.begin(); it != a.end(); ++it) // 用 auto 获得迭代器cout << *it << " "; cout << "\n"; // 输出每个元素for (auto i : a) // 直接访问 vector 中的每个元素cout << i << " "; cout << "\n"; // 输出每个元素a.insert(a.begin() + 1, 9); // 在 a[1] 处插入 9, a = {2 9 2 2 2}a.insert(a.begin() + 2, 2, 5); // 在 a[2] 处插入两个 5, a = {2 9 5 5 2 2 2}a.resize(3); // 改变 a 的大小为 3, a = {2 9 5}vector<int> c(a); // 复制 a 到 cvector<int> b; // 初始化一个空的 vector bb.insert(b.begin(), a.begin(), a.begin() + 3); // 将 a 的前 3 个数复制到 b// 下面演示二维 vectorvector<vector<char>> ch(2, vector<char>(3, '#')); // 初始化一个 2 行 3 列的二维 vector,所有元素为 '#'for (int i = 0; i < 2; i++) { // 遍历行for (int j = 0; j < 3; j++) // 遍历列cout << ch[i][j]; // 输出每个元素cout << "\n";}// 下面演示用 vector 存储物体struct point { int x, y; }; // 定义一个结构体 point,包含两个整型成员 x 和 yvector<point> PP; // 初始化一个存储 point 结构体的 vectorfor (int i = 0; i < 3; i++) { // 循环 3 次point t; t.x = i; t.y = i; // 创建一个 point 对象 t,并赋值PP.push_back(t); // 将 t 添加到 PP 中}for (int i = 0; i < PP.size(); i++) // 遍历 PPcout << PP[i].x << " " << PP[i].y << "\n"; // 输出每个 point 的 x 和 yauto it = PP.begin(); // 获取 PP 的起始迭代器for (; it != PP.end(); ++it) // 使用迭代器遍历 PPcout << it->x << " " << it->y << "\n"; // 输出每个 point 的 x 和 yreturn 0; // 主函数结束
}
四、总结
-
优点:
-
快速随机访问(通过下标或迭代器)。
-
尾部插入/删除高效。
-
内存自动管理,支持动态扩容。
-
-
缺点:
-
中间或头部插入/删除效率低(需移动元素)。
-
频繁扩容可能影响性能(可通过
reserve优化)。
-
-
适用场景:
-
需要频繁随机访问元素。
-
尾部操作较多,中间操作较少。
-
相关文章:
C++ vector 核心知识:常用操作与示例详解
在C编程中,vector 是标准模板库(STL)中最常用的容器之一。它以其动态数组的特性、高效的尾部操作和便捷的随机访问能力,成为处理动态数据的首选工具。无论是初学者还是经验丰富的开发者,掌握 vector 的使用方法和性能优…...
结构型模式之适配器模式:让不兼容的接口兼容
在软件开发中,经常会遇到这样一种情况:系统的不同部分需要进行交互,但由于接口不兼容,导致无法直接使用。这时,适配器模式(Adapter Pattern)就能派上用场。适配器模式是设计模式中的结构型模式&…...
从零开始探索C++游戏开发:性能、控制与无限可能
一、为何选择C开发游戏? 在虚幻引擎5渲染的次世代画面背后,在《巫师3》的庞大开放世界中,在《毁灭战士》的丝滑60帧战斗里,C始终扮演着核心技术角色。这门诞生于1983年的语言,至今仍占据着游戏引擎开发语言使用率榜首…...
使用mvn archetype命令,构建自定义springboot archetype脚手架创建工程的方法
使用mvn archetype命令,构建自定义springboot archetype脚手架创建工程的方法 文章目录 使用mvn archetype命令,构建自定义springboot archetype脚手架创建工程的方法一、背景二、环境三、archetype插件配置四、基于项目构建脚手架archetype包五、检查模…...
Hutool RedisDS:Java开发中的Redis极简集成与高阶应用
在Java开发中,Redis作为高性能内存数据库,广泛应用于缓存、分布式锁等场景。然而原生的客户端操作涉及连接管理、序列化等繁琐细节。Hutool工具包提供的RedisDS模块,通过高度封装显著简化了这一过程。本文从实战角度解析其核心特性与使用技巧…...
MacOS 15.3.1 安装 GPG 提示Error: unknown or unsupported macOS version: :dunno
目录 1. 问题锁定 2. 更新 Homebrew 3. 切换到新的 Homebrew 源 4. 安装 GPG 5. 检查 macOS 版本兼容性 6. 使用 MacPorts 或其他包管理器 7. 创建密钥(生成 GPG 签名) 往期推荐 1. 问题锁定 通常是因为你的 Homebrew 版本较旧,或者你…...
Sqlmap注入工具简单解释
安装 1. 安装 Python SQLMap 是基于 Python 开发的,所以要先安装 Python 环境。建议安装 Python 3.9 或更高版本,可从 Python 官方网站 下载对应操作系统的安装包,然后按照安装向导完成安装。 2. 获取 SQLMap 可以从 SQLMap 的官方 GitHu…...
硬件驱动——51单片机:独立按键、中断、定时器/计数器
目录 一、独立按键 1.原理 2.封装函数 3.按键控制点灯 数码管 二、中断 1.原理 2.步骤 3.中断寄存器IE 4.控制寄存器TCON 5.打开外部中断0和1 三、定时器/计数器 1.原理 2.控制寄存器TCON 3.工作模式寄存器TMOD 4.按键控制频率的动态闪烁 一、独立按键 1…...
语文-文言文
文章目录 短歌行归园田居梦游天姥吟留别 / 别东鲁诸公 学习文言文,适当个人分析; 短歌行 曹操 对酒当歌,人生几何(主题,人生很短暂); 譬如朝露,去日苦多(比喻,…...
P1259 黑白棋子的移动【java】【AC代码】
有 2n 个棋子排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为 n5 的情况: 移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但…...
【极光 Orbit·STC8AH】04. 深度探索 GPIO 底层逻辑
【极光 OrbitSTC8A&H】04. 深度探索 GPIO 底层逻辑 引言:当代码遇见硬件 上周我看着学生调试的工控产品,他们困惑地盯着自己编写的代码:“老师,这段C语言明明在PC上跑得没问题啊!” ,让我想起自己初学…...
67.Harmonyos NEXT 图片预览组件之性能优化策略
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! Harmonyos NEXT 图片预览组件之性能优化策略 文章目录 Harmonyos NEXT 图片预览组件之性能优化策略效果预览一、性能优化概述1. 性能优化的关键指标…...
uni-app+SpringBoot: 前端传参,后端如何接收参数
做项目中的一些小经验,方便后续 (1)前端代码中,请求的 URL 是通过查询参数(?id${articleId})传递的 后端接口: GetMapping("/knowledgeDetail") public Result getKnowledgeByid(R…...
【Vue.js】
一、简介 1、概述 官网GitHub - Vuejs Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。 Vue.js作为一个渐进式框架,其设计理…...
正则表达式入门及常用的正则表达式
正则表达式(Regular Expression,简称 Regex)是一种强大的文本处理工具,用于匹配、查找和替换字符串中的特定模式。以下是入门指南和常用正则表达式示例: 一、正则表达式入门 1. 基本语法 符号说明示例.匹配任意单个字…...
Windows下安装Git客户端
① 官网地址:https://git-scm.com/。 ② Git的优势 大部分操作在本地完成,不需要联网;完整性保证;尽可能添加数据而不是删除或修改数据;分支操作非常快捷流畅;与Linux 命令全面兼容。 ③ Git的安装 从官网…...
SAP IBP for Supply Chain Certification Guide (Parag Bakde, Rishabh Gupta)
SAP IBP for Supply Chain Certification Guide (Parag Bakde, Rishabh Gupta)...
【计算机网络通信 AMQP】使用 Qt 调用 qamqp 库进行 AMQP 通信
以下是一个使用 Qt 实现 AMQP 通信的代码示例。为了实现这个功能,我们可以使用 qamqp 库,它是一个基于 Qt 的 AMQP 客户端库。首先,你需要将 qamqp 库添加到你的 Qt 项目中,可以通过 qmake 或 CMake 进行配置。 #include <QCo…...
C语言中的指针与数组:概念、关系与应用
指针和数组都是C语言中极其重要的概念,本文将分步骤深入分析指针和数组在C语言中的概念、它们之间的关系以及它们在实际编程中的应用。 一、指针与数组的基本概念详解 1.1 指针详解 指针是一个变量,它存储的是另一个变量的内存地址。理解指针的核心就是“内存地址”,指针…...
如何处理PHP中的日期和时间问题
如何处理PHP中的日期和时间问题 在PHP开发中,日期和时间的处理是一个常见且重要的任务。无论是记录用户操作时间、生成时间戳,还是进行日期计算,PHP提供了丰富的函数和类来帮助开发者高效处理这些需求。本文将详细介绍如何在PHP中处理日期和…...
TDengine 使用最佳实践
简介 阅读本文档需要具备的基础知识: Linux系统的基础知识,及基本命令网络基础知识:TCP/UDP、http、RESTful、域名解析、FQDN/hostname、hosts、防火墙、四层/七层负载均衡 本文档的阅读对象有:架构师、研发工程师,…...
Spring、Spring Boot、Spring Cloud 的区别与联系
1. Spring 框架 定位:轻量级的企业级应用开发框架,核心是 IoC(控制反转) 和 AOP(面向切面编程)。 核心功能: 依赖注入(DI):通过 Autowired、Component 等注解…...
AutoGen-构建问答智能体
概述 如https://github.com/microsoft/autogen所述,autogen是一多智能体的框架,属于微软旗下的产品。 依靠AutoGen我们可以快速构建出一个多智能体应用,以满足我们各种业务场景。 环境说明 python,3.10AutoGen,0.4.2…...
C语言实现括号匹配检查及栈的应用详解
目录 栈数据结构简介 C语言实现栈 栈的初始化 栈的销毁 栈的插入 栈的删除 栈的判空 获取栈顶数据 利用栈实现括号匹配检查 总结 在编程中,经常会遇到需要检查括号是否匹配的问题,比如在编译器中检查代码的语法正确性,或者在…...
C语言中的字符串与数组的关系
在C语言中,字符串和数组之间有着紧密的关系。理解它们的区别和联系对于编写高效且可靠的代码至关重要。在本篇博文中,我们将详细分析字符串和数组在C语言中的概念、它们的关系以及如何在编程中应用它们。 一、字符串与数组的基础知识 1.1 数组概念 在C语言中,数组是一组相…...
阿里云魔笔低代码应用开发平台快速搭建教程
AI低代码,大模型时代应用开发新范式 什么是魔笔 介绍什么是魔笔低代码应用开发平台。 魔笔是一款面向全端(Web、H5、全平台小程序、App)场景的模型驱动低代码开发平台,提供一站式的应用全生命周期管理,包括可视化开发…...
A Survey on Mixture of Experts 混合专家模型综述(第二部分:混合专家系统设计)
A Survey on Mixture of Experts 混合专家模型综述 (第一部分:混合专家算法设计) A Survey on Mixture of Experts arxiv github:A-Survey-on-Mixture-of-Experts-in-LLMs 5 System Design of Mixture of Experts While Mixture of Exper…...
docker python:latest镜像 允许ssh远程
跳转到家目录 cd创建pythonsshdockerfile mkdir pythonsshdockerfile跳转pythonsshdockerfile cd pythonsshdockerfile创建Dockerfile文件 vim Dockerfile将Dockerfile的指令复制到文件中 # 使用 python:latest 作为基础镜像 # 如果我的镜像列表中没有python:latest镜像&…...
通过 CSS 的 命名页面(Named Pages) 技术实现作用域隔离,实现 @page 样式仅影响当前组件
以下是实现 page 样式仅影响当前组件的完整解决方案,通过 CSS 的 命名页面(Named Pages) 技术实现作用域隔离: vue <template><div><button v-print"printOptions">打印当前报表</button><…...
Aim Robotics电动胶枪:机器人涂胶点胶的高效解决方案
在自动化和智能制造领域,机器人技术的应用越来越广泛,而涂胶和点胶作为生产过程中的重要环节,也逐渐实现了自动化和智能化。Aim Robotics作为一家专注于机器人技术的公司,其推出的电动胶枪为这一领域带来了高效、灵活且易于操作的…...
