概述

1.C++ STL的容器分为三种,序列式容器,关联式容器,无序式容器,这里先说说常用的序列式容器。
2.array,vector,deque,list,forward_list这几种都是序列式容器,序列容器是以线性序列的方式存储元素,也就是说,在内存,是连续分配一块内存来存放元素的,是可以经过下标迭代的方式遍历元素。
3.C++的容器是不能用来装引用和函数的,容器的设计原则是以效率为先,安全为次的,所以容器本身并不带有异常处理。

一.基本用法

所有的序列式容器都有一些共同的属性和用法,这里我拿最学常用的std::vecot来举例子,这些属性array,vector,deque,list,forward_lis的使用方法是一样的。

  • 构造:
 using T = std::vector<float>;T a;T b(a);//拷贝构造T d = a;//拷贝构造,调用了operator =T e(std::move(b));//右值引用,执行完之后b里面为空值,但b所占的内存不变T c{ a };//C++ 11之后支持的拷贝方法T g(a.begin(), a.end());//区间拷贝
  • 属性:
 T t;int i = t.size();//返回容器大小,为了空间上的极致效率,forward_list没有这个属性bool tf = t.empty();//容器是否为空,等价于 t.size() != 0,但效率上要高一些auto max = t.max_size();//当前环境下最多还存放多少个该元素t.swap(a);//交换两个容器,但类型必须相同,实现是交换两个容器的指针(array除外)swap(t, a);//等价于上面t.begin();//返回容器头部迭代器位置t.end();//返回容器末尾部的迭代器合法位置的下一个位置,如果要解引用 *(t.end()-1)t.cbegin();//跟上面两不一样的是,这个返回的是const迭代器t.cend();t.rbegin();//反过来的迭代器t.rend();t.front();//返回头部元素的引用t.back();//返回尾部元素的引用t.clear();//清空容器,调用类的析构函数

二.std::array

1.概念
1.1 std::array是在C++11中才引入的容器,其实就是C++11对内置数组的重新封装,array对象在实例化的时候大小是固定的,并不支持动态添加或者删除元素,所以array默认是构造一个非空的实例。array的内存是分配在栈上的,对应的拷贝和赋值都要花掉一定的空间,绝不会重新分配内存。
1.2 在知道容器的大小情况,或者要与C进行交互时可以考虑使用std::array,毕竟array比内置的数组增加了一些常用的接口和可以对下标进行检查。
2. std::array的构造:

std::array<float, 100> a;//类型是float,有100个元素
std::array<float, 100> b = {};//全部按float的默认值初始化
std::array<float, 5> d = { 1.0f,33.0f,2.1f,4.3f,7.0f };//具体值初始化
std::array<float, 5> c = {2.0f};//第一个元素初始化为2.0,其余按类型默认值初始化

3.std::array的元素访问
遍历方法:

 //传统方法遍历for (size_t i = 0; i < d.size(); ++ i){std::cout << d[i] << std::endl;//中括号是不检查下标是否合法std::cout << d.at(i) << std::endl;//.at()会检查下标,如果不合法则抛出异常}//迭代器遍历for (auto iter = d.begin(); iter != d.end(); ++iter){std::cout << *iter << std::endl;//解引用}//auto 方式遍历for (auto v : d){std::cout << v << std::endl;}
  1. 与C接口互用
 std::array<char, 10> c_str;strcpy(c_str.data(), "array char\n");//在vs中头文件要加#include <cstring>,项目属性/C++/预处理器加入:_CRT_SECURE_NO_WARNINGSprintf("%s", c_str.data());

5.交换函数:

 t.swap(a);//交换两个容器,array是交换两个容器里面的值,而不是容器指针,这样容器一大效率就会降低swap(t, a);//等价于上面

三.std::vector

  1. 概念
    1.1 std::vector 是C++ 98就引入的动态数组,vector会在需要自动调整所占内存的大小,vector的这个特性让它比起静态数组所占用的内 存更多一些,因为它还分配了额外的内存以应对将来可能的内存扩张,在使用过程中,不用因为每次插入新的元素而重新分配内存,除非预留分配的那块内存用完,这样有效率会有很大的提升。
    1.2 std::vector的特点是能随机访问容器内的元素,在容器末端添加或者删除元素效率比较高,前端和中间则效率相对会低一些。
  2. 构造
 std::vector<float> d(10);//创建容器里面全部初始化为类型默认值(0.0)std::vector<float> e(10, 1.0f);// 创建容器里面全部初始化为1.0std::vector<float> c(e.begin(), e.end());//迭代器方式拷贝//C++ 11 std::vector<float> h({ 1.01, 1.1, 4.0, 3.0, 5.5 });std::vector<float> d{ 1.2, 3.7, 0.2, 10.4, 3.6 };
  1. 属性
 auto mun = h.capacity(); //返回容器当前能够容纳的元素数量h.reserve(10); //为容器预先分配内存,避免重新分配内存。h.assign(8, 1.1f);//压缩或者放大内存并指定默认值h.assign(e.begin(), e.end());//等价于 h = eh.assign({2.0,1.5,3.9});//压缩并指定初始化h.pop_back();//删掉最后一个元素,这里要确定容器不能为空h.push_back(11.12);//在容器尾部插入一个元素auto iterAfter =  h.erase(h.begin());//删掉指定元素,删掉后后面的元素要向前填补,//返回要删除元素的下一个元素的引用,如果全部//删完,则返回end(),使用该方法之后,迭代器有//可能会失效(pop_back(),push_back()也有这个现象)//因为vector有可能重新分配内存h.erase(h.begin(), h.end());//区间删掉元素,要确定区间值是闭合的auto iter = h.insert(h.end(),12.7f);//在指定位置插入一个新的元素,返回迭代器位置iter = h.insert(h.end(),10,12.1f);//在指定位置插入10元素,并初始化为指定值h.insert(h.end(), e.begin(), e.end());//在指定位置插入另一个容器区间h.resize(10);//缩小或者放大容器h.resize(20, 1.2f);//放大容器,如果之前不满20个,则插入的元素初始化为1.2,//如果原本的容器大于20个,则忽略掉。h.clear();//清空掉容器里面所有的值,但容器的所占的内存不会变小h.shrink_to_fit();//请求容器降低其容量与当前所要存的元素匹配,//但主动权在编译器,它决定是否真正释放多余的内存,//这个方法只是提出请求,是否要实现由编译器说了算//目前大部分的实现是内存能降下来t.swap(a);//交换两个容器,vector是交换两个容器的指针swap(t, a);//等价于上面
  1. 元素访问与容器遍历与array一样
 //传统方法遍历for (size_t i = 0; i < h.size(); ++i){std::cout << h[i] << std::endl;//中括号是不检查下标是否合法std::cout << h.at(i) << std::endl;//.at()会检查下标,如果不合法则抛出异常}//迭代器遍历for (auto iter = h.begin(); iter != h.end(); ++iter){std::cout << *iter << std::endl;//解引用}//auto 方式遍历for (auto v : h){std::cout << v << std::endl;}
  1. 与C接口互用
 std::vector<char> c_str(20);strcpy(c_str.data(), "vector char\n");//在vs中头文件要加#include <cstring>,项目属性/C++/预处理器加入:_CRT_SECURE_NO_WARNINGSprintf("%s", c_str.data());

四.std::deque

1.概念
1.1 std::deque是双端队列,头尾两端插入和删除元素比较高效,中间删除和添加元素效率低,在std::deque两端插入和删除并不会使其它元素的指针或引用失效。
1.2 元素的访问和迭代比vector慢,因为迭代器是智能指针而不是普通指针,内存分配不连续。
1.3 std::deque的存储空间会自动按需扩大和缩小,扩大std::deque比扩大std::vector的效率和开销会低很多,因为它不涉及到现有元素复制到新的内存位置。
2.定义方法和定义vecot的方法一样,没有不一样的地方。
3.属性
std::deque不提供 capacity(),reserve()这两个方法,因为deque分配的内存是一块一块的,不需要知道预分配多少内存。

 std::deque<float> d{ 1.2,3.7,0.2,10.4,3.6 };d.pop_back();//删除最后一个元素d.pop_front();//删除头元素;//在头部添加元素d.push_front(2.9f);d.emplace_front(3.7f);//在尾部添加元素d.push_back(3.3f);d.emplace_back(1.1f);d.emplace(d.end(),10.0f);//插入元素,指定初始化

4.元素访问与容器遍历与vector一样。
5.deque不能和C接口交互。
6.交换两个容器方法和效率跟vector一样。

五.std::list

1.概述
1.1 list是一个双向链表,不支持随机访问元素,访问头部和尾部元素速度快。
1.2 在list中任何位置进行插入/删除操作速度都很快,常量时间内完成,插入和删除不会造成迭代器失效。
1.3 对异常支持较好,出现异常对list而言,要么成功,要么什么影响都没有。
1.4 list在空间的成本上要比vector,deque高很多,因为list是一个双向列表,每个元素要有一个往前指针和往后的指针,list本身内部的元素是通过new的方式来生成的,比如用list存一个char元素时,在64位系统下,要开支33个字节左右(往前指针8个字节 + 往后指针8个字+new的16个字节 + char本身的一个字节)。

2.构造方法与vector一样。

3.属性。
list是一个个分配内存的,所以不提供capacity(),reserve(),shrink_to_fit() 这三个方法。

 std::list<float> d{ 1.2, 3.7, 0.2, 10.4, 3.6 };d.pop_back();//删除最后一个元素d.pop_front();//删除头元素//在头部添加元素d.push_front(2.9f);d.emplace_front(3.7f);//在尾部添加元素d.push_back(3.3f);d.emplace_back(1.1f);d.emplace(d.end(), 10.0f);//插入元素,指定初始化

4.元素访问与遍历
list不支持[]和at访问元素。

 //访问遍历元素auto iter_begin = d.begin();for (int i = 0; i < d.size()-1; ++i){std::cout << *(++iter_begin) << std::endl;}auto iter = std::next(iter_begin,2);//访问第三个元素,返回迭代器引用std::cout << *iter << std::endl;//auto遍历元素for (auto v : d){std::cout << v << std::endl;}

5.算法

d.remove(1.2);//删除掉容器里面所有等于1.2的值d.remove_if([](auto v) {return v > 5.0f; });//条件删除d.reverse();//翻转整个容器d.sort();//排序,默认是从小到大//std::sort(d.begin(), d.end());//不能这么用h.sort();d.merge(h);//把两个排好序的容器合并成一个容器,之后h里面没有元素d.unique();//把两个排好序的容器里面重复的元素删掉d.splice(d.begin(),c);//把C容器安插到d的指定位置

5.list不能和C接口交互。

C++ STL容器——序列式容器(array、vector、deque、list)相关推荐

  1. C++(STL):22 ---序列式容器queue使用

    queue是队列,特点是先进先出,后进后出,你可以理解为数据结构里的队列模型,他只允许你访问 queue<T> 容器适配器的第一个和最后一个元素.只能在容器的末尾添加新元素,只能从头部移除 ...

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

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

  3. STL浅析——序列式容器vector的数据结构

    vecotr 一词原来的意思是:矢量,向量,航向,顾名思义指的就是类似于数组的一个存储数据的序列,因此所采用的数据结构非常简单:连续的线性空间,它以两个迭代器 _M_start 和 _M_finish ...

  4. STL之序列式容器(五)、list容器

    一.list(STL list)使用.创建和初始化 list<T> 容器模板定义在 list 头文件中,是 T 类型对象的双向链表. list 容器具有一些 vector 和 deque ...

  5. C++(STL):25 ---序列式容器stack源码剖析

    一.stack概述 stack是一种先进后出(First In Last Out,FILO)的数据结构.它只有一个出口, 形式如下图所示 特点: stack允许新增元素.移除元素.取得最顶端元素.但除 ...

  6. C++(STL):24 ---序列式容器stack用法

    1.stack的定义 要使用stack,应先添加头文件#include <stack>, 并在头文件下面加上 "using namespace std" //定义 st ...

  7. C++(STL):23 ---序列式容器queue源码剖析

    一.queue概述 queue是一种先进先出(First In First Out,FIFO)的数据结构.它有两个出口,形式如下图所示 特点: queue允许新增元素.移除元素.从最底端加入元素.取得 ...

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

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

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

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

最新文章

  1. Sql Server数据库连接Oracle数据库
  2. python pandas dataframe 行列选择,切片操作 原创 2017年02月15日 21:43:18 标签: python 30760 python pandas dataframe
  3. C++阶段01笔记04【程序流程结构(选择结构、循环结构、跳转语句)】
  4. c#程序中使用quot;like“查询access数据库查询为空的问题
  5. java 类加载 双亲委派_Java类加载器和双亲委派机制
  6. linux报文高速捕获技术对比--napi/libpcap/afpacket/pfring/dpdk/xdp
  7. python 函数结果缓存一段时间的装饰器
  8. OLAP-ClickHouse-大数据Week13-DAY3-ClickHouse
  9. 基于SpringBoot的答题系统
  10. java jdbc 批处理_JDBC的批处理操作
  11. 贪心算法解决汽车加油问题
  12. PHP审计-RIPS
  13. Linux Centos7 防火墙(开启、关闭、重启、状态、端口)
  14. ubuntu8.10显卡驱动安装(8500gt)
  15. 基于Django搭建Python web项目——项目创建及配置(一)
  16. ArcGIS Pro发布WebScene
  17. 【论文】联邦学习区块链 论文集(三)
  18. P1413 坚果保龄球 AC于2018.7.30
  19. 为什么我从Flutter转投Electron的怀抱?
  20. 设置SecureCRT来正确显示彩色

热门文章

  1. mysql collation utf8_mysql数据库 表字段 的collation utf8_unicode_ci
  2. Redis【入门】就这一篇!
  3. NumberUtils用法
  4. 分布式事务?No, 最终一致性
  5. Java字符串中常见的10个问题
  6. 积跬步,聚小流------html知识大纲归纳总结
  7. Mybatis通用Mapper
  8. Python 异常处理 Python 基础教程 try..except
  9. 跟vczh看实例学编译原理——零:序言
  10. 入坑emacs之配置文件 .emas.d/init.el -v1.0