好的!既然你提到了 C++ 标准库中的容器类 <array>
,我将为你详细讲解它的用法,包括基本概念、特性、功能以及实用示例。<array>
是 C++11 引入的固定大小数组容器,提供比传统 C 风格数组更安全、更现代的接口。它是标准模板库(STL)的一部分,适合需要静态大小但希望使用 STL 功能的场景。以下是完整的内容,适合学习和实践。
C++ 标准库:<array>
<array>
是一个模板类,封装了固定大小的数组,提供与 STL 容器一致的接口。它的主要特点是:
- 固定大小:在编译时指定大小,无法动态调整。
- 连续内存:元素存储在连续的内存块中,与 C 风格数组相同。
- 安全性:提供边界检查(通过
at()
)和更现代的接口。 - 无额外开销:相比动态容器(如
vector
),没有内存管理开销。
包含头文件
#include <array>
#include <iostream> // 通常配合使用
定义格式
std::array<类型, 大小> 变量名;
类型
:数组元素的数据类型(如int
、double
、std::string
)。大小
:编译时常量,表示元素个数。
基本用法
1. 声明和初始化
#include <array>
#include <iostream>
int main() {
std::array<int, 5> arr = {1, 2, 3, 4, 5}; // 初始化列表
for (int i = 0; i < arr.size(); i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl; // 输出:1 2 3 4 5
return 0;
}
- 未初始化的元素默认值为类型的默认值(例如
int
为 0)。
2. 访问元素
#include <array>
#include <iostream>
int main() {
std::array<double, 3> arr = {1.5, 2.7, 3.9};
std::cout << "First: " << arr[0] << std::endl; // 下标访问
std::cout << "Second: " << arr.at(1) << std::endl; // 边界检查访问
std::cout << "Front: " << arr.front() << std::endl; // 第一个元素
std::cout << "Back: " << arr.back() << std::endl; // 最后一个元素
return 0;
}
输出:
First: 1.5
Second: 2.7
Front: 1.5
Back: 3.9
[]
:无边界检查,性能更高但不安全。at()
:有边界检查,超界时抛出std::out_of_range
异常。
3. 大小和容量
#include <array>
#include <iostream>
int main() {
std::array<int, 4> arr = {10, 20, 30, 40};
std::cout << "Size: " << arr.size() << std::endl; // 元素个数:4
std::cout << "Max size: " << arr.max_size() << std::endl; // 最大容量:4
std::cout << "Empty? " << (arr.empty() ? "Yes" : "No") << std::endl; // 是否为空:No
return 0;
}
size()
和max_size()
对于<array>
总是相等,因为大小固定。empty()
对于非零大小的<array>
总是返回false
。
4. 填充和交换
#include <array>
#include <iostream>
int main() {
std::array<int, 3> arr1;
arr1.fill(7); // 填充所有元素为 7
for (int val : arr1) {
std::cout << val << " "; // 输出:7 7 7
}
std::cout << std::endl;
std::array<int, 3> arr2 = {1, 2, 3};
arr1.swap(arr2); // 交换内容
for (int val : arr1) {
std::cout << val << " "; // 输出:1 2 3
}
std::cout << std::endl;
return 0;
}
5. 迭代器
#include <array>
#include <iostream>
int main() {
std::array<std::string, 3> arr = {"Apple", "Banana", "Orange"};
for (auto it = arr.begin(); it != arr.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl; // 输出:Apple Banana Orange
return 0;
}
- 支持 STL 迭代器:
begin()
、end()
、rbegin()
(逆向开始)、rend()
(逆向结束)。
与 C 风格数组的对比
特性 | std::array | C 风格数组(如 int arr[5] ) |
---|---|---|
大小 | 编译时固定 | 编译时固定 |
边界检查 | at() 提供检查 | 无 |
STL 兼容性 | 支持迭代器、算法 | 不支持 |
默认初始化 | 是(零初始化) | 否(未定义值) |
传递给函数 | 按值或引用传递 | 退化为指针 |
示例:传递给函数
#include <array>
#include <iostream>
void printArray(const std::array<int, 3>& arr) {
for (int val : arr) {
std::cout << val << " ";
}
std::cout << std::endl;
}
int main() {
std::array<int, 3> arr = {1, 2, 3};
printArray(arr); // 输出:1 2 3
return 0;
}
<array>
保留大小信息,传递时不会退化。
注意事项
- 大小固定:不能动态调整,需在编译时确定。
- 异常处理:使用
at()
时,需准备捕获std::out_of_range
。 - 性能:无动态内存分配,开销与 C 数组相同。
- 零大小:
std::array<T, 0>
是合法的,但访问元素会引发未定义行为。
小练习
以下是一个基于 <array>
的练习题,你可以尝试:
问题:
写一个 C++ 程序,定义一个大小为 5 的 std::array
,初始化为 {10, 20, 30, 40, 50},然后:
- 输出所有元素。
- 将第一个元素改为 99。
- 输出数组的最大值(使用
std::max_element
)。
参考答案(你可以先尝试)
#include <array>
#include <iostream>
#include <algorithm> // 需包含以使用 max_element
int main() {
std::array<int, 5> arr = {10, 20, 30, 40, 50};
// 输出所有元素
std::cout << "Original: ";
for (int val : arr) {
std::cout << val << " ";
}
std::cout << std::endl;
// 修改第一个元素
arr[0] = 99;
// 输出修改后的数组
std::cout << "Modified: ";
for (int val : arr) {
std::cout << val << " ";
}
std::cout << std::endl;
// 输出最大值
auto max = std::max_element(arr.begin(), arr.end());
std::cout << "Max value: " << *max << std::endl;
return 0;
}
输出:
Original: 10 20 30 40 50
Modified: 99 20 30 40 50
Max value: 99
下一步
- 如果你想试试这个练习,请写下你的代码,我会帮你检查。
- 如果你想要更复杂的内容(比如多维
array
、与算法结合),或者设计<array>
的测验题,请告诉我! - 你也可以提出具体问题,比如“如何用
<array>
实现矩阵?”或“<array>
和<vector>
的区别?”。
现在,你想做什么?试试练习,还是有其他需求?
发表回复