前言
在茶陵等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),成都全網(wǎng)營銷推廣,外貿(mào)網(wǎng)站制作,茶陵網(wǎng)站建設(shè)費(fèi)用合理。本章內(nèi)容相比第二章要簡單不少,里面比較重要的內(nèi)容主要是vector和迭代器,這里只是很簡單的介紹了一下,在后續(xù)的章節(jié)會(huì)有更詳細(xì)、復(fù)雜的說明。以下記錄的都是比較重要或者易混淆的知識(shí)點(diǎn),對(duì)于像string、vector只列舉了部分方法的例子。
文章目錄一、string
- 一、string
- 1.1string初始化和常見操作
- 1.2string對(duì)象字符處理API
- 二、標(biāo)準(zhǔn)庫類型vector
- 2.1vector常見操作
- 三、初識(shí)迭代器
- 3.1使用迭代器
- 3.2迭代器運(yùn)算
- 四、數(shù)組
- 4.1初始化
- 4.2訪問數(shù)組元素
- 4.3指針和數(shù)組
?string
是C++的一個(gè)標(biāo)準(zhǔn)庫類型,表示可變長的字符序列。string 定義在命名空間std中
。
初始化
? 下表是string
的初始化方式。值得注意的是當(dāng)我們使用=
號(hào)實(shí)際上執(zhí)行的是拷貝初始化,反之就是直接初始化。
string對(duì)象操作
? 下表是幾種string的操作方式。
? 對(duì)于讀寫string對(duì)象,在使用cin
讀取一個(gè)對(duì)象時(shí)會(huì)自動(dòng)忽略開頭的空白(空格、換行符、制表符等),直到遇到下一個(gè)空白為止。如下,當(dāng)我們輸入一段字符串" hhhh yyyy "
,程序自動(dòng)忽略開頭的幾個(gè)空格并在遇到下一個(gè)空格后停止讀入,所以最后的結(jié)果為hhhh
。在遇到字符串類型的算法題時(shí),使用cin可以減輕處理字符串的工作。
string s1;
cin >>s1; // 輸入" hhhh yyyy ";
cout<< s1; // 輸出 "hhhh"
? 如果我們想要保留輸入的一整段字符串,可以使用getline
來讀取一整行數(shù)據(jù)。如下,getline
需要兩個(gè)參數(shù),一個(gè)是輸入流,另一個(gè)是string
對(duì)象,在讀取的過程中,會(huì)把整段數(shù)據(jù)包括換行符都讀在緩沖區(qū)中,但是存儲(chǔ)的時(shí)候會(huì)舍棄掉換行符,所以最后的結(jié)果并沒有包含換行符,這也是為什么在輸出時(shí)要加上endl
,endl可以結(jié)束當(dāng)前行并刷新顯示緩沖區(qū)。
getline(cin,s1); //輸入" hhhh yyyy ";
cout<< s1<< endl; // 輸出" hhhh yyyy ";
?size()
會(huì)返回當(dāng)前字符串的一個(gè)大小,大部分和我一樣的初學(xué)者都會(huì)想當(dāng)然的以為返回的類型是一個(gè)int
,但其實(shí)類型是string::size_type
。size_type
是一個(gè)無符號(hào)類型的值,能夠存放任何string
對(duì)象的大小。【代碼風(fēng)格:在循環(huán)訪問一個(gè)字符串對(duì)象時(shí),標(biāo)識(shí)符的類型盡量定義成size_type
,這樣該標(biāo)識(shí)不可能為負(fù)數(shù)從而減少越界等錯(cuò)誤】。在上一章中學(xué)過auto和decltype
,我們在接收一個(gè)字符串對(duì)象的長度時(shí)可以用它們來定義變量。
auto len = s1.size(); // len 的類型是size_type
? 兩個(gè)字符串比較首先看長度是否相等,如果長度不一樣,不一定就是較長的字符串大,因?yàn)?code>string對(duì)象比較遵循第一相異字符比較結(jié)果,也就是說如果第一個(gè)不同字符,較長字符串改字符的字典序小于較短字符串,那么最后的結(jié)果就是較長字符串小于較短字符串。如下。
string str = "Hello";
string str2 = "Hiya"; // str2 >str
? 標(biāo)準(zhǔn)庫允許把字面值或字符字面值轉(zhuǎn)換為string
對(duì)象,前提是‘+’兩邊至少包含一個(gè)string對(duì)象。
string str = "123";
string str2 = str + "," + "456"; // 123456
string str3 = "123" + "456"; // 錯(cuò)誤,+兩邊不存在string對(duì)象
1.2string對(duì)象字符處理API? 要處理一個(gè)字符那么首先要判斷它的類型,在標(biāo)準(zhǔn)款中提供了一個(gè)cctype
函數(shù),這是C++
兼容C語言
的一個(gè)頭文件,如下有一些判斷字符類型的函數(shù)。
? 一般來說,我們都是從一個(gè)字符串中循環(huán)提取一個(gè)字符進(jìn)行處理,C++
提供了一個(gè)很方便的循環(huán)語句,范圍for語句
,包括在后面迭代器等章節(jié)都會(huì)經(jīng)常使用,定義如下。
for(auto x : str); // 循環(huán)取出原串的一個(gè)字符,不改變原串
for(auto &x : str); // 通過引用的方式可以改變原串
? 如果我們只需要處理一個(gè)字符串中的某個(gè)字符,可以使用下標(biāo)運(yùn)算符[index]
,里面接收的參數(shù)類型是size_type
,保證大于等于0。我們也可以直接通過[index]
改變相應(yīng)位置上的值。
混用C風(fēng)格字符串
?C語言定義字符串是通過char *
的方式,但是我們不能把一個(gè)string
對(duì)象拿來初始化C語言
風(fēng)格的字符串。需要使用c_str
轉(zhuǎn)換,它返回的是一個(gè)指針,指向一個(gè)以空字符串結(jié)束的字符數(shù)組,這個(gè)數(shù)組存儲(chǔ)的內(nèi)容就是我們定義的string
對(duì)象,返回的類型為const char *
來保證不會(huì)改變字符數(shù)組的內(nèi)容。
string str("asdasd");
char *str2 = str; // 錯(cuò)誤
const char*str2 = str.c_str()
二、標(biāo)準(zhǔn)庫類型vector?vector
表示對(duì)象的集合,里面的對(duì)象類型都是一致,每個(gè)對(duì)象對(duì)應(yīng)一個(gè)索引,用于訪問該對(duì)象。vector
是一個(gè)類模板,在后續(xù)的章節(jié)有專門一章來講解模板,感覺比較難懂。除了類模板,還有一個(gè)就是函數(shù)模板,模板本身不是類或函數(shù),編譯器根據(jù)模板生成類型和函數(shù)的過程稱為實(shí)例化,
初始化
? 定義和初始化的方法不同的API都差異不大。注意幾點(diǎn),當(dāng)使用拷貝初始化=
時(shí),只能提供一個(gè)初始值;如果這個(gè)初始值是類內(nèi)初始值(一個(gè)class
定義的值),只能使用拷貝初始化或使用花括號(hào)的形式初始化;使用列表初始化是用{}
。
? 在定義一個(gè)vector
時(shí)我們可能會(huì)給出一個(gè)大小n
,此時(shí)程序會(huì)進(jìn)行值初始化,如果 當(dāng)前vector
的類型是int
,那就會(huì)初始化n
個(gè)0。
? 總的來說,()
可以說是根據(jù)提供的值來構(gòu)造對(duì)象,{}
是根據(jù)提供的值來初始化對(duì)象,只有在無法初始化時(shí)才考慮其它方式。注意下面的表達(dá)式vector v4{10}。
vectorv1(10); // 構(gòu)造10個(gè)大小的整形容器
vectorv2{10}; // 容器含有一個(gè)元素10
vectorv3("hi"); //錯(cuò)誤,不能使用字面值構(gòu)建vector對(duì)象
vectorv4{10}; // 字面值10并不是string對(duì)象,所以不能拿來初始化,而是直接構(gòu)造含有10個(gè)空串的容器
添加元素
?push_back
可以往一個(gè)容器的尾部添加一個(gè)元素。vector
和C語言
中大的區(qū)別就是定義的時(shí)候可以不指定容量,vector
可以根據(jù)當(dāng)前存儲(chǔ)的元素動(dòng)態(tài)的改變?nèi)萜鞯拇笮?,是否要在定義時(shí)指定容量大小會(huì)在后續(xù)的章節(jié)中談到,vector
提供了一些方法允許我們提升動(dòng)態(tài)添加元素的性能。
vectorvec;
vec.push_back(1);
cout<< vec[0]; // 1 可以通過索引訪問值
vec[1] = 3; // 錯(cuò)誤,不能通過索引的添加值
? 其它的操作如下表所示,都是比較簡單的函數(shù),這里就不一一舉例了。記住v.size()返回的類型還是size_type。【代碼風(fēng)格:如果總是忘記定義size_type去接收容器的大小,可以使用上一章學(xué)的auto/decltype自動(dòng)獲取】。
三、初識(shí)迭代器? 前面我們知道可以通過下標(biāo)運(yùn)算符來訪問string
對(duì)象或者vector
對(duì)象的元素,使用迭代器也能達(dá)到此目的。除了vector
外,其它的一些容器也提供了迭代器,但是部分缺不支持下標(biāo)運(yùn)算符,string
對(duì)象雖然不是容器,但是也能使用迭代器。
?begin和end
是常用的兩個(gè)迭代器成員,begin
指向容器的第一個(gè)元素,end
指向容器尾部后一位,這個(gè)位置不存在元素,有點(diǎn)類似鏈表最后的null
,僅僅作為一個(gè)標(biāo)志。對(duì)于一個(gè)空的容器,它的begin和end都返回同一個(gè)迭代器。
? 下面是常用的迭代器的運(yùn)算符。*iter
返回的一個(gè)元素的引用,如果要訪問該元素下對(duì)應(yīng)的成員還得使用iter->mem(或者(*iter).mem,()不能少)
進(jìn)行解引用。移動(dòng)當(dāng)前迭代器使用++或--
。
迭代器類型
? 迭代器也有不同的類型,定義一個(gè)迭代器vector
,通過it
可以去讀寫vector
的元素;常量迭代器vector
則只能進(jìn)行讀操作。如何確定迭代器的類型依據(jù)對(duì)象的類型,如果對(duì)象是一個(gè)常量,那么只能使用常量迭代器,反之都可以。同理,我們在上面使用beging和end
返回的迭代器類型也是根據(jù)對(duì)象的類型。如果對(duì)于一個(gè)非常量容器,我們想得到一個(gè)常量迭代器,可以使用C++11
引入的新特性cbegin和cend
,直接返回一個(gè)常量迭代器。
? 解引用迭代器可以獲得迭代器所指的對(duì)象,如果對(duì)象的類型是一個(gè)類,我們可以通過iter->mem或者(*iter).mem
訪問類的成員函數(shù)。上面說過使用(*iter).mem
方式時(shí)()不能少,如下說明。
vectorvec{"hhhhh"};
vector::iterator it = vec.begin();
(*it).empty(); // false
*it.empty(); // it是一個(gè)迭代器,沒有empty成員,所以錯(cuò)誤
使用->
相當(dāng)于把解引用和訪問成員融合在一起,更加的方便。
? 前面提到,vector
會(huì)動(dòng)態(tài)的增長容器的大小,所以我們在使用迭代器遍歷容器元素時(shí)不能向容器中添加元素,否則當(dāng)前的迭代器會(huì)失效??傊?dāng)你定義了一個(gè)迭代器,任何將會(huì)改變原容器的操作都會(huì)使當(dāng)前的迭代器失效。
? 除了++和--
讓迭代器移動(dòng)一步,我們還可以使用下表的方法進(jìn)行多步移動(dòng)。注意一下當(dāng)兩個(gè)迭代器相減時(shí),返回的是這兩個(gè)迭代器的距離,返回的類型是difference_type
(帶符號(hào)整形數(shù))。很明顯這個(gè)距離可正可負(fù)。
? 數(shù)組也是一個(gè)能存放不同對(duì)象的容器,與vector
不同,數(shù)組的大小一旦確定就不能改變,不能隨意向數(shù)組中增加元素,在某些情況使用數(shù)組可以增加程序的運(yùn)行性能,但是靈活性也大大的降低。
? 數(shù)組是一種符合類型,聲明一個(gè)數(shù)組如a[d]
,其中a
是數(shù)組的名字,d
是數(shù)組的維度,維度是數(shù)組元素的個(gè)數(shù),它必須要是一個(gè)常量表達(dá)式。
unsigned cnt = 12; //非常量表達(dá)式
int arr[cnt]; // 錯(cuò)誤
constexpr unsigned cnt1 = 12;
int arr[cnt2]; // 定義一個(gè)含有12個(gè)元素的整形數(shù)組
和內(nèi)置類型的變量一樣,在函數(shù)外部定義了一個(gè)數(shù)組將會(huì)根據(jù)類型進(jìn)行默認(rèn)初始化,在內(nèi)部則會(huì)是未定義。在定義數(shù)組的時(shí)候必須要指定數(shù)組的類型,不能使用auto去根據(jù)初始值列表推斷類型。
不允許拷貝和賦值
? 我們不能用一個(gè)數(shù)組去初始化另外一個(gè)數(shù)組,雖然一些編譯器可能支持這個(gè)操作,但是為了程序的兼容盡量根據(jù)標(biāo)準(zhǔn)來書寫代碼。但是我們卻可以使用數(shù)組來初始化一個(gè)vector
。(begin(arr), end(arr)在4.3中有講解)
int arr[] = {1,2,3,4,5,6,67};
vectorvec(begin(arr), end(arr)); // 含有arr的全部元素
vectorvec2(arr + 2, arr + 4); // {3,4}
? 數(shù)組本身是一個(gè)對(duì)象,所以允許定義數(shù)組的指針及數(shù)組的引用,但是不存在引用的數(shù)組。有點(diǎn)繞,直接看書上的例子容易理解一點(diǎn)。
int arr[10];
int *prr[10]; // prr是含有10個(gè)指針的數(shù)組
int &rrr[10] = ??; // 錯(cuò)誤,不存在引用的數(shù)組
int (*Prr)[10] = &arr; // Prr指向一個(gè)含有10個(gè)整數(shù)的數(shù)組的指針
int (&Rrr)[10] = arr; // Rrr是對(duì)數(shù)組arr的引用
4.2訪問數(shù)組元素? 與vector、string
相同,數(shù)組的元素可以使用范圍for
循環(huán)或者下標(biāo)運(yùn)算符來訪問。在使用下標(biāo)運(yùn)算符時(shí),返回的類型是size_t
,與size_type
相同也是一個(gè)無符號(hào)類型。
? 一般來說,我們對(duì)數(shù)組名直接取地址編譯器會(huì)自動(dòng)的將其替換成數(shù)組首元素的地址。所以我們使用auto
自動(dòng)根據(jù)數(shù)組名判斷時(shí),得到的是一個(gè)指針,但是使用decltype
會(huì)返回?cái)?shù)組的類型,如下。
int arr[10];
int *p = &arr; // 等于 int *p = &arr[0];
auto arr2(arr); // arr2是一個(gè)指針
decltype(arr) arr3; // arr3是一個(gè)含有10個(gè)元素的整形數(shù)組
? 數(shù)組雖然沒有迭代器,但是數(shù)組的指針也可以看成迭代器,迭代器能完成的操作使用指針也能完成。迭代器可以通過begin和end
獲得容器的開頭和尾后元素,雖然數(shù)組不是類類型,沒有成員函數(shù),但是我們也可以將數(shù)組作為參數(shù)傳入進(jìn)去實(shí)現(xiàn)同樣的效果。
int arr[] = {1,2,3,4,5,56,6};
int *beg = begin(arr); // 指向arr第一個(gè)元素的指針
int *last = end(arr); // 指向arr尾后元素的指針
? 指針的運(yùn)算與上面迭代器的運(yùn)算基本一致,兩個(gè)指針相減返回的類型為ptrdiff_t
。
下標(biāo)和指針
? 使用指針的同時(shí)也能使用下標(biāo)訪問當(dāng)前指針操作后指向的元素(當(dāng)然指向合理的范圍)。從p2[-1]
可以看出指針和標(biāo)準(zhǔn)庫類型vector
等使用下標(biāo)運(yùn)算符的區(qū)別,內(nèi)置類型的下標(biāo)運(yùn)算符可以是一個(gè)有符號(hào)數(shù)。
int arr[] = {1,2,3,4,5,56,6};
int i = arr[2]; // 3
int *p = &arr; // p指向第一個(gè)元素1
cout<< p[2]; // 輸出3,相當(dāng)于p+2
int *p2 = &i;
cout<< p2[-1]; // 輸出2
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
標(biāo)題名稱:《c++primer》第三章字符串、vector、數(shù)組-創(chuàng)新互聯(lián)
鏈接地址:http://jinyejixie.com/article38/dhopsp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、云服務(wù)器、搜索引擎優(yōu)化、網(wǎng)站收錄、面包屑導(dǎo)航、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容