当初自学 c++ 与 c 语言时,一直被指针弄的云里雾里。后来 c++ 中引入了容器,避免了指针。但是,一些教材把容器的章节放在书本中后面的章节,太不合理。应该把这种方便的功能放到前面,这样一些初学者就不会遇到太多生硬难懂的知识点从而对这个语言望而却步了。这篇博客让 AI 总结了相关知识点,方便自己以后查阅。
总结:
- 对于定长数组,用 array
- 不定长数组,用 vector
- 计算规模巨大,实在想优化计算速度,用指针
文章目录
- 一、 C++ 中的 `std::vector`
- 1. `std::vector` 基本使用
- (1) 引入 `<vector>` 头文件
- (2) 创建和初始化
- 2. `std::vector` 的核心方法
- 3. `vector` 详细示例
- (1) `push_back()` 和 `pop_back()`
- (2) `insert()` 和 `erase()`
- 4. `vector` 与普通数组的对比
- 5. 总结
- 二、 C++ 中的 `std::array`
- 1. `std::array` 的特点
- 2. `std::array` 的基本用法
- (1) 创建与初始化
- 3. `std::array` 的常用方法
- 4. `std::array` 方法示例
- 5. `std::array` 与 C 风格数组的对比
- 6. `std::array` 在 STL 算法中的使用
- 7. 总结
一、 C++ 中的std::vector
在 C++ 中,std::vector是动态数组容器,提供了自动扩展、随机访问等功能,是std::array和std::list之间的高效选择。
std::vector定义在<vector>头文件中,属于STL(标准模板库)的一部分。
1.std::vector基本使用
(1) 引入<vector>头文件
#include<iostream>#include<vector>intmain(){std::vector<int>v={1,2,3,4,5};// 遍历 vectorfor(inti:v){std::cout<<i<<" ";}return0;}输出:
1 2 3 4 5(2) 创建和初始化
一般有两种方法:
- 用“大小 + 初始值”初始化
std::vector<int>v2(5);// 5 个 0 的一维数组std::vector<int>v2(5,1);// 5 个 1 的一维数组// 小括号与中括号是不同的std::vector<int>v2[5];// 这里表示创建 5 个一维空数组// 创建二维数组比较麻烦,下面是 4 行 3 列的二维数组,元素值都为 0std::vector<std::vector<double>>v1(4,std::vector<double>(3));// 下面是 4 行 3 列的二维数组,每列元素值都为 {1, 2, 3}std::vector<std::vector<double>>v1(4,std::vector<double>{1,2,3});// 创建二维数组还有下面的简便表达std::vectorv1(4,std::vector<double>(3));- 范围初始化
std::vector<int>v3={10,20,30};// 列表初始化std::vector<int>v5(v3.begin(),v3.end());// 迭代器初始化std::vector<int>v5(v3.begin(),v3.begin()+2);// 迭代器初始化还有一些例子:
#include<iostream>#include<vector>intmain(){std::vector<int>v1;// 空 vectorstd::vector<int>v2(5);// 5 个 0 的一维数组// 小括号与大括号是不同的std::vector<int>v2[5];// 这里表示创建 5 个一维空数组// 创建二维数组比较麻烦,下面是 4 行 3 列的二维数组,元素值都为 0std::vector<std::vector<double>>v1(4,std::vector<double>(3));// 下面是 4 行 3 列的二维数组,每列元素值都为 {1, 2, 3}std::vector<std::vector<double>>v1(4,std::vector<double>{1,2,3});// 创建二维数组还有下面的简便表达std::vectorv1(4,std::vector<double>(3));std::vector<int>v2(5,100);// 5 个 100std::vector<int>v3={10,20,30};// 列表初始化std::vector<int>v4(v3);// 复制 v3std::vector<int>v5(v3.begin(),v3.end());// 迭代器初始化for(intx:v2)std::cout<<x<<" ";// 输出: 100 100 100 100 100}- 注意:数组变量最后用小括号还是中括号是不一样的。
- 若数组为一个类中的属性,可以用大括号表示子数组的数量,例如,下面表示数组里面有两个子数组:
std::vector<std::vector<int>>recorded_pivot{2};- 初始化容器也可以使用列表初始化(适合固定内容):
std::vector<std::vector<int>>matrix={{1,2,3},{4,5,6},{7,8,9}};2.std::vector的核心方法
| 方法 | 作用 |
|---|---|
push_back(value) | 在末尾添加元素 |
pop_back() | 删除末尾元素 |
size() | 返回元素个数 |
capacity() | 返回当前容量 |
resize(n) | 调整大小(可能会丢弃元素) |
clear() | 清空所有元素 |
empty() | 判断是否为空 |
insert(it, value) | 在指定位置插入元素 |
erase(it) | 删除指定位置的元素 |
front()/back() | 返回首/尾元素 |
at(i) | 获取指定索引元素(带边界检查) |
operator[] | 获取指定索引元素(无边界检查) |
data() | 返回指向内部连续存储数组的指针(首元素地址) |
3.vector详细示例
(1)push_back()和pop_back()
#include<iostream>#include<vector>intmain(){std::vector<int>v;v.push_back(1);v.push_back(2);v.push_back(3);std::cout<<"Size: "<<v.size()<<std::endl;// 3std::cout<<"Last Element: "<<v.back()<<std::endl;// 3v.pop_back();// 删除 3std::cout<<"Size after pop: "<<v.size()<<std::endl;// 2}输出:
Size: 3 Last Element: 3 Size after pop: 2(2)insert()和erase()
#include<iostream>#include<vector>intmain(){std::vector<int>v={1,2,3,4,5};v.insert(v.begin()+2,99);// 在索引 2 位置插入 99v.erase(v.begin()+1);// 删除索引 1 位置的元素for(intx:v)std::cout<<x<<" ";}输出:
1 99 3 4 54.vector与普通数组的对比
| 特性 | std::vector | 普通数组(C-style array) |
|---|---|---|
| 大小可变 | ✅自动扩展 | ❌固定大小 |
| 安全性 | ✅带边界检查 (at()) | ❌无边界检查 |
| 初始化 | ✅支持列表初始化 | ⚠️手动初始化 |
| 复制 | ✅支持赋值 (=) | ❌需要memcpy() |
| 性能 | ⚠️可能有额外开销 | ✅更快(不涉及动态分配) |
| STL 支持 | ✅可与std::algorithm配合 | ❌手动实现排序、查找等 |
5. 总结
std::vector是 C++ 动态数组,支持自动扩展、插入、删除等功能。- 比普通数组更安全,支持
size(),push_back(),insert(),erase()等操作。 - 适用于大部分需要动态管理数组的场景,但在高性能需求下可以考虑
std::array或std::deque。
二、 C++ 中的std::array
在 C++ 中,std::array是STL(标准模板库)提供的定长数组容器,它是std::vector和 C 风格数组 (C-style array) 之间的折中方案,提供了更安全且性能优越的数组管理方式。
1.std::array的特点
| 特点 | 描述 |
|---|---|
| 固定大小 | std::array<T, N>的大小N在编译期确定,无法动态改变。 |
支持std::vector风格的接口 | 拥有.size(),.at(),.front(),.back(),.fill()等方法。 |
支持std::algorithm | 可与std::sort(),std::reverse()等标准库算法配合使用。 |
| 内存布局 | 与 C 风格数组相同,连续存储,性能与C-style array相当,但更安全。 |
2.std::array的基本用法
(1) 创建与初始化
#include<iostream>#include<array>intmain(){std::array<int,5>arr1={1,2,3,4,5};// 列表初始化std::array<int,5>arr2={0};// 仅初始化第一个元素为 0,其余为 0std::array<int,5>arr3{};// 全部初始化为 0for(intnum:arr1)std::cout<<num<<" ";// 1 2 3 4 5return0;}3.std::array的常用方法
| 方法 | 作用 |
|---|---|
size() | 返回数组大小(固定值N)。 |
at(index) | 获取指定索引的元素(带边界检查)。 |
operator[] | 获取指定索引的元素(不带边界检查)。 |
front() | 获取第一个元素。 |
back() | 获取最后一个元素。 |
fill(value) | 将所有元素设置为value。 |
swap(other) | 交换两个std::array的内容。 |
data() | 返回指向底层数组的指针。 |
4.std::array方法示例
#include<iostream>#include<array>intmain(){std::array<int,5>arr={10,20,30,40,50};std::cout<<"Size: "<<arr.size()<<std::endl;// 5std::cout<<"First: "<<arr.front()<<std::endl;// 10std::cout<<"Last: "<<arr.back()<<std::endl;// 50arr.fill(100);// 全部赋值为 100for(intx:arr)std::cout<<x<<" ";// 100 100 100 100 100return0;}输出:
Size: 5 First: 10 Last: 50 100 100 100 100 1005.std::array与 C 风格数组的对比
| 特性 | std::array | C 风格数组 (T arr[N]) |
|---|---|---|
| 大小 | 固定,编译期确定 | 固定,编译期确定 |
| 安全性 | ✅at()带边界检查 | ❌越界访问未定义行为 |
| STL 兼容性 | ✅支持std::algorithm | ❌不兼容 STL |
| 拷贝 | ✅支持赋值(深拷贝) | ❌数组名是指针,不能直接赋值 |
| 性能 | ✅等同于 C 数组 | ✅等同于std::array |
| 获取大小 | ✅.size() | ❌ 需sizeof(arr)/sizeof(arr[0]) |
6.std::array在 STL 算法中的使用
#include<iostream>#include<array>#include<algorithm>// 用于 sort()intmain(){std::array<int,5>arr={30,10,50,20,40};std::sort(arr.begin(),arr.end());// 排序for(intx:arr)std::cout<<x<<" ";// 10 20 30 40 50}输出:
10 20 30 40 50✅std::array支持std::sort()、std::reverse()、std::find()等 STL 算法。
7. 总结
| 特性 | std::array | std::vector | C 风格数组 |
|---|---|---|---|
| 大小可变 | ❌ 否 | ✅ 是 | ❌ 否 |
| 边界检查 | ✅at() | ✅at() | ❌ 否 |
| STL 兼容 | ✅ 是 | ✅ 是 | ❌ 否 |
| 性能 | ✅ 高效 | ⚠️ 可能有额外分配 | ✅ 高效 |
✅如果数组大小固定,推荐使用std::array。
✅如果数组需要动态扩展,使用std::vector。
✅C 风格数组适用于对性能要求极高且手动管理数组的情况。
🚀你对std::array还有其他问题吗?