C Primer 第三章 字串 向量和陣列

2022-02-10 05:18:35 字數 4368 閱讀 1134

string和vector是兩種最重要的標準庫型別。內建陣列是一種更基礎的資料型別,string和vector是對陣列的某種抽象。

命名空間的using宣告

使用using宣告可以更方便的使用命名空間中的成員。using namespace::name;,新增該語句後可以直接飲用name,而不用再新增namespace。注意命名空間中的每個成員都要使用using語句宣告才能直接引用。

標頭檔案中不應包括using宣告,因為標頭檔案會被引用到其他檔案中去,這可能造成始料未及的名稱衝突。

注意使用using宣告語句後將在當前命名空間中增加引用的成員名稱。

標準庫型別string

string表示可變長的字串行,使用string型別必須包含string標頭檔案,並且string定義在std命名空間中,因此使用string應包含以下兩條語句:#include using std::string;

如何初始化類是由類本身決定的,初始化string的一些常用方式s1="str1";

如果使用賦值語句「=」初始化,實際上執行的是拷貝初始化,建議使用直接初始化的方式如:string s("a string");。

字串字面值和字元字面值不是string型別,但是他們可以轉換成string型別,因此當執行加法操作時如果有乙個運算元為string型別則另乙個字面值將轉換成string型別,但是兩個字面值不能執行加法操作。string型別可以執行比較操作,字串相同,個數相等時是否相等比較返回true,如果字元不相等則根據字典順序比較。

string的size函式返回的型別為string::size_type,為無符號型別的值,在參與算數運算時要格外注意,因為有符號數會自動轉換為無符號數。

使用範圍for語句遍歷字串中的每個字元,

for

(auto c : str)

使用範圍for語句改變字串中的字元,需要把變數宣告為引用型別,如for(auto &c:str)

下標運算子()接受的引數型別為string::size_type型別,下標運算返回的是該位置上字元的引用。只要字串不是常量,就能為下標運算子返回的字元賦新值。

使用下標訪問字元時一定要注意下標的合法性,下標一定大於等於0而小於字串的size()值,也就是說用下標范文乙個空字串時一定會產生不可預知的結果。

標準庫型別vector

vector表示物件的集合,所有物件的型別都相同,要想使用vector,必須include相關的標頭檔案,並可以使用using語句宣告:using std::vector; vector是乙個類模板,編譯器根據模板建立類或函式的過程稱為例項化,在模板名字後面跟尖括號,尖括號中提供具體資訊。vector的型別不能是引用型別。列表初始化方法:vectorv,包含了初始值個數的元素。

通過push_back函式想vector物件新增元素,元素會新增到末尾。vector物件能高效增長,因此即使在知道元素個數時也建立乙個空vector然後在像其中新增元素。如果指定元素個數後再像其中新增元素可能效率會更低,除非需要新增的元素完全一樣。特別注意,範圍for語句中不能包含改變序列大小的**。

vector的size函式返回元素的個數,返回的型別為vector::size_type,注意vector::size_type的寫法是錯誤的。

vector可以通過下標運算子獲取指定的元素,下標的型別為size_type型別。只要vector物件不是乙個常亮,就能想下標運算子返回的元素賦值。不能用下標操作新增元素,只能對已經存在的元素執行下標操作。

迭代器介紹

所有標準庫容器都可以使用迭代器,string型別可以使用迭代器,迭代器提供了對元素的間接訪問,迭代器能從乙個元素移動到另乙個元素。迭代器分為有效和無效兩種狀態。有效的迭代器或者指向乙個元素,或者指向尾元素的下乙個位置。有迭代器的型別同時擁有返回迭代器的成員,begin返回指向第乙個元素的迭代器,end返回指向最後乙個元素下乙個位置的迭代器,稱為尾後迭代器,只是乙個標識,沒有實際意義。*iter返回迭代器所指元素的引用,iter->member返回迭代器所指元素的成員,++iter,指向下乙個元素,--iter,指向上乙個元素。

通過判斷begin返回的迭代器和end返回的迭代器是否相等確定容器是否為空,通過判斷迭代器是否為end返回的迭代器確定是否已遍歷完容器。

如果是常量容器,begin和end返回常量迭代器const_iterator,否則返回iterator型別。常量迭代器只能執行唯讀操作。可以通過呼叫cbegin和cend返回常量迭代器而不管容器是否為常量。

注意,通過解引用來訪問元素的成員的方式(*it).member,括號是必須的。為了簡化上述操作,c++定義了箭頭運算子->,箭頭運算子把解引用和成員訪問結合到一起,it->member與(*it).member等價。

注意,不能在範圍for迴圈中想vector新增元素,同樣任何改變容器容量的操作都會使迭代器失效。

陣列陣列與vector類似,是用來存放相同型別物件的容器,但陣列的大小固定。陣列是一種復合型別,宣告形式如a[d],a是陣列的名字,d是維度,編譯時陣列的維度必須是已知的,所以維度必須是常量表示式。預設情況下,陣列的元素被預設初始化。但是如果在函式內部定義內建型別的陣列,那麼預設初始化會另陣列含有未定義值。宣告陣列不允許使用auto關鍵字,並且陣列的元素必須為物件,不能是引用型別。可以通過賦值等號並使用列表初始化陣列,初始化時可以不指定維度而由編譯器根據初始化列表的元素個數推斷。如:int arr=;

字元陣列可以使用字串字面值進行初始化,但是會自動在最後乙個元素新增空字元'\0',如char a[4]="c++";,a陣列的緯數為4。

陣列不允許拷貝和賦值,即不允許使用乙個陣列賦值另乙個陣列,也不能使用乙個陣列初始化另乙個陣列。

要想很好的理解陣列宣告的含義,最好的方法是從陣列的名字開始由內向外的閱讀。

陣列中的元素可以通過範圍for語句或下標來訪問,陣列的索引從0開始,陣列下標通常定義為size_t型別,陣列下標的值需要由程式設計師來檢查控制。

陣列名稱是指標,編譯器一般會把陣列名稱轉換成指標,int *p=&arr[0]與int *p=arr等價。當使用陣列作為auto宣告的變數的初始值時,變數會被推斷為陣列累心,但注意使用decltype運算子時還是會得到陣列型別。

c++標準庫中定義了begin和end函式,引數為陣列,函式分別返回陣列首元素指標和尾元素下一位置的指標,與迭代器類似。特別注意end返回的指標不能解引用並且不能執行遞增操作。

如果指標指向了陣列,則該指標可以執行迭代器所能執行的大多數操作,給指標加上乙個整數,得到的指標仍指向陣列中的乙個元素,或者指向尾元素的下乙個位置,但注意不能超過元素的個數,即最多只能從首元素開始加元素個數的整數值,得到尾元素的下一位置。

陣列的下標運算可以支援負數,這和標準庫型別string,vector不同。

字串字面值是一種c風格字串,缺省會在字串的末尾新增空字元,當使用字串字面值初始化標準庫string型別時不包含最後的空字元。當操作c風格字串時,需要使用c標準庫函式的c++版本cstring.h,提供了strlen,strcmp,strcat,strcpy等函式用來操作c風格字串。在c++中盡量避免使用c風格字串。

混用string物件和c風格字串,允許使用c風格字串初始化string或給string賦值,string的加法運算中允許其中乙個為c風格字串,即字元陣列,字元陣列會自動轉換成string物件,相反string物件不能自動轉換為c風格字串,不過string提供方法c_str(),該函式返回c風格字串,即返回字元陣列,但無法保證返回的陣列一直有效,如果改變string物件本身,則返回的陣列也會改變。

可以使用陣列初始化vector物件,初始化時需要指明元素的開始指標和結束指標,如vector vec(begin(arr),end(arr)),這會用陣列arr中的所有元素初始化vector,也可以使用陣列的部分元素初始化vector。

現代c++程式應盡量使用標準庫型別如vector,迭代器,string,而盡量避免使用內建陣列和指標。

多維陣列

c++中的多維陣列實際上是陣列的陣列。多維陣列的定義arr[3][4],其含義是定義乙個有3個元素的陣列,每個元素是包含有4個元素的陣列,通常把二維陣列的第一維稱為行,第二維稱為列。

可以使用花括號來初始化多維陣列,每行可以用巢狀的花括號括起來,也可以不使用巢狀花括號,如

int arr[3][4] =,,};

int arr2[3][4] = ;

以上兩種初始化方式等價。

可以通過範圍for語句遍歷多維陣列,宣告迴圈變數時使用auto修飾符宣告引用型別,這樣可以改變陣列元素的值,但是只有最內層的陣列可以不使用引用型別,這是因為如果不宣告引用型別編譯器會自動把陣列轉換成指標,如**:

for (auto &row : arr)

}for (auto &row : arr)

}

以上兩種方法都是合法的,只是如果迴圈變數不是引用型別則不能改變陣列元素的值。

通過使用auto和decltype關鍵字可以省去晦澀難懂的復合型別宣告。也可以通過型別別名簡化多維陣列的指標宣告。

c Primer第三章 字串,向量,陣列

標頭檔案中不包含using宣告,可能會導致衝突 string s1 s2 string s1 n,c string s1 value 1.s寫入輸出流os中,返回os os 2.is讀取字串到s,以空白字串分割,返回is is s 3.從is中讀取一行賦給s,返回is,包括空格,以回車結束 getl...

第三章 字串 向量和陣列

標頭檔案不應包含using宣告。c 標準一方面對庫型別所提供的操作做了詳細規定,另一方面也對庫的實現者做出了一些效能上的需求。因此,標準庫型別對於一般應用場合來說有足夠的效率。如果使用等號 初始化乙個變數,實際上執行的是拷貝初始化 copy initialization 編譯器把等號右側的初始值拷貝...

第三章 字串 向量和陣列

1 以命名空間std為例,兩種宣告方式 1 using std cin 或cout,endl等 2 using namespace std 2 標頭檔案中不應包含using宣告。1 初始化的方式分為拷貝初始化 使用等號 與直接初始化 不使用等號 1 使用getline讀取一整行 直接讀只會讀乙個單詞...