39 C++ STL模板库8-容器1-array
C++ STL模板库8-容器1-array
文章目录
- C++ STL模板库8-容器1-array
- 1. 基础概念
- 2. 模板参数
- 3. 与C数组的核心差异
- 4. 元素访问方法
- 5. 迭代器支持
- 6. 容量操作
- 7. 其他关键操作
- 8. 完整示例
1. 基础概念
array
- 静态数组
- 本质:封装固定大小数组的容器模板(
#include <array>
)。 - 特性:
- 编译时确定大小(
size()
是constexpr
)。 - 内存布局与C风格数组完全兼容(可直接用于C 的 API)。
- 支持STL容器标准接口(迭代器、算法等)。
- 编译时确定大小(
2. 模板参数
std::array<T, N> arr; // T:元素类型, N:固定大小
- 示例:
std::array<int, 5> nums = {1, 2, 3};
- 未初始化元素默认值为
0
(剩余位置自动补零)。
- 未初始化元素默认值为
3. 与C数组的核心差异
特性 | std::array | C风格数组 |
---|---|---|
赋值/传参 | 支持拷贝赋值(深拷贝) | 退化为指针 |
大小查询 | arr.size() 直接获取 | 需额外计算 sizeof(arr)/sizeof(T) |
越界访问检查 | at(i) 抛出异常 | 无检查 |
类型安全 | 强类型容器 | 易退化为 void* |
4. 元素访问方法
- 安全访问:
arr.at(i)
→ 越界时抛std::out_of_range
。 - 快速访问:
arr[i]
→ 无边界检查(效率高,需自行保证安全)。
-arr.front()
→ 返回首元素引用
-arr.back()
→ 返回尾元素引用 - 底层指针:
arr.data()
→ 返回指向底层数组的T*
(兼容C API)。
5. 迭代器支持
-
正向迭代器
函数 功能 begin() / cbegin()
返回指向首元素的迭代器 end() / cend()
返回指向尾后位置的迭代器 -
反向迭代器
函数 功能 rbegin() / crbegin()
返回指向反向首元素的迭代器 rend() / crend()
返回指向反向尾后位置的迭代器 // 正向遍历 for (auto it = arr.begin(); it != arr.end(); ++it) { ... }// 反向遍历 for (auto rit = arr.rbegin(); rit != arr.rend(); ++rit) { ... }
- 支持所有
STL
算法(如std::sort(arr.begin(), arr.end())
)。
- 支持所有
6. 容量操作
函数 | 功能 |
---|---|
size() | 返回元素数量(编译时常量) |
max_size() | 恒等于 size() (保持容器接口兼容性) |
empty() | 仅当 size() == 0 时返回 true |
-
size()
是constexpr
函数(编译时可用)constexpr std::array arr{1, 2, 3}; static_assert(arr.size() == 3); // 编译期验证
7. 其他关键操作
- 填充:
arr.fill(42)
→ 所有元素赋值为42。 - 交换:
arr1.swap(arr2)
→ 交换两个同类型array
的内容。 - 关系运算:支持
==
,!=
,<
,>
等(按字典序比较元素)。 =
数组赋值,类型和大小相同时可以赋值。std::get<0>(arr)
访问数组元素
std::array<int, 4> a{7,8,9,0};
std::array<int, 4> b = a;//把数组 a 赋值给了数组 b//get<>()访问元素
std::get<0>(a) = 1, std::get<1>(a) = 2, std::get<2>(a) = 3;//get<>()访问元素
std::cout << '(' << std::get<0>(a) << ',' << std::get<1>(a) << ',' << std::get<2>(a) << ")\n";//(1,2,3)
8. 完整示例
#include <iostream>
#include <array>
#include <algorithm> // 用于排序
#include <string>int main() {// ========== 1. 初始化与声明 ==========std::array<int, 5> nums1{}; // 默认初始化(元素值未定义)std::array<double, 3> nums2{1.1, 2.2}; // 部分初始化(第三个元素=0.0)std::array<std::string, 3> colors{"Red", "Green", "Blue"}; // C++17 CTAD推导 // ========== 2. 元素访问 ==========// (1) 安全访问colors.at(0) = "Crimson"; // 修改首元素(越界会抛异常)// (2) 快速访问 nums2[2] = 3.3; // 直接修改第三个元素// (3) 首尾访问std::cout << "首元素: " << nums2.front() << "\n"; // 输出 1.1std::cout << "尾元素: " << nums2.back() << "\n"; // 输出 3.3// (4) 底层指针 double* ptr = nums2.data(); std::cout << "指针访问: " << *(ptr + 1) << "\n"; // 输出 2.2// ========== 3. 容量操作 ==========std::cout << "元素数量: " << colors.size() << "\n"; // 输出 3 std::cout << "最大容量: " << colors.max_size() << "\n"; // 输出 3std::cout << "是否为空: " << std::boolalpha << std::array<int, 0>{}.empty() << "\n"; // 输出 true// ========== 4. 迭代器操作 ==========// (1) 正向遍历std::cout << "正向: ";for (auto it = colors.begin(); it != colors.end(); ++it) std::cout << *it << " "; // 输出 Crimson Green Blue // (2) 反向遍历 + 算法 std::cout << "\n反向排序: ";std::sort(colors.rbegin(), colors.rend()); // 反向排序 (按字母排序)for (const auto& color : colors) std::cout << color << " "; // 输出 Green Crimson Blue// ========== 5. 填充与交换 ==========nums1.fill(100); // 所有元素设为100std::array<int, 5> nums3{};nums1.swap(nums3); // 交换内容 // ========== 6. 结构化绑定 (C++17) ==========auto [first, second, third] = colors;std::cout << "\n解构: " << second << "\n"; // 输出 Crimson // ========== 7. 编译时操作 ==========constexpr std::array<int, 4> const_arr{1, 2, 0, 5}; // static_assert(const_arr.size() == 4); // 编译期检查 static_assert(const_arr[3] == 5); // 编译期访问 // ========== 8. 非成员函数 ==========// (1) 元组接口访问 std::cout << "get<2>: " << std::get<2>(nums2) << "\n"; // 输出 3.3 // (2) 比较运算符std::array a{1,2}, b{1,3};std::cout << "字典序比较: " << (a < b) << "\n"; // true (1<3)// ========== 9. 清零内存验证 ==========std::cout << "内存连续: " << (&nums2[2] - &nums2[0] == 2) // 输出 true<< "\n";
}
注意两种写法对排序结果的影响:
colors1
排序流程std::string
colors2
排序流程const char*
#include <iostream>
#include <array>
#include <algorithm> int main() {// ========== 1. 初始化与声明 ==========std::array<std::string, 3> colors1{"Crimson", "Green", "Blue"};std::array colors2{"Crimson", "Green", "Blue"};// 反向遍历 + 算法 std::cout << "\n反向排序: ";std::sort(colors1.rbegin(), colors1.rend());// (按字母排序) for (const auto& color : colors1) std::cout << color << " "; // 输出 Green Crimson Blue std::cout << "\n反向排序: ";std::sort(colors2.rbegin(), colors2.rend());// (按编译器存储地址排序)for (const auto& color : colors2) std::cout << color << " "; // 输出 Blue Green Crimsonreturn 0;
}
std::string
类型始终按字典序排序,输出稳定可靠const char*
类型按编译器分配的地址值排序,结果不可预测,使用时应避免这种写法
💎综述
std::array
在保留C数组性能与内存布局的同时,提供了类型安全、迭代器支持、边界检查等现代容器特性。
适用场景:需固定大小数组 + 需要STL兼容性 + 避免动态内存开销的场景(如嵌入式系统、高频交易等)。