C++vector容器

咱們在聲明數組的時候,採用的是datatype array[len]的形式,數組在分配以後,不能調整大小,刪除和插入數據時操做十分的繁瑣,雖然能夠採用鏈表,可是鏈表的操做更麻煩,咱們但願有更簡單的方法。c++

與string類同樣, 向量vector 同屬於STL(Standard Template Library,標準模板庫)中的定義的類, vector是一個封裝了動態數組的順序容器(Sequence Container),它可以存放各類類型的數據和對象。程序員

能夠簡單的認爲vector容器是一個可以存聽任意類型的動態數組,與數組相比,vector容器的優勢在於它可以根據須要自動調整的大小,隨時放入更多的元素。此外, vector也提供了成員函數對自身進行操做。數組

1、容器的定義

首先,若是要在程序中使用vector容器,必須包含頭文件 \<vector\>。以下:數據結構

#include <vector>

vector類是一個模板類,位於std命名空間內,爲方便使用還須要增長:ide

using namespace std;

聲明一個容器很簡單:函數

vector<int> vi;              // 定義用於存放整數的容器
vector<double> vd;         // 定義用於存放浮點數的容器
vector<string> vs;           // 定義用於存放string字符串的容器
vector<struct st_girl> vgirl;  // 定義用於存放超女結構體的容器
vector<CGirl> vGirl;         // 定義用於存放超女類的容器

vector容器能夠存放C語言的基本數據類型,能夠存放結構體,還能夠存放類,這正是咱們想要的簡單的方法,鏈表?我已經有二十年沒有用它了。學習

2、容器的使用

vector的功能強大,成員函數不少,我不想按普通教程的方式來介紹它,那樣會太煩鎖,我根據實際開發中應用的場景,採用示例程序介紹vector經常使用的用法。測試

一、存放整數

示例(book220.cpp)spa

/*
 * 程序名:book220.cpp,此程序用於演示C++容器存放整數
 * 做者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h> 
#include <vector>      // vector須要的頭文件
#include <algorithm>   // sort函數須要的頭文件

int main () 
{ 
  int height=0;             // 存放從鍵盤輸入的超女身高
  std::vector<int> vheight; // 存放超女身高的容器

  while (true)
  {
    printf("請輸入超女身高(0-結束輸入):");
    scanf("%d",&height);         // 接受鍵盤輸入的數據
    if (height==0) break;        // 0-結束輸入
    vheight.push_back(height);   // 把數據追加入容器
  }

  for (int ii=0;ii<vheight.size();ii++) // 顯示排序前容器中的記錄
  { 
    printf("vheight[%d]=%d\n",ii,vheight[ii]);
  }

  sort(vheight.begin(),vheight.end());  // 容器中的記錄排序

  for (int ii=0;ii<vheight.size();ii++) // 顯示排序後容器中的記錄
  { 
    printf("vheight[%d]=%d\n",ii,vheight[ii]);
  }

  // vheight.clear();  // 清空容器,能夠不寫。
}

運行效果.net

在這裏插入圖片描述

程序解釋以下:

std::vector<int> vheight;   // 聲明容器用於存放整數,超女身高,單位是cm。

void push_back(const T& x)成員函數:向容器尾部增長一個元素x,x就是您要向容器中增長的變量,在本示例中是一個整數,注意,參數x是一個引用,要用變量的名稱,不是變量的地址,如vheight.push_back(height);。

int size()成員函數:返回容器中數據的元素總數。

像數組同樣訪問容器:容器像數組同樣,能夠用數組的下標訪問,vheight[0]表示容器的第1個元素,vheight[n]表示容器的第n+1個元素。注意,採用下標方式放問容器的時候,下標不要越界,不然可能會引發內存溢出。

iterator begin()成員函數:返回容器頭指針,指向第一個元素。

iterator end()成員函數:返回容器尾指針,指向容器最後一個元素的下一個位置。

容器中的元素排序:採用sort()函數對容器中的元素進行排序。如sort(vheight.begin(),vheight.end());表示對容器中所有的元素進行排序。

void clear():清空容器中的所有元素,注意兩點:1)容器被聲明的時候,原本就是空的;2)容器是類,有析構函數,析構函數中會自動清空容器中的元素,釋放內存資源,不須要程序員擔憂。可是,程序員也能夠調clear()函數手工清空容器中的元素。

示例book220.cpp程序展現了vector容器10%的功能和成員函數,可是,在實際開發中,對容器的操做,95%的內容就是這些。

二、存放字符串

示例(book222.cpp)

/*
 * 程序名:book222.cpp,此程序用於演示C++容器存放字符串
 * 做者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h> 
#include <string.h>    
#include <string>       // string須要的頭文件
#include <vector>       // vector須要的頭文件

int main () 
{ 
  char strtmp[50];                // 存放姓名的臨時變量
  std::string name;               // 存放從鍵盤輸入的超女姓名
  std::vector<std::string> vname; // 存放超女姓名的容器

  while (true)
  {
    printf("請輸入超女姓名(0-結束輸入):");
    scanf("%s",strtmp);               // 接受鍵盤輸入的數據
    if (strcmp(strtmp,"0")==0) break; // 0-結束輸入
    vname.push_back(strtmp);          // 把數據追加入容器
  }

  for (int ii=0;ii<vname.size();ii++) // 顯示容器中的記錄
  { 
    printf("vname[%d]=%s\n",ii,vname[ii].c_str());
  }
}

運行效果

在這裏插入圖片描述

注意幾個問題:

1)用容器存放字符串,數據類型用string,不是C語言用0結尾的字符數組char [],string是一個變量,char []是一組變量。

2)用vname.push_back()成員函數把數據追加到容器中,參數的類型能夠是string,也能夠是char[],可是,這並非vector的特徵,而是string的特徵,容器聲明的是string類型,string的構造函數支持char [],表面上看push_back()進去的是char [],實際上會被轉換爲string。

三、存放結構體

示例(book225.cpp)

/*
 * 程序名:book225.cpp,此程序用於演示C++容器存放結構體
 * 做者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h> 
#include <string.h>    
#include <vector>       // vector須要的頭文件

struct st_girl       // 超女數據結構
{
  char name[50];     // 姓名
  int  age;          // 年齡
};

int main () 
{ 
  struct st_girl stgirl;             // 超女數據結構
  std::vector<struct st_girl> vgirl; // 存放超女結構體的容器

  strcpy(stgirl.name,"西施"); stgirl.age=18;
  vgirl.push_back(stgirl);

  strcpy(stgirl.name,"楊玉環"); stgirl.age=28;
  vgirl.push_back(stgirl);

  // 採用數組下標訪問容器中的記錄
  for (int ii=0;ii<vgirl.size();ii++) 
  { 
    printf("vgirl[%d].name=%s,vgirl[%d].age=%d\n",\
            ii,vgirl[ii].name,ii,vgirl[ii].age);
  }

  // 把容器中的記錄複製到結構體
  for (int ii=0;ii<vgirl.size();ii++) 
  { 
    memcpy(&stgirl,&vgirl[ii],sizeof(struct st_girl));
    printf("stgirl.name=%s,stgirl.age=%d\n",stgirl.name,stgirl.age);
  }
}

運行結果

在這裏插入圖片描述

總的來講,存放結構體的容器和數組的用法基本相同。

在book225.cpp中,採用了memcpy函數,它是C語言的庫函數,用於內存中的數據複製,聲明以下:

void *memcpy(void *dest, const void *src, size_t n);

dest:指向用於存儲複製內容的目標地址,類型強制轉換爲 void* 指針。

src:指向要複製的數據源地址,類型強制轉換爲 void* 指針。

n:要被複制的字節數。

該函數返回dest。

四、存放類

示例(book222.cpp)演示的存放字符串,string就是類。

3、其它成員函數

vector的成員函數比較多,爲了避免增長各位的學習負擔,我只介紹經常使用的。

一、定位的函數

iterator begin():返回容器頭的指針,指向容器第一個元素的位置。

iterator end():返回容器尾的指針,指向容器最後一個元素的下一個位置。

iterator是跌代器,這個名字讓人難以理解,那就先不要管它,如下我會舉例說明用法,通常來講,begin()和end()成員函數用於其它成員函數的參數中。

二、增長元素的函數

void push_back(const T& x):向容器的尾部增長一個元素x。

iterator insert(iterator it,const T& x):向容器中指定位置(it)前插入一個元素x。

strcpy(stgirl.name,"王昭羣"); stgirl.age=22;
vgirl.insert(vgirl.begin()+1,stgirl);  // 在第2個元素前插入一個元素。

三、刪除元素的函數

iterator erase(iterator it):刪除容器中指定位置(it)的元素。

vgirl.erase(vgirl.begin()+2);  // 刪除容器中第3個元素。
void pop_back():刪除容器中最後一個元素。
void clear():清空容器中所有的元素。

四、判斷容器的大小

bool empty():判斷容器是否爲空。

int size():返回容器中元素的個數。

4、容器的排序

在實際開發中,每每須要對vector容器中的元素進行排序,sort函數能夠實現排序功能。

sort(begin,end,cmp);

sort函數包含在頭文件爲#include \<algorithm\>的c++標準庫中,調用排序方法沒必要知道其內部是如何實現的,只要出現咱們想要的結果就行。

sort函數有三個參數:

(1)第一個是要排序的數組的起始地址。

(2)第二個是結束的地址。

(3)第三個參數是排序的方法,能夠是從大到小也但是從小到大,還能夠不寫第三個參數,此時缺省的排序方法是從小到大排序。若是vector容器中元素的數據類型不是基本數據類型,sort函數必須指定排序方法函數。

示例(book227.cpp)

/*
 * 程序名:book227.cpp,此程序用於演示C++容器的排序
 * 做者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h> 
#include <string.h>    
#include <vector>      // vector須要的頭文件
#include <algorithm>   // sort函數須要的頭文件

struct st_girl       // 超女數據結構
{
  char name[50];     // 姓名
  int  age;          // 年齡
};

// 自定義排序函數,按超女姓名排序
bool sortbyname(const st_girl &p1,const st_girl &p2)
{
  if (strcmp(p1.name,p2.name)<=0) return true;
  return false;
}

// 自定義排序函數,按超女年齡排序
bool sortbyage(const st_girl &p1,const st_girl &p2)
{
  if (p1.age<p2.age) return true;
  return false;
}

int main () 
{ 
  struct st_girl stgirl;             // 超女數據結構
  std::vector<struct st_girl> vgirl; // 存放超女結構體的容器

  strcpy(stgirl.name,"西施"); stgirl.age=18;
  vgirl.push_back(stgirl);

  strcpy(stgirl.name,"楊玉環"); stgirl.age=28;
  vgirl.push_back(stgirl);

  //sort(vgirl.begin(),vgirl.end());   // 若是不指定排序函數,編譯將報錯
  //sort(vgirl.begin(),vgirl.end(),sortbyname); // 按超女的姓名排序
  sort(vgirl.begin(),vgirl.end(),sortbyage);  // 按超女的年齡排序

  for (int ii=0;ii<vgirl.size();ii++) 
  { 
    printf("vgirl[%d].name=%s,vgirl[%d].age=%d\n",\
            ii,vgirl[ii].name,ii,vgirl[ii].age);
  }
}

5、課後做業

1)編寫示例程序,相似本章節的book220.cpp、book222.cpp、book225.cpp、book227.cpp,編譯並運行它,記住,程序員是寫出來的,不是看出來的,熟能生巧,您天天的付出都有意義。

2)編寫示例程序,測試一下vector容器其它成員函數的用法,玩一下就好了,有些成員函數之後可能有用。

3)豐富您的函數庫,寫一個類,封裝隨機數功能,類的聲明以下:

class CRand
{
public:
  vector<int> m_val;  // 用於存放生成好的隨機數
  CRand();
 ~CRand();
  void Rand(const int minvalue,const int maxvalue,bool brep=true);
}

注意:

(1)隨機數的種子不能只用time(0)的秒,還能夠利用微秒,同一秒內取到的隨機數將不一樣。

(2)Rand(const int minvalue,const int maxvalue,bool brep=true)生成指定範圍的隨機數,minvalue是最小值,maxvalue是最大值,brep是否容許重複。

4)vector容器的排序在實際開發中應用比較多,必須掌握。

5)vector容器存放超女類,能不寫排序函數嗎?若是存放string類,能不寫排序函數嗎?爲何?

6、版權聲明

C語言技術網原創文章,轉載請說明文章的來源、做者和原文的連接。
來源:C語言技術網(www.freecplus.net)
做者:碼農有道

若是這篇文章對您有幫助,請點贊支持,或在您的博客中轉發個人文章,謝謝!!!若是文章有錯別字,或者內容有錯誤,或其餘的建議和意見,請您留言指正,很是感謝!!!

相關文章
相關標籤/搜索