点击蓝字 关注我们

主要内容

本篇内容主要介绍STL六大组件之一的序列式容器(vector),容器其实就是各种数据结构;另外,迭代器部分的内容可以看看《STL源码剖析》,它的的主要作用是作为容器和算法之间的胶合剂,单独的算法和容器是没有意义的,需要用合适的方法将两者结合起来,因此这部分内容主要结合容器实现原理来讲。如果对文章内容感兴趣,欢迎大家多多关注公众号"爱折腾的码农"。

迭代器

定义:提供一种方法,保证在不暴露容器的内部实现细节的情况下能够依序访问容器中的各个元素。

容器

定义:各种数据结构,其实就是用来存放数据的,例如:vector、list、deque、map、unordered_map,容器分为两类:序列式容器和关联式容器,从底层实现上来说容器是一种类模板。

序列式容器

概念:其实就是类似于一维数组的概念,以线性排列来存储指定类型的数据,但是存储的数据并不一定是有序的(有序是指从大到小或从小到大)。

vector

可变大小数组。支持快速随机访问,在尾部之外的位置插入或删除元素可能很慢。

deque

双端队列。支持快速随机访问。在头尾位置插入或删除速度很快

list
   双向链表。只支持双向顺序访问。在list中任何位置进行插入或删除操作速度都很快

forward_list

单向链表。只支持单向顺序访问。在链表任何位置进行插入或删除操作速度都很快

array
   固定大小数组。支持快速随机访问,不能添加或删除元素

string

与vector相似的容器,但专门用于保存字符。随机访问快。在尾部插入或删除速度快

vector

其实C++语言本身提供了一个存储数组的序列式容器array,但是它是静态空间,一旦设置好大小就不能改变,因此STL设计了一款可以动态改变内存大小的序列式容器vector(其实底层还是基于数组实现的)。

动态分配内存实现原理:分配内存好内存后,如果发现现有内存不够存放元素,则需扩充内存,主要就是另外分配一块新的内存空间,然后将旧地址元素复制到新的地址,最后将原来的空间释放。

vector的迭代器

vector数据结构

vector的数据结构非常简单:线性连续空间。它用两个迭代器start和finish分别指向配置的连续空间中目前已使用的范围,并且用end_of_storage指向整块连续空间的尾端。

为什么多申请内存留做备用空间?

为了降低空间配置时的速度成本,vector实际配置的大小可能比客户端需求量更大一些,以备将来可能的扩充(其实这也是容量的概念),就是一旦容量已经满了,下次再有新增元素,整个vector就要实现扩容了。如果频繁的扩容就需要频繁的申请内存和释放内存,这样比较影响性能。

vector元素的基本函数实现(本部分只介绍了部分,具体请看《STL源码剖析》)

vector扩容原理

注意:vector的扩容可分成2倍扩容和1.5倍扩容,其中1.5扩容的话原空间可能还会被使用,不会另外寻找新的内存,但是2倍扩容一定需要另外寻找新的内存空间。

vector使用方法

接下来主要说一下vector在实际中的使用,其实完全没有必要死记硬背这些,多刷一些题就自然而然记住了。

1、初始化和拷贝

//初始化

vector ivec1;    //默认初始化,初始状态为空
    vector ivec2 = {1, 2, 3};    //列表初始化vector对象
    vector ivec3(10, -1);    //创建指定元素的元素, 10个int类型的元素,每个都被初始化为-1
    vector ivec4(10);  //值初始化,10个元素,每个元素初始化为0 //拷贝
    vector ivec5(ivec1);   //把ivec1的元素拷贝给ivec2
    vector ivec6 = ivec1;  //把ivec1的元素拷贝给ivec6

2、其他操作

vector v{1, 2, 3, 4, 5, 6, 7};
    for(auto &i : v)    //对于v中的每个元素(注意:i是一个引用)
       i *= i;         //求元素值的平方

for(auto i : v)     //对于v中的每个元素
       cout << i << " ";   //输出该元素

//迭代器输出元素,其中it的定义类型应该是 vector::iterator it = v.begin();
    for(auto it = v.begin(); it != v.end(); ++it)
       cout << *it << " ";
    cout << endl;

3、vector迭代器失效问题

vector v{1, 2, 3, 4, 5, 6, 7};
    for(auto it = v.begin(); it != v.end(); ++it){
      if(*it == 3)
           v.erase(it);
    }

注意,当使用v.erase(it)语句执行后,it就变成了一个野指针,如果对一个野指针进行 it++操作就会出现错误,因此在删除元素时上述代码需要写成下面这样。

vector v{1, 2, 3, 4, 5, 6, 7};
    for(auto it = v.begin(); it != v.end(); ++it){
       if(*it == 3)
           it = v.erase(it);
    }

这样就不会出错的原因是:erase会返回下一个元素的有效迭代器(vector的可以理解为指针)

resize()和reserve()的区别?

resize(size_type n)用来强制将容器改为存放n个元素。如果n小于当前vector对象大小的话,容器尾部的元素会被销毁。如果n大于当前大小,则新默认构造的元素添加到容器尾端。如果n大于当前容量,则在添加元素之前会进行重新分配新的内存。

reserve(size_type n)强制将vector对象的容量改为不小于n;如果n小于当前容器,vector忽略它。

vector对象大小和容量区别?

大小(size)是指元素的个数(即已存放到内存空间的元素个数),容量(capacity)指的是分配内存的大小(即使用空间配置器分配的内存空间)。

最后预告一下接下来几篇文章会写序列式容器list、deque、list和vector的区别、关联式容器map、unordered_map等,如果对内容感兴趣的话,欢迎关注本公众号。

欢迎扫码关注我们

微信公众号|爱折腾的码农

容器大小_C++复习篇(7)序列式容器vector相关推荐

  1. STL序列式容器Standard Template Library Sequence Container

    STL序列式容器 STL Sequence Container 目录 STL序列式容器 STL Sequence Container STL(Standard Template Library)概述 ...

  2. C++基本序列式容器 vector (一)

    我们以 vector.deque 和 list 为例介绍基本序列式容器,先来看一个关于 vector 容器的例子. #include <iostream> #include <vec ...

  3. C++ STL容器——序列式容器(array、vector、deque、list)

    概述 1.C++ STL的容器分为三种,序列式容器,关联式容器,无序式容器,这里先说说常用的序列式容器. 2.array,vector,deque,list,forward_list这几种都是序列式容 ...

  4. 容器大小_C++ 顺序容器基础知识总结

    阅读目录 0.前言 1.容器概论 2.std::array 2.1.底层数据结构 2.2.内存分配策略 2.3.array的优势在哪 3.forward_list 3.1.底层数据结构 3.2.for ...

  5. STL源码剖析 序列式容器|Vector

    容器的概观和分类 array 数组 .list 链表.tree树 .stack堆栈.queue队列.hash table散列表.set集合.map映射表 根据数据在容器中的排列顺序,将上述数据结构分为 ...

  6. 第四章 序列式容器(sequence containers)

    序列式容器(sequence containers) 1.容器的概观与分类 2.vector 3.list 4.deque 5.stack 6.queue 7.heap(隐私表述,implicit r ...

  7. 【C++ STL学习笔记】C++ STL序列式容器(array,vector,deque,list)

    文章目录 C++ STL容器是什么? 迭代器是什么,C++ STL迭代器(iterator)用法详解 迭代器类别 迭代器的定义方式 C++序列式容器(STL序列式容器)是什么 容器中常见的函数成员 C ...

  8. C++基本序列式容器效率比较

    前面介绍序列式的三种容器时,我们简单介绍了在容器各部位插入或删除元素时的处理效率,在此节我们做一个总结. 根据 STL 公布的容器各种操作效率,我们可以根据不同的需求来选择合适的容器.例如,我们需要频 ...

  9. STL之序列式容器(三)、vector容器

    一.vector的使用.创建及初始化 vector<T> 容器是包含 T 类型元素的序列容器,和 array<T,N> 容器相似,不同的是 vector<T> 容器 ...

最新文章

  1. Linux+Apache+MySQL+PHP5的安装与配置与phpBB2论坛的架设
  2. flume ng之组件介绍
  3. 简单介绍tomcat中maxThreads,acceptCount,connectionTimeout
  4. Python的逻辑判断和循环 || 打印九九乘法表
  5. HDU - 4348 To the moon
  6. Leetcode上的解法看不懂?试着用动画的方式去辅助理解
  7. 【宽度优先搜索笔记】BFS输出最短路径
  8. 如何让debuge的dll名字改变_杨石头:如何给品牌取个好名字?
  9. 【教程搬运】廖雪峰Git的使用教程(一)
  10. C# SendMessage 控制其他进程程序
  11. sqlitespy可以打开MySQL吗_SQLite 数据库访问
  12. VMware虚拟机Ubuntu系统如何连接网络
  13. 如何查询一个 app 的 Android 和 iOS 下载量?
  14. mysql在centos下改24小时制
  15. Mac 开启局域网smb文件共享(附全平台连接方法)
  16. springboot---fastDFS 简单文件上传/下载/删除
  17. SpringBoot项目中的 ClassPath路径指的是哪个路径
  18. php 字符串中英文混合截取,PHP截取中英混合的字符串
  19. python初中数学建模培训_中学生数学建模训练营VIP班
  20. 山东莱芜市民在省内91家医院就医可即时结算

热门文章

  1. 计算机二级office函数日期,Excel函数-日期和文本函数-计算机二级Office
  2. JQ实现 todolist案例(记事本)
  3. vue 地图使用navigator_初识ABP vNext(6):vue+ABP实现国际化
  4. 在datasnap 中使用unidac 访问数据(客户端)
  5. 深入理解JAVA锁的机制
  6. Unity 2D和3D对象的点击
  7. python中encode()函数的用法
  8. 我眼中的ASP.NET Core之微服务 (二)
  9. hive on tez集成完整采坑指南(含tez-ui及安全环境)
  10. 【解决方案】pytorch中loss变成了nan | 神经网络输出nan | MSE 梯度爆炸/梯度消失