最详细STL(一)vector

vector的本质还是数组,但是可以动态的增加和减少数组的容量(当数组空间内存不足时,都会执行: 分配新空间(容量为2^n)-复制元素-释放原空间),首先先讲讲vector和数组的具体区别

一、vector和数组的区别

  1. vector封装了很多数组没有的方法,可以更方便的处理数据;数组相比起vector就少了很多
  2. 二维vector在声明中可以方便的初始化;数组需要用cstring库里面的memset函数来初始化(且只能直接初始化为0或-1)
  3. 一维vector一维数组;内存都是连续的
  4. 二维vector中,第二维的内存不是连续的,但是第一维是连续的;二维数组中内存是连续的

下面是样例代码

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;


int main()
{
    // 普通数组的声明并且初始化 
    int a_arr[3];
    memset(a_arr, -1, sizeof(a_arr)); 
    // vector可以更方便的初始化 ,且可以初始化为任何值 
    vector<int> a_vector(3,50);
    
    for(int i=0;i<3;i++)
        printf("%d ",a_arr[i]);
    printf("\n");
    for(int i=0;i<3;i++)
        printf("%d ",a_vector[i]);
    printf("\n");
    printf("\n一维上数组和vector的内存都是连续的\n");
    // 一维上数组和vector的内存都是连续的 
    for(int i=0;i<sizeof(a_arr)/sizeof(int);i++)
        printf("%d ", &a_arr[i]);
    printf("\n");
    for(int i=0;i<a_vector.size();i++)
        printf("%d ", &a_vector[i]);
    printf("\n");
        
        
    int b_arr[3][3];
    memset(*b_arr, -1, sizeof(b_arr)); 
    // vector<vector <int > > b_vector(3,(3));    自动初始化为0 
    vector<vector <int > > b_vector(3,vector<int>(3,50)); // 初始化为50 
    printf("\n二维上数组和vector的内存有差异\n");
    // 地址是连续的 
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            printf("b_arr[%d][%d]的地址为:%d\n", i, j, &b_arr[i][j]);
    // 地址不是连续的 
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            printf("b_vector[%d][%d]的地址为:%d\n", i, j, &b_vector[i][j]);
    // 由于地址不是连续的所以下面的访问方式vector不适用
    for(int i=0;i<9;i++)
        printf("%d ",b_arr[0][i]);
    printf("\n");
    for(int i=0;i<9;i++)
        printf("%d ",b_vector[0][i]);
    // 至于为什么vector越界访问的第一个值(也就是vector[0][3])总是0,我猜测是为了更快的push,顺便也初始化了 
    return 0;
}
  

 

 

 

   好了,看到了他们的区别现在再来讲讲vector什么时候用?怎么用?用的时候要注意些什么?

 二、什么时候用

  在需要使用数组而且不能确定数组的容量,但是又不想开太大的普通数组的时候,可以使用vector。

 三、怎么用

 

方法名称 解释
v.capacity() 容器容量
v.size() 容器大小
v.at(int idx) 用法和[]运算符相同
v.push_back() 尾部插入
v.pop_back() 尾部删除
v.front() 获取头部元素
v.back() 获取尾部元素
v.begin() 头元素的迭代器
v.end() 尾部元素的迭代器
v.insert(pos,elem) pos是vector的插入元素的位置
v.insert(pos, n, elem) 在位置pos上插入n个元素elem
v.insert(pos, begin, end)  
v.erase(pos) 移除pos位置上的元素,返回下一个数据的位置
v.erase(begin, end) 移除[begin, end)区间的数据,返回下一个元素的位置
reverse(pos1, pos2) 将vector中的pos1~pos2的元素逆序存储

 

下面这段代码可以让大家初步了解到vector的使用,并且观察到vector动态申请数组的过程

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;


int main()
{
    vector<int> a;
    for(int i=0;i<5;i++)
    {
        a.push_back(i);
        printf("%d %d\n", a.capacity(), a.size());
    }
    printf("\n");
    for(int i=0;i<3;i++)
    {
        int num =  a.back();
        a.pop_back();
        printf("%d %d %d\n",a.capacity(),a.size(),num);
    }
    return 0;
}
   

 

  四、用的时候要注意什么?

  1. vector自带了insert和erase来再vector中任意位置来插入元素,但是离尾部越远效率越低,所以需要频繁的在元素中任意位置插入删除元素可以选用其它的容器,比如list
  2. 还有就是通过下标访问的时候不要越界访问。

 

  参考于:https://blog.csdn.net/weixin_41588502/article/details/87978490

posted @ 2021-10-06 12:30  小兜兜me  阅读(372)  评论(0编辑  收藏  举报