成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

《c++primer》第三章字符串、vector、數(shù)組-創(chuàng)新互聯(lián)

前言

在茶陵等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),成都全網(wǎng)營銷推廣,外貿(mào)網(wǎng)站制作,茶陵網(wǎng)站建設(shè)費(fèi)用合理。

本章內(nèi)容相比第二章要簡單不少,里面比較重要的內(nèi)容主要是vector和迭代器,這里只是很簡單的介紹了一下,在后續(xù)的章節(jié)會(huì)有更詳細(xì)、復(fù)雜的說明。以下記錄的都是比較重要或者易混淆的知識(shí)點(diǎn),對(duì)于像string、vector只列舉了部分方法的例子。

文章目錄
    • 一、string
      • 1.1string初始化和常見操作
      • 1.2string對(duì)象字符處理API
    • 二、標(biāo)準(zhǔn)庫類型vector
      • 2.1vector常見操作
    • 三、初識(shí)迭代器
      • 3.1使用迭代器
      • 3.2迭代器運(yùn)算
    • 四、數(shù)組
      • 4.1初始化
      • 4.2訪問數(shù)組元素
      • 4.3指針和數(shù)組

一、string

?string是C++的一個(gè)標(biāo)準(zhǔn)庫類型,表示可變長的字符序列。string 定義在命名空間std中。

1.1string初始化和常見操作

初始化

? 下表是string的初始化方式。值得注意的是當(dāng)我們使用=號(hào)實(shí)際上執(zhí)行的是拷貝初始化,反之就是直接初始化。

image-20230112134356526

string對(duì)象操作

? 下表是幾種string的操作方式。

image-20230112134725104

? 對(duì)于讀寫string對(duì)象,在使用cin讀取一個(gè)對(duì)象時(shí)會(huì)自動(dòng)忽略開頭的空白(空格、換行符、制表符等),直到遇到下一個(gè)空白為止。如下,當(dāng)我們輸入一段字符串" hhhh yyyy ",程序自動(dòng)忽略開頭的幾個(gè)空格并在遇到下一個(gè)空格后停止讀入,所以最后的結(jié)果為hhhh。在遇到字符串類型的算法題時(shí),使用cin可以減輕處理字符串的工作。

string s1;
cin >>s1; // 輸入"   hhhh yyyy  ";
cout<< s1; // 輸出 "hhhh"

? 如果我們想要保留輸入的一整段字符串,可以使用getline來讀取一整行數(shù)據(jù)。如下,getline需要兩個(gè)參數(shù),一個(gè)是輸入流,另一個(gè)是string對(duì)象,在讀取的過程中,會(huì)把整段數(shù)據(jù)包括換行符都讀在緩沖區(qū)中,但是存儲(chǔ)的時(shí)候會(huì)舍棄掉換行符,所以最后的結(jié)果并沒有包含換行符,這也是為什么在輸出時(shí)要加上endl,endl可以結(jié)束當(dāng)前行并刷新顯示緩沖區(qū)。

getline(cin,s1); //輸入"   hhhh yyyy  ";
cout<< s1<< endl; // 輸出"   hhhh yyyy  ";

?size()會(huì)返回當(dāng)前字符串的一個(gè)大小,大部分和我一樣的初學(xué)者都會(huì)想當(dāng)然的以為返回的類型是一個(gè)int,但其實(shí)類型是string::size_type。size_type是一個(gè)無符號(hào)類型的值,能夠存放任何string對(duì)象的大小。【代碼風(fēng)格:在循環(huán)訪問一個(gè)字符串對(duì)象時(shí),標(biāo)識(shí)符的類型盡量定義成size_type,這樣該標(biāo)識(shí)不可能為負(fù)數(shù)從而減少越界等錯(cuò)誤】。在上一章中學(xué)過auto和decltype,我們在接收一個(gè)字符串對(duì)象的長度時(shí)可以用它們來定義變量。

auto len = s1.size(); // len 的類型是size_type

? 兩個(gè)字符串比較首先看長度是否相等,如果長度不一樣,不一定就是較長的字符串大,因?yàn)?code>string對(duì)象比較遵循第一相異字符比較結(jié)果,也就是說如果第一個(gè)不同字符,較長字符串改字符的字典序小于較短字符串,那么最后的結(jié)果就是較長字符串小于較短字符串。如下。

string str = "Hello";
string str2 = "Hiya"; // str2 >str

? 標(biāo)準(zhǔn)庫允許把字面值或字符字面值轉(zhuǎn)換為string對(duì)象,前提是‘+’兩邊至少包含一個(gè)string對(duì)象。

string str = "123";
string str2 = str + "," + "456"; // 123456
string str3 = "123" + "456"; // 錯(cuò)誤,+兩邊不存在string對(duì)象
1.2string對(duì)象字符處理API

? 要處理一個(gè)字符那么首先要判斷它的類型,在標(biāo)準(zhǔn)款中提供了一個(gè)cctype函數(shù),這是C++兼容C語言的一個(gè)頭文件,如下有一些判斷字符類型的函數(shù)。

image-20230113101033414

? 一般來說,我們都是從一個(gè)字符串中循環(huán)提取一個(gè)字符進(jìn)行處理,C++提供了一個(gè)很方便的循環(huán)語句,范圍for語句,包括在后面迭代器等章節(jié)都會(huì)經(jīng)常使用,定義如下。

for(auto x : str); // 循環(huán)取出原串的一個(gè)字符,不改變原串
for(auto &x : str); // 通過引用的方式可以改變原串

? 如果我們只需要處理一個(gè)字符串中的某個(gè)字符,可以使用下標(biāo)運(yùn)算符[index],里面接收的參數(shù)類型是size_type,保證大于等于0。我們也可以直接通過[index]改變相應(yīng)位置上的值。

混用C風(fēng)格字符串

?C語言定義字符串是通過char *的方式,但是我們不能把一個(gè)string對(duì)象拿來初始化C語言風(fēng)格的字符串。需要使用c_str轉(zhuǎn)換,它返回的是一個(gè)指針,指向一個(gè)以空字符串結(jié)束的字符數(shù)組,這個(gè)數(shù)組存儲(chǔ)的內(nèi)容就是我們定義的string對(duì)象,返回的類型為const char *來保證不會(huì)改變字符數(shù)組的內(nèi)容。

string str("asdasd");
char *str2 = str; // 錯(cuò)誤
const char*str2 = str.c_str()
二、標(biāo)準(zhǔn)庫類型vector

?vector表示對(duì)象的集合,里面的對(duì)象類型都是一致,每個(gè)對(duì)象對(duì)應(yīng)一個(gè)索引,用于訪問該對(duì)象。vector是一個(gè)類模板,在后續(xù)的章節(jié)有專門一章來講解模板,感覺比較難懂。除了類模板,還有一個(gè)就是函數(shù)模板,模板本身不是類或函數(shù),編譯器根據(jù)模板生成類型和函數(shù)的過程稱為實(shí)例化,

2.1vector常見操作

初始化

? 定義和初始化的方法不同的API都差異不大。注意幾點(diǎn),當(dāng)使用拷貝初始化=時(shí),只能提供一個(gè)初始值;如果這個(gè)初始值是類內(nèi)初始值(一個(gè)class定義的值),只能使用拷貝初始化或使用花括號(hào)的形式初始化;使用列表初始化是用{}

image-20230113104005448

? 在定義一個(gè)vector時(shí)我們可能會(huì)給出一個(gè)大小n,此時(shí)程序會(huì)進(jìn)行值初始化,如果 當(dāng)前vector的類型是int,那就會(huì)初始化n個(gè)0。

? 總的來說,()可以說是根據(jù)提供的值來構(gòu)造對(duì)象,{}是根據(jù)提供的值來初始化對(duì)象,只有在無法初始化時(shí)才考慮其它方式。注意下面的表達(dá)式vector v4{10}。

vectorv1(10); // 構(gòu)造10個(gè)大小的整形容器
vectorv2{10}; // 容器含有一個(gè)元素10
vectorv3("hi"); //錯(cuò)誤,不能使用字面值構(gòu)建vector對(duì)象
vectorv4{10}; // 字面值10并不是string對(duì)象,所以不能拿來初始化,而是直接構(gòu)造含有10個(gè)空串的容器

添加元素

?push_back可以往一個(gè)容器的尾部添加一個(gè)元素。vectorC語言中大的區(qū)別就是定義的時(shí)候可以不指定容量,vector可以根據(jù)當(dāng)前存儲(chǔ)的元素動(dòng)態(tài)的改變?nèi)萜鞯拇笮?,是否要在定義時(shí)指定容量大小會(huì)在后續(xù)的章節(jié)中談到,vector提供了一些方法允許我們提升動(dòng)態(tài)添加元素的性能。

vectorvec;
vec.push_back(1);
cout<< vec[0]; // 1 可以通過索引訪問值
vec[1] = 3; // 錯(cuò)誤,不能通過索引的添加值

? 其它的操作如下表所示,都是比較簡單的函數(shù),這里就不一一舉例了。記住v.size()返回的類型還是size_type【代碼風(fēng)格:如果總是忘記定義size_type去接收容器的大小,可以使用上一章學(xué)的auto/decltype自動(dòng)獲取】

image-20230113140316324

三、初識(shí)迭代器

? 前面我們知道可以通過下標(biāo)運(yùn)算符來訪問string對(duì)象或者vector對(duì)象的元素,使用迭代器也能達(dá)到此目的。除了vector外,其它的一些容器也提供了迭代器,但是部分缺不支持下標(biāo)運(yùn)算符,string對(duì)象雖然不是容器,但是也能使用迭代器。

3.1使用迭代器

?begin和end是常用的兩個(gè)迭代器成員,begin指向容器的第一個(gè)元素,end指向容器尾部后一位,這個(gè)位置不存在元素,有點(diǎn)類似鏈表最后的null,僅僅作為一個(gè)標(biāo)志。對(duì)于一個(gè)空的容器,它的begin和end都返回同一個(gè)迭代器。

? 下面是常用的迭代器的運(yùn)算符。*iter返回的一個(gè)元素的引用,如果要訪問該元素下對(duì)應(yīng)的成員還得使用iter->mem(或者(*iter).mem,()不能少)進(jìn)行解引用。移動(dòng)當(dāng)前迭代器使用++或--。

image-20230113142908949

迭代器類型

? 迭代器也有不同的類型,定義一個(gè)迭代器vector::iterator it,通過it可以去讀寫vector的元素;常量迭代器vector::const_iterator it2則只能進(jìn)行讀操作。如何確定迭代器的類型依據(jù)對(duì)象的類型,如果對(duì)象是一個(gè)常量,那么只能使用常量迭代器,反之都可以。同理,我們在上面使用beging和end返回的迭代器類型也是根據(jù)對(duì)象的類型。如果對(duì)于一個(gè)非常量容器,我們想得到一個(gè)常量迭代器,可以使用C++11引入的新特性cbegin和cend,直接返回一個(gè)常量迭代器。

? 解引用迭代器可以獲得迭代器所指的對(duì)象,如果對(duì)象的類型是一個(gè)類,我們可以通過iter->mem或者(*iter).mem訪問類的成員函數(shù)。上面說過使用(*iter).mem方式時(shí)()不能少,如下說明。

vectorvec{"hhhhh"};
vector::iterator it = vec.begin();
(*it).empty(); // false
*it.empty(); // it是一個(gè)迭代器,沒有empty成員,所以錯(cuò)誤

使用->相當(dāng)于把解引用和訪問成員融合在一起,更加的方便。

? 前面提到,vector會(huì)動(dòng)態(tài)的增長容器的大小,所以我們在使用迭代器遍歷容器元素時(shí)不能向容器中添加元素,否則當(dāng)前的迭代器會(huì)失效??傊?dāng)你定義了一個(gè)迭代器,任何將會(huì)改變原容器的操作都會(huì)使當(dāng)前的迭代器失效。

3.2迭代器運(yùn)算

? 除了++和--讓迭代器移動(dòng)一步,我們還可以使用下表的方法進(jìn)行多步移動(dòng)。注意一下當(dāng)兩個(gè)迭代器相減時(shí),返回的是這兩個(gè)迭代器的距離,返回的類型是difference_type(帶符號(hào)整形數(shù))。很明顯這個(gè)距離可正可負(fù)。

image-20230113152346127

四、數(shù)組

? 數(shù)組也是一個(gè)能存放不同對(duì)象的容器,與vector不同,數(shù)組的大小一旦確定就不能改變,不能隨意向數(shù)組中增加元素,在某些情況使用數(shù)組可以增加程序的運(yùn)行性能,但是靈活性也大大的降低。

4.1初始化

? 數(shù)組是一種符合類型,聲明一個(gè)數(shù)組如a[d],其中a是數(shù)組的名字,d是數(shù)組的維度,維度是數(shù)組元素的個(gè)數(shù),它必須要是一個(gè)常量表達(dá)式。

unsigned cnt = 12; //非常量表達(dá)式
int arr[cnt]; // 錯(cuò)誤
constexpr unsigned cnt1 = 12;
int arr[cnt2]; // 定義一個(gè)含有12個(gè)元素的整形數(shù)組

和內(nèi)置類型的變量一樣,在函數(shù)外部定義了一個(gè)數(shù)組將會(huì)根據(jù)類型進(jìn)行默認(rèn)初始化,在內(nèi)部則會(huì)是未定義。在定義數(shù)組的時(shí)候必須要指定數(shù)組的類型,不能使用auto去根據(jù)初始值列表推斷類型

不允許拷貝和賦值

? 我們不能用一個(gè)數(shù)組去初始化另外一個(gè)數(shù)組,雖然一些編譯器可能支持這個(gè)操作,但是為了程序的兼容盡量根據(jù)標(biāo)準(zhǔn)來書寫代碼。但是我們卻可以使用數(shù)組來初始化一個(gè)vector(begin(arr), end(arr)在4.3中有講解)

int arr[] = {1,2,3,4,5,6,67};
vectorvec(begin(arr), end(arr)); // 含有arr的全部元素
vectorvec2(arr + 2, arr + 4); // {3,4}

? 數(shù)組本身是一個(gè)對(duì)象,所以允許定義數(shù)組的指針及數(shù)組的引用,但是不存在引用的數(shù)組。有點(diǎn)繞,直接看書上的例子容易理解一點(diǎn)。

int arr[10];
int *prr[10]; // prr是含有10個(gè)指針的數(shù)組
int &rrr[10] = ??; // 錯(cuò)誤,不存在引用的數(shù)組
int (*Prr)[10] = &arr; // Prr指向一個(gè)含有10個(gè)整數(shù)的數(shù)組的指針
int (&Rrr)[10] = arr; // Rrr是對(duì)數(shù)組arr的引用
4.2訪問數(shù)組元素

? 與vector、string相同,數(shù)組的元素可以使用范圍for循環(huán)或者下標(biāo)運(yùn)算符來訪問。在使用下標(biāo)運(yùn)算符時(shí),返回的類型是size_t,與size_type相同也是一個(gè)無符號(hào)類型。

4.3指針和數(shù)組

? 一般來說,我們對(duì)數(shù)組名直接取地址編譯器會(huì)自動(dòng)的將其替換成數(shù)組首元素的地址。所以我們使用auto自動(dòng)根據(jù)數(shù)組名判斷時(shí),得到的是一個(gè)指針,但是使用decltype會(huì)返回?cái)?shù)組的類型,如下。

int arr[10];
int *p = &arr; // 等于 int *p = &arr[0];
auto arr2(arr); // arr2是一個(gè)指針
decltype(arr) arr3; // arr3是一個(gè)含有10個(gè)元素的整形數(shù)組

? 數(shù)組雖然沒有迭代器,但是數(shù)組的指針也可以看成迭代器,迭代器能完成的操作使用指針也能完成。迭代器可以通過begin和end獲得容器的開頭和尾后元素,雖然數(shù)組不是類類型,沒有成員函數(shù),但是我們也可以將數(shù)組作為參數(shù)傳入進(jìn)去實(shí)現(xiàn)同樣的效果。

int arr[] = {1,2,3,4,5,56,6};
int *beg = begin(arr); // 指向arr第一個(gè)元素的指針
int *last = end(arr);  // 指向arr尾后元素的指針

? 指針的運(yùn)算與上面迭代器的運(yùn)算基本一致,兩個(gè)指針相減返回的類型為ptrdiff_t。

下標(biāo)和指針

? 使用指針的同時(shí)也能使用下標(biāo)訪問當(dāng)前指針操作后指向的元素(當(dāng)然指向合理的范圍)。從p2[-1]可以看出指針和標(biāo)準(zhǔn)庫類型vector等使用下標(biāo)運(yùn)算符的區(qū)別,內(nèi)置類型的下標(biāo)運(yùn)算符可以是一個(gè)有符號(hào)數(shù)。

int arr[] = {1,2,3,4,5,56,6};
int i = arr[2]; // 3
int *p = &arr; // p指向第一個(gè)元素1
cout<< p[2]; // 輸出3,相當(dāng)于p+2
int *p2 = &i;
cout<< p2[-1]; // 輸出2

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

標(biāo)題名稱:《c++primer》第三章字符串、vector、數(shù)組-創(chuàng)新互聯(lián)
鏈接地址:http://jinyejixie.com/article38/dhopsp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、云服務(wù)器、搜索引擎優(yōu)化網(wǎng)站收錄、面包屑導(dǎo)航、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營
望奎县| 肥西县| 荔波县| 汶川县| 新野县| 榆中县| 铜川市| 台东市| 万全县| 收藏| 焉耆| 疏附县| 息烽县| 平南县| 嵊泗县| 天祝| 中方县| 永康市| 陇西县| 新野县| 天镇县| 临沂市| 正宁县| 武乡县| 罗田县| 凉山| 通辽市| 诏安县| 淮滨县| 察隅县| 洛川县| 泰宁县| 高青县| 清远市| 长宁县| 建水县| 若尔盖县| 清水河县| 家居| 灵台县| 镇康县|