C++ Primer 筆記-第3章 字符串、向量和數(shù)組

3.1 命名空間的?using
?聲明
位于頭文件的代碼,一般不應(yīng)該使用?
using
?聲明。

3.2 標(biāo)準(zhǔn)庫(kù)類(lèi)型?string
3.2.1 定義和初始化?string
?對(duì)象
拷貝初始化?copy initialization
直接初始化?direct initialization
3.2.2?string
?對(duì)象上的操作
string
?的?size()
?返回的是一個(gè)?string::size_type
?類(lèi)型的值,如果表達(dá)式中已經(jīng)有了?size()
?函數(shù)據(jù)就不要再使用?int
?了,這樣可以避免混用?int
?和?unsigned
?可能帶來(lái)的問(wèn)題。當(dāng)把?
string
?對(duì)象和字符字面值及字符串字面值混在一條語(yǔ)句中使用時(shí),必須確保每個(gè)加法運(yùn)算符(+)的兩側(cè)運(yùn)算對(duì)象至少有一個(gè)是?string
:

string s1 = "hello" + "."; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 錯(cuò)誤
string s2 = "world"; string s3 = "hello" + "," + s2; ? ? // 錯(cuò)誤

為了兼容 C,C++ 中的字符串字面值并不是標(biāo)準(zhǔn)庫(kù)類(lèi)型?
string
?的對(duì)象。
3.2.3 處理?string
?對(duì)象中的字符
C++ 標(biāo)準(zhǔn)庫(kù)兼容了 C 語(yǔ)言的標(biāo)準(zhǔn)庫(kù)。C 語(yǔ)言的頭文件形式是?name.h, C++ 則將這些文件命名為?cname。
在名為?cname?的頭文件中定義的名字從屬于命名空間?
std
,而定義在名為 .h 的頭文件中的則不然。

3.3 標(biāo)準(zhǔn)庫(kù)類(lèi)型?vector
可以將模板看作為編譯器生成類(lèi)或函數(shù)編寫(xiě)的一份說(shuō)明。
編譯器根據(jù)模板創(chuàng)建類(lèi)或函數(shù)的過(guò)程叫做?實(shí)例化 instantiation。
因?yàn)橐貌皇菍?duì)象,所以不存在包含引用的?
vector
。
3.3.1 定義和初始化?vector
?對(duì)象
列表初始化?
vector
?過(guò)程會(huì)盡可能地把花括號(hào)內(nèi)的值當(dāng)成是元素初始值的列表來(lái)處理,只有當(dāng)無(wú)法執(zhí)行列表初始化時(shí)才會(huì)考慮其他初始化方式。確定無(wú)法執(zhí)行列表初始化后,編譯器會(huì)嘗試用默認(rèn)值初始化?vector
?對(duì)象。

vector<int> ? ? v1{10}; ? ? ? ? ?// v1有一個(gè)元素,該元素為10
vector<string> ?v2{10}; ? ? ? ? ?// v2有10個(gè)默認(rèn)初始化的元素
vector<int> ? ? v3{10, 1}; ? ? ? // v3有2個(gè)元素,值分別是10和1
vector<string> ?v4{10, "hi"}; ? ?// v4有10個(gè)值為 "hi" 的元素

3.3.2 向?vector
?對(duì)象中添加元素
在定義?
vector
?對(duì)象的時(shí)候先設(shè)定其大小,可能性能還會(huì)降低。除非所有的元素的值都是一樣時(shí)效率才會(huì)高。
3.3.3 其他?vector
?操作
要使用?
size_type
,需首先指定它是由哪種類(lèi)型定義的。

vector<int>::size_type ?// 正確
vector::size_type ? ? ? // 錯(cuò)誤


3.4 迭代器介紹
3.4.1 使用迭代器
尾后迭代器?off-the-end iterator
但凡使用范圍?
for
?循環(huán)或者迭代器的循環(huán)體,都不要向容器中添加元素。(因?yàn)槿萜鞅惶砑釉睾笃鋬?nèi)存地址可能會(huì)變)。
3.4.2 迭代器運(yùn)算
指向同一個(gè)容器的兩個(gè)迭代器相減得到迭代器之間的距離,類(lèi)型為?
difference_type
?的帶符號(hào)整型數(shù)。

3.5 數(shù)組
3.5.1 定義和初始化內(nèi)置數(shù)組
數(shù)組的元素應(yīng)為對(duì)象,因此不存在引用的數(shù)組。
字符串字面值初始化字符數(shù)組時(shí),要注意結(jié)尾處還有一個(gè)空字符。
不能將數(shù)組的內(nèi)容拷貝給其他數(shù)組作為其初始值,也不能用數(shù)組為其他數(shù)組賦值。
想要理解數(shù)組聲明的含義,最好的辦法是從數(shù)組的名字開(kāi)始按照由內(nèi)向外的順序閱讀。

int arr[10]; ? ? ? ? ? ? ? ?// 含有10個(gè)整數(shù)的數(shù)組
int *ptrs[10]; ? ? ? ? ? ? ?// 含有10個(gè)整型指針的數(shù)組
int (*p_array)[10] = &arr; ?// 指向一個(gè)含有10個(gè)整數(shù)的數(shù)組
int (&arr_ref)[10] = arr; ? // 引用一個(gè)含有10個(gè)整數(shù)的數(shù)組
int *(&array)[10] ?= ptrs; ?// array是數(shù)組的引用,該數(shù)組含有10個(gè)整型指針

3.5.2 訪(fǎng)問(wèn)數(shù)組元素
使用數(shù)組下標(biāo)的時(shí)候,通常將其定義為?
size_t
?類(lèi)型。size_t
?類(lèi)型是一種機(jī)器相關(guān)的無(wú)符號(hào)類(lèi)型,它被設(shè)計(jì)得足夠大以便能表示內(nèi)存中任意對(duì)象的大小。
3.5.3 指針和數(shù)組
當(dāng)使用?
decltype
?關(guān)鍵字時(shí),數(shù)組名字轉(zhuǎn)換為指針的操作不會(huì)發(fā)生。數(shù)組不是類(lèi)類(lèi)型。
兩個(gè)指向同一個(gè)數(shù)組的數(shù)組指針相減的結(jié)果類(lèi)型是一種定義在?cstddef?頭文件中的帶符號(hào)的機(jī)器相關(guān)的標(biāo)準(zhǔn)庫(kù)類(lèi)型:
ptrdiff_t
?。標(biāo)準(zhǔn)庫(kù)類(lèi)型限定使用的下標(biāo)必須是無(wú)符號(hào)類(lèi)型,而內(nèi)置的下標(biāo)運(yùn)算無(wú)此要求可以為負(fù)數(shù)(為負(fù)時(shí)相當(dāng)于當(dāng)前位置往后移)。
3.5.4 C 風(fēng)格字符串
對(duì)于大多數(shù)應(yīng)用來(lái)說(shuō),使用標(biāo)準(zhǔn)庫(kù)?
string
?要比使用 C 風(fēng)格字符串更安全、更高效。
3.5.5 與舊代碼的接口

// string轉(zhuǎn)字符數(shù)組
string s;char *str = s; ? ? ? ? ? ? ? ? ? ? ? ? // 錯(cuò)誤
const char *str = s.c_str(); ? ? ? ? ? ? ? ? ? ?// 正確
// 數(shù)組轉(zhuǎn)vector
int int_arr[] = {0, 1, 2, 3, 4, 5};
vector<int> ivec(begin(int_arr), end(int_arr)); // 正確
vector<int> subVec(int_arr + 1, int_arr + 4); ? // 正確


3.6 多維數(shù)組
對(duì)于二維數(shù)組來(lái)說(shuō)常把第一個(gè)維度稱(chēng)為行,第二個(gè)維度稱(chēng)為列。
要使用范圍for語(yǔ)句處理多維數(shù)組,除了最內(nèi)層的循環(huán)外,其他所有循環(huán)的控制變量都應(yīng)該是引用類(lèi)型(不用引用的話(huà),會(huì)被隱式轉(zhuǎn)換為指針)。

