好的!既然你提到了 C++ 标准库中的容器类 <array>,我将为你详细讲解它的用法,包括基本概念、特性、功能以及实用示例。<array> 是 C++11 引入的固定大小数组容器,提供比传统 C 风格数组更安全、更现代的接口。它是标准模板库(STL)的一部分,适合需要静态大小但希望使用 STL 功能的场景。以下是完整的内容,适合学习和实践。


C++ 标准库:<array>

<array> 是一个模板类,封装了固定大小的数组,提供与 STL 容器一致的接口。它的主要特点是:

  • 固定大小:在编译时指定大小,无法动态调整。
  • 连续内存:元素存储在连续的内存块中,与 C 风格数组相同。
  • 安全性:提供边界检查(通过 at())和更现代的接口。
  • 无额外开销:相比动态容器(如 vector),没有内存管理开销。

包含头文件

#include <array>
#include <iostream> // 通常配合使用

定义格式

std::array<类型, 大小> 变量名;
  • 类型:数组元素的数据类型(如 intdoublestd::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::arrayC 风格数组(如 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> 保留大小信息,传递时不会退化。

注意事项

  1. 大小固定:不能动态调整,需在编译时确定。
  2. 异常处理:使用 at() 时,需准备捕获 std::out_of_range
  3. 性能:无动态内存分配,开销与 C 数组相同。
  4. 零大小std::array<T, 0> 是合法的,但访问元素会引发未定义行为。

小练习

以下是一个基于 <array> 的练习题,你可以尝试:

问题:

写一个 C++ 程序,定义一个大小为 5 的 std::array,初始化为 {10, 20, 30, 40, 50},然后:

  1. 输出所有元素。
  2. 将第一个元素改为 99。
  3. 输出数组的最大值(使用 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> 的区别?”。

现在,你想做什么?试试练习,还是有其他需求?