真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

【C++】string類接口的了解和使用-創(chuàng)新互聯(lián)

為什么我們要學(xué)string類呢?那是必須是為了方便??!在C語言中,我們創(chuàng)建一個字符串,有很多操作或者必須要注意的細節(jié)會把控不住,所以C++中出現(xiàn)了string類,讓我們應(yīng)對字符串等oj題也方便快捷了許多!

創(chuàng)新互聯(lián)提供高防服務(wù)器、云服務(wù)器、香港服務(wù)器、達州電信機房


目錄

一、STL的介紹

二、標(biāo)準(zhǔn)庫中的string類

1、簡介string?編輯

2、庫中的string類的常用接口說明?編輯

1.構(gòu)造函數(shù)

?2.npos?

?3.遍歷?

3.capacity

1.size,lenth,max_size,capacity

2.shrink_to_fit

3.reserve、resize(重點)

4.operator[],at

5、Modifiers

1.push_back, append, operator+=

2.insert,erase

???3.assign,replace(不重要)

4.find,c_str,substr

總結(jié)?


一、STL的介紹 STL(standard template libaray- 標(biāo)準(zhǔn)模板庫 ) : 是 C++ 標(biāo)準(zhǔn)庫的重要組成部分 ,不僅是一個可復(fù)用的組件庫,而且 是一個包羅數(shù)據(jù)結(jié)構(gòu)與算法的軟件框架 。 STL 的六大組件 :仿函數(shù)、算法、迭代器、空間配置器、容器、配接器。 這些在我們接下來的學(xué)習(xí)都會深入學(xué)習(xí)! 網(wǎng)上有句話說: “ 不懂 STL ,不要說你會 C++” 。 STL 是 C++ 中的優(yōu)秀作品,有了它的陪伴,許多底層的數(shù)據(jù)結(jié)構(gòu) 以及算法都不需要自己重新造輪子,站在前人的肩膀上,健步如飛的快速開發(fā)。
二、標(biāo)準(zhǔn)庫中的string類 1、簡介string

string是一個模板,是因為編碼不同,導(dǎo)致char的字節(jié)數(shù)不同,所以需要模板來適應(yīng)不同的編碼類型,原型差不多就是這樣的:

我們接下來研究的:utf-8,char為一個字節(jié)的string類

?2、庫中的string類的常用接口說明1.構(gòu)造函數(shù)

在學(xué)習(xí)任何類之前,當(dāng)然要先看它的構(gòu)造函數(shù)了?。ㄎ覀冎涣私庵匾页S玫模?/p>

構(gòu)造函數(shù):直接上例子:

可以看得出,s1為默認的構(gòu)造函數(shù)

s2是帶參的構(gòu)造函數(shù)(理解:會開辟一段空間,將內(nèi)容存起來)

s3的構(gòu)造方式,會發(fā)生隱式類型轉(zhuǎn)換,會產(chǎn)生臨時變量,先構(gòu)造,再拷貝構(gòu)造,優(yōu)化后就是構(gòu)造

s4構(gòu)造是用n個char c 字符去初始化

拷貝構(gòu)造:自定義類型拷貝會發(fā)生深拷貝,所以形參一般要用引用減少拷貝,提高效率

s5,s6都是拷貝構(gòu)造


2.npos

npos是一個靜態(tài)成員變量,無符號整型,是一個極大的數(shù)。

對于這個構(gòu)造函數(shù),是在str的pos位置開始向后len的長度,這段字符串進行初始化。

那默認不傳len,len的值就是npos,是一個非常大的數(shù),當(dāng)len大于str的長度時,默認到了str的最后一位。

3.遍歷?

共有三種遍歷方式:

void test2()
{
	string s1("12345678");
	// 1、下標(biāo) []
	for (size_t i = 0; i< s1.size(); ++i)
	{
		s1[i]++;
	}
	cout<< s1<< endl;


	// 2、范圍for
	for (auto& ch : s1)
	{
		ch--;
	}
	cout<< s1<< endl;


	// 3、迭代器  -- 通用的訪問形式
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		*it1 += 1;
		++it1;    // 把string里的內(nèi)容每一個都加了一
	}

	it1 = s1.begin();
	while (it1 != s1.end())
	{
		cout<< *it1<< " ";   //打印每一個內(nèi)容
		++it1;
	}
	cout<< endl;
}

可以看的出:operator[]有兩個接口,一個是有const,一個沒有const

operator[],是一個可讀且可寫的接口。

當(dāng)const只讀對象調(diào)用時,就會調(diào)用const接口

當(dāng)只寫對象調(diào)用時,就會調(diào)用非const,

所以對于即可寫又可讀的接口函數(shù)來說,就有兩個版本,const和非const

還有一點:operator[]內(nèi)部有防止越界訪問的功能:assert(pos<=size);

迭代器的遍歷方法:

這里的迭代器是string類的自定義的一種類型,需要string::

迭代器我們現(xiàn)在可以看作是 和指針相差不多的東西(行為像指針),但他又不是指針,具體的底層我們后面會見面。

begin()就是指向第一個位置,end()指向最后一個有效字符的下一個位置

迭代器要注意的地方:

我們可以看到:迭代器也分為const和非const,那什么時候分別用哪個呢?

const_iterator:只能在const對象下使用,并且const迭代器可以改變迭代器本身,但不能改變迭代器所指向的內(nèi)容?

迭代器有正向迭代器和反向迭代器:

void Print(const string& s)
{

	// 只讀不寫,可以遍歷改變it,但不能改變他指向內(nèi)容
	string::const_iterator it = s.begin(); //正向迭代器
	while (it != s.end())
	{
		// *it += 1;  錯誤!

		cout<< *it<< " ";
		++it;
      //正向迭代器就是正著迭代++
	}
	}
	cout<< endl;

	//string::const_reverse_iterator rit = s.rbegin();
	auto rit = s.rbegin();       //反向迭代器
	while (rit != s.rend())
	{
		cout<< *rit<< " ";
		++rit;
       //都是++,這里不可以類比指針反向迭代器就是反著迭代++
	}
	cout<< endl;
}

學(xué)會了嗎?


3.capacity

1.size,lenth,max_size,capacity

在string中,我們會怎么描述字符串長度??length是不是更貼合,那為什么又有size呢??

因為string是早于stl的,在它之后size更普遍適用,為了普遍化,那只能添加一個size了

size==length,就是求長度或者字符個數(shù)。(length淘汰!?。?/p>

只讀接口,加const

capacity:string的容量,和size可不相同。

clear:因為stl只是規(guī)范了每個接口名字或者參數(shù),但并沒有將每一個容器函數(shù)的細節(jié)拿捏死,所以對于clear,我們并不知道他清空數(shù)據(jù)以后,是否還要回收空間。得需要驗證!

void test4()
{
	string s("hello world");
	cout<< s.size()<< endl;
	cout<< s.length()<< endl;
	cout<< s.capacity()<< endl;

	s.clear();
	cout<< s<< endl;
	cout<< s.capacity()<< endl;
}

可以發(fā)現(xiàn),clear之后并沒有回收空間,也不會縮容

empty(),就是來判空的


2.shrink_to_fit

當(dāng)capacity大于size時,將size和capacity保持一致,會縮容,但縮容代價還是挺大的,一般也不這么搞。


3.reserve、resize(重點)

只改變capacity

在我們知道需要多少空間時,插入數(shù)據(jù),為了防止反復(fù)擴容(擴容代價大),我們可以提前預(yù)留空間,開辟好。

那到底是怎么擴的呢??一次擴多少?

我們在vs和g++上分別測試得出:vs上面會1.5倍擴容,但是存在內(nèi)存對齊問題,會有些許偏差,但空間還是大于我們要開辟的。g++就是2倍擴容,要多少擴多少,不會有偏差。

第一次預(yù)留500,第一次擴容到766,第二次擴容1149,差不多就是1.5倍

resize:它改變的是?size

當(dāng)n不同,resize會分為三種情況:(n為size改變后的值)

舉例說明:

void test6()
{
    //當(dāng)ncapacity,  (擴容+插入數(shù)據(jù))

	string s3("hello world");
	s3.resize(20, '#');
	cout<< s3.size()<< endl;
	cout<< s3.capacity()<< endl;
	cout<< s3<< endl<< endl;
}

所以resize功能還是比較完善健全的。

?4.operator[],at

他們是一樣的,都是讀寫到string中的某個值,進行操作。

但是區(qū)別在于:當(dāng)發(fā)生越界時,operator[]會直接assert()報警告;而at則會拋異常(后面我們會詳細了解)

5、Modifiers 1.push_back, append, operator+=

插入:

push_back :尾插

下面通過舉例來觀察:?

void test7()
{
 //push_back
	string s1("hello world");
	s1.push_back('x');
	s1.push_back('y');
	cout<< s1<< endl;

 //append
	string s2("1111111111");
	s2.append(s1);
	cout<< s2<< endl;

//operator+=
	string s3("666");
	s3 += ' ';
	s3 += "hello world";
	s3 += s2;
	cout<< s3<< endl;
}

2.insert,erase

適用于頭插,頭刪,中間插入和刪除

但這兩種函數(shù)我們都不建議經(jīng)常使用,因為它的效率很低,在刪除或者插入時,就會有數(shù)據(jù)挪動,效率很低。

void test8()
{
	string s("hello world");
	s.insert(0, "bit");
	cout<< s<< endl;

	s.erase(0, 3);
	cout<< s<< endl;

	s.insert(5, "bit");
	cout<< s<< endl;

	s.erase(5,3);
	cout<< s<< endl;

	s.erase(5);  //第二個參數(shù)不提供,默認是npos,直接從pos刪到最后一個。
	cout<< s<< endl;
}

?3.assign,replace(不重要)

assign(功能):先clear,再賦值?

replace:替換內(nèi)容

void test9()
{
	string s("3456789");
	s.assign("1234");
	cout<< s<< endl;

	string s1("hello world");
	s1.replace(6, 10, "666");
	cout<< s1;
}

4.find,c_str,substr

find:也有缺省值,默認不提供,直接找到最后一個

c_str:取出C形式字符串(底層指針)

substr:取出str的一部分,再將其構(gòu)建成新對象返回

getline:輸入可以中間帶空格的字符串


總結(jié)

這就是我們經(jīng)常要用到的函數(shù)接口,更底層的內(nèi)容,需要我們在模擬實現(xiàn)的時候,去好好感悟,下期再見!

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


分享標(biāo)題:【C++】string類接口的了解和使用-創(chuàng)新互聯(lián)
分享路徑:http://weahome.cn/article/geshj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部