概述
std::vector是 C++ 标准模板库(STL)中最常用的顺序容器,它表示一个动态数组,可以在运行时自动调整大小。vector 提供了对元素的随机访问,支持在尾部高效地添加和删除元素。
头文件
#include <vector>
基本特性
-
动态数组:自动管理内存,可按需增长
-
连续存储:元素在内存中连续存储,支持随机访问
-
自动扩容:当容量不足时自动重新分配更大的内存空间
-
RAII:自动管理内存,离开作用域时自动释放
-
模板类:可以存储任意类型的元素
基本操作
1. 创建和初始化
#include <iostream>
#include <vector>
#include <string>
void create_vector() {
// 1. 默认构造函数 - 创建空vector
std::vector<int> vec1;
// 2. 指定初始大小
std::vector<int> vec2(5); // 5个元素,默认值0
std::vector<int> vec3(5, 10); // 5个元素,每个都是10
// 3. 从初始化列表
std::vector<int> vec4 = {1, 2, 3, 4, 5};
std::vector<std::string> vec5 = {"Hello", "World", "C++"};
// 4. 从数组
int arr[] = {10, 20, 30, 40, 50};
std::vector<int> vec6(arr, arr + 5);
// 5. 复制构造函数
std::vector<int> vec7(vec4);
// 6. 从其他vector的部分元素
std::vector<int> vec8(vec4.begin() + 1, vec4.end() - 1);
// 7. 移动构造函数 (C++11)
std::vector<int> vec9 = std::move(vec4);
std::cout << "移动后vec4大小: " << vec4.size() << std::endl; // 0
std::cout << "移动后vec9大小: " << vec9.size() << std::endl; // 5
// 输出验证
std::cout << "vec2: ";
for (int n : vec2) std::cout << n << " "; // 0 0 0 0 0
std::cout << "\nvec3: ";
for (int n : vec3) std::cout << n << " "; // 10 10 10 10 10
std::cout << "\nvec5: ";
for (const auto& s : vec5) std::cout << s << " "; // Hello World C++
std::cout << "\nvec8: ";
for (int n : vec8) std::cout << n << " "; // 2 3 4
std::cout << std::endl;
}
2. 元素访问
void vector_access() {
std::vector<int> vec = {10, 20, 30, 40, 50};
// 1. 使用下标运算符[] (不进行边界检查)
std::cout << "vec[0] = " << vec[0] << std::endl; // 10
std::cout << "vec[2] = " << vec[2] << std::endl; // 30
// 2. 使用at()成员函数 (进行边界检查,越界时抛出异常)
try {
std::cout << "vec.at(1) = " << vec.at(1) << std::endl; // 20
std::cout << "vec.at(10) = " << vec.at(10) << std::endl; // 抛出异常
} catch (const std::out_of_range& e) {
std::cout << "异常: " << e.what() << std::endl;
}
// 3. 访问第一个和最后一个元素
std::cout << "第一个元素: " << vec.front() << std::endl; // 10
std::cout << "最后一个元素: " << vec.back() << std::endl; // 50
// 4. 通过data()获取底层数组指针
int* ptr = vec.data();
std::cout << "通过指针访问: " << *(ptr + 2) << std::endl; // 30
// 5. 使用迭代器
std::cout << "通过迭代器遍历: ";
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 6. 范围for循环 (C++11)
std::cout << "范围for循环: ";
for (int num : vec) {
std::cout << num << " ";
}
std::cout << std::endl;
// 7. 反向访问
std::cout << "反向遍历: ";
for (auto rit = vec.rbegin(); rit != vec.rend(); ++rit) {
std::cout << *rit << " ";
}
std::cout << std::endl;
}
3. 容量和大小操作
void vector_capacity() {
std::vector<int> vec = {1, 2, 3};
// 1. 获取大小和容量
std::cout << "当前大小: " << vec.size() << std::endl; // 3
std::cout << "当前容量: " << vec.capacity() << std::endl; // >=3
std::cout << "最大可能大小: " << vec.max_size() << std::endl; // 理论最大值
std::cout << "是否为空: " << std::boolalpha << vec.empty() << std::endl; // false
// 2. 修改大小
vec.resize(5); // 扩大,新增元素初始化为0
std::cout << "resize(5)后大小: " << vec.size() << std::endl; // 5
std::cout << "元素: ";
for (int n : vec) std::cout << n << " "; // 1 2 3 0 0
std::cout << std::endl;
vec.resize(8, 100); // 扩大,新增元素初始化为100
std::cout << "resize(8, 100)后: ";
for (int n : vec) std::cout << n << " "; // 1 2 3 0 0 100 100 100
std::cout << std::endl;
vec.resize(3); // 缩小
std::cout << "resize(3)后: ";
for (int n : vec) std::cout << n << " "; // 1 2 3
std::cout << std::endl;
// 3. 预留容量 (提高性能)
std::vector<int> vec2;
std::cout << "\nvec2初始容量: " << vec2.capacity() << std::endl;
vec2.reserve(100); // 预留100个元素的空间
std::cout << "reserve(100)后容量: " << vec2.capacity() << std::endl;
// 4. 缩减容量到合适大小
vec2.push_back(1);
vec2.push_back(2);
std::cout << "添加元素后大小: " << vec2.size()
<< ", 容量: " << vec2.capacity() << std::endl;
vec2.shrink_to_fit(); // 请求减少容量到合适大小
std::cout << "shrink_to_fit后容量: " << vec2.capacity() << std::endl;
// 5. 容量增长策略演示
std::vector<int> vec3;
std::cout << "\n容量增长演示:" << std::endl;
for (int i = 0; i < 20; ++i) {
vec3.push_back(i);
std::cout << "大小: " << vec3.size()
<< ", 容量: " << vec3.capacity() << std::endl;
}
}
4. 元素修改操作
void vector_modification() {
std::vector<int> vec = {1, 2, 3, 4, 5};
std::cout << "初始vector: ";
for (int n : vec) std::cout << n << " ";
std::cout << std::endl;
// 1. 在末尾添加元素
vec.push_back(6);
std::cout << "push_back(6)后: ";
for (int n : vec) std::cout << n << " ";
std::cout << std::endl;
// 2. 在末尾删除元素
vec.pop_back();
std::cout << "pop_back()后: ";
for (int n : vec) std::cout << n << " ";
std::cout << std::endl;
// 3. 在指定位置插入元素
auto it = vec.begin() + 2; // 指向第三个元素
vec.insert(it, 99);
std::cout << "在位置2插入99后: ";
for (int n : vec) std::cout << n << " "; // 1 2 99 3 4 5
std::cout << std::endl;
// 4. 插入多个相同元素
vec.insert(vec.begin() + 4, 3, 88); // 在第4个位置插入3个88
std::cout << "插入3个88后: ";
for (int n : vec) std::cout << n << " "; // 1 2 99 3 88 88 88 4 5
std::cout << std::endl;
// 5. 插入一个范围
std::vector<int> other = {100, 200, 300};
vec.insert(vec.end(), other.begin(), other.end());
std::cout << "插入另一个vector后: ";
for (int n : vec) std::cout << n << " "; // 1 2 99 3 88 88 88 4 5 100 200 300
std::cout << std::endl;
// 6. 删除指定位置元素
vec.erase(vec.begin() + 3); // 删除第4个元素(索引3)
std::cout << "删除位置3后: ";
for (int n : vec) std::cout << n << " "; // 1 2 99 88 88 88 4 5 100 200 300
std::cout << std::endl;
// 7. 删除一个范围
vec.erase(vec.begin() + 3, vec.begin() + 6); // 删除位置3-5
std::cout << "删除位置3-5后: ";
for (int n : vec) std::cout << n << " "; // 1 2 99 4 5 100 200 300
std::cout << std::endl;
// 8. 清空所有元素
vec.clear();
std::cout << "clear()后大小: " << vec.size() << std::endl; // 0
// 9. 赋值操作
vec = {10, 20, 30, 40, 50};
std::cout << "赋值后: ";
for (int n : vec) std::cout << n << " ";
std::cout << std::endl;
// 10. 交换两个vector
std::vector<int> vec2 = {100, 200, 300};
std::cout << "\n交换前: vec大小=" << vec.size()
<< ", vec2大小=" << vec2.size() << std::endl;
vec.swap(vec2);
std::cout << "交换后: vec大小=" << vec.size()
<< ", vec2大小=" << vec2.size() << std::endl;
std::cout << "vec: ";
for (int n : vec) std::cout << n << " "; // 100 200 300
std::cout << "\nvec2: ";
for (int n : vec2) std::cout << n << " "; // 10 20 30 40 50
std::cout << std::endl;
// 11. 使用emplace_back (C++11, 避免临时对象)
struct Person {
std::string name;
int age;
Person(std::string n, int a) : name(std::move(n)), age(a) {
std::cout << "构造Person: " << name << std::endl;
}
Person(const Person& other) : name(other.name), age(other.age) {
std::cout << "拷贝Person: " << name << std::endl;
}
};
std::vector<Person> people;
std::cout << "\nemplace_back演示:" << std::endl;
// 传统方法: 创建临时对象再拷贝
people.push_back(Person("Alice", 25)); // 构造+拷贝
// 现代方法: 直接在vector中构造
people.emplace_back("Bob", 30); // 只构造一次
// 12. 使用emplace在指定位置构造
people.emplace(people.begin(), "Charlie", 35);
}
5. 迭代器和算法
#include <algorithm>
#include <numeric>
void vector_algorithms() {
std::vector<int> vec = {5, 2, 8, 1, 9, 3, 7, 4, 6};
// 1. 使用STL算法排序
std::sort(vec.begin(), vec.end());
std::cout << "排序后: ";
for (int n : vec) std::cout << n << " ";
std::cout << std::endl;
// 2. 反转
std::reverse(vec.begin(), vec.end());
std::cout << "反转后: ";
for (int n : vec) std::cout << n << " ";
std::cout << std::endl;
// 3. 查找
auto it = std::find(vec.begin(), vec.end(), 7);
if (it != vec.end()) {
std::cout << "找到7,位置: " << std::distance(vec.begin(), it) << std::endl;
}
// 4. 二分查找 (需要先排序)
std::sort(vec.begin(), vec.end());
bool found = std::binary_search(vec.begin(), vec.end(), 5);
std::cout << "二分查找5: " << (found ? "找到" : "未找到") << std::endl;
// 5. 统计
int count = std::count(vec.begin(), vec.end(), 3);
std::cout << "数字3出现次数: " << count << std::endl;
// 6. 累加
int sum = std::accumulate(vec.begin(), vec.end(), 0);
std::cout << "总和: " << sum << std::endl;
// 7. 变换
std::vector<int> squared;
std::transform(vec.begin(), vec.end(), std::back_inserter(squared),
[](int x) { return x * x; });
std::cout << "平方: ";
for (int n : squared) std::cout << n << " ";
std::cout << std::endl;
// 8. 删除重复元素
std::vector<int> with_duplicates = {1, 2, 2, 3, 3, 3, 4, 5};
std::sort(with_duplicates.begin(), with_duplicates.end());
auto last = std::unique(with_duplicates.begin(), with_duplicates.end());
with_duplicates.erase(last, with_duplicates.end());
std::cout << "去重后: ";
for (int n : with_duplicates) std::cout << n << " ";
std::cout << std::endl;
// 9. 删除满足条件的元素
std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
numbers.erase(std::remove_if(numbers.begin(), numbers.end(),
[](int x) { return x % 2 == 0; }), // 删除偶数
numbers.end());
std::cout << "删除偶数后: ";
for (int n : numbers) std::cout << n << " ";
std::cout << std::endl;
}
性能特性
时间复杂度
| 操作 | 时间复杂度 | 说明 |
|---|---|---|
| 随机访问 | O(1) | 通过索引直接访问 |
| 尾部插入/删除 | 平摊O(1) | push_back/pop_back |
| 中间/头部插入/删除 | O(n) | 需要移动元素 |
| 查找 | O(n) | 线性查找 |
| 排序 | O(n log n) | std::sort |
| 扩容 | O(n) | 需要复制所有元素到新内存 |
内存管理
void vector_memory_demo() {
std::cout << "vector内存管理演示:" << std::endl;
std::vector<int> vec;
std::cout << "初始状态:" << std::endl;
std::cout << "大小: " << vec.size()
<< ", 容量: " << vec.capacity() << std::endl;
// 添加元素,观察容量增长
for (int i = 0; i < 20; ++i) {
vec.push_back(i);
std::cout << "添加" << i << "后: 大小=" << vec.size()
<< ", 容量=" << vec.capacity() << std::endl;
}
// 注意:不同编译器的扩容策略可能不同
// 常见策略是容量翻倍或按固定系数增长
}
高级用法
1. 二维vector
void two_dimensional_vector() {
// 创建二维vector
std::vector<std::vector<int>> matrix;
// 方法1: 逐行添加
matrix.push_back({1, 2, 3});
matrix.push_back({4, 5, 6});
matrix.push_back({7, 8, 9});
std::cout << "矩阵1:" << std::endl;
for (const auto& row : matrix) {
for (int val : row) {
std::cout << val << " ";
}
std::cout << std::endl;
}
// 方法2: 指定大小
int rows = 3, cols = 4;
std::vector<std::vector<int>> matrix2(rows, std::vector<int>(cols, 0));
// 初始化值
int count = 1;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
matrix2[i][j] = count++;
}
}
std::cout << "\n矩阵2:" << std::endl;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << matrix2[i][j] << "\t";
}
std::cout << std::endl;
}
// 访问元素
std::cout << "\nmatrix2[1][2] = " << matrix2[1][2] << std::endl;
// 获取行数和列数
std::cout << "行数: " << matrix2.size() << std::endl;
if (!matrix2.empty()) {
std::cout << "列数: " << matrix2[0].size() << std::endl;
}
}
2. vector存储自定义对象
class Student {
private:
std::string name;
int score;
public:
Student() : name(""), score(0) {}
Student(std::string n, int s) : name(std::move(n)), score(s) {}
// 用于排序的比较函数
bool operator<(const Student& other) const {
return score > other.score; // 按分数降序
}
// 用于find_if的匹配函数
bool hasName(const std::string& searchName) const {
return name == searchName;
}
void display() const {
std::cout << name << ": " << score << "分" << std::endl;
}
int getScore() const { return score; }
};
void custom_object_vector() {
std::vector<Student> students;
// 添加学生
students.emplace_back("Alice", 85);
students.emplace_back("Bob", 92);
students.emplace_back("Charlie", 78);
students.emplace_back("David", 88);
students.emplace_back("Eve", 95);
std::cout << "学生列表:" << std::endl;
for (const auto& student : students) {
student.display();
}
// 按分数排序
std::sort(students.begin(), students.end());
std::cout << "\n按分数排序后:" << std::endl;
for (const auto& student : students) {
student.display();
}
// 查找特定学生
std::string searchName = "Charlie";
auto it = std::find_if(students.begin(), students.end(),
[&searchName](const Student& s) {
return s.hasName(searchName);
});
if (it != students.end()) {
std::cout << "\n找到" << searchName << ": ";
it->display();
}
// 计算平均分
int total = std::accumulate(students.begin(), students.end(), 0,
[](int sum, const Student& s) {
return sum + s.getScore();
});
double average = static_cast<double>(total) / students.size();
std::cout << "\n平均分: " << average << std::endl;
// 使用lambda表达式过滤
std::cout << "\n90分以上的学生:" << std::endl;
std::for_each(students.begin(), students.end(),
[](const Student& s) {
if (s.getScore() >= 90) {
s.display();
}
});
}
3. vector的性能优化技巧
void vector_performance_tips() {
std::cout << "vector性能优化技巧:" << std::endl;
// 技巧1: 预先分配足够容量
{
std::cout << "\n1. 预先分配容量:" << std::endl;
const int N = 1000000;
// 方法1: 不预分配 (多次重新分配)
std::vector<int> vec1;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; ++i) {
vec1.push_back(i);
}
auto end = std::chrono::high_resolution_clock::now();
auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "不预分配耗时: " << duration1.count() << "ms" << std::endl;
// 方法2: 预分配容量
std::vector<int> vec2;
vec2.reserve(N); // 关键步骤
start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; ++i) {
vec2.push_back(i);
}
end = std::chrono::high_resolution_clock::now();
auto duration2 = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "预分配耗时: " << duration2.count() << "ms" << std::endl;
std::cout << "性能提升: " << (duration1.count() - duration2.count()) << "ms" << std::endl;
}
// 技巧2: 使用emplace_back避免拷贝
{
std::cout << "\n2. emplace_back vs push_back:" << std::endl;
struct Point {
int x, y, z;
Point(int a, int b, int c) : x(a), y(b), z(c) {
// std::cout << "构造Point" << std::endl;
}
Point(const Point& other) : x(other.x), y(other.y), z(other.z) {
// std::cout << "拷贝Point" << std::endl;
}
};
std::vector<Point> points1;
std::cout << "使用push_back(会创建临时对象):" << std::endl;
points1.push_back(Point(1, 2, 3)); // 构造临时对象 + 拷贝
std::vector<Point> points2;
std::cout << "使用emplace_back(直接构造):" << std::endl;
points2.emplace_back(1, 2, 3); // 只构造一次
}
// 技巧3: 避免在vector中存储大对象
{
std::cout << "\n3. 存储指针而不是大对象:" << std::endl;
struct LargeObject {
int data[1000]; // 大对象
};
// 存储对象本身 (可能效率低)
std::vector<LargeObject> objects;
// 存储智能指针 (更高效)
std::vector<std::shared_ptr<LargeObject>> object_ptrs;
object_ptrs.push_back(std::make_shared<LargeObject>());
}
// 技巧4: 正确使用swap
{
std::cout << "\n4. 使用swap快速清空vector:" << std::endl;
std::vector<int> vec(1000000, 42);
std::cout << "清空前: 大小=" << vec.size()
<< ", 容量=" << vec.capacity() << std::endl;
// 方法1: clear() 不释放内存
vec.clear();
std::cout << "clear()后: 大小=" << vec.size()
<< ", 容量=" << vec.capacity() << std::endl;
// 方法2: swap技巧释放内存
std::vector<int>().swap(vec);
std::cout << "swap后: 大小=" << vec.size()
<< ", 容量=" << vec.capacity() << std::endl;
}
}
常见错误和注意事项
void common_mistakes() {
std::cout << "常见错误和注意事项:" << std::endl;
// 错误1: 迭代器失效
{
std::cout << "\n1. 迭代器失效问题:" << std::endl;
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin() + 2; // 指向3
// 在插入/删除后,迭代器可能失效
vec.push_back(6); // 可能导致重新分配内存
// it 可能已经失效!
// 安全做法:重新获取迭代器
it = vec.begin() + 2;
std::cout << "安全访问: " << *it << std::endl;
}
// 错误2: 越界访问
{
std::cout << "\n2. 越界访问:" << std::endl;
std::vector<int> vec = {1, 2, 3};
// 危险:不检查边界
// int val = vec[10]; // 未定义行为
// 安全:使用at(),会抛出异常
try {
int val = vec.at(10); // 抛出std::out_of_range
} catch (const std::out_of_range& e) {
std::cout << "捕获异常: " << e.what() << std::endl;
}
}
// 错误3: 引用失效
{
std::cout << "\n3. 引用失效问题:" << std::endl;
std::vector<int> vec = {1, 2, 3};
int& ref = vec[1]; // 引用第二个元素
vec.push_back(4); // 可能导致重新分配
// ref 现在可能无效!
// 安全做法:避免在修改操作后使用引用
std::cout << "安全做法: 立即使用引用" << std::endl;
}
// 错误4: 错误使用reserve
{
std::cout << "\n4. reserve不改变大小:" << std::endl;
std::vector<int> vec;
vec.reserve(10); // 只分配内存,不创建元素
// vec[0] = 1; // 错误!size()还是0
// 正确做法
vec.push_back(1); // 或者使用resize
std::cout << "正确: vec[0] = " << vec[0] << std::endl;
}
}
综合示例:学生成绩管理系统
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
#include <iomanip>
class StudentGradeSystem {
private:
struct Student {
int id;
std::string name;
double grade;
Student(int i, std::string n, double g)
: id(i), name(std::move(n)), grade(g) {}
void display() const {
std::cout << std::setw(5) << id
<< std::setw(15) << name
<< std::setw(8) << std::fixed << std::setprecision(2) << grade << std::endl;
}
};
std::vector<Student> students;
public:
// 添加学生
void addStudent(int id, const std::string& name, double grade) {
students.emplace_back(id, name, grade);
std::cout << "添加学生: " << name << " (ID: " << id << ")" << std::endl;
}
// 显示所有学生
void displayAll() const {
if (students.empty()) {
std::cout << "没有学生记录。" << std::endl;
return;
}
std::cout << "\n学生成绩列表:" << std::endl;
std::cout << std::setw(5) << "ID"
<< std::setw(15) << "姓名"
<< std::setw(8) << "成绩" << std::endl;
std::cout << std::string(30, '-') << std::endl;
for (const auto& student : students) {
student.display();
}
}
// 按成绩排序
void sortByGrade(bool descending = true) {
std::sort(students.begin(), students.end(),
[descending](const Student& a, const Student& b) {
return descending ? a.grade > b.grade : a.grade < b.grade;
});
std::cout << "已按成绩" << (descending ? "降序" : "升序") << "排序。" << std::endl;
}
// 查找学生
void findStudent(int id) const {
auto it = std::find_if(students.begin(), students.end(),
[id](const Student& s) { return s.id == id; });
if (it != students.end()) {
std::cout << "找到学生:" << std::endl;
it->display();
} else {
std::cout << "未找到ID为" << id << "的学生。" << std::endl;
}
}
// 查找学生(按姓名)
void findStudent(const std::string& name) const {
auto it = std::find_if(students.begin(), students.end(),
[&name](const Student& s) { return s.name == name; });
if (it != students.end()) {
std::cout << "找到学生:" << std::endl;
it->display();
} else {
std::cout << "未找到姓名为" << name << "的学生。" << std::endl;
}
}
// 删除学生
void removeStudent(int id) {
auto it = std::remove_if(students.begin(), students.end(),
[id](const Student& s) { return s.id == id; });
if (it != students.end()) {
students.erase(it, students.end());
std::cout << "已删除ID为" << id << "的学生。" << std::endl;
} else {
std::cout << "未找到ID为" << id << "的学生。" << std::endl;
}
}
// 统计信息
void showStatistics() const {
if (students.empty()) {
std::cout << "没有学生数据可统计。" << std::endl;
return;
}
// 计算平均分
double total = std::accumulate(students.begin(), students.end(), 0.0,
[](double sum, const Student& s) { return sum + s.grade; });
double average = total / students.size();
// 找到最高分和最低分
auto minmax = std::minmax_element(students.begin(), students.end(),
[](const Student& a, const Student& b) {
return a.grade < b.grade;
});
std::cout << "\n成绩统计:" << std::endl;
std::cout << "学生总数: " << students.size() << std::endl;
std::cout << "平均成绩: " << std::fixed << std::setprecision(2) << average << std::endl;
std::cout << "最高分: " << minmax.second->name << " - " << minmax.second->grade << std::endl;
std::cout << "最低分: " << minmax.first->name << " - " << minmax.first->grade << std::endl;
}
// 筛选优秀学生
void showTopStudents(double threshold = 90.0) const {
std::vector<Student> topStudents;
std::copy_if(students.begin(), students.end(), std::back_inserter(topStudents),
[threshold](const Student& s) { return s.grade >= threshold; });
if (topStudents.empty()) {
std::cout << "没有学生达到" << threshold << "分以上。" << std::endl;
return;
}
std::cout << "\n优秀学生 (" << threshold << "分以上):" << std::endl;
for (const auto& student : topStudents) {
student.display();
}
}
};
void student_system_demo() {
StudentGradeSystem system;
// 添加学生
system.addStudent(1001, "张三", 85.5);
system.addStudent(1002, "李四", 92.0);
system.addStudent(1003, "王五", 78.5);
system.addStudent(1004, "赵六", 88.0);
system.addStudent(1005, "钱七", 95.5);
system.addStudent(1006, "孙八", 91.0);
// 显示所有学生
system.displayAll();
// 按成绩排序
system.sortByGrade();
system.displayAll();
// 查找学生
system.findStudent(1003);
system.findStudent("李四");
// 统计信息
system.showStatistics();
// 显示优秀学生
system.showTopStudents(90.0);
// 删除学生
system.removeStudent(1003);
system.displayAll();
// 再次统计
system.showStatistics();
}
int main() {
std::cout << "===== C++ vector 容器详细文档 =====\n" << std::endl;
std::cout << "=== 1. 创建和初始化 ===" << std::endl;
create_vector();
std::cout << "\n=== 2. 元素访问 ===" << std::endl;
vector_access();
std::cout << "\n=== 3. 容量和大小 ===" << std::endl;
vector_capacity();
std::cout << "\n=== 4. 元素修改 ===" << std::endl;
vector_modification();
std::cout << "\n=== 5. 算法应用 ===" << std::endl;
vector_algorithms();
std::cout << "\n=== 6. 二维vector ===" << std::endl;
two_dimensional_vector();
std::cout << "\n=== 7. 自定义对象vector ===" << std::endl;
custom_object_vector();
std::cout << "\n=== 8. 性能优化 ===" << std::endl;
vector_performance_tips();
std::cout << "\n=== 9. 常见错误 ===" << std::endl;
common_mistakes();
std::cout << "\n=== 10. 综合示例: 学生成绩管理系统 ===" << std::endl;
student_system_demo();
return 0;
}
总结
vector的主要优点:
-
动态大小:自动管理内存,根据需要增长
-
随机访问:通过索引快速访问元素,时间复杂度O(1)
-
连续存储:内存局部性好,缓存友好
-
丰富的接口:提供多种操作和算法支持
-
类型安全:编译时类型检查
适用场景:
-
需要频繁随机访问元素
-
主要在尾部添加/删除元素
-
元素数量不确定或经常变化
-
需要与其他STL算法配合使用
不适用场景:
-
频繁在头部或中间插入/删除元素(考虑使用list或deque)
-
元素非常大且频繁重新分配(考虑存储指针)
-
需要固定大小数组(考虑使用array)
最佳实践:
-
使用
reserve()预分配空间以提高性能 -
使用
emplace_back()替代push_back()避免拷贝 -
注意迭代器和引用失效问题
-
使用
at()进行安全的边界检查访问 -
使用范围for循环简化遍历
-
结合STL算法提高代码可读性和效率