Day 23 C++ vector容器

这篇具有很好参考价值的文章主要介绍了Day 23 C++ vector容器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

vector基本概念

定义

C++的vector容器是一个动态数组,提供了存储和操作元素的功能。它是标准模板库(STL)的一部分,在头文件中定义。

vector数据结构和数组非常相似,也称为单端数组动态数组)(也被称为向量

使用vector容器前,需要引入头文件:

#include <vector>

vector容器的迭代器——支持随机访问的迭代器

vector与普通数组区别

大小的灵活性

数组是静态空间,而vector可以动态扩展普通数组在创建时需要指定固定的大小,而且不能动态改变大小。而vector容器是动态数组,可以根据需要自动调整大小。它会自动管理内存,并提供了函数来添加、删除、插入和操作元素。

内存管理

普通数组是在栈上分配内存,而vector容器使用堆内存。这意味着当数组很大时,使用vector可以避免栈溢出问题。另外,vector还提供了自动释放内存的机制,不需要手动释放内存。

访问效率

普通数组的元素访问效率更高,因为它们在内存中是连续存储的,可以直接通过索引来访问元素。而vector容器的元素存储在堆内存中,需要通过指针进行间接访问,可能会稍微降低一些效率。

功能和灵活性

vector容器提供了许多便捷的函数和操作符,使得处理和操作元素更加方便。它可以动态调整大小、插入和删除元素,提供了范围-based for循环和迭代器等功能,而普通数组需要手动编写相应的代码来实现这些功能。

综上所述,vector容器相比普通数组更加灵活和方便,尤其适用于需要动态改变大小或者进行复杂操作的场景。而普通数组则更适合在大小固定且访问效率要求较高的情况下使用。

动态扩展

并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间

vector容器在初始化时没有固定的大小限制,可以动态地添加或删除元素,以适应不同的需求。添加元素时,如果已经达到容器的容量上限,vector会自动分配更大的内存空间,并将原有的元素拷贝到新的内存中。这样就实现了动态扩展。


vector构造函数——创建vector容器

函数原型

  • vector<T> v; //采用模板实现类实现,默认构造函数
  • vector(v.begin(), v.end()); //将v[begin(), end())区间中的元素拷贝给本身。
  • vector(n, elem); //构造函数将n个elem拷贝给本身。
  • vector(const vector &vec); //拷贝构造函数。

示例

#include <iostream>
#include <vector>

int main() {
    // 使用默认构造函数创建空的vector容器
    std::vector<int> emptyVector;
    
    // 使用迭代器范围方式创建vector容器
    int arr[] = {1, 2, 3, 4, 5};
    std::vector<int> rangeVector(arr, arr + 5);
    
    // 使用重复元素方式创建vector容器
    std::vector<int> repeatVector(5, 10);
    
    // 使用拷贝构造函数创建vector容器
    std::vector<int> copyVector(rangeVector);

    // 打印各个vector容器的元素
    for (int element : emptyVector) {
        std::cout << element << " ";
    }
    std::cout << std::endl;
    
    for (int element : rangeVector) {
        std::cout << element << " ";
    }
    std::cout << std::endl;
    
    for (int element : repeatVector) {
        std::cout << element << " ";
    }
    std::cout << std::endl;
    
    for (int element : copyVector) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}

在上述示例中,我们通过不同的方式创建了四个vector容器:使用默认构造函数创建了一个空的容器emptyVector,使用迭代器范围方式从数组中拷贝元素创建了容器rangeVector,使用重复元素方式创建了容器repeatVector,使用拷贝构造函数从另一个容器中拷贝元素创建了容器copyVector。然后,我们分别使用for循环打印四个vector容器的元素。

注意,在示例代码中,emptyVector是空的,因此不会输出任何内容。

运行该示例代码,输出为:

1 2 3 4 5
10 10 10 10 10
1 2 3 4 5

vector赋值操作

函数原型

  • vector& operator=(const vector &vec); //重载等号操作符
  • assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
  • assign(n, elem); //将n个elem拷贝赋值给本身。

注意
begend 都是迭代器

示例

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec1 = {1, 2, 3, 4, 5};
    std::vector<int> vec2;
    
    // 使用重载等号操作符将vec1的元素赋值给vec2
    vec2 = vec1;
    
    // 使用assign函数将vec1的元素拷贝赋值给vec2
    vec2.assign(vec1.begin(), vec1.end());
    
    // 使用assign函数将重复的元素拷贝赋值给vec2
    vec2.assign(5, 10);
    
    // 打印vec1和vec2的元素
    for (int element : vec1) {
        std::cout << element << " ";
    }
    std::cout << std::endl;
    
    for (int element : vec2) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}



对vector容器的容量和大小操作

函数原型

  • empty(); //判断容器是否为空

  • capacity(); //容器的容量

  • size(); //返回容器中元素的个数

  • resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除。

  • resize(int num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除

示例

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    
    // 使用empty()函数判断容器是否为空
    if (vec.empty()) {
        std::cout << "Vector is empty" << std::endl;
    } else {
        std::cout << "Vector is not empty" << std::endl;
    }
    
    // 使用capacity()函数获取容器的容量
    std::cout << "Capacity: " << vec.capacity() << std::endl;
    
    // 使用size()函数获取容器中元素的个数
    std::cout << "Size: " << vec.size() << std::endl;
    
    // 使用resize()函数修改容器的长度为5,默认使用0填充新位置
    vec.resize(5);
    
    // 输出修改后的容器元素
    for (int element : vec) {
        std::cout << element << " ";
    }
    std::cout << std::endl;
    
    // 使用resize()函数将容器的长度修改为3,并使用10填充新位置
    vec.resize(3, 10);
    
    // 输出修改后的容器元素
    for (int element : vec) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}

在上述示例中,我们创建了一个初始容器vec,包含元素1、2和3。首先,使用empty()函数判断容器是否为空,如果为空则输出相应的提示信息。然后,使用capacity()函数获取容器的容量,并使用size()函数获取容器中元素的个数。接下来,使用resize()函数将容器的长度修改为5,默认使用0填充新位置。打印修改后的容器元素。接着,使用resize()函数将容器的长度修改为3,并使用10填充新位置。再次打印修改后的容器元素。

输出结果

Vector is not empty
Capacity: 3
Size: 3
1 2 3 0 0
1 2 3


对vector容器进行插入、删除操作

函数原型

  • push_back(ele); //尾部插入元素ele
  • pop_back(); //删除最后一个元素
  • insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele
  • insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count个元素ele
  • erase(const_iterator pos); //删除迭代器指向的元素
  • erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素
  • clear(); //删除容器中所有元素

示例

#include <iostream>
#include <vector>

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

    // 尾部插入元素ele
    vec.push_back(4);
    
    // 删除最后一个元素
    vec.pop_back();
    
    // 迭代器指向位置pos插入元素ele
    auto it = vec.begin() + 1;
    vec.insert(it, 10);
    
    // 迭代器指向位置pos插入count个元素ele
    vec.insert(it, 3, 20);
    
    // 删除迭代器指向的元素
    vec.erase(vec.begin() + 2);
    
    // 删除迭代器从start到end之间的元素
    vec.erase(vec.begin(), vec.begin() + 2);
    
    // 删除容器中所有元素
    vec.clear();
    
    // 输出修改后的容器元素
    for (int element : vec) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}


对vector中的数据的存取操作

函数原型

  • at(int idx); //返回索引idx所指的数据
  • operator[]; //返回索引idx所指的数据
  • front(); //返回容器中第一个数据元素
  • back(); //返回容器中最后一个数据元素

示例

#include <iostream>
#include <vector>

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

    // 使用 at() 函数返回索引 idx 所指的数据
    int value1 = vec.at(2);
    std::cout << "Value at index 2: " << value1 << std::endl;

    // 使用 operator[] 返回索引 idx 所指的数据
    int value2 = vec[3];
    std::cout << "Value at index 3: " << value2 << std::endl;

    // 使用 front() 函数返回容器中第一个数据元素
    int first = vec.front();
    std::cout << "First element: " << first << std::endl;

    // 使用 back() 函数返回容器中最后一个数据元素
    int last = vec.back();
    std::cout << "Last element: " << last << std::endl;

    return 0;
}

在上述示例中,我们创建了一个初始容器 vec,包含元素 1、2、3、4 和 5。然后,我们使用 at() 函数和索引 2 来访问容器中的元素。同样地,我们使用 operator[] 和索引 3 来访问容器中的元素。接下来,我们使用 front() 函数来访问容器中的第一个元素,并使用 back() 函数来访问容器中的最后一个元素。

输出结果

Value at index 2: 3
Value at index 3: 4
First element: 1
Last element: 5

使用迭代器存取数据

#include <iostream>
#include <vector>

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

    // 使用迭代器访问容器中的数据
    std::vector<int>::iterator it;
    
    // 使用迭代器遍历容器并输出数据
    std::cout << "Elements in the vector: ";
    for (it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}

在上述示例中,我们创建了一个初始容器 vec,包含元素 1、2、3、4 和 5。
然后,我们声明了一个迭代器 it,并将其初始化为容器的起始位置(begin())
接下来,我们使用迭代器 it 遍历容器,并通过解引用操作符 *访问迭代器指向的元素。
在循环中,迭代器 it逐个移动到下一个元素,直到达到容器的末尾位置(end())为止
在循环过程中,我们输出迭代器指向的元素值。最后,我们输出一个换行符


实现两个vector容器内元素进行互换

函数原型

swap(vec); // 将vec与本身的元素互换

示例

#include <iostream>
#include <vector>

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

    std::cout << "Before swap:" << std::endl;
    for (const auto& value : vec) {
        std::cout << value << " ";
    }
    std::cout << std::endl;

    swap(vec); // 使用 std::swap 交换 vec 与本身的元素

    std::cout << "After swap:" << std::endl;
    for (const auto& value : vec) {
        std::cout << value << " ";
    }
    std::cout << std::endl;

    return 0;
}

在上述示例中,我们创建了一个初始容器 vec,包含元素 1、2、3、4 和 5。

然后,我们输出容器交换前的元素值。

接下来,我们调用 swap(vec),使用 std::swap 函数交换容器 vec 与其本身的元素,实现元素的重新排列。

最后,我们输出容器交换后的元素值

输出结果

Before swap:
1 2 3 4 5 
After swap:
5 4 3 2 1 

vector预留空间

可以减少vector在动态扩展容量时的扩展次数

函数原型

reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问。
在调用 reserve() 函数时,需要提供一个整数值作为参数,表示预分配的最小容量。这个容量是指可以容纳的元素数量,并不是占用的字节大小

示例

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec;

    std::cout << "Capacity before reserve: " << vec.capacity() << std::endl;
    
    vec.reserve(10); // 预留至少能容纳10个元素的空间

    std::cout << "Capacity after reserve: " << vec.capacity() << std::endl;

    return 0;
}

我们创建了一个空的 std::vector 容器 vec。

然后,我们输出容器调用 reserve() 函数之前的容量。

接下来,我们调用 vec.reserve(10),预留至少能容纳 10 个元素的空间。

最后,我们输出容器调用 reserve() 函数之后的容量。

输出

Capacity before reserve: 0
Capacity after reserve: 10

注意——如果数据量较大,可以一开始利用reserve预留空间


如果事先知道容器将要存储大量的元素,那么通过使用 reserve() 函数来预留空间是一个很好的做法。这样可以避免在插入元素时多次重新分配内存,从而提高性能。

预留足够的空间以容纳数据可以减少频繁的重新分配和复制操作,从而提高程序的效率。特别是对于大型数据集或需要频繁插入或添加元素的情况,这一点尤为重要。文章来源地址https://www.toymoban.com/news/detail-634939.html

到了这里,关于Day 23 C++ vector容器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】vector容器的模拟实现

    目录 一,框架设计 二,构造函数 三,析构函数 四,赋值运算符 五,容器接口的实现 1,迭代器实现 2,“ [] ”运算符的实现 3,swap交换和resize重设大小 4,insert插入和erase删除 介绍:         本文,我们重点实现vector容器的用法,这里要注意的是vector容器可以接纳任意类

    2024年02月02日
    浏览(44)
  • C++ —— STL容器【vector】模拟实现

    本章代码gitee仓库:vector模拟实现、vector源码 看源码发现 vector 是类模板定义的,成员是采用迭代器进行管理 当涉及到容器类时,通常有一些关键函数,如构造函数、析构函数和拷贝构造函数,它们负责初始化容器对象、销毁对象和进行对象的拷贝等 这里注意拷贝构造要实现

    2024年02月16日
    浏览(30)
  • 【C++】:C++中的STL序列式容器vector源码剖析

    vector定于与stl_vector.h头文件中 例如: vector的数据结构非常简单:一个线性连续空间 下面介绍vector的3个数据结构: start:表示目前使用空间的头 finish:表示目前使用空间的尾 end_of_storage:表示目前可用空间的尾 说明:为了降低空间配置时的速度成本,vector实际配置的大小可

    2024年01月22日
    浏览(35)
  • C++ stl容器vector的底层模拟实现

    目录 前言:   1.成员变量,容量与大小 2.构造函数 无参构造: 带参的使用值进行构造:  使用迭代器区间进行构造: 3.交换 4.拷贝构造 5.赋值重载 6.迭代器 7.扩容 reserve: resize: 8.插入与删除 insert: erase: insert迭代器失效问题: erase迭代器失效问题: 9.头插头删 10.[]重载

    2024年04月15日
    浏览(29)
  • C++容器(vector、deque、list、map)

    数组尾部添加或删除元素非常迅速。但在中部或头部就比较费时。 *代码演示:* 取: at在下标越界时会抛出异常,我们能捕获异常进行处理;而[]下标越界会让程序直接终止; 构造函数: cbegin, cend, crbegin, crend返回的是常量迭代器,不能通过迭代器修改vector元素的值。 插入(

    2024年02月02日
    浏览(40)
  • 【C++】容器篇(一)—— vector 的基本概述以及模拟实现

    前言: 在之前,我们已经对 string类进行了基本的概述,并且手动的实现了string类中常用的接口函数。本期,我将带领大家学习的是STL库中的一个容器 -- vector 的学习。相比于之前的string类,本期的 vector 相对来说实现起来略微难一点,难点就在于要考虑关于 “ 迭代器失效 ”

    2024年02月07日
    浏览(32)
  • 【C++入门】STL容器--vector底层数据结构剖析

    目录  前言  1. vector的使用       vector的构造  vector迭代器  vector空间相关的接口  vector 功能型接口  find  swap  insert  erase 2. vector内部数据结构剖析 reserve  push_back和pop_back size、capacity、empty、operator[ ];  insert和erase resize swap  拷贝构造和赋值重载 构造函数补充  迭代器

    2024年01月25日
    浏览(36)
  • 探索C++中的动态数组:实现自己的Vector容器

    🎉个人名片 : 🐼作者简介:一名乐于分享在学习道路上收获的大二在校生 🙈个人主页🎉:GOTXX 🐼个人WeChat:ILXOXVJE 🐼本文由GOTXX原创,首发CSDN🎉🎉🎉 🐵系列专栏:零基础学习C语言----- 数据结构的学习之路----C++的学习之路 🐓每日一句:如果没有特别幸运,那就请特

    2024年03月16日
    浏览(33)
  • 【C++庖丁解牛】vector容器的简易模拟实现(C++实现)(最后附源码)

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 我们前面介绍了vector容器的概念以及对其基本使用进行了介绍,如果你在这里不知道vector是什么以及不知

    2024年03月14日
    浏览(32)
  • 【C++庖丁解牛】STL之vector容器的介绍及使用 | vector迭代器的使用 | vector空间增长问题

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 vector的文档介绍 vector是表示可变大小数组的序列容器。 就像数组一样,vector也采用的连续存储空间来存

    2024年03月14日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包