C++之STL整理(2)之vector超详用法整理

C++之STL整理(2)之vector用法(创建、赋值、方法)整理

注:整理一些突然学到的C++知识,随时mark一下
例如:忘记的关键字用法,新关键字,新数据结构


C++ 的vector用法整理

  • C++之STL整理(2)之vector用法(创建、赋值、方法)整理
  • 一、vector的初始化
    • 1、默认构造函数
    • 2、拷贝构造函数copy区间
    • 3、指定数量和元素值的构造函数
    • 4、指定数量的构造函数
    • 5、拷贝构造函数
  • 二、vector的初始化-赋值
    • 1、.assign(beg, end) 赋值操作
    • 2、.assign(n, elem) 赋值操作
    • 3、重载等号操作符 operator=
    • 4、直接列表初始化 `Vector<T> {,};`
    • 5、swap 函数
  • 三、数据得增删查改
    • 1、at(int id)接口
    • 2、front()接口
    • 3、back()接口
    • 4、[id]直接取
    • 5、插入函数
    • 6、尾部添加 push_back(ele)
    • 7、尾部删去 pop_back()
    • 8、删区间
    • 9、删指定位置
    • 10、清空
  • 四、其他接口
    • 1、size()成员函数
    • 2、empty()
    • 3、resize(int num)
    • 4、capacity()
    • 5、reserve(int len)
  • 总结


提示:本文为 C++ 中 vector构造、赋值、接口 的写法和举例


一、vector的初始化

  根据vector的以下封装好的构造函数,现在示例每种构造方式的创建:

vector构造函数:vector<T> v; //默认构造函数
vector(v.begin(), v.end());//将v[begin(), end())区间中的元素copy给对象。
vector(n, elem);//构造函数将n个elem赋给对象。
vector(n);//构造函数将n个0或空赋值给对象。
vector(const vector &vec);//拷贝构造函数。

1、默认构造函数

创建一个空的vector。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v; // 创建一个空的vector  std::cout << "Size of vector v: " << v.size() << std::endl; // 输出:Size of vector v: 0  return 0;  
}

2、拷贝构造函数copy区间

假设有一个已存在的vector,我们想要创建一个新的vector并拷贝其中一部分元素。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {1, 2, 3, 4, 5};  std::vector<int> v2(v.begin(), v.begin() + 3); // 拷贝前3个元素  for (int num : v2) {  std::cout << num << " "; // 输出:1 2 3  }  std::cout << std::endl;  return 0;  
}

3、指定数量和元素值的构造函数

创建一个包含特定数量且所有元素都具有相同值的vector。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v(5, 10); // 创建一个包含5个10的vector  for (int num : v) {  std::cout << num << " "; // 输出:10 10 10 10 10  }  std::cout << std::endl;  return 0;  
}

4、指定数量的构造函数

创建一个包含特定数量的vector,所有元素默认初始化为该类型的默认值(对于基本类型如int,默认值为0)。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v(5); // 创建一个包含5个0的vector  for (int num : v) {  std::cout << num << " "; // 输出:0 0 0 0 0  }  std::cout << std::endl;  return 0;  
}

5、拷贝构造函数

从另一个已存在的vector创建一个新的vector,作为它的拷贝。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {1, 2, 3, 4, 5};  std::vector<int> v2(v); // 使用拷贝构造函数创建v2,它是v的拷贝  for (int num : v2) {  std::cout << num << " "; // 输出:1 2 3 4 5  }  std::cout << std::endl;  return 0;  
}

二、vector的初始化-赋值

vector常用赋值方式:
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值。
assign(n, elem);//将n个elem拷贝赋值。
vector& operator=(const vector  &vec);//重载=
Vector<T> = {,,,};//直接赋值一个数组
Vector<T>  {,,,};
swap(vec);// 与vec的元素互换。

1、.assign(beg, end) 赋值操作

使用区间迭代器将另一个容器或数组中的数据拷贝到vector中。

#include <iostream>  
#include <vector>  
#include <algorithm> // for std::next  int main() {  std::vector<int> v = {1, 2, 3, 4, 5};  int arr[] = {6, 7, 8, 9, 10};  v.assign(std::begin(arr), std::end(arr)); // 赋值arr数组到v  for (int num : v) {  std::cout << num << " "; // 输出:6 7 8 9 10  }  std::cout << std::endl;  return 0;  
}

2、.assign(n, elem) 赋值操作

将n个值为elem的元素拷贝到vector中。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v;  v.assign(5, 10); // 赋值5个10到v  for (int num : v) {  std::cout << num << " "; // 输出:10 10 10 10 10  }  std::cout << std::endl;  return 0;  
}

3、重载等号操作符 operator=

使用重载的等号操作符将一个vector的内容赋给另一个vector。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v1 = {1, 2, 3, 4, 5};  std::vector<int> v2;  v2 = v1; // 使用重载的等号操作符赋值v1到v2  for (int num : v2) {  std::cout << num << " "; // 输出:1 2 3 4 5  }  std::cout << std::endl;  return 0;  
}

4、直接列表初始化 Vector<T> {,};

在创建vector对象时,直接使用列表初始化语法。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {21, 22, 23, 24, 25}; // 直接列表初始化  for (int num : v) {  std::cout << num << " "; // 输出:21 22 23 24 25  }  std::cout << std::endl;  return 0;  
}

5、swap 函数

使用std::swap或vector的成员函数swap来交换两个vector的内容。

#include <iostream>  
#include <vector>  
#include <algorithm> // for std::swap  int main() {  std::vector<int> v1 = {1, 2, 3};  std::vector<int> v2 = {4, 5, 6};  std::swap(v1, v2); // 使用std::swap交换v1和v2的内容  // 输出交换后的v1  for (int num : v1) {  std::cout << num << " "; }std::cout << std::endl;  return 0;
}

三、数据得增删查改

vector数据存取操作,主要有at()、front()、back()接口和括号[]取得方法。
vector插入和删除操作,主要有insert、erase、clear、pushback、popback接口。

1、at(int id)接口

at成员函数用于通过索引访问元素,并且在索引越界时会抛出std::out_of_range异常。

#include <iostream>  
#include <vector>  
#include <stdexcept> // for std::out_of_range  int main() {  std::vector<int> v = {10, 20, 30, 40, 50};  try {  std::cout << v.at(2) << std::endl; // 输出:30  std::cout << v.at(10) << std::endl; // 抛出std::out_of_range异常  } catch (const std::out_of_range& e) {  std::cerr << "Index out of range: " << e.what() << std::endl;  }  return 0;  
}

2、front()接口

front成员函数返回容器中第一个元素的引用。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30, 40, 50};  std::cout << v.front() << std::endl; // 输出:10  return 0;  
}

3、back()接口

back成员函数返回容器中最后一个元素的引用。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30, 40, 50};  std::cout << v.back() << std::endl; // 输出:50  return 0;  
}

4、[id]直接取

operator[]通过索引直接访问元素,如果越界,行为是未定义的(通常会导致程序崩溃)。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30, 40, 50};  std::cout << v[2] << std::endl; // 输出:30  // std::cout << v[10] << std::endl; // 未定义行为,通常会导致程序崩溃  return 0;  
}

5、插入函数

insert(const_iterator pos, int count, ele)在迭代器pos指向的位置插入count个值为ele的元素。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 40, 50};  v.insert(v.begin() + 1, 2, 30); // 在索引1的位置插入2个30  for (int num : v) {  std::cout << num << " "; // 输出:10 30 30 20 40 50  }  std::cout << std::endl;  return 0;  
}

6、尾部添加 push_back(ele)

在容器的尾部插入一个元素ele。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30};  v.push_back(40); // 在尾部插入40  for (int num : v) {  std::cout << num << " "; // 输出:10 20 30 40  }  std::cout << std::endl;  return 0;  
}

7、尾部删去 pop_back()

删去容器的最后一个元素。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30, 40};v.pop_back(); // 删除最后一个元素40  for (int num : v) {  std::cout << num << " "; // 输出:10 20 30  }  std::cout << std::endl;  return 0;  
}

8、删区间

erase(const_iterator start, const_iterator end)删去从迭代器start到end(不包括end)之间的所有元素。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30, 40, 50};  v.erase(v.begin() + 1, v.begin() + 3); // 删除索引1到2之间的元素(即20和30)  for (int num : v) {  std::cout << num << " "; // 输出:10 40 50  }  std::cout << std::endl;  return 0;  
}

9、删指定位置

erase(const_iterator pos)删除迭代器pos指向的元素。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30, 40, 50};  v.erase(v.begin() + 2); // 删除索引2的元素(即30)  for (int num : v) {  std::cout << num << " "; // 输出:10 20 40 50  }  std::cout << std::endl;  return 0;  
}

10、清空

clear()删掉容器中的所有元素。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30, 40, 50};  v.clear(); // 删除所有元素  if (v.empty()) {  std::cout << "Vector is empty." << std::endl; // 输出:Vector is empty.  }  return 0;  
}

这些操作提供了对vector容器内容的灵活操作,可以轻松地插入和删除元素,以满足程序的需要。使用迭代器(或索引)时,请确保它们指向有效的容器位置,以避免未定义行为或异常。

四、其他接口

1、size()成员函数

返回容器中的元素个数。这个数量等于当前vector实际包含的元素数。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30, 40, 50};  std::cout << "Size of vector: " << v.size() << std::endl; // 输出:Size of vector: 5  return 0;  
}

2、empty()

empty成员函数检查容器是否为空。如果容器中没有元素,它返回true;否则返回false。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v;  if (v.empty()) {  std::cout << "Vector is empty." << std::endl; // 输出:Vector is empty.  } else {  std::cout << "Vector is not empty." << std::endl;  }  return 0;  
}

3、resize(int num)

resize成员函数用于改变容器的大小。如果新的大小num大于当前大小,则容器会增长,新添加的元素会被初始化为默认值(对于内置类型,通常是0)。如果num小于当前大小,则末尾超出的元素会被删除。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30};  v.resize(5); // 容器增长,新元素初始化为0  for (int num : v) {  std::cout << num << " "; // 输出:10 20 30 0 0  }  std::cout << std::endl;  v.resize(2); // 容器缩短,超出的元素被删除  for (int num : v) {  std::cout << num << " "; // 输出:10 20  }  std::cout << std::endl;  return 0;  
}

resize(int num, elem) 是resize的另一种重载形式。它允许你为新的元素指定一个初始值elem。如果容器增长,新添加的元素会被初始化为elem。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30};  v.resize(5, 42); // 容器增长,新元素初始化为42  for (int num : v) {  std::cout << num << " "; // 输出:10 20 30 42 42  }  std::cout << std::endl;  return 0;  
}

4、capacity()

capacity成员函数返回容器当前分配的存储空间大小。这通常大于或等于size返回的值,因为vector为了效率可能会预留一些额外的空间。

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v = {10, 20, 30};  std::cout << "Size: " << v.size() << ", Capacity: " << v.capacity() << std::endl;  // 输出可能类似于:Size: 3, Capacity: 3 或 Size: 3, Capacity: 4(取决于实现)  return 0;  
}

5、reserve(int len)

reserve成员函数用于预分配容器的存储空间。它并不改变容器的大小(即size的值不变),但会增加容器的capacity。预分配空间可以提高插入元素的效率,因为当容器需要增长时,它可能不需要重新分配整个存储空间。reserve成员函数用于预分配容器的存储空间,它可以帮助提高插入元素的效率,因为当容器需要增长时,如果已经有足够的预留空间,它就可以避免重新分配整个存储空间。

这里是一个更详细的例子,展示了如何使用reserve来预分配vector的存储空间:

#include <iostream>  
#include <vector>  int main() {  std::vector<int> v;  // 初始时,size和capacity都是0  std::cout << "Initial size: " << v.size() << ", Initial capacity: " << v.capacity() << std::endl;  // 使用reserve预分配至少10个元素的存储空间  v.reserve(10);  // size仍然是0,因为我们没有添加任何元素  // 但capacity至少为10  std::cout << "After reserve, size: " << v.size() << ", Capacity: " << v.capacity() << std::endl;  // 添加元素,直到达到或超过预留的capacity  for (int i = 0; i < 15; ++i) {  v.push_back(i);  }  // size现在是15,因为我们添加了15个元素  // capacity可能已经增长,以容纳更多的元素  std::cout << "After adding elements, size: " << v.size() << ", Capacity: " << v.capacity() << std::endl;  return 0;  
}

输出可能类似于:

Initial size: 0, Initial capacity: 0  
After reserve, size: 0, Capacity: 10  
After adding elements, size: 15, Capacity: 20 (或更大,取决于实现)

capacity的确切值可能因不同的vector实现而异。在上面的例子中,当添加超过预留capacity的元素时,vector可能会再次分配内存,并可能增加其capacity。这样做是为了避免在每次添加元素时都重新分配内存,从而提高性能。在实践中,如果你知道将要向vector中添加大量元素,使用reserve来预分配足够的空间通常是一个好习惯,因为这可以避免不必要的内存分配和元素复制。

总结

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

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

相关文章

苹果智能戒指专利获批,Find My功能为智能穿戴提供智能防丢

根据美国商标和专利局&#xff08;USPTO&#xff09;近日公示的清单&#xff0c;苹果公司获得了一项关于智能戒指的专利&#xff0c;展示了多种交互手势&#xff0c;不仅支持捏合、画圈等&#xff0c;而且支持玩“石头剪刀布”游戏。 这项新专利名为“皮肤间接触检测”&#xf…

解决“ValueError: negative dimensions are not allowed”错误的全面指南

一、问题背景与错误描述 在使用numpy库进行数组操作时&#xff0c;有时会遇到一个常见的错误&#xff1a;“ValueError: negative dimensions are not allowed”。这个错误通常发生在尝试创建或者调整numpy数组的形状时&#xff0c;提供的维度&#xff08;shape&#xff09;参数…

南京观海微电子---Vitis HLS设计流程介绍——Vitis HLS教程

1. 传统的FPGA设计流程 传统的RTL设计流程如下图所示&#xff1a; 传统的FPGA RTL设计流程主要是采用VHDL、VerilogHDL或System Verilog进行工程的开发&#xff0c;同时也是通过硬件描述语言来编写测试案例&#xff08;Test Bench&#xff09;对开发的工程进行仿真验证。 随后…

第十六节 JDBC PrepareStatement对象执行批量处理实例

以下是使用PrepareStatement对象进行批处理的典型步骤顺序 - 使用占位符创建SQL语句。使用prepareStatement()方法创建PrepareStatement对象。使用setAutoCommit()将自动提交设置为false。使用addBatch()方法在创建的Statement对象上添加SQL语句到批处理中。在创建的Statement…

基于单片机热电偶智能体温检测系统设计

**单片机设计介绍&#xff0c;基于单片机热电偶智能体温检测系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机热电偶智能体温检测系统设计概要 一、引言 本系统旨在通过单片机实现对人体体温的智能检测&#…

SpringBoot集成FreeMarker时访问不到.ftl文件

代码如下&#xff1a; RestController public class HelloController {RequestMapping("index")public String index(HttpServletRequest request){request.setAttribute("msg","这是freemarker页面........");return "index";} } 结…

一文教你学会用群晖NAS配置WebDAV服务结合内网穿透实现公网同步Zotero文献库

文章目录 前言1. Docker 部署 Trfɪk2. 本地访问traefik测试3. Linux 安装cpolar4. 配置Traefik公网访问地址5. 公网远程访问Traefik6. 固定Traefik公网地址 前言 Trfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件&#xff0c;能轻易的部署微服务。它支持多种后端 (D…

电缆故障测试仪的原理和组成部件分别是什么?

电缆故障测试仪是专为检测电缆线路中的各种故障而设计制造的精密电子设备&#xff0c;广泛应用于电力、通信、石油化工、航空航天等领域。这类仪器的工作原理和组成相对复杂&#xff0c;下面将详细阐述。 电缆故障测试仪的工作原理 电缆故障测试仪的核心原理通常涉及电磁波反…

【C语言】 gets()puts()fgets()fputs()字符串输入输出函数的用法

文章目录 C语言中的字符串输入输出函数&#xff1a;gets、puts、fgets与fputsgets函数puts函数fgets函数fputs函数 C语言中的字符串输入输出函数知识点总结结语 C语言中的字符串输入输出函数&#xff1a;gets、puts、fgets与fputs 在C语言中&#xff0c;处理字符串的输入和输出…

SpringBoot -- 自动配置机制

使用SpringBoot框架可以让我们快速的构建一个web项目并能成功运行&#xff0c;而之前的SSM则需要我们大量的配置。那么&#xff0c;SpringBoot为什么可以如此神奇&#xff0c;这是怎么做到的呢&#xff1f;那就要介绍一下SpringBoot的自动配置机制。那么&#xff0c;SpringBoot…

用系统观念打造智慧公厕,引领智慧城市的发展

智慧公厕&#xff0c;作为智慧城市建设的一部分&#xff0c;具有重要意义。在高度发达的科技条件下&#xff0c;如何打造高质量的智慧公厕是一个值得思考的问题。本文将以智慧公厕源头实力厂家广州中期科技有限公司&#xff0c;大量精品案例项目现场实景实图实例&#xff0c;探…

Java I/O

什么是 IO流&#xff1f; 存储和读取数据的解决方案 I: input O: output 流&#xff1a;像水流一样传输数据 IO流的作用&#xff1f; 用于读写数据&#xff08;本地文件&#xff0c;网络&#xff09; IO流从 传输方式 分类 字符是给人看的&#xff0c;字节是给计算机看的。 …

【SpringBoot】了解简单原理 Bean管理 配置优先级

文章目录 一、配置优先级1.1 命令行设置端口号1.2 打包后修改端口号1.3 优先级 小结 二、Bean的管理2.1 获取Bean2.2 Bean作用域2.3 第三方Bean 三、剖析Springboot的底层原理3.1 起步依赖3.2 自动配置3.2.1 第三方类装配3.2.2 原理分析 总结Web后端开发总结&#xff1a;源码跟…

计算机专业学习单片机有什么意义吗?

玩单片机跟玩计算机区别还是很大的, 单片机有众多的种类,每一种又可能有很多个系列.可以说单片机就是为了专款专用而生的.这样来达到产品成本的降低,这就是现在身边的很多的电子产品价格一降再降的原因之一.在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一…

阅读FAST-LIO2(Lidar-IMU)论文

一、摘要 本文介绍了 FAST-LIO2&#xff1a;一种快速、稳健且通用的 LiDAR 惯性里程计框架。 FASTLIO2 建立在高效紧耦合迭代卡尔曼滤波器的基础上&#xff0c;具有两个关键创新&#xff0c;可实现快速、稳健和准确的 LiDAR 导航&#xff08;和映射&#xff09;。第一个是直接将…

热门主食冻干希喂/PURPOSE/百利测评对比!真实喂养分享!

在当今科学养宠的时代里&#xff0c;主食冻干已经成为猫咪日常饮食的重要一环。主食冻干的高肉含量特性使其易于被猫咪吸收和消化&#xff0c;同时&#xff0c;它还能提供其他猫粮所无法提供的微量物质&#xff0c;满足猫咪的全面营养需求。然而&#xff0c;面对市面上众多品牌…

Java SPI 机制

SPI 机制的定义 在Java中&#xff0c;SPI&#xff08;Service Provider Interface&#xff09;机制是一种用于实现软件组件之间松耦合的方式。它允许在应用程序中定义服务接口&#xff0c;并通过在类路径中发现和加载提供该服务的实现来扩展应用程序功能。 SPI 机制通常涉及三…

信创实力进阶,Smartbi再获华为云鲲鹏技术认证

日前&#xff0c;经华为技术有限公司评测&#xff0c;思迈特商业智能与数据分析软件Smartbi Insight V11与华为技术有限公司Kunpeng 920 Taishan 200完成并通过相互兼容性测试认证&#xff0c;成功再获华为云鲲鹏技术认证书&#xff0c;标志着Smartbi与华为云鲲鹏产业生态合作更…

动态规划相关题目

文章目录 1.动态规划理论基础2.斐波那契数3.爬楼梯4.使用最小花费爬楼梯5.不同路径6.不同路径 II7. 整数拆分8. 不同的二叉搜索树 1.动态规划理论基础 1.1 什么是动态规划? 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一…

nginx mirror 流量镜像

流量镜像 (Traffic Mirroring)&#xff0c;也称为流量影子 (Traffic Shadowing)&#xff0c;是一种强大的、无风险的测试应用版本的方法&#xff0c;它将实时流量的副本发送给被镜像的服务。 采用这种方法&#xff0c;您可以搭建一个与原环境类似的环境以进行验收测试&#xff…