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