根据数组大小是否在编译时确定来选择std::array或std::vector:若大小固定且已知,使用std::array以获得零运行时开销和更好缓存性能;若大小需在运行时动态调整,则选用std::vector,并通过reserve()等策略优化性能,避免频繁内存重新分配。

C++中高效管理数组,核心在于根据数据特性和使用场景,明智地选择
std::array
std::vector
std::array
std::vector
在使用C++管理数组时,
std::array
std::vector
std::array
std::array
begin()
end()
size()
empty()
立即学习“C++免费学习笔记(深入)”;
at()
std::array
示例:
#include <array>
#include <iostream>
#include <numeric> // For std::iota
void processFixedData() {
std::array<int, 5> scores; // 声明一个包含5个整数的array
// 初始化
for (size_t i = 0; i < scores.size(); ++i) {
scores[i] = (i + 1) * 10;
}
// 使用at()进行安全访问
try {
std::cout << "Score at index 2: " << scores.at(2) << std::endl;
// scores.at(10) = 100; // 这会抛出std::out_of_range异常
} catch (const std::out_of_range& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
// 遍历
for (int score : scores) {
std::cout << score << " ";
}
std::cout << std::endl;
}std::vector
std::vector
std::vector
new
delete
vector
示例:
#include <vector>
#include <iostream>
#include <algorithm> // For std::sort
void processDynamicData() {
std::vector<double> temperatures; // 声明一个空的double类型vector
// 添加元素
temperatures.push_back(25.5);
temperatures.push_back(28.1);
temperatures.push_back(22.0);
std::cout << "Current temperatures: ";
for (double temp : temperatures) {
std::cout << temp << " ";
}
std::cout << std::endl;
// 动态调整大小
temperatures.push_back(30.2); // 可能会触发重新分配
std::cout << "After adding one more, size: " << temperatures.size() << ", capacity: " << temperatures.capacity() << std::endl;
// 排序
std::sort(temperatures.begin(), temperatures.end());
std::cout << "Sorted temperatures: ";
for (double temp : temperatures) {
std::cout << temp << " ";
}
std::cout << std::endl;
}选择策略:
std::array
unsigned char
std::vector
在我看来,选择
std::array
std::vector
std::array
首先,
std::array
std::array
std::vector
std::array
其次,
std::array
std::array<float, 3>
std::array<unsigned char, 4>
std::array
再者,
std::array
std::array<T, N>
当然,我们不能忽视其类型安全的特性。虽然C风格数组也可以是固定大小,但
std::array
at()
[]
at()
总而言之,当你面对以下情况时,不妨优先考虑
std::array
std::vector
std::vector
std::vector
std::vector
push_back
为了缓解这个问题,最有效的策略就是使用
std::vector::reserve()
reserve()
示例:使用reserve()
#include <vector>
#include <iostream>
#include <chrono>
void demoVectorReserve() {
std::vector<int> data;
const int num_elements = 1000000;
// 不使用 reserve()
auto start_no_reserve = std::chrono::high_resolution_clock::now();
std::vector<int> vec_no_reserve;
for (int i = 0; i < num_elements; ++i) {
vec_no_reserve.push_back(i);
}
auto end_no_reserve = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff_no_reserve = end_no_reserve - start_no_reserve;
std::cout << "Without reserve(): " << diff_no_reserve.count() << " s" << std::endl;
std::cout << "Capacity without reserve: " << vec_no_reserve.capacity() << std::endl;
// 使用 reserve()
auto start_with_reserve = std::chrono::high_resolution_clock::now();
std::vector<int> vec_with_reserve;
vec_with_reserve.reserve(num_elements); // 预留足够的空间
for (int i = 0; i < num_elements; ++i) {
vec_with_reserve.push_back(i);
}
auto end_with_reserve = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff_with_reserve = end_with_reserve - start_with_reserve;
std::cout << "With reserve(): " << diff_with_reserve.count() << " s" << std::endl;
std::cout << "Capacity with reserve: " << vec_with_reserve.capacity() << std::endl;
}通过上面的例子,你会发现使用
reserve()
除了
reserve()
shrink_to_fit()
std::vector
shrink_to_fit()
vector
vector
emplace_back()
push_back()
vector
push_back()
emplace_back()
std::vector
insert()
push_back()
std::vector
理解并应用这些策略,能让
std::vector
深入理解
std::array
std::vector
std::array
std::array
std::array
std::array
std::array
这意味着对于
std::array
std::array
std::array
std::array
这种稳定性是
std::array
std::vector
std::vector
std::vector
这个过程直接导致了
std::vector
以下是导致
std::vector
push_back()
emplace_back()
vector
capacity()
insert()
vector
insert()
erase()
vector
erase()
clear()
vector
resize()
resize()
vector
assign()
vector
如何处理迭代器失效:
理解迭代器失效的规则至关重要。在实际编程中,我们通常需要采取以下策略来避免问题:
重新获取迭代器: 在可能导致迭代器失效的操作之后,立即重新获取所需的迭代器。
std::vector<int> myVec = {1, 2, 3, 4, 5};
auto it = myVec.begin() + 2; // 指向3
myVec.push_back(6); // 可能导致重新分配,it失效
// 错误的使用方式:std::cout << *it << std::endl;
// 正确的做法:重新获取迭代器
it = myVec.begin() + 2;
std::cout << *it << std::endl; // 仍然指向3结构化循环: 在循环中进行
erase()
insert()
erase()
for (auto it = myVec.rbegin(); it != myVec.rend(); ++it) {
if (*it % 2 != 0) { // 删除奇数
myVec.erase(std::next(it).base()); // 注意rbegin/rend与erase的配合
}
}erase()
it = myVec.erase(it);
for (auto it = myVec.begin(); it != myVec.end(); ) {
if (*it % 2 != 0) {
it = myVec.erase(it); // erase返回指向下一个元素的迭代器
} else {
++it;
}
}使用索引而非迭代器: 如果你只是需要访问元素,并且不进行
insert
erase
[]
掌握这些内存管理和迭代器失效的细微之处,能让你在C++中使用
std::array
std::vector
以上就是C++如何使用std::array和std::vector高效管理数组的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号