【C++】string類的深入介紹(1)
作者:愛寫代碼的剛子
時間:2023.5.26
本篇博客主要深入介紹string類、string類的常用接口及操作,string中迭代器的使用,以及string中的部分方法。(由于篇幅有限,剩余方法以及string的深淺拷貝將在之后的博客介紹)
前言:C語言中,字符串是以’\0’結(jié)尾的一些字符的集合,為了操作方便,C標(biāo)準(zhǔn)庫中提供了一些str系列的庫函數(shù),但是這些庫函數(shù)與字符串是分離開的,不太符合OOP的思想,而且底層空間需要用戶自己管理,稍不留神可能還會越界訪問。
C++參考網(wǎng)站:
C++參考
C++官網(wǎng)
如果方便地查找網(wǎng)頁中的關(guān)鍵字可以使用ctrl + f進行搜索
以C++參考網(wǎng)站為例,演示查找string類:
標(biāo)準(zhǔn)庫中的string類
string類(了解即可)
- 字符串是表示字符序列的類
- 標(biāo)準(zhǔn)的字符串類提供了對此類對象的支持,其接口類似于標(biāo)準(zhǔn)字符容器的接口,但添加了專門用于操作
單字節(jié)字符字符串的設(shè)計特性。 - string類是使用char(即作為它的字符類型,使用它的默認char_traits和分配器類型(關(guān)于模板的更多信
息,請參閱basic_string)。 - string類是basic_string模板類的一個實例,它使用char來實例化basic_string模板類,并用char_traits
和allocator作為basic_string的默認參數(shù)(根于更多的模板信息請參考basic_string)。 - 注意,這個類獨立于所使用的編碼來處理字節(jié):如果用來處理多字節(jié)或變長字符(如UTF-8)的序列,這個類的所有成員(如長度或大小)以及它的迭代器,將仍然按照字節(jié)(而不是實際編碼的字符)來操作。
總結(jié):
- string是表示字符串的字符串類
- 該類的接口與常規(guī)容器的接口基本相同,再添加了一些專門用來操作string的常規(guī)操作。
- string在底層實際是:basic_string模板類的別名,typedef basic_string<char, char_traits, allocator> string;
- 不能操作多字節(jié)或者變長字符的序列。
- 在使用string類時,必須包含#include頭文件以及using namespace std;
string類的常用接口說明(最常用的)
學(xué)會查文檔對C++的學(xué)習(xí)是非常重要的?。ㄒ韵率褂脜⒖季W(wǎng)站為例):
這里只列舉的部分,大家學(xué)習(xí)的時候一定要學(xué)會查文檔!
- string類對象的常見構(gòu)造
(constructor)函數(shù)名稱 | 功能說明 |
---|---|
string()(重點) | 構(gòu)造空的string類對象,即空字符串 |
string(const char* s)(重點) | 用C-string來構(gòu)造string類對象 |
string(size_t n,char c) | string類對象中包含n個字符c |
string(const string&s)(重點) | 拷貝構(gòu)造函數(shù) |
- string類對象的容量操作
函數(shù)名稱 | 功能說明 |
---|---|
size(重點) | 返回字符串有效字符長度 |
length | 返回字符串有效字符長度 |
capacity | 返回空間總大小 |
empty(重點) | 檢測字符串釋放為空串,是返回true,否則返回false |
clear(重點) | 清空有效字符 |
reserve(重點) | 為字符串預(yù)留空間 |
resize(重點) | 將有效字符的個數(shù)改成n個,多出的空間用字符c填充 |
注意:
- size()與length()方法底層實現(xiàn)原理完全相同,引入size()的原因是為了與其他容器的接口保持一
致,一般情況下基本都是用size()。- clear()只是將string中有效字符清空,不改變底層空間大小。
- resize(size_t n) 與 resize(size_t n, char c)都是將字符串中有效字符個數(shù)改變到n個,不同的是當(dāng)字符個數(shù)增多時:resize(n)用0來填充多出的元素空間,resize(size_t n, char c)用字符c來填充多出的元素空間。注意:resize在改變元素個數(shù)時,如果是將元素個數(shù)增多,可能會改變底層容量的大小,如果是將元素個數(shù)減少,底層空間總大小不變。
- reserve(size_t res_arg=0):為string預(yù)留空間,不改變有效元素個數(shù),當(dāng)reserve的參數(shù)小于
string的底層空間總大小時,reserver不會改變?nèi)萘看笮 ?/mark>
- string類對象的訪問及遍歷操作
函數(shù)名稱 | 功能說明 |
---|---|
operator(重點) | 返回pos位置的字符,const string類對象調(diào)用 |
begin + end | begin獲取一個字符的迭代器 + end獲取最后一個字符下一個位置的迭代器 |
rbegin + rend | rbegin返回一個逆向迭代器,指向字符串的最后一個字符+rend返回一個逆向迭代器,指向字符串的開頭(第一個字符的前一個位置)。 |
范圍for | C++11支持更簡潔的范圍for的新遍歷方式 |
- string類對象的修改操作
函數(shù)名稱 | 功能說明 |
---|---|
push_back | 在字符串后尾插字符c |
append | 在字符串后追加一個字符串 |
operator+=(重點) | 在字符串后追加字符串str |
c_str(重點) | 返回C格式字符串 |
find + npos(重點) | 從字符串pos位置開始往后找字符c,返回該字符在字符串中的位置 |
rfind | 從字符串pos位置開始往前找字符c,返回該字符在字符串中的位置 |
substr | 在str中從pos位置開始,截取n個字符,然后將其返回 |
注意:
- 在string尾部追加字符時,s.push_back? / s.append(1, c) / s += 'c’三種的實現(xiàn)方式差不多,一般情況下string類的+=操作用的比較多,+=操作不僅可以連接單個字符,還可以連接字符串。
- 對string操作時,如果能夠大概預(yù)估到放多少字符,可以先通過reserve把空間預(yù)留好。
- string類非成員函數(shù)
函數(shù) | 功能說明 |
---|---|
operator+ | 盡量少用,因為傳值返回,導(dǎo)致深拷貝效率低 |
operator>>(重點) | 輸入運算符重載 |
operator<<(重點) | 輸出運算符重載 |
getline(重點) | 獲取一行字符串 |
relational operators(重點) | 大小比較 |
-
需要注意的一個小點:
在對string類使用<<的運算符重載進行比較時,我們一定要注意==<<的優(yōu)先級較高(相較于普通的運算符)==,所有我們進行比較時要帶上括號! -
正確使用:
-
- npos靜態(tài)變量的介紹:
npos不是-1,而是整形的最大值(因為npos是無符號整型)
- 其他一些重要的修飾符和字符串操作:
append(追加字符串)以及push_back(尾插一個字符)等一些函數(shù)已經(jīng)實現(xiàn)了自動擴容(C++的好處,本質(zhì)是字符管理的順序表),但是建議使用 += ,因為 += 重載了這兩種方法(例:string str;str += ('0' + val);
(直接將整型val轉(zhuǎn)成字符串))
(注意有些情況+=不能替代append)
下面是append具體信息:
具體用法查文檔即可
詳細介紹string::operator[]
示例:
上述代碼中str和a雖然都是字符串,但是str的實現(xiàn)邏輯是調(diào)用string::operator,而a的實現(xiàn)邏輯是*(a+1);(在clion編譯器中編譯器跳過了第9行的a[1];語句,沒有執(zhí)行(編譯器的優(yōu)化))
迭代器
string中的迭代器(任何容器都支持,用法都是類似的)
示例:
- iterator是像指針一樣的類型,有可能是指針,有可能不是指針(封裝的指針)。(其實iterator的底層是用指針來實現(xiàn)的)
-
范圍for(底層替換為迭代器,可以查看反匯編代碼,一個類支持迭代器就支持范圍for)
以上代碼中若要進行對str2的修改可以使用引用:
-
鏈表中使用迭代器
iterator提供了一種統(tǒng)一的方式,訪問和修改容器的數(shù)據(jù)。算法通過迭代器去處理容器中的數(shù)據(jù) -
迭代器可以和容器進行配合
以reverse函數(shù)舉例:
由于reverse提供了list模版,所以可以對鏈表實現(xiàn)逆置。
當(dāng)然,也可以使用范圍for來替代迭代器:
string中的反向迭代器
而范圍for不能反向遍歷
begin()、end()以及rbegin()、rend()具體指向的位置
如下圖所示
const迭代器
注意auto在自動識別類型時并不帶上常量屬性!
- 如果我們想要使迭代器帶上常量屬性需要加上const_
此時使用迭代器時不能改變存儲在容器中的數(shù)據(jù)。
附:其他迭代器補充:
可以去作者提供的C++參考網(wǎng)站上去查詢函數(shù)的具體用法(建議多查找網(wǎng)站)
string中的Capacity
- string類中有兩種表示字符串長度的方法(size()和length()),這里只推薦使用size(),因為有些STL不支持length()(比如map)
max_size
max_size在不同的編譯器上的結(jié)果不同。(所以使用時需謹(jǐn)慎,因為STL只是規(guī)范,它有許多不同的版本(大同小異),導(dǎo)致結(jié)果不同)
演示:
clion下:
- Linux下:
capacity
同max_size,在不同的編譯器下的結(jié)果并不相同!
clion下:
Linux下:
同時不同的編譯器的擴容機制也不相同:
演示:
clion下:
Linux下:
clear(清理空間但并不釋放空間)
clion下:
Linux下:
所以clear()并不會釋放空間
reserve(提前給string開空間)
clion下:
clion即使清理了數(shù)據(jù),也不會進行縮容
Linux下:
如果清理了數(shù)據(jù)使用reserve就會進行縮容,縮為0
如果沒有清理數(shù)據(jù)也進行縮容,縮小到size大小
不同的編譯器reserve的效果不同,同時還與clear函數(shù)有關(guān),clion下沒實現(xiàn)縮容,而Linux的g++編譯器下會實現(xiàn)縮容(使用clear清理數(shù)據(jù)后會縮到0,如果沒有清理數(shù)據(jù)則會縮小到size大?。?。文章來源:http://www.zghlxwxcb.cn/news/detail-481464.html
resize 不單單擴容,而是開空間加初始化(不給初始化值默認/0)
resize如果給的值比原來string的size小,并不會縮容,capacity不會改變,空間沒銷毀,但是字符串的長度改變了 因為縮容是有代價的,所以resize不會改變空間,以免之后還要開空間文章來源地址http://www.zghlxwxcb.cn/news/detail-481464.html
- 如果想要實現(xiàn)縮容可以用shrink_to_fit函數(shù)(具體用法查網(wǎng)站即可),但不建議縮容。
到了這里,關(guān)于【C++】string類的深入介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!