2020 我的C++的学习之路
以C++ Primer Plus為參考書籍,自身歸納知識(shí)點(diǎn),加深記憶。
第四章 復(fù)合類型
4.1 數(shù)組
數(shù)組(array)是一種數(shù)據(jù)格式,存儲(chǔ)多個(gè)同類型的值。聲明數(shù)組應(yīng)指出數(shù)組中元素的類型,元素?cái)?shù)量以及數(shù)組名稱。
聲明格式:TypeName ArrayName[ArraySize] ,其中ArraySize必須為整型常量或者const值或常量表達(dá)式,即所有的值在編譯時(shí)已知,不能為變量。
數(shù)組的初始化規(guī)則:① 只有定義數(shù)組才能使用初始化,不能將一個(gè)數(shù)組賦給另一個(gè)數(shù)組,但可以用數(shù)組下標(biāo)分別賦值;
② 初始化數(shù)組時(shí)可以進(jìn)行部分初始化,其余部分編譯器默認(rèn)為0;
③ C++11 新方法:初始化數(shù)組,可以省略 = 號(hào);int ary[3] {1,2,3};
④ C++11 新方法:大括號(hào)內(nèi)可為空,則所有元素均為0;int ary[4] {};//ary數(shù)組中元素初始化為0.
⑤ C++11 新方法:列表初始化禁止縮窄轉(zhuǎn)換。long ary[3] {25,30,32.5};//ary[2]為float類型,浮點(diǎn)數(shù)轉(zhuǎn)為整型是縮窄操作,小數(shù)部分的精度會(huì)喪失。
4.2 字符串
字符串是存儲(chǔ)在內(nèi)存中連續(xù)字節(jié)中的一系列字符。傳統(tǒng)C語言中字符串末尾以空字符 ‘\0’ 結(jié)尾,但有一種更好的初始化字符串的方法,那就是直接用引號(hào)括起來字符串,這種字符串成為字符串常量(string constant)。char food[10] = "bread";引號(hào)括起的字符串隱式包括結(jié)尾的 ‘\0’ ,因此不顯式包括。
字符串的輸入
iostream中的cin會(huì)將鍵盤輸入中的空格,制表符,換行符以分界線結(jié)束位置,因此在輸入名字時(shí)會(huì)導(dǎo)致“Smith Young”只錄入“Smith”一個(gè)單詞。在istream中提供了面向行的類成員函數(shù)。
4.2.1 getline()
getline()讀取整行,通過回車鍵入的換行符確定輸入結(jié)尾,調(diào)用方式為 cin.geiline(arrayname,size) ,getline讀取的字符數(shù)為 size-1,剩下的空間存儲(chǔ)一個(gè) ‘\0’。
4.2.2 get()
get()接受的參數(shù)與getline()相同,同樣讀取到結(jié)尾,但是get()不丟棄換行符,而是將其保留在輸入隊(duì)列中。因此在使用get()時(shí)應(yīng)考慮在鍵入回車時(shí)殘留下的換行符,通常的解決方式為
另外一種方式是將兩個(gè)類成員函數(shù)拼接起來,效果一樣:
cin.get(name,size).get();//cin.get()返回一個(gè)cin對(duì)象,該對(duì)象又被用來調(diào)用get(),故可以這樣拼接。//cin.getline(name1,size).getline(name2,size) 則是讀取兩行分別讀入到name1和name2數(shù)組中,其效果與調(diào)用兩次getline()相當(dāng)。4.3 string類
要使用string類,必須包含頭文件string,string類位于名稱空間std中,因此需要一條using編譯指令,或者std::string引用。
聲明: string ArrayName,string對(duì)象和字符數(shù)組的區(qū)別就是可以將string對(duì)象聲明為簡(jiǎn)單變量,而不是數(shù)組,并且類設(shè)計(jì)讓程序自動(dòng)處理string的大小,自動(dòng)調(diào)整string的長度。string str = "amazing" ;//或采取C++11 string str = {"amazing"};“=”可以省略。
4.3.1 賦值、拼接與附加
① string對(duì)象可以賦給另一個(gè)string對(duì)象
char food1[10];char food2[10] = "bread";food1 = food2; //編譯不可通過,字符串間不能直接賦值string drink1 = "milk";string drink2;drink2 = drink1; //string對(duì)象的特殊性② string簡(jiǎn)化了字符串合并,可以直接用 + 將兩個(gè)string對(duì)象合并,還可以用 += 附加到對(duì)象末尾
string str1 = "talking";string str2 = " to the moon";string str3;str3 = str1 + str2; //str3 = "talking to the moon"str1 += str2; //str1 = "talking to the moon"4.3.2 string的其他事項(xiàng)
在C++新增string之前,使用頭文件cstring來完成拼接等操作。
使用函數(shù)strcpy()實(shí)現(xiàn)字符串的復(fù)制,使用函數(shù)strcat()實(shí)現(xiàn)字符串附加在末尾:
strcpy(str1,str2) //將str2復(fù)制到str1中
strcat(str1,str2) //將str2接到str1的末尾
但strcat,strcpy存在安全隱患,由于str1,str2的字符數(shù)組大小已定,因此在拼接,復(fù)制過程中容易出現(xiàn)str1的大小過小,導(dǎo)致無法完整存儲(chǔ)信息的危險(xiǎn),因此提供了strncpy()與strncat()函數(shù),它們接受第三個(gè)參數(shù)為目標(biāo)數(shù)組最大允許長度,但還是不如string類自動(dòng)調(diào)整大小的功能。
4.3.3 string類的I/O
#include<iostream> #include<string> int main () {using namespace std;char food[20];string drink;cout << "Please input food name:";cin.getline(food,20);cout << "Please input drink name:";getline(cin,drink);return 0; }在引入string之前,C++就有istream類,因此沒有考慮到string類型,所以沒有處理string對(duì)象的方法,因此字符串常量采取cin.getline(),而string對(duì)象采取getline()。
4.3.4 其他形式的字符串字面值
① 類型wchar_t,C++11還新增了char16_t 和 char32_t,分別用前綴L、u和U表示
wchar_t food[] = L"Sssnjk JHbuihbi";
char16_t food2[] = u"Sssnjk JHbuihbi";
char32_t food3[] = U"ssnjk JHbui";
② C++11 還新增原始(raw)字符串,在原始字符串中,字符表示的就是自己,比如轉(zhuǎn)義序列 \n不再是換行符而是獨(dú)立的 \ 和 n。原始字面符將 "( 和 )"用作界定符,并在前標(biāo)R標(biāo)識(shí)。
4.4 結(jié)構(gòu)簡(jiǎn)介
結(jié)構(gòu)是一種比數(shù)組更靈活的數(shù)據(jù)格式,同一個(gè)結(jié)構(gòu)可以存儲(chǔ)多種類型的數(shù)據(jù)。
定義結(jié)構(gòu):
結(jié)構(gòu)的初始化
fish Fish ={"carp",3,4.2};//使用逗號(hào)分隔,并用花括號(hào)括起,C++11中(=)可選并且不允許縮窄轉(zhuǎn)換,而且花括號(hào)可以為空。結(jié)構(gòu)內(nèi)可以使用string對(duì)象,但是必須讓結(jié)構(gòu)訪問名稱空間std,可以將using放在結(jié)構(gòu)聲明之前或者采取 std::string name。
4.4.1 結(jié)構(gòu)數(shù)組
fish Fishs[20]; 此時(shí)Fishs是一個(gè)fish數(shù)組,其中的每個(gè)元素都是fish的對(duì)象,Fishs本身是個(gè)數(shù)組,而不是結(jié)構(gòu)
結(jié)構(gòu)數(shù)組的初始化:
fish Fishs[2] = {{"carp",2,1.9},{"salmon",4,6.7}};4.5 共用體(聯(lián)合)
共用體(union)是一種數(shù)據(jù)形式,能夠存儲(chǔ)不同的數(shù)據(jù)類型,但只能同時(shí)存儲(chǔ)一種類型,語法與結(jié)構(gòu)類似。
union world{int cnt;double money;long maximum;};//共用體的長度為最大成員的長度4.6 枚舉
enum color {red, orange, yellow, green, blue, violet, indigo};red、orange、yellow等作為符號(hào)常量,對(duì)應(yīng)整數(shù)值0~6,常量叫枚舉量,枚舉量為整型,可被提升為int型。
4.7 指針與自由存儲(chǔ)空間
指針是一個(gè)變量,其存儲(chǔ)的是值的地址,而不是值本身。 *運(yùn)算符成為解引用運(yùn)算符,應(yīng)用于指針。
int cnt = 8;int *pcnt;pcnt = &cnt;//對(duì)變量cnt取址,并賦予pcntint *ptr = &cnt/*還有簡(jiǎn)潔寫法*/? 指針的聲明需要與*聯(lián)合使用,不能省略
int *ptr,str;//此時(shí)聲明了一個(gè)str變量與一個(gè)指向int型的指針ptr4.7.1 分配內(nèi)存
C語言中分配內(nèi)存采用malloc()函數(shù),C++也可以采用這個(gè),同時(shí)還有更好的辦法 — new運(yùn)算符。
TypeName *pointer_name = new typename
#include<iostream> int main() {using namespace std;int cnt = 200;int *ptr = new int;*ptr = 200;cout << "cnt = " << cnt <<" location cnt = " << &cnt << endl; //cnt = 200 location cnt = 0x7ffe1ed8b8c4cout << "*ptr = " << *ptr << " location ptr = " << ptr <<endl;//*ptr = 200 location ptr = 0x108d010cout << "sizeof cnt = " << sizeof(cnt) << endl;//sizeof cnt = 4cout << "sizeof *ptr = " << sizeof(*ptr) << endl;//sizeof *ptr = 4cout << "sizeof ptr = " << sizeof(ptr) <<endl;//sizeof ptr = 8 ,64位機(jī)器的編譯器指針大小為8byte,32位則為4bytereturn 0; }4.7.2 釋放內(nèi)存
C語言中與malloc()對(duì)應(yīng)的釋放內(nèi)存函數(shù)為free(),C++中則用delete()。
int *ptr = new int;delete ptr;注意:delete必須指向new的指針對(duì)應(yīng)的內(nèi)存,只會(huì)釋放ptr指向的內(nèi)存但不會(huì)把指針ptr本身刪除,delete與new配對(duì)使用,否則會(huì)導(dǎo)致內(nèi)存泄漏,被分配的內(nèi)存再也無法使用,如果內(nèi)存泄露嚴(yán)重,程序?qū)⒂捎诓粩鄬ふ腋鄡?nèi)存而終止。delete不能用于釋放聲明變量所獲的內(nèi)存。
4.7.3 new 與 動(dòng)態(tài)數(shù)組
數(shù)組分配內(nèi)存的格式:
typename *pointername = new typenamep[num];
數(shù)組釋放內(nèi)存格式:
delete [] ponitername;
上述代碼中,可以用數(shù)組表示法表示數(shù)組中元素的值 cout << "ptr[2]= " << ptr[3] <<endl;,也可以用指針表示法表示cout << "ptr[2]= " << *(ptr+2) << endl;
4.7.4 new 與 結(jié)構(gòu)
new用于結(jié)構(gòu)首先需要?jiǎng)?chuàng)建一個(gè)結(jié)構(gòu),然后訪問其成員
#include<iostream>struct fish{char name[20];int num;};int main(){using namespace std;fish *ptr = new fish;//new創(chuàng)建內(nèi)存cout<<"Enter name of fish: ";cin.getline(ptr->name,20);//指針表示法表示結(jié)構(gòu)cout<<"Enter num of fish: ";cin>>(*ptr).num;//常規(guī)結(jié)構(gòu)表示法,*ptr是fish結(jié)構(gòu)本身cout<<"NAME: "<<(*ptr).name<<endl;cout<<"NUM: "<<ptr->num<<endl;delete ptr;//釋放結(jié)構(gòu)內(nèi)存return 0;}4.7.4.1 new與結(jié)構(gòu)數(shù)組
structname *pointname = new structname[num]
struct fish{char name[20];int num;}fish *pfish = new fish[2];//new結(jié)構(gòu)數(shù)組4.8 數(shù)組的替代品
4.8.1 模板類vector
模板類vector類似于string類,自動(dòng)完成new與delete的內(nèi)存管理,是new創(chuàng)建動(dòng)態(tài)數(shù)組的替代品。要使用vector對(duì)象,頭文件包含vector并且存在于名稱空間std中,因此使用using編譯或者using聲明或者std::vector。
聲明格式:
vector name(num); num可以是整型常量或者整型變量。
4.8.2 模板類array(C++11)
創(chuàng)建array對(duì)象需要array頭文件,以及名稱空間std,與數(shù)組一樣,array對(duì)象長度固定,使用棧(靜態(tài)內(nèi)存分配),效率與數(shù)組相同,但array可以對(duì)數(shù)組進(jìn)行直接賦值,arr1=arr2;
聲明格式:
array<typename,num>name;,num只能為整型常量。
總結(jié)
以上是生活随笔為你收集整理的2020 我的C++的学习之路的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文件安全传输服务器,安全传输:从文件加载
- 下一篇: 2020 我的C++学习之路 C++Pr