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);
交换后 arrarr2 内容互换。
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 }

关键特性总结

  1. 固定大小N 在编译时确定,不可动态调整。
  2. 栈分配:元素存储在栈内存,访问速度快。
  3. 兼容STL:支持迭代器、算法(如 std::sort)。
  4. 零开销抽象:性能与原生数组相当,但更安全。
文章目录