最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ STL中容器string超詳細(xì)講解

 更新時(shí)間:2025年10月21日 09:38:29   作者:田野追逐星光  
STL是C++標(biāo)準(zhǔn)庫(kù)的重要組成部分,不僅是一個(gè)可復(fù)用的 組件庫(kù),而且是一個(gè)包羅數(shù)據(jù)結(jié)構(gòu)與算法的軟件框架,本文給大家介紹C++ STL中容器string超詳細(xì)講解,感興趣的朋友跟隨小編一起看看吧

前言:在學(xué)習(xí)string之前,我們得先了解STL容器,什么是STL容器呢?

STL(standard template libaray-標(biāo)準(zhǔn)模板庫(kù)):是C++標(biāo)準(zhǔn)庫(kù)的重要組成部分,不僅是一個(gè)可復(fù)用的 組件庫(kù),而且是一個(gè)包羅數(shù)據(jù)結(jié)構(gòu)與算法的軟件框架。

下圖是STL的六大組件,后面會(huì)一一的了解容器,算法,仿函數(shù),迭代器等等

那么C++的STL庫(kù)的作用是什么?這就不得不說(shuō)沒(méi)學(xué)C++之前都是使用的C語(yǔ)言刷題,寫(xiě)一道題需要大量的代碼,而C++提供STL庫(kù),我們可以使用里面的算法,它都幫我實(shí)現(xiàn)好了,比如兩個(gè)隊(duì)列模擬實(shí)現(xiàn)棧,C語(yǔ)言需要手動(dòng)創(chuàng)建隊(duì)列的結(jié)構(gòu),而利用STL直接套用就行。

好了話不多說(shuō),我們直接開(kāi)始學(xué)習(xí)第一個(gè)容器string!??!

1. 標(biāo)準(zhǔn)庫(kù)中的string

1.1 auto和范圍for

auto:

在早期C/C++中auto的含義是:使用auto修飾的變量,是具有自動(dòng)存儲(chǔ)器的局部變量,后來(lái)這個(gè)不重要了。C++11中,標(biāo)準(zhǔn)委員會(huì)變廢為寶賦予了auto全新的含義即:auto不再是一個(gè)存儲(chǔ)類(lèi)型指示符,而是作為一個(gè)新的類(lèi)型指示符來(lái)指示編譯器,auto聲明的變量必須由編譯器在編譯時(shí)期推導(dǎo)而得。

什么意思呢?就跟類(lèi)模板推導(dǎo)參數(shù)類(lèi)型類(lèi)似。

#include<iostream>
#include<string>
using namespace std;
int func1()
{
	return 10;
}
auto func2()
{
	return 100;
}
void func3(auto x) //error: 不允許使用auto做參數(shù)
{
}
int main()
{
	auto a = 10; //這里的auto=int
	auto* ra = &a; //auto=int
	auto rra = &a; //auto=int*
    auto b=3.14; //auto=char
    auto& rb=b;
    int ma = 10, mb = 30, mc = 90;
	auto md = 100, me = 200;
	auto ch = 'a', z = 10;//error,auto只對(duì)ch推導(dǎo)
	return 0;
}

1. auto聲明指針類(lèi)型時(shí):用auto和auto*沒(méi)有區(qū)別;但是在聲明引用類(lèi)型時(shí),必須加&(即auto&);

2. 當(dāng)在同一行聲明多個(gè)變量時(shí),這些變量必須是相同的類(lèi)型,否則編譯器將會(huì)報(bào)錯(cuò),因?yàn)榫幾g器實(shí)際只對(duì)第一個(gè)類(lèi)型進(jìn)行推導(dǎo),然后用推導(dǎo)出來(lái)的類(lèi)型定義其他變量;

3. auto不能作為函數(shù)的參數(shù),可以做返回值,但是建議謹(jǐn)慎使用;

4. auto不能直接用來(lái)聲明數(shù)組。

這里可能覺(jué)得使用auto沒(méi)什么用,但是到了后面的容器就會(huì)覺(jué)得太安逸了。

范圍for:

for循環(huán)后的括號(hào)由冒號(hào)“ :”分為兩部分:第一部分是范圍 內(nèi)用于迭代的變量,第二部分則表示被迭代的范圍,自動(dòng)迭代(自動(dòng)++),自動(dòng)取數(shù)據(jù),自動(dòng)判斷結(jié)束。(即arr數(shù)組中取得值賦值給ch,ch自動(dòng)++,自動(dòng)判斷結(jié)束)

相對(duì)于for循環(huán),三個(gè)自動(dòng)勝過(guò)一切。常用于數(shù)組和對(duì)象的遍歷。那范圍for是如何實(shí)現(xiàn)的?這就得去理解它的底層迭代器,至于什么是迭代器,模擬實(shí)現(xiàn)得時(shí)候會(huì)初步講解,現(xiàn)在只需要理解如何使用!

void test01()
{
	int arr[10] = { 1,2,3,4,5 };
	for (auto& e : arr)
	{
		cout << e << " ";
	}
	cout << endl;
	char s[] = { "hello,world" };
	for (auto& ch : s)
	{
		cout << ch;
	}
	cout << endl;
	string str("hello world");
	for (auto ch : str)
	{
		cout << ch << " ";
	}
	cout << endl;
}
int main()
{
	test01();
	return 0;
}

這里建議使用引用,這里是普通數(shù)組還好,如果是對(duì)象呢?那每次取值得時(shí)候就得調(diào)用拷貝構(gòu)造!

2. string常用接口說(shuō)明

2.1 string類(lèi)的常見(jiàn)構(gòu)造

https://legacy.cplusplus.com/reference/string/string/?kw=string(官網(wǎng)關(guān)于string的介紹)

這里來(lái)說(shuō)一些構(gòu)造非常常用的接口:

函數(shù)名功能說(shuō)明
string()默認(rèn)構(gòu)造,構(gòu)造空字符串
string(const char* s)用字符串構(gòu)造string類(lèi)型字符串(string不含\0)
string(size_t n, char c)構(gòu)造由n個(gè)字符c構(gòu)成的字符串
string(const string&s) 拷貝構(gòu)造,用string對(duì)象構(gòu)造另一個(gè)string對(duì)象
~string()析構(gòu)函數(shù):淺拷貝(自動(dòng)生成的足夠)/深拷貝(需要手動(dòng)實(shí)現(xiàn))
void test02()
{
	string s1;
	cout << s1 << endl;
	string s2("A ship in harbor is safe, but that's not what ships are built for");
	cout << s2 << endl;
	string s3("hello world");
	cout << s3 << endl;
	string s4(10, 'x');
	cout << s4 << endl;
	string s5(s2);
	cout << s5 << endl;
}

2.2 string類(lèi)的插入

(1)尾插:末尾插入數(shù)據(jù)

void push_back(char);
void test03()
{
	string s1("hello world");
	s1.push_back(' ');
	s1.push_back('x');
	s1.push_back('i');
	s1.push_back('a');
	s1.push_back('o');
	s1.push_back('l');
	s1.push_back('i');
	cout << s1 << endl;
	s1.pop_back();
	cout << s1 << endl;
}

(2)使用insert在指定位置插入數(shù)據(jù)

string& insert (size_t pos, size_t n, char c); //在pos位置插入n個(gè)字符c
string& insert (size_t pos, const char* s); //在pos位置插入字符串
string& insert (size_t pos, const string& str); //在pos位置插入string
void test05()
{
	string s1("hello,xiaoli");
	//頭插
	s1.insert(0, 3, 'x');
	s1.insert(0, "excuse");
	//中間插入
	string s2("hi");
	s2.insert(1,3,'z');
	s2.insert(2, "hello");
	//尾插
	string s3("today");
	s3.insert(4, s2);
}

2.3 string類(lèi)的刪除

(1)尾刪:尾部刪除數(shù)據(jù)

void pop_back();
void test06()
{
	string s1("hello,xiaoli");
	s1.pop_back();
	s1.pop_back();
	s1.pop_back();
	cout << s1 << endl;
}

(2)erase:任意位置的刪除

string& erase (size_t pos = 0, size_t len = npos);
iterator erase (iterator first, iterator last); //迭代器版本的刪除指定范圍數(shù)據(jù)
void test07()
{
	string s1("hello,xiaoli");
	s1.erase(0, 2);
	s1.erase(5, 3);
	string s2("hello,tomorror");
	string::iterator it = s2.begin();//迭代器
	s2.erase(it + 3, it + 5);
}

2.4 string類(lèi)的拼接

(1)append:在字符末尾拼接字符/字符串

string& append (const string& str);
string& append (const char* s);
string& append (size_t n, char c);
void test08()
{
	string s1("hello,xiaoli");
	s1.append(3, 'x');
	string s2("hello,tomorror");
	s2.append(" today");
    s2.append(s1);
}

2.5 string類(lèi)的替換

(1)assign:為字符串分配一個(gè)新值,替換其當(dāng)前內(nèi)容。

string& assign (size_t n, char c); 
string& assign (const char* s);
string& assign (const string& str);
void test09()
{
	string s1("hello,xiaoli");
	s1.assign("excuse me");
	cout << s1 << endl;
	string s2("hello,tomorror");
	s2.assign(s1);
	cout << s2 << endl;
}

(2)replace:將字符串中以字符pos開(kāi)頭并跨len字符的部分(或字符串中介于[i1,i2) 之間的部分替換為新內(nèi)容

string& replace (size_t pos,  size_t len,  const string& str);
string& replace (size_t pos,  size_t len,  const char* s);
string& replace (size_t pos,  size_t len,  size_t n, char c);

這里每一個(gè)都有對(duì)應(yīng)的迭代器版本!

//replace
void test10()
{
	string s1("hello,xiaoli");
	s1.replace(2, 3, 5,'x');//從下標(biāo)為2的位置開(kāi)始長(zhǎng)度為3個(gè)字符替換成5個(gè)x
	cout << s1 << endl; ////hexxxxx,xiaoli
	string s2("hello,tomorror");
	s2.replace(3, 5, "excuse"); //helexcusemorror
	cout << s2 << endl;
}

可能有點(diǎn)懵,就是我只是保證從pos開(kāi)始跨len個(gè)字符的部分內(nèi)容修改,其余內(nèi)容不變。這len個(gè)字符替換成給的內(nèi)容。就比如s1,我只保證llo內(nèi)容改變,llo替換成xxxxx,其余不動(dòng)。

2.6 string類(lèi)的查找

(1)find:查找字符串中的內(nèi)容(如果指定pos,就從pos位置開(kāi)始查找,僅匹配其中一個(gè)字符是不夠的,而是整個(gè)序列必須匹配;如果匹配返回匹配的第一個(gè)位置的下標(biāo),否則返回npos)

size_t find (char c, size_t pos = 0) const;
size_t find (const char* s, size_t pos = 0) const;
size_t find (const string& str, size_t pos = 0) const;
//find
void test11()
{
	string s1("hello,xiaoli");
	cout<<s1.find("llo")<<endl; //從下標(biāo)為0開(kāi)始找,返回2
	cout << s1.find("he",6)<< endl; //從下標(biāo)為6開(kāi)始找,返回18446744073709551615
	string s2("hello,tomorror");
	cout << s2.find(s1, 3) << endl; //返回18446744073709551615
}

(2)rfind:從后往前開(kāi)始匹配

size_t rfind (char c, size_t pos = 0) const;
size_t rfind (const char* s, size_t pos = 0) const;
size_t rfind (const string& str, size_t pos = 0) const;
//rfind
void test12()
{
	string s1("hello,xiaoli");
	cout << s1.rfind("llo") << endl; //從下標(biāo)為0開(kāi)始往前找
	cout << s1.rfind("he", 6) << endl; //從下標(biāo)為6開(kāi)始往前找
	string s2("hello,tomorror");
	cout << s2.rfind(s1, 3) << endl;
	string s3("hello,today,hello tomorror");
	cout<<s3.rfind("hello")<<endl; //12,匹配第二個(gè)hello
	cout<<s3.find("hello")<<endl; //0,匹配第一個(gè)hello
}

注意:rfind是從尾往前(即從右往左)開(kāi)始找,但是子字符串時(shí)從左往右開(kāi)始匹配。

2.7 string類(lèi)的容量

(1)size:字符串的有效字符的長(zhǎng)度

size_t size() const;
void test13()
{
	string s1("hello,xiaoli");
	cout << s1.size() << endl; //12
	string s2("hello,tomorror");
	cout << s2.size() << endl; //14
}

(2)capacity:字符串的總空間大小

size_t capacity() const;
void test14()
{
	string s1("A ship in harbor is safe, but that's not what ships are built for");
	cout << s1.capacity() << endl; //79
	string s2("hello,tomorror");
	cout << s2.capacity() << endl; //15
}

(3)length:字符串的有效字符的長(zhǎng)度

size_t length() const;
void test13()
{
	string s1("hello,xiaoli");
	cout << s1.length() << endl; //12
	string s2("hello,tomorror");
	cout << s2.length() << endl; //14
}

(4)reserve:開(kāi)辟指定大小的空間,當(dāng)n<size()時(shí),reserver不會(huì)改變?nèi)萘看笮 ?/p>

void reserve (size_t n = 0);
void test15()
{
	string s1("A ship in harbor is safe, but that's not what ships are built for");
	s1.reserve(120);
	cout << s1.capacity() << endl;
	string s2("hello,tomorror");
	cout << s2.capacity() << endl;
	s2.reserve(10);
	cout << s2.capacity() << endl;
}

注意:這里reserve(120),編譯器會(huì)多開(kāi)幾個(gè)空間,因?yàn)榫幾g器的擴(kuò)容是按1.5倍增長(zhǎng)。

(5)empty:檢查字符串是否是空串

bool empty() const;

(6)clear:清空有效字符

(7)resize:將有效字符的個(gè)數(shù)變成n個(gè),多出的空間用字符c填充。

void resize (size_t n);
void resize (size_t n, char c);

void test16()
{
	string s1("xiaoli");
	cout << s1.size() << endl;//6
	cout << s1.capacity() << endl;//15
	//s1.resize(20);
	//cout << s1.size() << endl; //20
	//s1.resize(12);
	//cout << s1.size() << endl; //12
	s1.resize(3);
	cout << s1.size() << endl; //3
    cout << s1.capacity() << endl; //15
}

2.8 string類(lèi)的遍歷和訪問(wèn)

(1)operator[ ]:訪問(wèn)指定下標(biāo)的元素(string類(lèi)里面已經(jīng)實(shí)現(xiàn)operator[ ]的重載)

char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
void test17()
{
	string s1("xiaoli");
	cout << s1[2] << endl;
}

at同operator[ ],就不再敘述了。

(2)front和back:取首元素和最后一個(gè)元素,一樣的操作。

(3)begin:返回第一個(gè)字符迭代器(通俗一點(diǎn):返回第一個(gè)字符的指針)

         end:返回最后一個(gè)字符迭代器(通俗一點(diǎn):返回最后一個(gè)字符的指針)

(4)rbegin:返回最后一個(gè)字符迭代器(通俗一點(diǎn):返回第一個(gè)字符的指針)

         rend:返回第一個(gè)字符迭代器(通俗一點(diǎn):返回最后一個(gè)字符的指針)

注意:(3)和(4)與迭代器有著非常緊密的關(guān)系,會(huì)常常使用

這里一般用于數(shù)組或者對(duì)象的遍歷。如下:有三種遍歷方式

void test18()
{
	string s1("hello xiaoli");
	//遍歷方式
	// 下標(biāo) + []
	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;
	// 迭代器
	string::iterator it = s1.begin(); //在模擬實(shí)現(xiàn)的時(shí)候具體講解
	while (it != s1.end())
	{
		(*it)++;
		cout << *it << " ";
		it++;
	}
	cout << endl;
	// 范圍for
	for (auto ch : s1)
	{
		ch--;
		cout << ch << " ";
	}
	cout << endl;
}

2.9 string類(lèi)的交換

(1)swap:交換兩個(gè)string的內(nèi)容

void swap (string& str);
void test19()
{
	string s1("hello xiaoli");
	string s2("A ship in harbor is safe, but that's not what ships are built for");
	swap(s1, s2);
	cout << s1 << endl;
	cout << s2 << endl;
}

2.10 string類(lèi)的運(yùn)算符

(1)operator=:賦值運(yùn)算符,在string中實(shí)現(xiàn)了函數(shù)重載(相當(dāng)于修改字符串內(nèi)容),其實(shí)功能和assign是類(lèi)似的。

string& operator= (char c);
string& operator= (const char* s);
string& operator= (const string& str);
void test20()
{
	string s1("I Love you!");
	s1 = "hello,world";
	cout << s1 << endl;
    s1 = 'x';
	cout << s1 << endl;
}

(2)operator+=:在string中實(shí)現(xiàn)了函數(shù)重載(相當(dāng)于在末端追加字符串內(nèi)容),相當(dāng)于push_back的升級(jí)版,多了尾插字符串和string功能。

string& operator+= (char c);
string& operator+= (const char* s);
string& operator+= (const string& str);
void test21()
{
	string s1("I Love you!");
	s1 += "hello,world";
	cout << s1 << endl;
	s1 += ' x';
	cout << s1 << endl;
}

(3)上面兩個(gè)都是成員函數(shù),這里余下的大小關(guān)系的比較是不屬于成員函數(shù)的,因?yàn)槌蓡T函數(shù)的第一個(gè)參數(shù)是隱藏的this指針,而比較可能是字符和字符比較,也可以是字符串和字符串比較。

并且字符和字符串比較都是先比較第一個(gè)字符,比較的是字符的ascll碼值

void test21()
{
	string s1("I Love you!");
	string s2("I love Code");

	cout << (s1 < s2) << endl;//注意優(yōu)先級(jí)關(guān)系
	cout << (s1 == s2) << endl;//注意優(yōu)先級(jí)關(guān)系
}

(4)operator>> 和 operator<< :輸入流和輸出流,也是非成員函數(shù),理由和上面一樣,第一個(gè)不一定是this指針。

2.11 string類(lèi)中g(shù)etline函數(shù)

在 C++ 中,使用 >> 運(yùn)算符進(jìn)行輸入提取時(shí),默認(rèn)情況下確實(shí)會(huì)以空白字符(包括空格、制表符、換行符等)作為分隔符,并在遇到空白字符時(shí)停止當(dāng)前的提取操作.

而使用getline,則分為兩種情況,一種是遇到'\0'停止;另一種是遇到自己定義的終止符停止提取。

istream& getline (istream& is, string& str);(遇到'\0'停止)
istream& getline (istream& is, string& str, char delim);(遇到delim停止)
void test22()
{
	string str;
	cin >> str;  // 輸入 "Hello World"
	cout << str; // 輸出 "Hello"(只提取到第一個(gè)空格前的內(nèi)容)
}

第一種:讀取一整行,遇到'\0'停止

void test23()
{
	string s;
	getline(cin, s);  // 輸入 "Hello World"
	cout << s;             // 輸出 "Hello World"(讀取整行內(nèi)容)
}

第二種:讀取一整行,遇到delim停止

void test24()
{	
    string s1;
	getline(cin, s1, '#');  // 輸入 "Hello World"
	cout << s1;             // 輸出 "Hello World"(讀取整行內(nèi)容)
}

2.11 string類(lèi)中的substr函數(shù)

string substr (size_t pos = 0, size_t len = npos) const;

substr:生成子字符串,返回一個(gè)新構(gòu)造的對(duì)象,其值初始化為該對(duì)象的子字符串的副本。也就是選取該字符串的一部分構(gòu)造一個(gè)新對(duì)象。

void test25()
{
	string s1("A ship in harbor is safe, but that's not what ships are built for");
	cout << s1.substr(3, 15) << endl;
	string s2 = s1.substr(5, 10);
	cout << s2 << endl;
}

那么到這里,string一些常見(jiàn)的接口就了解的差不多了,下一期來(lái)模擬實(shí)現(xiàn)string。

到此這篇關(guān)于C++ STL中容器string超詳細(xì)講解的文章就介紹到這了,更多相關(guān)stl容器string內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

沁源县| 泽州县| 新龙县| 湘乡市| 宣武区| 台北市| 留坝县| 合水县| 万安县| 宝丰县| 温州市| 揭东县| 星座| 通河县| 信丰县| 城步| 香格里拉县| 阿荣旗| 沈阳市| 芜湖市| 余江县| 蒙阴县| 广宁县| 璧山县| 尤溪县| 赞皇县| 增城市| 武威市| 西昌市| 卫辉市| 山阳县| 兴业县| 镇沅| 昂仁县| 漾濞| 微山县| 桂阳县| 牙克石市| 黔南| 阜平县| 连城县|