最詳細STL(一)vector

小兜兜me發表於2021-10-06

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中任意位置來插入元素,但是離尾部越遠效率越低,所以需要頻繁的在元素中任意位置插入刪除元素可以選用其它的容器,比如map
  2. 還有就是通過下標訪問的時候不要越界訪問。

 

  參考於:https://blog.csdn.net/weixin_41588502/article/details/87978490

相關文章