好的!既然你提到了 C++ 标准库中的容器类 <vector>,我将为你详细讲解它的用法,包括基本概念、特性、功能以及实用示例。<vector> 是 C++ STL 中最常用的动态数组容器,适合需要动态调整大小的场景。它提供了灵活性和丰富的接口,是编程中不可或缺的工具。以下是完整的内容,适合学习和实践。


C++ 标准库:<vector>

<vector> 是一个模板类,表示动态大小的数组。它的主要特点是:

  • 动态大小:可以在运行时添加或删除元素。
  • 连续内存:元素存储在连续的内存块中,访问效率高。
  • STL 兼容:支持迭代器、算法和丰富的成员函数。
  • 自动管理内存:无需手动分配或释放内存。

包含头文件

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

定义格式

std::vector<类型> 变量名;
  • 类型:元素的数据类型(如 intdoublestd::string)。
  • 可选:初始大小或初始化列表。

基本用法

1. 声明和初始化

#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec1;               // 空向量
    std::vector<int> vec2(5, 10);        // 5 个元素,每个值为 10
    std::vector<int> vec3 = {1, 2, 3, 4}; // 初始化列表(C++11 起)

    std::cout << "vec3: ";
    for (int val : vec3) {
        std::cout << val << " ";
    }
    std::cout << std::endl; // 输出:1 2 3 4
    return 0;
}

2. 添加和删除元素

#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec;
    vec.push_back(10); // 在末尾添加元素
    vec.push_back(20);
    vec.push_back(30);

    std::cout << "Original: ";
    for (int val : vec) {
        std::cout << val << " "; // 输出:10 20 30
    }
    std::cout << std::endl;

    vec.pop_back(); // 删除最后一个元素
    std::cout << "After pop: ";
    for (int val : vec) {
        std::cout << val << " "; // 输出:10 20
    }
    std::cout << std::endl;

    return 0;
}
  • push_back():O(1) 均摊复杂度,但可能触发内存重新分配。
  • pop_back():O(1) 复杂度。

3. 访问元素

#include <vector>
#include <iostream>

int main() {
    std::vector<double> vec = {1.5, 2.7, 3.9};
    std::cout << "First: " << vec[0] << std::endl;      // 下标访问
    std::cout << "Second: " << vec.at(1) << std::endl;  // 边界检查访问
    std::cout << "Front: " << vec.front() << std::endl; // 第一个元素
    std::cout << "Back: " << vec.back() << std::endl;   // 最后一个元素
    return 0;
}

输出:

First: 1.5
Second: 2.7
Front: 1.5
Back: 3.9
  • []:无边界检查,性能更高。
  • at():有边界检查,超界抛出 std::out_of_range

4. 大小和容量

#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3};
    std::cout << "Size: " << vec.size() << std::endl;         // 当前元素数:3
    std::cout << "Capacity: " << vec.capacity() << std::endl; // 当前容量:3 或更大
    std::cout << "Empty? " << (vec.empty() ? "Yes" : "No") << std::endl; // 是否为空:No

    vec.push_back(4);
    std::cout << "After push - Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;
    return 0;
}
  • size():当前元素个数。
  • capacity():当前分配的内存可容纳的元素数(可能大于 size())。
  • 容量不足时,vector 会重新分配内存,通常翻倍增长。

5. 修改和调整

#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4};
    vec.insert(vec.begin() + 1, 99); // 在第 2 个位置插入 99
    std::cout << "After insert: ";
    for (int val : vec) {
        std::cout << val << " "; // 输出:1 99 2 3 4
    }
    std::cout << std::endl;

    vec.erase(vec.begin()); // 删除第一个元素
    std::cout << "After erase: ";
    for (int val : vec) {
        std::cout << val << " "; // 输出:99 2 3 4
    }
    std::cout << std::endl;

    vec.resize(2); // 调整大小为 2
    std::cout << "After resize: ";
    for (int val : vec) {
        std::cout << val << " "; // 输出:99 2
    }
    std::cout << std::endl;

    return 0;
}
  • insert():O(n) 复杂度(移动后续元素)。
  • erase():O(n) 复杂度。
  • resize():若缩小则截断,若扩大则填充默认值。

6. 迭代器

#include <vector>
#include <iostream>

int main() {
    std::vector<std::string> vec = {"Apple", "Banana", "Orange"};
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl; // 输出:Apple Banana Orange
    return 0;
}
  • 支持 begin()end()rbegin()(逆向)、rend()

<array> 的对比

特性std::vectorstd::array
大小动态调整编译时固定
内存管理自动,动态分配无额外分配
性能可能有重新分配开销无开销,接近 C 数组
STL 接口丰富(插入、删除等)基础接口

注意事项

  1. 内存重新分配push_back() 可能导致容量翻倍,旧迭代器失效。
  2. 异常安全at() 抛异常,[] 不安全。
  3. 性能优化:用 reserve(n) 预分配容量,避免频繁重新分配。
  4. 清空clear() 清空元素,但不释放容量;shrink_to_fit() 可减少多余容量(C++11)。

小练习

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

问题:

写一个 C++ 程序:

  1. 定义一个 std::vector<int>,初始化为 {1, 2, 3, 4, 5}。
  2. 在第 3 个位置插入 99。
  3. 删除第 1 个元素。
  4. 输出所有元素和当前大小。

参考答案(你可以先尝试)

#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 插入 99 到第 3 个位置(索引 2)
    vec.insert(vec.begin() + 2, 99);

    // 删除第 1 个元素(索引 0)
    vec.erase(vec.begin());

    // 输出所有元素和大小
    std::cout << "Elements: ";
    for (int val : vec) {
        std::cout << val << " ";
    }
    std::cout << "\nSize: " << vec.size() << std::endl;

    return 0;
}

输出:

Elements: 2 3 99 4 5
Size: 5

下一步

  • 如果你想试试这个练习,请写下你的代码,我会帮你检查。
  • 如果你想要更复杂的内容(比如多维 vector、排序、查找),或者设计 <vector> 的测验题,请告诉我!
  • 你也可以提出具体问题,比如“如何用 <vector> 实现堆栈?”或“<vector> 的内存管理细节?”。

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