当前位置:首页 » 《关于电脑》 » 正文

C++里的vector详细讲解

26 人参与  2024年10月08日 17:21  分类 : 《关于电脑》  评论

点击全文阅读


在C++的标准模板库(STL)中,vector是一个非常有用的动态数组容器。它允许我们存储可变大小的同类型元素序列,并且能够动态地增长和缩小。由于其灵活性和易用性,vector在C++编程中得到了广泛的应用。

一、vector的基本操作

1. 包含头文件

要使用vector,首先需要包含相应的头文件:

#include <vector>
2. 创建vector对象

创建一个空的int类型的vector

std::vector<int> v;

创建一个包含10个整数的vector,并初始化为0:

std::vector<int> v(10, 0);
3. 添加元素

使用push_back()函数向vector的末尾添加一个元素:

v.push_back(1);v.push_back(2);
4. 访问元素

使用下标运算符[]来访问vector中的元素:

int first_element = v[0];  // 访问第一个元素v[1] = 3;  // 修改第二个元素的值为3
5. 删除元素

使用erase()函数删除指定位置的元素:

v.erase(v.begin() + 1);  // 删除第二个元素
6. 遍历元素

使用迭代器或范围for循环遍历vector中的元素:

// 使用迭代器遍历for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {    std::cout << *it << " ";}std::cout << std::endl;// 使用范围for循环遍历for (const auto& element : v) {    std::cout << element << " ";}std::cout << std::endl;
7. 获取vector的大小和容量

使用size()函数获取vector中元素的数量,使用capacity()函数获取vector当前分配的内存空间能够容纳的元素数量:

std::cout << "Size: " << v.size() << std::endl;std::cout << "Capacity: " << v.capacity() << std::endl;

二、vector的特点和优势

动态扩展:当向vector中添加元素时,如果当前分配的内存空间不足以容纳新元素,vector会自动重新分配更大的内存空间,并复制或移动原有元素到新的内存空间。这个过程对用户是透明的,无需手动管理内存。连续存储vector中的元素在内存中是连续存储的,这使得访问和操作元素非常高效。同时,连续存储也方便了元素的遍历和查找。类型安全vector是模板类,可以存储任意类型的元素(包括基本数据类型、自定义类型等),并且保证了类型安全。在编译时会检查元素的类型,避免了运行时类型错误的风险。易于使用vector提供了丰富的成员函数和操作符重载,使得对容器的操作更加直观和方便。例如,可以使用==运算符比较两个vector是否相等,使用+=运算符向vector中添加元素等。

三、示例代码

下面是一个简单的示例代码,演示了如何使用vector进行基本的操作:

#include <iostream>#include <vector>int main() {    // 创建一个空的int类型的vector    std::vector<int> v;        // 向vector中添加元素    v.push_back(1);    v.push_back(2);    v.push_back(3);        // 访问和修改元素    std::cout << "First element: " << v[0] << std::endl;  // 输出:First element: 1    v[1] = 4;  // 修改第二个元素的值为4        // 遍历元素并输出    std::cout << "Elements in vector: ";    for (const auto& element : v) {        std::cout << element << " ";    }    std::cout << std::endl;  // 输出:Elements in vector: 1 4 3         // 删除第二个元素(现在的值为4的元素)    v.erase(v.begin() + 1);        // 再次遍历元素并输出    std::cout << "Elements after deletion: ";    for (const auto& element : v) {        std::cout << element << " ";    }    std::cout << std::endl;  // 输出:Elements after deletion: 1 3         return 0;}

四、vector的性能考虑

虽然vector提供了很多便利,但在某些情况下,其性能可能并不是最优的。这主要源于vector在动态扩展时可能涉及大量的内存分配和数据复制。以下是一些使用vector时需要考虑的性能因素:

内存分配和复制:当vector需要增长时,它通常会分配一个更大的内存块,并将旧元素复制到新位置。这个过程可能很耗时,特别是对于大型vector。因此,如果你知道将要存储的元素数量,最好提前使用reserve()函数预留足够的空间。

连续内存访问:由于vector的元素在内存中是连续存储的,因此访问它们的性能通常很好。然而,插入或删除元素(特别是在vector的中间)可能会导致大量元素的移动,从而影响性能。在这种情况下,使用其他数据结构(如listdeque)可能更为合适。

缓存友好性:由于vector的元素是连续存储的,因此它们更容易被CPU缓存,从而提高访问速度。但是,当vector变得非常大时,它可能无法完全适应缓存,导致性能下降。

五、高级用法和注意事项

1. 使用emplace_back()避免不必要的复制或移动

当你想在vector的末尾添加一个元素时,如果元素类型是一个复杂的对象,使用emplace_back()而不是push_back()可以避免不必要的复制或移动操作。emplace_back()允许你在容器内直接构造元素,而无需先创建一个临时对象再将其复制或移动到容器中。

std::vector<std::string> strVec;strVec.emplace_back("Hello");  // 直接在vector中构造std::string对象
2. 使用reserve()优化性能

如果你知道将要添加到vector中的元素数量,可以使用reserve()函数提前分配足够的内存空间。这样可以避免多次重新分配内存和数据复制,从而提高性能。

std::vector<int> intVec;intVec.reserve(1000);  // 预留空间以存储1000个整数for (int i = 0; i < 1000; ++i) {    intVec.push_back(i);}
3. 使用shrink_to_fit()释放未使用的内存

在删除大量元素后,vector可能不会立即释放未使用的内存。你可以调用shrink_to_fit()来请求容器减小其容量以匹配当前的大小。但请注意,这只是一个请求,标准库并不保证一定会释放内存。

std::vector<int> intVec(1000);// ... 使用intVec ...intVec.clear();  // 清除所有元素intVec.shrink_to_fit();  // 请求释放未使用的内存
4. 避免在循环中多次调用size()

在循环中多次调用size()函数可能会导致不必要的性能开销,特别是当循环体很大且迭代次数很多时。最好将size()的结果存储在一个变量中,并在循环中使用该变量。

std::vector<int> intVec = {1, 2, 3, 4, 5};size_t size = intVec.size();for (size_t i = 0; i < size; ++i) {    // ... 使用intVec[i] ...}

六、总结

vector是C++ STL中非常强大且易于使用的动态数组容器。它提供了灵活的内存管理、高效的元素访问和丰富的操作函数。然而,在使用vector时,我们也应该注意其性能特点和最佳实践,以确保代码的高效运行。通过合理使用vector的成员函数和注意避免一些常见陷阱,我们可以充分利用这个容器的优势来编写高效且可靠的C++代码。


点击全文阅读


本文链接:http://zhangshiyu.com/post/169136.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1