咱們在聲明數組的時候,採用的是datatype array[len]的形式,數組在分配以後,不能調整大小,刪除和插入數據時操做十分的繁瑣,雖然能夠採用鏈表,可是鏈表的操做更麻煩,咱們但願有更簡單的方法。c++
與string類同樣, 向量vector 同屬於STL(Standard Template Library,標準模板庫)中的定義的類, vector是一個封裝了動態數組的順序容器(Sequence Container),它可以存放各類類型的數據和對象。程序員
能夠簡單的認爲vector容器是一個可以存聽任意類型的動態數組,與數組相比,vector容器的優勢在於它可以根據須要自動調整的大小,隨時放入更多的元素。此外, vector也提供了成員函數對自身進行操做。數組
首先,若是要在程序中使用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語言的基本數據類型,能夠存放結構體,還能夠存放類,這正是咱們想要的簡單的方法,鏈表?我已經有二十年沒有用它了。學習
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就是類。
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()
:返回容器中元素的個數。
在實際開發中,每每須要對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); } }
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類,能不寫排序函數嗎?爲何?
C語言技術網原創文章,轉載請說明文章的來源、做者和原文的連接。
來源:C語言技術網(www.freecplus.net)
做者:碼農有道
若是這篇文章對您有幫助,請點贊支持,或在您的博客中轉發個人文章,謝謝!!!若是文章有錯別字,或者內容有錯誤,或其餘的建議和意見,請您留言指正,很是感謝!!!