第三章 字符串器予、向量和數(shù)組
這一章中介紹了C++語言定義的抽象數(shù)據(jù)類型庫,包括string和vector等重要的標(biāo)準(zhǔn)庫類型,迭代器是這兩種標(biāo)準(zhǔn)庫類型的配套類型,常用于訪問string和vector中的數(shù)據(jù)辜膝。
在學(xué)習(xí)了第二章介紹的一些內(nèi)置的類型后,我們進(jìn)入了更深層次的數(shù)據(jù)類型的學(xué)習(xí)漾肮,這些類型未像數(shù)組或者字符那樣直接實(shí)現(xiàn)到計(jì)算機(jī)硬件中厂抖。
命名空間的using聲明
目前我們用到的庫函數(shù)大多都來自命名空間std,在之前的學(xué)習(xí)中我們將其顯式地標(biāo)示了出來初橘,如std::cin
验游,此處的作用域操作符::
表示編譯器從操作符左側(cè)名字瑣事的作用域中尋找右側(cè)的名字,所以std::cin
的意思就是使用命名空間std
中的名字cin
保檐。
這種方法很繁瑣耕蝉,我們可以通過簡單的途徑使用命名空間中的成員,也就是using聲明夜只,其形式如下:using namespace::name
垒在,在程序中使用了這條語句就可以直接訪問命名空間中的名字。注意:每個名字都需要獨(dú)立的using聲明
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main() {
int i = 0;
cin >> i;
cout << i << endl;
return 0;
}
頭文件中不應(yīng)包含using聲明扔亥,因?yàn)轭^文件的內(nèi)容會拷貝到所有引用它的文件中场躯,如果頭文件中包含某個using聲明,那么可能會產(chǎn)生名字沖突旅挤。
標(biāo)準(zhǔn)庫類型string
string類型表示可變長的字符序列踢关,使用需包含頭文件string
,其作為標(biāo)準(zhǔn)庫類型定義在std
命名空間中粘茄。
根據(jù)上一小節(jié)所說命名空間的聲明签舞,我們可以在文件中包含using std::string
聲明,便可以直接在程序中使用string
類型而不用標(biāo)示其命名空間柒瓣。
定義儒搭、初始化string對象
四種初始化string對象的方式:
string s1; //默認(rèn)初始化,s1是一個空字符串
string s2 = s1 //s2是s1的副本
string s2(s1) //s2是s1的副本
string s3 = "zhc"; //s3是該字符串字面值的副本
string s3("ahc")
string s4(4, 'z'); //s4的內(nèi)容為zzzz
注意在第四行和第五行的初始化中芙贫,該字面值中除了最后的空字符外其他所有字符都被拷貝到新創(chuàng)建的string對象中搂鲫,第六行中提供了一個數(shù)字和一個字符,string對象被初始化為給定字符連續(xù)重復(fù)若干次后得到的序列
直接初始化和拷貝初始化
使用等號=
初始化一個變量磺平,實(shí)際上執(zhí)行的是拷貝初始化魂仍,不使用等號則執(zhí)行直接初始化
string對象的操作
讀寫string對象
可以使用第一章中的IO操作符讀寫string對象
#include<iostream>
#include<string>
using std::cin;
using std::cout;
using std::string;
int main() {
string s;
cin >> s;
cout << s << endl;
return 0;
}
在執(zhí)行讀寫操作時,string對象會自動忽略開頭的空白(空格符褪秀、換行符蓄诽、制表符等),從第一個真正的字符開始讀起媒吗,直到遇到下一處空白為止仑氛。如果程序輸入"Hello World", 程序會輸出"Hello"。string讀寫中闸英,多個輸入或者輸出可以連寫在一起锯岖。
使用getline讀取一整行
使用getline讀取字符串可以保留輸入時的空白符,getline接收一個輸入流和一個string對象甫何,從給定的輸入流中讀入內(nèi)容出吹,直到遇到換行符為止(換行符也被讀入)饮戳,所讀內(nèi)容存入string對象中兰珍。
getline返回它的流參數(shù),因此可以作為判斷條件饺蔑。流的判斷條件為:流有效為真,流無效(結(jié)束標(biāo)記或非法輸入)則為假秋麸。
#include<iostream>
#include<string>
using std::cin;
using std::cout;
using std::string;
int main() {
string s;
while(getline(cin, s))
cout << s << endl;
return 0;
}
string的empty和size操作
empty檢測string對象是否為空渐排,返回一個布爾類型的值它是string的一個成員函數(shù),調(diào)用該函數(shù)只要使用點(diǎn)操作符指明是哪個對象執(zhí)行了empty函數(shù)就行灸蟆,以getline中string對象為例:s.empty()
即可判斷s是否為空驯耻。
size函數(shù)返回string對象的長度(即string對象中字符個數(shù)),使用同empty函數(shù)相同:s.size()
炒考。
string::size_type類型
size函數(shù)的返回類型為size_type
可缚。其為string的配套類型,體現(xiàn)了標(biāo)準(zhǔn)庫類型與機(jī)器無關(guān)的特性斋枢,它是在類string中定義的帘靡。
size_type
是一個無符號類型的值,能夠存放任何string對象的大小瓤帚。在C++11新標(biāo)準(zhǔn)中测柠,允許編譯器通過auto或者decltype來推斷變量類型:auto length = s.size();
需要注意size_type
是一個無符號類型!
比較string對象
string類定義了用于比較字符串的運(yùn)算符,這些運(yùn)算符逐一比較string對象中的字符缘滥,且對大小寫敏感轰胁。
相等性運(yùn)算符==和!=
分別檢驗(yàn)兩個stirng對象相等或不想等,相等意味著它們的長度相同且包含的字符也全部相同朝扼。
<赃阀、<=、>擎颖、>=
操作按照字典排序
兩個string對象相加
兩個string對象相加得到一個新的string對象榛斯,使用加法運(yùn)算符+
,也可使用+=
操作符將string對象的內(nèi)容追加到目標(biāo)string對象中搂捧。
字面值和string對象相加
可以將string對象和字面值直接相加:
string s4 = "zhc";
string s5 = s4 + "jiayou";
需要注意字面值之間不能直接相加驮俗,C++語言中的字符串字面值并不是標(biāo)準(zhǔn)庫類型string的對象
處理string對象中的字符
單獨(dú)處理string對象中的字符涉及到如何獲取字符本身的問題以及如何對特定字符進(jìn)行操作。在頭文件cctype
中定義了一組標(biāo)準(zhǔn)庫函數(shù)來進(jìn)行這些操作:
函數(shù) | 作用 |
---|---|
isalnum(c) | 當(dāng)c是字母或數(shù)字時為真 |
isalpha(c) | 當(dāng)c是字母時為真 |
iscntrl(c) | 當(dāng)c是控制字符時為真 |
isdigit(c) | 當(dāng)c是數(shù)字時為真 |
isgraph(c) | 當(dāng)c不是空格但可打印時為真 |
islower(c) | 當(dāng)c是小寫字母時為真 |
isprint(c) | 當(dāng)c是可打印字符時為真(即c是空格或c具有可視形式) |
ispunct(c) | 當(dāng)c是標(biāo)點(diǎn)符號時為真(即c不是控制字符允跑、數(shù)字王凑、字母、可打印空白中的一種) |
isspace(c) | 當(dāng)c是空白時為真(即c是空格聋丝、橫向制表符索烹、縱向制表符、回車符弱睦、換行符百姓、進(jìn)紙符中的一種) |
isupper(c) | 當(dāng)c是大寫字母時為真 |
isxdigit(c) | 當(dāng)c時十六進(jìn)制數(shù)字時為真 |
tolower(c) | 如果c是大寫字母,輸出對應(yīng)的小寫字母况木,否則原樣輸出c |
toupper(c) | 如果c是小寫字母垒拢,輸出對應(yīng)的大寫字母旬迹,否則原樣輸出c |
使用基于范圍的for語句處理每個字符
范圍for語句遍歷給定序列中的每個元素并對序列中的每個值執(zhí)行某種操作。下面是一個例子:
string s("zhc");
for(auto c : s)
cout << c << endl;
這里通過auto關(guān)鍵字讓編譯器決定變量c的類型求类。這里c的類型是char舱权,每一次迭代,s的下一個字符被拷貝給c仑嗅。
如果想要改變string對象中字符的值,需要把循環(huán)變量c定義成引用類型张症。
這樣c實(shí)際上被綁定到了序列的每個元素上仓技,使用這個引用,我們就能修改其綁定字符的值俗他。
string s("zhc");
for(auto &c : s)
c = toupper(c);
cout << s << endl;
這個例子的輸出是ZHC
脖捻,s中的每個字符都被修改為對應(yīng)的大寫字母。
如果我們需要訪問的只是string對象中的一個字符兆衅,或者訪問多個字符但是遇到某個條件就要停下來地沮,比如說我們指向把string對象中的第一個字母大寫,有兩種方式:一種是下標(biāo)羡亩,另外一種是迭代器摩疑。
下標(biāo)運(yùn)算符
接收string::size_type
類型的參數(shù),這個參數(shù)表示要訪問的字符的位置畏铆,返回值是該位置上字符的引用雷袋。
string對象的下標(biāo)從0開始計(jì)數(shù),s[s.size() -1]
是最后一個字符辞居。
string對象的下標(biāo)必須大于等于0而小于s.size()
楷怒。使用超出此范圍的下標(biāo)將引發(fā)不可預(yù)知的后果,使用下標(biāo)訪問空string也會引發(fā)后果
下標(biāo)的值被稱為“下標(biāo)”或“索引”瓦灶,下面是一個輸出string對象中第一個字符的例子:
if(!s.empty())
cout << s[0] << endl;
這里使用了邏輯非運(yùn)算符!
鸠删,它返回與其運(yùn)算對象相反的結(jié)果。
首先我們檢查string對象是否為空贼陶,如果為空刃泡,則s[0]的結(jié)果是未定義的。現(xiàn)在我們修改上一小節(jié)的程序碉怔,使用下標(biāo)修改字符:
string s("zhc");
if(!s.empty())
s[0] = toupper(s[0]);
程序輸出Zhc
捅僵。
我們可以自己嘗試自己用下標(biāo)替代范圍for進(jìn)行迭代。
使用下標(biāo)可以對string對象進(jìn)行隨機(jī)訪問眨层,也就是可以通過下標(biāo)值訪問string對象對應(yīng)的字符庙楚。注意下標(biāo)范圍!!
標(biāo)準(zhǔn)庫類型vector
vector表示對象的集合,其中所有對象的類型都相同趴樱,結(jié)合中每個對象都有對應(yīng)的索引馒闷,用于訪問對象酪捡。因?yàn)関ector“容納著”其他對象,所以它也被稱為容器纳账。
使用vector需要引入頭文件vector
逛薇。注意using聲明操作
#include <vector>
using std::vector
vector是一個類模版。類模版可以看作為編譯器生成類或函數(shù)編寫的一份說明疏虫,編譯器根據(jù)模版創(chuàng)建類或函數(shù)的過程稱之為實(shí)例化永罚。
對于類模版來說,我們通過提供一些額外信息來制定模版到底實(shí)例化成什么樣的類卧秘。提供信息的方式為在模版名字后面跟一對尖括號呢袱,在括號內(nèi)放上信息,以vector為例:vector<int> ivec
ivec保存int類型的對象翅敌。
因?yàn)橐貌皇菍ο笮吒#圆淮嬖诎玫膙ector。組成vector的元素也可以是vector:vector<vector<string>> file
在早期的C++版本中蚯涮,如果vector的元素還是vector治专,或者其他模版類型,則其定義的形式與現(xiàn)在的C++11新標(biāo)準(zhǔn)有所不同遭顶,必須在外層vector對象的右尖括號和其元素之間添加一個空格张峰,例如:vector<vector<int> >
。在某些編譯器中可能還在使用這種風(fēng)格棒旗,這點(diǎn)需要注意挟炬。
定義和初始化vector對象
常用方法:
vector<T> v1 //v1是一個空vector,它潛在的元素是T類型的嗦哆,執(zhí)行默認(rèn)初始化
vector<T> v2(v1) //v2中包含有v1所有元素的副本
vector<T> v2 = v1 //等價于v2(v1)
vector<T> v3(n, val) //v3包含了n個重復(fù)的元素谤祖,每個元素的值都是val
vector<T> v4(n) //v4包含了n個重復(fù)地執(zhí)行了值初始化的對象
vector<T> v5{a,b,c...} //v5包含了初始值個數(shù)的元素,每個元素被賦予相應(yīng)的初始值
vector(T) v5 = {a,b,c...} //等價于v5{a,b,c...}
列表初始化vector對象
vector<string> sv = {"a", "ab", "abc"};
C++11新標(biāo)準(zhǔn)提供了列表初始化方法老速,上述表達(dá)式中vector包含三個字符串對象粥喜。
初始化方式很多且可以相互等價使用,不過要注意兩種情況:1.使用拷貝初始化時(=
)橘券,只能提供一個初始值额湘;2.如果提供的是一個類內(nèi)初始值,則只能使用拷貝初始化或使用花括號形式初始化旁舰。且有一種特殊要求锋华,如果提供的是初始元素值列表,則只能把初始值都放在花括號里進(jìn)行列表初始化箭窜。
值初始化
通常情況下可以只提供vector對象容納的元素?cái)?shù)量而不用略去初始值毯焕,此時庫會創(chuàng)建一個值初始化的元素初值,并把它賦給容器中的所有元素。這個初值由vector對象中元素的類型決定:
vector<int> ivec(10) //10個元素纳猫,每個都初始化為0
vector<string> svec(10) //10個元素婆咸,每個都是空string對象
這里有兩個限制:1.有些類要求必須明確地提供初始值。2.如果只提供了元素的數(shù)量而沒有設(shè)定初始值芜辕,只能使用直接初始化尚骄。
向vector對象中添加元素
對于大量的數(shù)據(jù),運(yùn)用初始化的方式便不太方便侵续,更好的處理方法是先創(chuàng)建一個空vector倔丈,然后在運(yùn)行時再利用vector的成員函數(shù)push_back
向其中添加元素,push_back
把一個值當(dāng)成vector對象的尾元素“壓到(push)“vector對象的”尾端(back)“:
vector<int> v2; //空的vector對象
for(int i = 0; i < 100; ++i)
v2.push_back(i); //依次把整數(shù)值i放到v2的尾端
循環(huán)完成后v2對象中有100個0-99
的int
類型的元素状蜗。
如果循環(huán)體內(nèi)部包含有向vector對象添加元素的語句需五,則不能使用范圍for循環(huán)
其他vector操作
函數(shù) | 作用 |
---|---|
v.empty() | 判斷v是否為空 |
v.size() | 返回v中元素的個數(shù) |
v.push_back(t) | 向v的尾端添加一個值為t的元素 |
v[n] | 返回v中第n個位置上元素的引用 |
v1 = v2 | 用v2中元素的拷貝替換v1中的元素 |
v1 = {a,b,c...} | 用列表中元素的拷貝替換v1中的元素 |
v1 == v2, v1 != v2 | v1和v2相等當(dāng)且僅當(dāng)它們的元素?cái)?shù)量相同且對應(yīng)位置的元素值都相同 |
<, <=, >, >= | 以字典順序進(jìn)行比較 |
使用范圍for語句處理vector對象中的所有元素:
vector<int> v{1,2,3,4,5,6,7,8,9};
for(auto &i : v)
i *= i;
for(auto i : v)
cout << i << " ";
cout << endl;
vector的size()
函數(shù)返回類型是由vector定義的size_type類型:
vector<int>::size_type
不能用下標(biāo)形式添加元素,用push_back诗舰!
迭代器
通用的訪問string對象的字符或vector對象的元素的機(jī)制,所有標(biāo)準(zhǔn)庫容器都可以使用迭代器训裆。類似于指針類型眶根,迭代器提供了對對象的簡介訪問。就迭代器而言边琉,其對象是容器中的元素或者string對象中的字符属百。
使用迭代器
有迭代器的類型同時擁有返回迭代器的成員。比如這些類型都擁有名為begin和end的成員变姨,其中begin成員返回指向第一個元素(或第一個字符)的迭代器:
auto b = v.begin(), e = v.end(); //b和e類型相同族扰,b表示v的第一個元素,e表示v尾元素的下一位置
end成員指示的是容器的一個本不存在的“尾后”元素定欧。end成員返回的迭代器常被稱作尾后迭代器渔呵。特殊情況下如果容器為空,則begin和end返回的是同一個迭代器砍鸠,都是尾后迭代器扩氢。
迭代器運(yùn)算符
使用==
和!=
來比較兩個合法的迭代器是否相等,如果兩個迭代器指向的元素相同或者都是同一個容器的尾后迭代器爷辱,則它們相等录豺。
操作 | 作用 |
---|---|
*iter | 返回迭代器iter所指元素的引用 |
iter->men | 解引用iter并獲取該元素的名為men的成員,等價于(*iter).men |
++iter | 令iter指示容器中的下一個元素 |
--iter | 令iter指示容器中的上一個元素 |
iter1 == iter2或iter1 != iter2 | ...... |
迭代器通過解引用方式來獲取它所指示元素饭弓,執(zhí)行解引用的迭代器必須合法并確實(shí)指示著某個元素双饥。
使用迭代器便利string對象,將string對象中的第一個單詞改為大寫形式:
string s("ahc cpp");
for(auto i = s.begin(); i != s.end() && !isspace(*i); ++i)
*i = toupper(*i);
程序輸出ZHC cpp
弟断。
迭代器類型
擁有迭代器的標(biāo)準(zhǔn)庫類型使用iterator和const_iterator來表示迭代器的類型咏花。
vector<int>::iterator it; //it能讀寫vector<int>的元素
string::iterator it2; //it2能讀寫string對象中的字符
vector<int>::const_iterator it3; //it3只能讀元素,不能寫元素
string::const_iterator it4; //it4只能讀字符阀趴,不能寫字符
如果vector對象或stirng對象是一個常量迟螺,只能使用const_iterator冲秽;如果不是,則都能用矩父。
我們認(rèn)定某個類型是迭代器當(dāng)且僅當(dāng)它支持一套操作锉桑,這套操作使得我們能訪問容器的元素或者某個元素移動到另外一個元素。
為了便于專門得到const_iterator類型的返回值窍株,C++11新標(biāo)準(zhǔn)引入了兩個新函數(shù)民轴,分別是cbegin
和cend
。
push_back會使vector對象的迭代器失效球订,單反使用了迭代器的循環(huán)體后裸,都不要向迭代器所屬的容器添加元素。
迭代器運(yùn)算
string和vector的迭代器提供了許多額外的運(yùn)算符冒滩,一方面可使得迭代器的每次移動跨國多個元素微驶,另外也支持迭代器進(jìn)行關(guān)系運(yùn)算。所有這些運(yùn)算被稱作迭代器運(yùn)算开睡。
迭代器的算術(shù)運(yùn)算
可以令迭代器和一個整數(shù)值相加(或相減)因苹,其返回值是向前(或向后)移動了若干個位置的迭代器:
auto mid = vi.begin() + vi.size() / 2;
mid
指向vector對象中間位置的元素。
只要兩個迭代器指向的是同一個容器中的元素或者尾元素的下一位置篇恒,就能將其相減扶檐,所得結(jié)果是兩個迭代器的距離,其類型是名為difference_type的帶符號整型數(shù)胁艰。
數(shù)組
數(shù)組是一種類似于標(biāo)準(zhǔn)庫類型vector的數(shù)據(jù)機(jī)構(gòu)款筑。與vector相似的地方是,數(shù)組也是存放類型相同的對象的容器腾么。與vector不同的地方時奈梳,數(shù)組的大小確定不變,不能隨意向數(shù)組中增加元素解虱。如果不清楚元素的確切個數(shù)颈嚼,請使用vector。
定義和初始化內(nèi)置數(shù)組
數(shù)組是一種復(fù)合類型饭寺。數(shù)組的聲明形如a[d]
阻课,其中a是數(shù)組的名字,d是數(shù)組的維度艰匙。維度說明了數(shù)組中元素的個數(shù)限煞,因此必須大于0。維度必須是一個常量表達(dá)式员凝。
unsigned cnt = 42; //不是常量表達(dá)式
constexpr unsigned sz = 42; //常量表達(dá)式
int arr[10]; //含有10個整數(shù)的數(shù)組
int *parr[sz]; //42個整型指針的數(shù)組
string bad[cnt]; //錯誤:cnt不是常量表達(dá)式
string strs[get_size()]; //當(dāng)get_size是constexpr時正確署驻,否則錯誤
默認(rèn)情況下,數(shù)組的元素被默認(rèn)初始化。
數(shù)組的元素應(yīng)是對象旺上,因此不存在引用的數(shù)組瓶蚂。不允許用auto關(guān)鍵字推斷數(shù)組類型。
顯式初始化數(shù)組元素
可以對數(shù)組元素進(jìn)行列表初始化宣吱,此時允許忽略數(shù)組的維度窃这。編譯器會根據(jù)初始值的數(shù)量計(jì)算并推測出來。
字符數(shù)組的特殊性
字符數(shù)組有一種額外的初始化形式征候,用字符串字面值對數(shù)組進(jìn)行初始化杭攻。注意字符串字面值的結(jié)尾還有一個空字符。
const char a4[6] = "Daniel"; //錯誤:沒有空間可存放空字符串
不能將數(shù)組的內(nèi)容拷貝給其他數(shù)組作為初始值疤坝,也不能用數(shù)組為其他數(shù)組復(fù)制兆解。
數(shù)組的指針或引用
int *ptrs[10]; //ptrs是含有10個整型指針的數(shù)組
int &refs[10] = ... //錯誤:不存在引用的數(shù)組
int (*Parray)[10] = &arr; //Parray指向一個含有10個整數(shù)的數(shù)組
int (&arrRef)[10] = arr; //arrRef引用一個含有10個整數(shù)的數(shù)組
訪問數(shù)組元素
數(shù)組的元素能夠使用范圍for語句或下標(biāo)運(yùn)算符來訪問。
在使用數(shù)組下標(biāo)的時候跑揉,通常將其定義為size_t類型锅睛。這是一種機(jī)器相關(guān)的無符號類型,它足夠大历谍,能表示內(nèi)存中任意對象的大小现拒,其頭文件為cstddef
。
與vector和stinrg一樣扮饶,數(shù)組的下標(biāo)是否在合理范圍之內(nèi)由程序員負(fù)責(zé)檢查具练,就說指下標(biāo)應(yīng)該大于等于0且小與數(shù)組的大小乍构。
指針和數(shù)組
使用數(shù)組的時候編譯器一般會把它轉(zhuǎn)換成指針甜无。對數(shù)組的元素使用取地址符就能得到指向該元素的指針:
string nums[] = {"one", "two", "three"}; //數(shù)組的元素是string對象
string *p = &nums[0]; //p指向nums的第一個元素
在很多用到數(shù)組名字的地方,編譯器都會自動地將其替換為一個指向數(shù)組首元素的指針:string *p2 = nums; //等價于p2 = &nums[0]
哥遮。
在一些情況下數(shù)組的操作實(shí)際上是指針的操作岂丘,所以當(dāng)使用數(shù)組作為一個auto變量的初始值時,推斷得到的類型是指針而非數(shù)組眠饮。
當(dāng)使用decltype關(guān)鍵字時奥帘,數(shù)組返回的類型是由10個整數(shù)構(gòu)成的數(shù)組:
decltype(某數(shù)組) ia = {0,1,2,3,4,5,6,7,8,9};
//這個時候ia是一個數(shù)組
指針也是迭代器
vector和string的迭代器支持的運(yùn)算,數(shù)組的指針全部支持仪召。
有一個問題是如何獲取指向數(shù)組尾后指針寨蹋,這需要用到數(shù)組的一個特殊性質(zhì),我們可以設(shè)法獲取數(shù)組尾元素之后的那個并不存在的地址扔茅,這個時候也就獲取到了數(shù)組之后一個并不存在的元素已旧,也就相當(dāng)于尾后迭代器一樣。
但是這樣做并不安全召娜。C++11新標(biāo)準(zhǔn)引入了兩個名為begin
和end
的函數(shù)运褪,這里的函數(shù)不像是vector里的同名函數(shù)那樣是vector標(biāo)準(zhǔn)庫的成員函數(shù):
int ia[] = {0,1,2,3,4,5,6,7,8,9};;
int *beg = begin(ia); //指向ia首元素的指針
int *last = end(ia); //指向ia尾元素的下一位置的指針
begin
和end
定義在頭文件iterator
中。
尾后指針不能進(jìn)行解引用和遞增操作!
指針運(yùn)算的操作與迭代器類似,可翻看前面幾節(jié)迭代器的操作秸讹。
數(shù)組中兩個指針相減的結(jié)果是一種名為ptrdiff_t
的標(biāo)準(zhǔn)庫類型檀咙,和size_t
一樣定義在頭文件cstddef
中,與機(jī)器相關(guān)璃诀,是一種帶符號的類型弧可。
C風(fēng)格字符串
字符串字面值是一種通用結(jié)構(gòu)的實(shí)例,是C++由C即成而來的C風(fēng)格字符串文虏。按此結(jié)構(gòu)書寫的字符串存放在字符數(shù)組中并以空字符'\0'
結(jié)束侣诺。
對大多數(shù)應(yīng)用來說,使用標(biāo)準(zhǔn)庫string要比使用C風(fēng)格字符串更安全氧秘、更高效年鸳。
c_str
函數(shù)將string對象轉(zhuǎn)換為C風(fēng)格字符串,返回值是一個C風(fēng)格的字符串丸相,是一個指針搔确,指向一個以空字符結(jié)束的字符數(shù)組。指針的類型是const char*
灭忠。
如果執(zhí)行完c_str()
函數(shù)后程序想一直都能使用其返回的數(shù)組膳算,最好將該數(shù)組重新拷貝一份。
允許使用數(shù)組初始化vector:
int int_arr[] = {0,1,2,3,4,5};
vector<int> ivec(begin(int_arr), end(int_arr));
創(chuàng)建ivec的兩個指針指明了用來初始化的值在int_arr中的為孩子弛作,其中第二個指針應(yīng)指向待拷貝區(qū)域尾元素的下一位置涕蜂。
現(xiàn)代的C++程序應(yīng)當(dāng)盡量使用vector和迭代器,避免使用內(nèi)置數(shù)組和指針映琳;應(yīng)該盡量使用string机隙,避免使用C風(fēng)格的基于數(shù)組的字符串。
多維數(shù)組
嚴(yán)格來說萨西,C++語言中沒有多維數(shù)組有鹿,通常所說的多維數(shù)組其實(shí)是數(shù)組的數(shù)組。
int ia[3][4]; //二維數(shù)組
int arr[10][20][30]; //三維數(shù)組谎脯,且數(shù)組哪元素都被初始化為0
對于二維數(shù)組來說葱跋,常把第一個維度稱為行,第二個維度稱為列源梭。
對于多維數(shù)組的初始化和操作可以參考網(wǎng)上或書本資料娱俺,《C++ primer》上有些繁雜,在此就不加入筆記了废麻。