zoukankan      html  css  js  c++  java
  • C++学习笔记一

    前言

    说起打算写这篇博客的原因,那可真的是曲折离奇。故事追溯到今天早上,像往常一样,我逃了第一节早课计算机网络安全,老画大饼的课程了来到学校的实验楼这边学习,但是正在第一小节下课时,我的几个线人都说不妙,老师有点名的想法,于是我骑着我的破单车,以一个小时七十码的速度赶往教学楼,幸运的是,最终还是赶上了。但是正是因为太过匆忙,我只带了一串钥匙和手机,啥书都没带,又不想听课(虽然后面看到老师正在讲的是病毒章节的内容,里面讲到的几个点譬如恶意代码的动态反规避和静态反规避技术,有点对应于逆向题的反动态调试和反静态调试),所以就掏出手机刷刷公众号的内容,然后发现更新了一条关于递归学习的,想到自己那弱鸡的写代码能力,就点进去学习一下。发现挺有不错,里面还对应了力扣的一道题。再之因为自己之前就有打算做做力扣的题目,提高一下自己的代码水平以及算法水平,然后当时就有想法说下午做一下。然后再等到早上第二节课,讲密码学,老师又讲到了递归的内容,所以学习递归的想法就确定了。

    然后等到晚上去做完那道力扣,想做做其他题的时候,看到vector这个容器。想到自己之前打比赛的时候遇到了好几次这个东西,但是一直不是很了解,再之自己之前就有想法去学C++,所以就去学习了一下,就当作学习C++的第一个内容吧 。

    也许,冥冥中一切都已经有安排了吧。。。。。

    C++ Vector容器浅析

    什么是vector

    向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。

    vector是STL中最常见的容器,它是一种顺序容器,支持随机访问。vector是一块连续分配的内存,从数据安排的角度来讲,和数组极其相似,不同的地方就是:数组是静态分配空间,一旦分配了空间的大小,就不可再改变了;而vector是动态分配空间,随着元素的不断插入,它会按照自身的一套机制不断扩充自身的容量。

    vector的扩充机制:按照容器现在容量的一倍进行增长。vector容器分配的是一块连续的内存空间,每次容器的增长,并不是在原有连续的内存空间后再进行简单的叠加,而是重新申请一块更大的新内存,并把现有容器中的元素逐个复制过去,然后销毁旧的内存。这时原有指向旧内存空间的迭代器已经失效,所以当操作容器时,迭代器要及时更新。(虽然是一个末流pwn手,但个人感觉这里有点奇妙)

    vector的数据结构

    vector数据结构,采用的是连续的线性空间,属于线性存储。他采用3个迭代器_First、_Last、_End来指向分配来的线性空间的不同范围,下面是声明3个迭代器变量的源代码。

    template<class _Ty, class _A= allocator< _Ty> > 
    class vector{ 
        ... 
        protected: 
        iterator _First, _Last, _End; 
    };
    

    _First指向使用空间的头部,_Last指向使用空间大小(size)的尾部,_End指向使用空间容量(capacity)的尾部。例如:

    int data[6]={3,5,7,9,2,4}; 
    vector<int> vdata(data, data+6); 
    vdata.push_back(6); 
    

    vector初始化时,申请的空间大小为6,存放下了data中的6个元素。当向vdata中插入第7个元素“6”时,vector利用自己的扩充机制重新申请空间,数据存放结构如图1所示:

    简单描述一下。当插入第7个元素“6”时,vector发现自己的空间不够了,于是申请新的大小为12的内存空间(自增一倍),并将前面已有数据复制到新空间的前部,然后插入第7个元素。此时_Last迭代器指向最后一个有效元素,而_End迭代器指向vector的最后有效空间位置。我们利用vector的成员函数size可以获得当前vector的大小,此时为7;利用capacity成员函数获取当前vector的容量,此时为12。

    定义方式

    • Vector<类型>标识符
    • Vector<类型>标识符(最大容量)
    • Vector<类型>标识符(最大容量,初始所有值)
    • vector<类型>标识符(vector b)//用b向量来创建新向量,整体复制性赋值
    • vectora(b.begin(),b.begin+3)//定义了a,值为b中第0个到第2个(共3个)元素
    • Vector< vector< int> >v; 二维向量 //这里最外的<>要有空格。否则在比较旧的编译器下无法通过

    基本函数实现

    1.构造函数

    • vector():创建一个空vector
    • vector(int nSize):创建一个vector,元素个数为nSize
    • vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
    • vector(const vector&):复制构造函数
    • vector(begin,end):复制[begin,end]区间内另一个数组的元素到vector中

    2.增加函数

    • void push_back(const T& x):向量尾部增加一个元素X
    • iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元素x
    • iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n个相同的元素x
    • iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据

    3.删除函数

    • iterator erase(iterator it):删除向量中迭代器指向元素
    • iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
    • void pop_back():删除向量中最后一个元素
    • void clear():清空向量中所有元素

    4.遍历函数

    • reference at(int pos):返回pos位置元素的引用
    • reference front():返回首元素的引用
    • reference back():返回尾元素的引用
    • iterator begin():返回向量头指针,指向第一个元素
    • iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
    • reverse_iterator rbegin():反向迭代器,指向最后一个元素
    • reverse_iterator rend():反向迭代器,指向第一个元素之前的位置

    5.判断函数

    • bool empty() const:判断向量是否为空,若为空,则向量中无元素

    6.大小函数

    • int size() const:返回向量中元素的个数
    • int capacity() const:返回当前向量所能容纳的最大元素值
    • int max_size() const:返回最大可允许的vector元素数量值

    7.其他函数

    • void swap(vector&):交换两个同类型向量的数据
    • void assign(int n,const T& x):设置向量中第n个元素的值为x
    • void assign(const_iterator first,const_iterator last):向量中[first,last)中元素设置成当前向量元素

    这里说明一点, vector 类是随标准 C++引入的标准库的一部分,使用时需包含头文件:

    #include <vector>
    

    vector属于std命名域的,因此需要通过命名限定,如下:

    using std::vector;
    

    或者连在一起,使用全名:

    std::vector<int> **;
    

    迭代器

    其实迭代器是C++容器的概念,并不局限于vector。

    迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。

    迭代器分类

    迭代器按照定义方式分成以下四种。

    1. 正向迭代器,定义方法如下:
      容器类名::iterator 迭代器名;

    2. 常量正向迭代器,定义方法如下:
      容器类名::const_iterator 迭代器名;

    3. 反向迭代器,定义方法如下:
      容器类名::reverse_iterator 迭代器名;

    4. 常量反向迭代器,定义方法如下:
      容器类名::const_reverse_iterator 迭代器名;

    迭代器用法

    通过迭代器可以读取它指向的元素,*迭代器名就表示迭代器指向的元素。通过非常量迭代器还能修改其指向的元素。

    迭代器都可以进行++操作。反向迭代器和正向迭代器的区别在于:

    • 对正向迭代器进行++操作时,迭代器会指向容器中的后一个元素;
    • 而对反向迭代器进行++操作时,迭代器会指向容器中的前一个元素。

    迭代器的辅助函数

    STL 中有用于操作迭代器的三个函数模板,它们是:

    • advance(p, n):使迭代器 p 向前或向后移动 n 个元素。
    • distance(p, q):计算两个迭代器之间的距离,即迭代器 p 经过多少次 + + 操作后和迭代器 q 相等。如果调用时 p 已经指向 q 的后面,则这个函数会陷入死循环。
    • iter_swap(p, q):用于交换两个迭代器 p、q 指向的值。

    注:要使用上述模板,需要包含头文件 algorithm

    参考

    https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html
    https://blog.csdn.net/fanyun_01/article/details/56842637
    https://blog.csdn.net/fanyun_01/article/details/56842637

  • 相关阅读:
    ES6 基础
    JavaScript 基础
    Java 虚拟机
    MinIO 搭建使用
    .NET 半天搭建Jenkins持续集成与自动化部署系统
    驱动领域DDD的微服务设计和开发实战
    走向架构师必备的技能
    分布式系统与消息的投递¶
    求数组的子数组之和的最大值
    KVO初探
  • 原文地址:https://www.cnblogs.com/T1e9u/p/13887314.html
Copyright © 2011-2022 走看看