日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ vector 初始化_什么?还不懂c++vector的用法,你凭什么勇气来的!

發布時間:2024/9/27 c/c++ 83 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ vector 初始化_什么?还不懂c++vector的用法,你凭什么勇气来的! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:良知猶存

轉載授權以及圍觀:歡迎添加微信公眾號:羽林君

前言

?? ?今天繼續肝C++,一入C++深似海。越學越有意思。今天給大家帶來一篇c++vector的介紹,難以置信這篇文章寫了我三天,不過總算整理完畢,現在分享給大家。

????????模板類vector 和 array是數組的替代品。模板類vector 類似于string類,也是一種動態數組。?在 c++ 中,vector 是一個十分有用的容器。它能夠像容器一樣存放各種類型的對象,簡單地說,vector是一個能夠存放任意類型的動態數組,能夠增加和壓縮數據。

????在C++ primer plus 這本書中關于vectir不是進行一次性介紹的,而是分別在不同板塊使用vctor而去介紹的,今天我就融合起來介紹一些vector的使用。

vector做一個模板類

? ? C++語言既有類模板,也有函數模板,其中vector是一個類模板。只有對C++有一定深入的理解才能寫出模板。

????模板本身不是類或是函數,相反可以將模板看作編譯器生成類或函數編寫的一份說明。編譯器根據模板創建類或函數的過程叫做實例化,當使用模板時,需要指出編譯器應把類或者函數實例化成何種類型。

????對于類模板來說,我們通過提供一些額外的信息,來指定模板到底實例化成什么樣的類,需要提供哪些信息由模板決定。而提供信息的方式如下所示,即在模板名字后面跟一對尖括號,在括號上面放上信息。

以vector為例子:

vector<int>?ivec;?//ivec保存int類型的對象vector?Sales_vec;//保存Sales_item類型的對象vector<vector<string>> file; //一個二維數組,該元素的vector對象

????上面的例子中,編譯器根據模板vector生成了三種不同的類型:vector>,vector>和vector>>。

vector是模板而非類型,由vector生成的類型必須包含vector中的元素類型,例如vector>,int就是vector元素的類型。

vector能容納大部分類型的對象作為參數,但是因為引用不是對象,所以不存在包含引用的vector。

vector> int;?//是錯誤的

定義和初始化vector類型

vector v1; //v1是一個空vector,它潛在的元素是T類型的,執行默認初始化vector v2(v1); //v2中包含有v1所有元素的副本vector?v2?=?v1;//等價于v2(v1),v2中包含有v1所有元素的副本vector v3(n,val);//v3包含了n個重復的元素,每個元素的初始值都是valvector v4(n); //v4包含了n個重復執行了值初始化的對象vector v5{a,b,c...};//v5包含了初始值個數的元素,每個元素被賦予相應的初始值vector v5={a,b,c...};//等價于 v5{a,b,c...};

????看到第一個初始化例子,初始化了一個空vector,看上去空vector好像沒什么用處。但是別忘了,vector是一個數組,在程序運行中,我們是可以很高效的往vector對象中添加元素。事實上,vector最常用方式就是先定義一個空vector,然后當運行時獲取到元素,再逐一添加。????

????當然也可以在定義vector對象時指定元素的初始值。例如,允許一個vector對象的元素拷貝給另一個vector對象。此時,新vector對象的元素就是原vector對象對應的副本。注意兩個vector對象的類型必須相同。

vector?ivec;?//初始狀態為空vector?ivec2(ivec);?//把ivec的值拷貝給ivec2vector?ivec3?=?ivec;?//把ivec的元素拷貝給ivec3vector svec(ivec2);?//錯誤:svec的元素時string對象,不是int

列表初始化vector對象

????列表初始化即使用花括號括起來的0個或多個初始元素值被賦給vector對象:

vector<string>?article???=?{"a","an","the"};vector<string>?article1?=?("a","an","the");//錯誤?不能放置于圓括號內

創建指定數量的元素:

????還可以用vector對象容納的元素數量和所有元素的統一初始值來初始化vector對象:

vector<int>?ivec(10,-1);?//10個int類型的元素,每個都被初始化為-1vector<string> svec(10,"hi!");//10個sting類型的元素,每個都被初始化為"hi!"

vector迭代器功能

????要訪問順序容器和關聯容器中的元素,需要通過“迭代器(iterator)”進行。迭代器是一個變量,相當于容器和操縱容器的算法之間的中介。迭代器可以指向容器中的某個元素,通過迭代器就可以讀寫它指向的元素。從這一點上看,迭代器和指針類似。

????不過和指針不一樣的是,獲取迭代器不是使用取地址符,有迭代器的類型同時返回迭代器的成員。比如,這些類型都擁有名為begin和end的成員,其中begin負責返回指向第一個元素的迭代器,

auto b = v.begin(), c = v.end(); //b表示v的第一個元素 c表示v尾元素的下一個位置

end成員則負責返回指向容器"尾元素的下一個位置"的迭代器。這樣的迭代器

?指示的是容器的一個不存在的"尾后"元素。

*iter //返回迭代器iter所指元素的應用iter->mem //解應用iter并獲取該元素名為mem的成員,等價于(*iter).mem++iter //令iter指向容器中的下一個元素--iter //令iter指向容器的上一個元素

舉例子:依次輸出text的每一行直至遇到第一個空白行為止

for(auto it = text.cbegin(); it != text.cend()&& !it->empty();++it) count << *it <<endl

:cbegin()和cend()是C++11新增的,它們返回一個const的迭代器,不能用于修改元素。

vector當作容器

? ? 一個容器就是一些特定類型對象的集合。順序容器類型有vector(可變大小數組,支持快速隨機訪問,在尾部之外的位置插入或刪除元素可能很慢)、deque(雙端隊列,支持快速隨機訪問,在頭尾插入/刪除元素很快)、list(雙向列表,只支持雙向順序訪問,在list中任何位置進行插入/刪除操作速度都很快)、forward_list(單向列表,只支持單向順序訪問,在列表中任何位置進行插入/刪除操作速度都很快)、array(固定大小數組,支持快速隨機訪問,不能添加或刪除元素)、string(與vector類似的容器,但專門用于保存字符,隨機訪問快,在尾部插入/刪除速度快)。

向vector對象中添加元素

????對vector對象來說,直接初始化的方式適用于三種情況:初始值已知且數量較少、初始值是另一個vector對象的副本、所有元素的初始值都一樣。然后更常見的情況是:創建一個vector對象時并不清楚實際所許需要的元素個數,元素的值也無法確定。還有些時候即使元素的初值已知,但如果這些值的總量較大且各不相同,那么在創建vector對象的時候執行初始化操作也會顯得過于繁瑣。

????舉個例子:如果想創建一個vector對象令其包含從0到9共10個元素,使用列表初始化的方法很容易做到這一點;但如果vector對象所包含的元素是從0到99或者0到999呢?這時候通過列表初始化把所有元素都一一羅列出來就不太合適了。對于此例來說,更好的處理方法是先創建一個空的vector,然后在運行時再利用vector的成員函數push_back向其中添加元素。push_back負責把一個值當成vector對象的尾元素"壓到(push)"vector對象的"尾端(back)",例如:

string word;vector<string>?text;//空vector對象while(cin>>word)//cin>>word??是對word?進行賦值{????text.push_back(word);//把word添加到text后面?}

????在這上面有進一步優化的空間就是使用emplace_back(順序容器(如vector、deque、list)新標準引入了三個新成員:emplace_front、emplace和emplace_back,這些操作構造而不是拷貝元素。這些操作分別對應push_front、insert和push_back,允許我們將元素放置在容器頭部、一個指定位置之前或容器尾部。)

????在容器尾部添加一個元素,這個元素原地構造,不需要觸發拷貝構造和轉移構造。而且調用形式更加簡潔,直接根據參數初始化臨時對象的成員。

????當調用push或insert成員函數時,我們將元素類型的對象傳遞給它們,這些對象被拷貝到容器中。而當我們調用一個emplace成員函數時,則是將參數傳遞給元素類型的構造函數。emplace成員使用這些參數在容器管理的內存空間中直接構造元素。

??? emplace_back在引入右值引用,轉移構造函數,轉移復制運算符之前,通常使用push_back()向容器中加入一個右值元素(臨時對象)的時候,首先會調用構造函數構造這個臨時對象,然后需要調用拷貝構造函數將這個臨時對象放入容器中。原來的臨時變量釋放。這樣造成的問題是臨時變量申請的資源就浪費。

所以現在我們可以用emplace_back替換push_back使用,上面例子就可以這么表示:

text.emplace_back(word);//把word添加到text后面

其他的vector操作

v.empty() //v.size()v[n] //返回v中第n個位置上的元素引用

不能用下標形式添加元素

v[idex] = a; //錯誤

此外還有好多vector屬于容器的操作,大家可以參考容器使用的函數,都是一樣的:具體使用另一位朋友寫的很詳細,我就不多做贅述了,大家可以去看看《vector容器!》

v.capacity();//容器的容量v.size();//返回容器中的元素個數v.resize(int num);//重新指定容器的長度為num,若容器變長,則以默認值填充新位置;如果容器變短,則末尾超出容器長度的元素被刪除v.resize(int num, eles);v.insert(const_iterator?pos,ele);//迭代器指向位置pos插入元素elsv.erase(const_iterator pos);//刪除迭代器指向的元素v.erase(const_iterator start,const_iteartor end);//刪除迭代器從start到end之間的元素v.clear();//刪除容器中所有元素?

vector當作參數

????在C++里很多時候我們會遇到函數想返回兩個以上結果的情況,這時候可以用數組(vector)、類來作為容器返回,也可以聲明一個全局變量的數組,將數值存放在數組里解決。

使用引用來解決,將vector的引用在函數間傳遞

這是一個例子,假設我要傳入一個數,我的函數的功能是返回這個數后面十個數的序列。

#include#includeusing?namespace?std;/*輸入一個數,返回這個數后面的十個數字序列注意參數的這個 & 符號不能省略*/ void getSequence(int num,vector<int>& sequence){ for(int i=0;i<10;i++){ sequence.push_back(i+num); }}int main(){ int num=9; vector<int> sequence; //在主調函數這邊,直接傳入該vector變量 getSequence(num,sequence); //訪問該vector的值的時候,也是直接訪問即可 for(vector<int>::iterator it=sequence.begin();it!=sequence.end();it++){ cout<endl; }}

使用vector注意事項:

1、如果你要表示的向量長度較長(需要為向量內部保存很多數),容易導致內存泄漏,而且效率會很低;

2、Vector 作為函數的參數或者返回值時,需要注意它的寫法:

double Distance(vector<int>&a,vector<int>&b)

?其中的“&”絕對不能少!!

文件處理和vector應用

????主要是嘗試在文件中記錄和讀取信息,中間用到了vector,C++導出excel表格的過程太過繁瑣,所以這里直接用很簡單的方法導出一個.csv的文本文件,該文件也可用excel打開。

#include#include#include // 文件流#include#include using namespace std; int main(){ //寫文件 ofstream outFile; outFile.open("data.csv", ios::out); outFile << "name" << ',' << "age"<< ',' << "hobby" << endl; outFile << "Mike" << ',' << 18 << ','<< "paiting" << endl; outFile << "Tom" << ',' << 25 << ','<< "football" << endl;???outFile.close(); //寫文件 ifstream inFile("data.csv", ios::in); string lineStr; vector< vector<string> > strArray; //vector 類型文string while(getline(inFile, lineStr)) // 從 inFile 中讀取一行,放到 lineStr 中 { cout<< lineStr<<endl; stringstream ss(lineStr); //讀取內容放置在 ss流 中, 括號相當于初始化 string str; vector<string> lineArray; // 按照逗號分隔 while(getline(ss, str, ',')) // ss 中, 按照 “,” 逗號分割將ss 分割成一個個str { lineArray.push_back(str); // 將字符串放置到 line Array cout<< str<<endl; } strArray.push_back(lineArray); } getchar(); return 0;}

? ?outFile.open("data.csv", ios::out);前面的雙引號內容為csv文件路徑,若沒有輸入文件路徑,則在編譯器默認路徑下生成一個csv文件。‘

這就是我分享的vector的一些介紹和使用,如果大家有什么更好的思路,也歡迎分享交流哈。

END—

推薦閱讀

【1】嵌入式的我們為什么要學ROS【2】嵌入式底層開發的軟件框架簡述?【3】CPU中的程序是怎么運行起來的?必讀【4】C++的匿名函數(lambda表達式)【5】階段性文章總結分析

本公眾號全部原創干貨已整理成一個目錄,回復[ 資源 ]即可獲得。

更多分享,掃碼關注我

此外CSDN的C++特訓營課程正式開始啦,掃碼提前占位?

總結

以上是生活随笔為你收集整理的c++ vector 初始化_什么?还不懂c++vector的用法,你凭什么勇气来的!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。