c++字符串辨赐、向量和數(shù)組

1. 標(biāo)志庫(kù)類型string

1.1 string的初始化

string的初始化方式有5種,詳細(xì)見下面程序1京办。在c++標(biāo)準(zhǔn)規(guī)定了對(duì)象初始化分為直接初始化和拷貝初始化掀序,在string對(duì)象中有體現(xiàn),詳見程序2惭婿。那問題來了什么時(shí)候使用直接初始化或者拷貝初始化不恭?如果初始單個(gè)值,無論使用哪種初始化都行财饥,如果初始是多個(gè)值换吧,推薦使用直接初始化,這樣可以減少拷貝成本钥星。

程序1
string s;   //默認(rèn)初始化沾瓦,初始的值為空串
string s2(s1);  //s2是s1的副本
string s3 = s1; // 與s2(s1)等價(jià)
string s4 = "hello"; // s4是字面值“hello”的副本
string s5("hello");  //與s4="hello"等價(jià)
string s6(10,'h'); //把s6初始化為10個(gè)h字符

程序2
拷貝初始化:它是執(zhí)行拷貝完成初始化操作的,因此他最大的特點(diǎn)就是帶有=號(hào);
直接初始化:與拷貝初始化相反贯莺,沒有等號(hào)风喇;
string s7="hello2"; //拷貝初始化
string s8("hello2"); //直接初始化
string s9(s7); //直接初始化
string s10(10,'c'); //直接初始化

1.2 string的操作

1.2.1 string的讀寫

string的寫通常只有一種輸出方式,就是通過cout輸出乖篷,見程序3:

程序3:
string s = "hello";
cout << s << endl;

string的讀有兩種方式响驴,一種是從輸入流讀取當(dāng)個(gè)字符串給string對(duì)象透且,另一種是從輸入流讀出一行給string對(duì)象撕蔼。詳細(xì)區(qū)別見程序4:

程序4:
string s;
cin >> s; // 在讀取的過程中,string對(duì)象會(huì)自動(dòng)忽略開頭的空白(空格符秽誊、換行符鲸沮、制表符等),并從第一個(gè)字符讀起锅论,
//直到遇到下一個(gè)空白為止讼溺。讀取的字符對(duì)象不包含結(jié)尾空白,同時(shí)讀取流的緩沖區(qū)有不包含結(jié)尾的空白
//例如最易,如果程序輸入"  hello  "怒坯,輸入實(shí)際字符串值為:"hello"
getline(cin,s); //在讀取的過程中,它會(huì)最開始輸入字符(包含空白)開始藻懒,直到遇到換行符為止剔猿;讀取的
//字符對(duì)象不包含結(jié)尾的換行符,但是讀取流的緩沖區(qū)有包含結(jié)尾的換行符的嬉荆,這有時(shí)會(huì)影響下一次字符串讀取

1.2.2 string::size_type類型

string::size_type是string的size函數(shù)的返回值归敬,由于string的下標(biāo)是非負(fù)的,因此該類型為無符號(hào)類型的值鄙早。

1.2.3 string對(duì)象的比較

>汪茧、=、<限番、<=舱污、>=是string對(duì)象比較大小的關(guān)系運(yùn)算符,都是按照字典順序比較大小的

1.2.4 string對(duì)象賦值和相加

string對(duì)象允許把一個(gè)對(duì)象的值賦值另外一個(gè)對(duì)象弥虐,并且允許兩個(gè)string對(duì)象相加扩灯,相加string就等價(jià)于兩個(gè)字符串的拼接,同時(shí)也支持字面值和string對(duì)象相加躯舔,但是不允許兩個(gè)字面值相加驴剔。見程序5:

程序5
string s = s1+",";  //正確,字面值會(huì)自動(dòng)轉(zhuǎn)換成string對(duì)象粥庄,再執(zhí)行string加法運(yùn)算
string s2 = "hello"+"kuang"; //錯(cuò)誤丧失,兩個(gè)都是字面值,字面值無法轉(zhuǎn)換惜互,無法執(zhí)行string加法運(yùn)算布讹,報(bào)錯(cuò)

1.3 string中字符處理

string對(duì)象對(duì)字符可以對(duì)整個(gè)string對(duì)象全部字符處理琳拭,通常采用for循環(huán)的方法;也可對(duì)單獨(dú)描验、特殊字符進(jìn)行處理白嘁,通常采用下標(biāo)或者迭代器,采用下標(biāo)運(yùn)算符訪問當(dāng)個(gè)元素膘流,在string對(duì)象下標(biāo)運(yùn)算符[]返回值是字符的引用絮缅。注意:下標(biāo)可以訪問或修改string對(duì)象已有字符,但不能通過下標(biāo)添加字符到string對(duì)象呼股,vector下標(biāo)符號(hào)也是一樣的耕魄。見程序6:

程序6
//訪問string對(duì)象內(nèi)字符
string str("hello kuang");
for(auto c:str)
 {
        cout << c << endl;
 }
//修改string對(duì)象內(nèi)字符
string str("hello kuang");
for(auto &c:str)             //auto &c = char,把變量c變成單個(gè)字符的引用
 {
        c = toupper(c);  //小寫轉(zhuǎn)大寫
 }
//采用下標(biāo)運(yùn)算符訪問當(dāng)個(gè)元素彭谁,在string對(duì)象下標(biāo)運(yùn)算符[]返回值是字符的引用
str[0]='y'; //str的值會(huì)變成"yello kuang"

2. vector

vector表示對(duì)象的集合吸奴,其中包含的對(duì)象類型相同。vector是對(duì)象的集合缠局,而引用不是對(duì)象则奥,在c++內(nèi)置對(duì)象中引用和指針區(qū)別中講過,所以不存在包含引用的vector狭园。

2.1 vector的初始化

vector初始化的方法有7中读处,詳細(xì)見程序7。一般情況下對(duì)vector對(duì)象初始一般用括號(hào)妙啃,如果要對(duì)vector對(duì)象包含值初始化档泽,通常是使用花括號(hào),采用初始化列表的方式進(jìn)行初始化揖赴。有時(shí)這兩種情況會(huì)出現(xiàn)等價(jià)的情況馆匿,當(dāng)vector集合包含的對(duì)象不是int,vector<T> v1(10)vector<T> v1={10}是等價(jià)的燥滑,造成這種情況是由c++首先判斷10能不能用來作為列表初始值
渐北,顯然不能,c++編譯器就會(huì)把它作為初始化對(duì)象個(gè)數(shù)的參數(shù)铭拧,如果還不滿足就報(bào)錯(cuò)赃蛛。當(dāng)vector集合包含的對(duì)象是int,就必須嚴(yán)格按照規(guī)定來初始化搀菩,因?yàn)榇藭r(shí)編譯器無法判斷這個(gè)整形參數(shù)是列表初始值還是元素?cái)?shù)量呕臂。詳細(xì)見程序8:

程序7
vector<T> v1; //默認(rèn)初始化
vector<T> v2(v1); // v2包含v1的副本
vector<T> v2 = v1; //等價(jià)于 v2(v1)
vector<T> v3(n,val) //v3包含了n個(gè)重復(fù)元素,其中n為int肪跋,val為T類型
vector<T> v4(n);  // v4包含了n個(gè)具有默認(rèn)值重復(fù)元素
vector<T> v5{a,b,c}; //a歧蒋、b、c類型為T,v5包含了3個(gè)具有不同初值的元素
vector<T> v5={a,b,c}; //v5{a,b,c}等價(jià)谜洽,其中a萝映、b、c類型為T

程序8
//輸入元素的個(gè)數(shù)
vector<int> v2(99);              
cout << v2.size() << endl;    // 99
vector<int> v3(22,100);
cout << v3.size() << endl;  // 22
vector<int> v4{33};
cout << v4.size() << endl;  // 1
vector<int> v5{11,33};
cout << v5.size() << endl; // 2
vector<string> v6{1000};
cout << v6.size() << endl; // 1000
vector<string> v7{44,"he"};
cout << v7.size() << endl; // 44

2.2 vector操作

vector的操作與string操作大致相同阐虚,那咱們說vector獨(dú)有方法序臂,v.push_back(t)方法是vector添加元素的方法,還有vector對(duì)象比較和string對(duì)象比較也類似实束,如果兩個(gè)vector對(duì)象容量不同奥秆,但在相同位置上元素都相等的話,則元素多的大磕洪,如果元素的值有區(qū)別吭练,則vector對(duì)象大小有第一個(gè)開始不等元素大小決定诫龙。vector比string不同的是析显,只有vector包含元素是能夠比較的,才能夠進(jìn)行比較签赃。最后一點(diǎn)谷异,vector不能用下標(biāo)形式添加元素,這與string對(duì)象一致锦聊。

3. 迭代器

在c++標(biāo)準(zhǔn)庫(kù)中容器對(duì)象和string對(duì)象都具有(包含)迭代器對(duì)象歹嘹,所謂的迭代器對(duì)象類似于指針,它提供了對(duì)象元素的訪問孔庭,其對(duì)象元素比如說:容器中的元素或者string對(duì)象中的字符尺上。那么迭代器對(duì)象該如何獲得呢?所有的容器對(duì)象和string對(duì)象可通過自己成員函數(shù)beginend獲得圆到,begin函數(shù)返回指向第一個(gè)元素的迭代器怎抛;end函數(shù)返回指向最后一個(gè)元素下一個(gè)位置的迭代器(尾迭代器),這是本身就容器或者string對(duì)象末尾的一個(gè)標(biāo)志芽淡,并不指向容器或者string內(nèi)任何一個(gè)元素马绝。

3.1 標(biāo)準(zhǔn)迭代器運(yùn)算符號(hào)

程序 解釋
*iter 返回迭代器指向元素的引用
iter->mem 解引用iter并獲取該元素對(duì)象的mem成員,等價(jià)于(*iter).mem
++iter 令iter指向容器或string對(duì)象的下一個(gè)元素
--iter 令iter指向容器或string對(duì)象的上一個(gè)元素
iter1 == iter2 判斷兩個(gè)迭代器是否相等挣菲,如果兩個(gè)迭代器指向的是同一個(gè)元素或者他們同時(shí)指向尾迭代器富稻,則相等,反之白胀,不相等

注:從標(biāo)準(zhǔn)的迭代運(yùn)算符號(hào)表來看椭赋,迭代器跟指針太像了

3.2 迭代器類型(類似于指針類型)

迭代器為了更好控制程序訪問元素讀寫權(quán)限,迭代器引入了iterator和const_iterator兩種類型或杠,其中iterator類型的迭代器可以對(duì)元素可讀可寫哪怔,而const_iterator只能讀取,不能寫。這兩種迭代器類型是由其對(duì)象(容器或string)決定的蔓涧,如果它們是常量件已,它們的迭代器類型就是const_iterator;如果它們不是是常量元暴,它們的迭代器類型可以是兩種類型的任何一種篷扩,但通常它們調(diào)用begin或者end函數(shù)返回的迭代器類型一定是iterator。

vector<int>::iterator it; //it指向元素可讀可寫
vector<int>::const_iterator ct;//it指向元素可讀不可寫

3.3 string或vector支持迭代器運(yùn)算

程序 解釋
iter+n 迭代器指示由當(dāng)前元素向后移動(dòng)n個(gè)元素
iter-n 迭代器指示由當(dāng)前元素向前移動(dòng)n個(gè)元素
iter1-iter2 返回兩個(gè)迭代器指向元素之間相差的元素茉盏,這個(gè)是有正負(fù)的鉴未,正的表示iter1比iter2在容器中位置靠后,負(fù)的反過來
>鸠姨、>=铜秆、<、<= 比較迭代器指向的位置讶迁,位置越小代表的值越小

4. 數(shù)組

數(shù)據(jù)與vector類似连茧,也是保存一系列對(duì)象,引用不是對(duì)象巍糯,因此也不存在引用數(shù)組啸驯,這一點(diǎn)與vector一樣的;它們之間的區(qū)別祟峦,數(shù)據(jù)大小在初始化時(shí)候固定不變的罚斗,而vector大小是隨時(shí)可變的,同時(shí)vector具有良好動(dòng)態(tài)性能宅楞,適合動(dòng)態(tài)添加元素针姿。

4.1 數(shù)組初始化

通用數(shù)組初始化。

unsigned cnt = 42; //不是常量表達(dá)式
constexpr unsigned sz = 42; //常量表達(dá)式
int arr[sz];  //正確
int arr2[cnt]; //錯(cuò)誤厌衙,在定義數(shù)組形如a[d]時(shí)候距淫,d只能是常量表達(dá)式、字面值迅箩、整形常量
const unsinged yz = 3;
int ial[yz] = {0,1,2}; //采用列表初始化數(shù)組
int a2[] = {0,2};  //等價(jià)于維度為2的數(shù)組
int a3[4] = {0,1}; //等價(jià)于a3={0,1,0,0}
int a4[2]={0,1,2}; //錯(cuò)誤:當(dāng)定義數(shù)組的大小要比列表初始化值個(gè)數(shù)要小時(shí)候溉愁,報(bào)錯(cuò)

字符數(shù)組初始化在使用列表初始化和使用字面值初始化是不同的,字符串?dāng)?shù)組使用字面值初始化會(huì)自動(dòng)在字面值字符串后面加上空字符('\0')饲趋,這是因?yàn)樽址置嬷翟赾++底層就是字符數(shù)組拐揭,并且在末尾帶有'\0',而使用列表初始化時(shí)候不會(huì)加奕塑。注意堂污,使用字面值初始化字符數(shù)組要加上空字符,因此字符數(shù)據(jù)長(zhǎng)度=可見字符數(shù)目+1龄砰,見程序

char a1[] = {'c','h','i','n','a'} ;  //列表初始化字符數(shù)組盟猖,沒有空字符
char a2 = "china" ;  //字面值初始化字符數(shù)組讨衣,其實(shí)相當(dāng)于拷貝初始化,帶有空字符'\0'

在標(biāo)準(zhǔn)c++當(dāng)中式镐,數(shù)組之間是不允許拷貝和賦值的反镇。注意,有些編譯器上可以行的娘汞,我們一般建議采用c++標(biāo)準(zhǔn)歹茶,這樣的代碼具有更強(qiáng)的兼容性

int a[] = {1,2,3};
int b[] = a; //錯(cuò)誤,不能使用一個(gè)數(shù)組采用拷貝初始化方式初始化數(shù)據(jù)
b = a; //錯(cuò)誤你弦,數(shù)組之間不能賦值

復(fù)雜數(shù)組聲明:對(duì)于復(fù)雜的數(shù)據(jù)聲明我們安裝向內(nèi)向外惊豺,再?gòu)挠业阶蟮捻樞蜷喿x,理解含義禽作。

int (*Parray)[10] = &arr;  // 首先看最里面括號(hào)部分尸昧,*Parray是一個(gè)指針,然后在看外層右邊旷偿,[10]可知Parray是個(gè)指向大小為10的數(shù)組指針烹俗,
//最后看到外層左邊int,最終可知:Parray是個(gè)指向大小為10的整形數(shù)組指針
int *(&array)[10] = ptrs; //array是個(gè)數(shù)組引用狸捅,這個(gè)數(shù)組包含10個(gè)int型的指針

4.2 數(shù)組元素的訪問

數(shù)組元素的訪問是采用下標(biāo)訪問的衷蜓,同時(shí)也支持for循環(huán),大致與string對(duì)象元素訪問類似尘喝,不同一點(diǎn)是,string對(duì)象可以采用迭代器訪問元素斋陪。

4.3 指針和數(shù)組

c++編譯器會(huì)把數(shù)組名自動(dòng)替換成指向數(shù)組首元素的指針朽褪,數(shù)組操作等同于指針操作。

int ia[] = {0,1,2,3,4,5}
int *p = ia;
int *p1 = &ia[0]; //兩種寫法等價(jià)

指針也是迭代器无虚,數(shù)組的指針也支持運(yùn)算缔赠,運(yùn)算方式也迭代器類似,同時(shí)為了數(shù)組指針能夠更好的獲得首指針和尾后指針(最后一個(gè)元素的下一位置)友题,c++提供了begin(數(shù)組名)和end(數(shù)組名)兩個(gè)函數(shù)嗤堰,例如:

int a[] = {1,2,3,4};
int *beg = begin(a);
int *end = end(a);
for(int *b = beg;b!=end;++b)
{
  cout << *b << endl;
}

數(shù)組的指針和string、vector都支持下標(biāo)運(yùn)算度宦,不同的是指針的下標(biāo)運(yùn)算可以為負(fù)值下標(biāo)踢匣。

int a=[0,2,4,6,8}
int *p = &a[2];
int j = p[1];  // j = a[3]
int x = p[-2];  // x = a[0]

4.4 C風(fēng)格的字符串與標(biāo)準(zhǔn)c++的string的區(qū)別

c風(fēng)格字符串在c中是使用字符數(shù)組存儲(chǔ)的,c為了表達(dá)字符戈抄,通常在存放字符數(shù)組的最后加上'\0'字符离唬,而標(biāo)準(zhǔn)string不用。例如:

char ca[] = {'a','b','c'};
cout << strlen(ca) << endl; //嚴(yán)重錯(cuò)誤划鸽,ca數(shù)組沒有空字符結(jié)束输莺,strlen函數(shù)無法判斷c字符串的長(zhǎng)度

字符串比較的差別戚哎,標(biāo)準(zhǔn)字符串string通過>、<嫂用、==號(hào)就比較型凳,而c風(fēng)格的字符串只能通過strcmp函數(shù)來實(shí)現(xiàn)。標(biāo)準(zhǔn)字符串可通過加號(hào)實(shí)現(xiàn)string對(duì)象和string對(duì)象或者string對(duì)象和字符串字面值實(shí)現(xiàn)字符串的拼接嘱函,而c風(fēng)格的字符串只能通過strcat()和strcpy()實(shí)現(xiàn)字符串的拼接啰脚,而且目標(biāo)字符串的需要程序員自己調(diào)節(jié),一旦目標(biāo)字符串的元素個(gè)數(shù)設(shè)置不合理实夹,就會(huì)導(dǎo)致程序出錯(cuò)橄浓。
4.5 標(biāo)準(zhǔn)庫(kù)提供給與舊代碼的接口
string的c_str()函數(shù),能夠把標(biāo)準(zhǔn)庫(kù)的string對(duì)象轉(zhuǎn)換為字符數(shù)組亮航;c++標(biāo)準(zhǔn)不允許用vector初始化數(shù)組荸实,但數(shù)組可以初始化vector對(duì)象:

int a = {0,2,3,4};
vector<int> ivec = (begin(a),end(a)); //通過首數(shù)組指針和尾后指針來初始化vector對(duì)象

5 多維數(shù)組

二維數(shù)組的第一個(gè)維度稱為行,第二個(gè)維度稱為列缴淋。

5.1 多維數(shù)組的初始化

int a[3][4] = {
{0,1,2,3},
{4,5,6,7},
{8,9,10,11}
};   //初始化 3行*4列數(shù)組
int a2[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11}; //與上一句等價(jià)
int a3[3][4] = { {0},{4},{8}};  //顯示初始化每行的首元素
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末准给,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子重抖,更是在濱河造成了極大的恐慌露氮,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钟沛,死亡現(xiàn)場(chǎng)離奇詭異畔规,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)恨统,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門叁扫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人畜埋,你說我怎么就攤上這事莫绣。” “怎么了悠鞍?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵对室,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我咖祭,道長(zhǎng)掩宜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上赶么,老公的妹妹穿的比我還像新娘砰粹。我一直安慰自己,他們只是感情好睬澡,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布切平。 她就那樣靜靜地躺著扳躬,像睡著了一般锅减。 火紅的嫁衣襯著肌膚如雪糖儡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天怔匣,我揣著相機(jī)與錄音握联,去河邊找鬼。 笑死每瞒,一個(gè)胖子當(dāng)著我的面吹牛金闽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剿骨,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼代芜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了浓利?” 一聲冷哼從身側(cè)響起挤庇,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贷掖,沒想到半個(gè)月后嫡秕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡苹威,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年昆咽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屠升。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡潮改,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腹暖,到底是詐尸還是另有隱情,我是刑警寧澤翰萨,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布脏答,位于F島的核電站,受9級(jí)特大地震影響亩鬼,放射性物質(zhì)發(fā)生泄漏殖告。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一雳锋、第九天 我趴在偏房一處隱蔽的房頂上張望黄绩。 院中可真熱鬧,春花似錦玷过、人聲如沸爽丹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粤蝎。三九已至真仲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間初澎,已是汗流浹背秸应。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碑宴,地道東北人软啼。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像延柠,于是被迫代替她去往敵國(guó)和親祸挪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344