当前位置: 首页 > article >正文

「C++笔记」vector:C++中的新式“数组”

「C++笔记」这个系列是我最近学习新版本的 C++ 版本的笔记,材料主要是《A Tour of C++ Third Edition》。这本书的作者就是 C++ 的作者 Bjarne Stroustrup,所以也会记录一些他的思想。
版本主要是 20/23 这些,不过我对 11 的了解也不完善,所以可能也会有一些大家早就知道的。

介绍

C++ 中,有一种容器叫做 vector,它的定义和作用与数组差不多,都是同一种类型的元素序列,在内存中连续存储。

但是在实现的时候,要比数组要复杂一些:大致来说,它会动态分配内存空间,然后有三个指针指向元素序列的开头和结尾,以及空闲区域的末尾(有的会用偏移量记录)。所以 vector 的结构是一个内存分配器和三个指针。如下:
请添加图片描述

不过 vector 有一些新的特性,非常方便使用,就连 C++ 创始人 Bjarne Stroustrup 都推荐使用vector,如下是《A Tour of C++ Third Edition》中的内容,并且也强调不用担心效率、性能问题:

请添加图片描述

容器还有个很好的特性就是不用担心内存回收。因为 C++ 没有垃圾回收机制,很容易粗心使得内存只分配,不回收,最后占用一大堆内存,这也是 C++ 一直被诟病的问题。但是容器很容易解决了这个问题,因为构造函数分配了内存,最后不用了会有析构函数回收(我是看这书才反应过来析构函数的作用是这个,之前一直当作结束生命周期的,没反应过来)。所以使用 vector 要比数组好很多,不然很容易忘记最后free或者delete[]

用法

相似

简单地声明和定义一个 vector 与数组差不多,如下:

vector<int> v1;
v1= {1, 2, 3, 4};
vector<int> v1 = {1, 2, 3, 4};

这里的<>中的int表示这里的元素类型是int,其余部分会发现和数组一样,比如赋值是大括号,序号从 0 开始等等。

同样,我们可以预先声明 vector 的大小:

vector<int> v2(23);

上面这个 vector 的尺寸是 23(需要注意不是数组的方括号,而是圆括号)。

如果你想声明一个整数指针的序列,那么使用下面的样式:

vector<int*> v3;

新玩意

本文无意做翻译文档的作用,所以只记录一些我觉得有用,或者学了之后一通百通的内容。

声明尺寸与初始值

vector 有一些新的特性:假设你想声明有 10 个整数的数组,但是这个数组的初始值为 3。按照数组的方法,需要先声明一个固定尺寸的数组,然后用循环赋值。如下:

int a[10];
for (int i=0; i<10; i++) {
	a[i]=3;
}

但是 vector 就很方便了,声明的时候就能搞定,如下:

vector<int> a(10, 3);
新增单个元素

增加元素需要使用成员函数push_back()(给结尾)和insert()

前者如下:

#include <iostream>

using namespace std;

int main() {
    std::vector<int> v1 = {1, 2, 3, 4};
    //循环输出
    for (const auto& x : v1)
        cout << x << ' ';
    cout << '\n';
    //在尾部添加两个元素
    v1.push_back(1);
    v1.push_back(2);
    //循环输出
    for (const auto& x : v1)
        cout << x << ' ';
    cout << '\n';
}

输出:

1 2 3 4 
1 2 3 4 1 2 

后者麻烦一些,如下:

#include <iostream>
#include <valarray>

using namespace std;

int main() {
    std::vector<int> v1 = {1, 2, 3, 4};
    //循环输出
    for (const auto& x : v1)
        cout << x << ' ';
    cout << '\n';
    //插入到从头开始第三个位置(因为从0开始,所以+2)
    v1.insert(v1.begin()+2,100);
    //循环输出
    for (const auto& x : v1)
        cout << x << ' ';
    cout << '\n';   
}

输出:

1 2 3 4 
1 2 100 3 4 

代码中的v1.begin()+2是位置,这个参数也可以设置成中间的某个元素的位置。

valarray:vector向量计算

vector 虽然有向量的意思,但是并不能进行向量计算。不过标准库<valarray>里提供了一个 vector 类的模板 valarray,可以像 SIMD 一样进行计算,这使得处理一些数据的时候方便了很多:

#include <iostream>
#include <valarray>

using namespace std;

int main() {
    valarray<int> v1 = {1, 2, 3, 4};
    valarray<int> v2 = {4, 3, 2, 1};
    
    //这里会对整个valarray进行计算,不用自己写循环
    valarray<int> v3 = v1*v2 + v1/v2 + v1 * 12;
    
    //循环输出
    for (const auto& x : v3)
        cout << x << '\n';
    
}

其实如果你使用过其他现代语言的数组,会发现很多成员函数都是相似的,语法除了名字几乎没什么不同,只不过一开始上手还是需要熟悉一下。

希望能帮到有需要的人~

参考资料

《A Tour of C++ Third Edition》

std::vector - cppreference.com:C++ vector 中文文档,很多本文没有提到的功能都可以自行查看这里。


http://www.kler.cn/a/466863.html

相关文章:

  • 【数据结构05】排序
  • YIG带通滤波器
  • docker中使用Volume完成数据共享
  • springboot3 redis 批量删除特定的 key 或带有特定前缀的 key
  • 解决 ffmpeg “Unknown encoder ‘hevc_nvenc‘“
  • 我用AI学Android Jetpack Compose之开篇
  • 新服务器Linux网络配置
  • vue+js+Java在分页的el-table里实现上移、下移;置顶
  • 计算机网络复习(学习通作业4、5、6系统答案)
  • 细说STM32F407单片机轮询方式CAN通信
  • 【读书笔记·VLSI电路设计方法解密】问题36:一个好的设计流程有哪些特点
  • C语言里面的size_t是什么意思
  • 云计算在医疗行业的应用
  • 设计模式中的代理模式
  • Node.js - 文件操作
  • C++例程:使用其I/O模拟IIC接扣(2)
  • 电脑更新后无法连接网络怎么解决 网络恢复方法
  • Transformer中Self-Attention以及Multi-Head Attention模块详解(附pytorch实现)
  • web漏洞之文件包含漏洞
  • [网络安全]DVWA之SQL注入—low level解题详析
  • Spring Boot自动装配代码详解
  • python +tkinter绘制彩虹和云朵
  • 2025年股指期货每月什么时候交割?
  • 探索光耦:光耦在风力发电中的应用——保障绿色能源的高效与安全
  • ubuntu16 重启之后lvm信息丢失故障恢复
  • Eureka 介绍与原理详解