100 std::array(固定大小的顺序容器)
作者Lou Xiao, deepseek创建时间2025-04-02 16:52:54更新时间2025-04-02 16:52:54
1. 概述
- 定义:
std::array
是 C++11 引入的固定大小的顺序容器,封装了传统 C 风格数组并提供 STL 接口。 - 特点:
- 大小固定,编译时确定。
- 存储在栈内存(除非显式分配在堆上)。
- 支持迭代器、算法、范围遍历等 STL 特性。
- 比原生数组更安全(如边界检查的
at()
方法)。
2. 基本用法
2.1 头文件:
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
#include <array>
2.2 声明与初始化:
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
std::array<int, 5> arr1; // 未初始化
2
std::array<int, 3> arr2 = {1, 2, 3}; // 聚合初始化
3
std::array<int, 4> arr3{}; // 值初始化(全 0)
2.3 访问元素:
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
arr[0] = 10; // 下标访问(无边界检查)
2
arr.at(1) = 20; // 带边界检查(越界抛出 std::out_of_range)
3
int front = arr.front(); // 首元素
4
int back = arr.back(); // 末元素
3. 核心成员函数
方法 | 功能描述 |
---|---|
size() | 返回元素数量(编译时常量)。 |
empty() | 检查是否为空(对 std::array 始终为 false ,除非大小为 0)。 |
fill(val) | 用 val 填充所有元素。 |
data() | 返回指向底层数组的指针(兼容 C 接口)。 |
begin()/end() | 返回迭代器,支持范围遍历。 |
rbegin()/rend() | 反向迭代器。 |
4. 与原生数组的对比
特性 | std::array | 原生数组(如 int[5] ) |
---|---|---|
内存管理 | 自动析构 | 需手动管理 |
边界检查 | 支持 at() | 无 |
赋值操作 | 支持 = 深拷贝 | 仅支持逐元素复制 |
作为函数参数 | 传值/传引用均可(不退化) | 退化为指针 |
类型信息 | 保留大小信息(模板参数) | 丢失大小信息 |
5. 高级特性
5.1 编译时大小获取:
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
constexpr size_t size = std::tuple_size<std::array<int, 5>>::value; // C++11
2
constexpr auto size = arr.size(); // C++17 起支持 constexpr
5.2 结构化绑定(C++17):
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
std::array<int, 3> arr = {1, 2, 3};
2
auto [x, y, z] = arr; // x=1, y=2, z=3
5.3 与其他容器交互:
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
std::vector<int> vec(arr.begin(), arr.end()); // 转换为 vector
6. 性能与注意事项
- 性能:
- 与原生数组几乎相同(无额外开销)。
operator[]
不检查边界,比at()
更快。- 限制:
- 大小必须在编译时已知(动态大小需用
std::vector
)。 - 不可扩容或缩容。
- 最佳实践:
- 优先使用
std::array
替代原生数组以提高安全性。 - 需要动态大小时改用
std::vector
。
7. 示例代码
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
#include <array>
2
#include <iostream>
3
4
int main() {
5
std::array<int, 4> arr = {10, 20, 30, 40};
6
7
// 遍历
8
for (int x : arr) {
9
std::cout << x << " ";
10
}
11
12
// 修改元素
13
arr.fill(0); // 全部置 0
14
arr[1] = 100;
15
16
// 检查大小
17
std::cout << "\nSize: " << arr.size(); // 输出 4
18
}
8. 总结
- 适用场景:已知固定大小的数组需求,需安全性或 STL 兼容性时。
- 不适用场景:需要动态调整大小或大小在运行时确定时。
通过 std::array
,C++ 程序员可以更安全、更高效地处理固定大小的数组操作,同时享受现代 C++ 的便利特性。
附录:Array方法表
以下是 std::array
常用 API 的整理表格,包含名称、用途、原型、代码示例和注释:
名称 | 用途 | 原型 | 代码示例 | 注释 |
---|---|---|---|---|
构造函数 | 创建 std::array 对象 | array<T, N> arr; array<T, N> arr = {init_list}; | std::array<int, 3> arr = {1, 2, 3}; | 默认构造或通过初始化列表构造。N 为编译时常量。 |
at | 安全访问元素(带边界检查) | reference at(size_type pos); const_reference at(size_type pos) const; | int x = arr.at(1); arr.at(2) = 5; | 越界时抛出 std::out_of_range 异常。 |
operator[] | 快速访问元素(无边界检查) | reference operator[](size_type pos); const_reference operator[](size_type pos) const; | int x = arr[0]; arr[1] = 10; | 性能更高,但越界行为未定义。 |
front | 访问第一个元素 | reference front(); const_reference front() const; | int first = arr.front(); | 等价于 arr[0] 或 arr.at(0) 。 |
back | 访问最后一个元素 | reference back(); const_reference back() const; | int last = arr.back(); | 等价于 arr[N-1] 或 arr.at(N-1) 。 |
data | 获取底层数组指针 | T* data() noexcept; const T* data() const noexcept; | int* ptr = arr.data(); std::cout << *(ptr + 1); | 返回指向连续内存的指针,可用于 C 风格 API。 |
begin | 返回指向首元素的迭代器 | iterator begin() noexcept; const_iterator begin() const noexcept; | for (auto it = arr.begin(); it != arr.end(); ++it) { ... } | 支持范围遍历,常与 end() 配合使用。 |
end | 返回尾后迭代器 | iterator end() noexcept; const_iterator end() const noexcept; | auto it = std::find(arr.begin(), arr.end(), 42); | 指向最后一个元素的下一个位置。 |
size | 返回元素数量 | constexpr size_type size() const noexcept; | std::cout << "Size: " << arr.size(); | 编译时确定的值,固定为 N 。 |
empty | 检查是否为空 | constexpr bool empty() const noexcept; | if (!arr.empty()) { ... } | 对 std::array 恒返回 N == 0 (编译时常量)。 |
fill | 填充所有元素为指定值 | void fill(const T& value); | arr.fill(42); | 所有元素被赋值为 value 。 |
swap | 交换两个同类型数组的内容 | void swap(array& other) noexcept; | std::array<int, 3> arr2 = {4, 5, 6}; arr.swap(arr2); | 交换后 arr 和 arr2 内容互换。 |
get (非成员) | 通过索引或类型访问元素(结构化绑定) | template<size_t I, class T, size_t N> T& get(array<T, N>& arr) noexcept; | auto [a, b, c] = arr; int x = std::get<1>(arr); | 需 C++17 支持结构化绑定,索引必须在 [0, N) 范围内。 |
示例代码(综合)
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
#include <array>
2
#include <iostream>
3
4
int main() {
5
std::array<int, 3> arr = {1, 2, 3};
6
7
// 访问元素
8
std::cout << arr.at(1) << "\n"; // 2
9
std::cout << arr[0] << "\n"; // 1
10
11
// 迭代器遍历
12
for (auto it = arr.begin(); it != arr.end(); ++it) {
13
std::cout << *it << " "; // 1 2 3
14
}
15
16
// 填充并交换
17
arr.fill(10);
18
std::array<int, 3> arr2 = {4, 5, 6};
19
arr.swap(arr2);
20
21
// C++17 结构化绑定
22
auto [x, y, z] = arr;
23
std::cout << x << "," << y << "," << z; // 4,5,6
24
}
关键特性总结
- 固定大小:
N
在编译时确定,不可动态调整。 - 栈分配:元素存储在栈内存,访问速度快。
- 兼容STL:支持迭代器、算法(如
std::sort
)。 - 零开销抽象:性能与原生数组相当,但更安全。
文章目录