C++復合類型

Tags:C++,《C++ Primer Plus》筆記


一、分類##

如下圖,大概分為這些類型,每種類型的聲明語法已列出,當然不同類型可能有多種賦值方式。

ICP structures
ICP structures

</br>

二、數組類##

</br>

數組###

數組有兩種賦值的方法,另外,尤其需要注意數組不能復制給另一個數組:

  • 第一種:先聲明,然后用索引依次賦值。
int yams[3];
yams[0] = 1;
yams[1] = 2;
yams[2] = 3;
int no[] = yams; //非法的!

由于數組名其實是指針,因此訪問沒賦值的元素會返回內存的地址。

  • 第二種:采用列表賦值法,不支持縮窄轉化,默認值為0。
int yams[3] = {1,2}; //yams[2] = 0;

</br>

vector###

vector 本意為模板類,之后還要深入學習。這里只需要知道它可以作為數組的替代品,封裝的功能更強大,但耗費的性能更多。

  • 需要頭文件 <vector>
  • 對象存儲在自由存儲區(堆)中。
  • 允許超界索引,比如 yams[-2],本質指針是指針移動越界指向了其他(非 yams)內存,但不會報錯,返回蜜汁結果。可以用成員函數 at() 來避免越界,這樣越界時會報錯。

</br>

array###

array 是類似于 string 的存在,其行為類似于JS中的 array

  • 需要頭文件 <array>
  • 對象存儲在自動存儲區(棧)中。
  • 允許超界索引,比如 yams[-2],本質指針是指針移動越界指向了其他(非 yams)內存,但不會報錯,返回蜜汁結果。可以用成員函數 at() 來避免越界,這樣越界時會報錯。

</br>

三、字符串##

</br>

char數組字符串###

本質上其實是 char 類型的數組。通過字符串常量賦值。

  • 注意 "string" 是字符串常量,不是字符常量。只能賦給 char 數組和 string 類,不能賦給 char變量。
  • 數組中默認值(多余的部分)會用 \0(空字符)填充。coutcin 輸入輸出時以 \0 作為結尾。因此注意數組長度要為字符串長度+1。
  • 頭文件 <cstring> 中提供一些字符串常量相關的方法。其中 strlen() 可以獲取字符串的長度。
  • 連起來的字符串常量會自動拼接連起來,后一個的第一個字符取代前一個的最后一個空字符。
  • 因為數組不能參與運算,所以使用 strcpy(a,b,size) 將b字符串數組復制給 a ;或使用 strcat(a,b,size)b 字符串數組裁接在 a 后面。sizetarget 最大長度。

</br>

string類###

類似于JS中string類型,使用非常方便的字符串類。

  • 支持賦值運算符 = 和列表賦值法 {} 進行賦值。
  • 支持拼接和附加。

</br>

字符串Input###

對于 cinchar 數組字符串 ,在Input操作時時遇到空字符 \0 即停止操作。可用 getline(target,size)get(target,size) 直接讀取輸入的 size 長度或一行,并返回一個新的 cin 對象。

對于 string 類字符串,直接封裝有函數 getline(cin,str) ,將隱式創建一個 cin 流,并將輸入直接賦給 str

區別在于前者會拿走換行符,后者會保留換行符,因此后者第二次讀取時為空,此時可用 get() 跳過下一字符。

</br>

四、結構##

C++中的結構相當于聲明一種全新的數據類型,且與C不同,使用時可以省略 struct

當創建一個結構后,可以通過成員運算符 . 進行成員訪問,初始化時可以一一賦值,但建議使用列表賦值法。

struct inflatable {
    char name[20];
    float colume;
    double price;  //聲明時注意用分號
    unsigned int SN : 4; //可以用比號設置成員的位數
}
inflatable guest = { //C中為struct inflatable guest
    "Glorious Gloria",
    1.88,
    29.99  //列表賦值用逗號
}

</br>

五、共用體##

共用體實際上是一個內存地址,其可能的成員共用該一地址,因此同一時刻只能給其中一個成員賦值。

匿名共用體可以省略共用體標識符。

struct widget {
 char brand[20];
 int type;
 union{
    long id_num;
    char id_char[20];
 };
};
widget prize;
if(prize.type == 1)
    cin >> prize.id_num;
else
    cin >> prize.id_char;

</br>

五、枚舉#

enum 工具用于創建符號常量,被枚舉類型聲明的量只能取其定義枚舉類型時的枚舉值,且枚舉值不需要再額外聲明。比如:

enum spectrum {red,orange,yellow,green,blue};
spectrum band = yellow;

需注意以下幾點:

  • 枚舉量也屬于整型的一種,可以提升為int類型,但int類型不能自動轉化為整型,只能強行轉化。
    比如:
band = 3 + red;  //No!red被轉化為int,int + int = int,int不能賦給spectrum band。
band = spectrum(3);  //OK
  • 枚舉值默認從0開始,依次+1,但可以設置枚舉值:
enum bits{one = 1,two = 2,four = 4};
  • 一個枚舉值的范圍為大于其最大枚舉值的最小2次冪。如最大值為7,則枚舉范圍為2^3 = 8

</br>

六、指針#

</br>

指針賦值###

指針是個稍微復雜些的東西,簡單來說,指針就是儲存了一個值的內存地址。

我們通過 typeName* pointName 聲明一個指針。其中 * 為解除引用運算符,對指針使用時返回其內存地址對應的值。

對于任意值,用地址運算符 & 可以返回該值的內存地址。

給指針賦值,有三種方法:

  • 第一種是賦值給 *pointNamepointName 指針會自動指向其地址。比如:
long a = 2233;
long* haha;
*haha = a;
  • 第二種是通過 & 運算符賦值。比如:
int a = 1;
int* pt = &a;
int* pn;
pn = &a;
  • 第三種是通過 new 操作符先指向一個空的堆內存,之后將值寫入內存中:
int* pn = new int;
*pn = 1001; 

因此,對于前兩種方法,賦值時只是把已存在的數據內存地址值復制給指針,其中并沒有申請一個儲存數據內存的過程。這意味著,下面這樣的代碼是無效的:

//無效!必須用已經存儲在內存中的值來賦值。
long* try;
*try = 1122;

long* try;
try = &1122;

long* try = &1122;

而對于第三種,因為 new 專門申請了一塊動態內存,字面量可以儲存于動態內存中,所以沒有這樣的問題。也因為這個特點,new 操作符可以實現動態操作內存。

</br>

指針算術###

數組名本身其實也是一個指針,默認指向第一個元素的內存地址。

int a[] = {1,2,3};
cout << a;
int* b = &a[0];
cout << b; //一模一樣!

所以當指針+1時,指向下一個內存地址,在數組中,就是下一個元素。

數組名與指針的區別只在于:

  • sizeof 的運算結果不同,對數組使用會得到數組的長度。
  • 指針的值可以修改,數組名不可以修改。

字符串也是如此,但要注意的是,如果指針的類型為 char*cout 會將其解析為一個字符串。

</br>

內存分配###

說到指針,就不得不說內存分配。C++有三種內存:

  • 棧內存。又叫自動存儲內存,用于函數的私有作用域。函數結束時,棧內存中的存儲值即消失,這一點和JS相同。
  • 靜態存儲。靜態存儲的變量可以在整個程序生命周期中拿到,因此要么就在函數體外定義它,要么就用 static 前綴定義它。
  • 動態存儲。為了使程序員對內存的使用有更大的權力,C++引入了動態存儲,相當于堆內存。它通過 new 來申請,delete 來刪除。如果不刪除,在程序結束后動態內存甚至還在被占用,這就導致了內存泄漏。

</br>

動態內存###

指針的重要性就在于,當它與 new 結合起來的時候,就提供了實現自動調整數組大小、自動創建復合類型的可能。

比如,與數組結合起來,可以根據輸入創建動態大小的數組:

int size;
cin >> size;
int* pn = new int[size];
...
delete [] size;

與字符串的 strlen() 方法結合,也可以根據輸入創建動態大小的字符串:

char animal[100];  //臨時寄存的數組,在棧內存中
cin >> animal;
int* pn = new char[strlen(animal)+1];
strcpy(pn,animal); //不能直接把animal賦過去,否則函數結束就拿不到了
delete [] pn;

C++還提供了箭頭成員運算符 ->,可以通過指針訪問其指向結構的成員,當然用成員運算符也行:

struct band {
    char name[20];
    float volume;
};
...
band* pn = new band;
cin >> pn->name;  //method 1
cin >> (*pn).name;  //method 2
delete pn;

強調:為了防止內存泄漏,動態內存操作完后,一定要用 delete 釋放內存!!

最后,指針的學習是一個漫長的過程,更多用法移步后續筆記。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容

  • 指針是C語言中廣泛使用的一種數據類型。 運用指針編程是C語言最主要的風格之一。利用指針變量可以表示各種數據結構; ...
    朱森閱讀 3,464評論 3 44
  • 版權聲明:本文為 gfson 原創文章,轉載請注明出處。注:作者水平有限,文中如有不恰當之處,請予以指正,萬分感謝...
    gfson閱讀 3,127評論 0 6
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,855評論 1 10
  • 一、框架 1、Mac系統及常用工具、進制;C數據類型、常量變量、運算符、表達式、格式化輸入輸出 2、關系運算符、邏...
    師景福閱讀 711評論 0 2
  • 相信在iOS應用里面很常用的功能之一就是視頻錄制了,但是往往系統的錄制界面不是我們想要的,所以這時候就得自定義視頻...
    Geek_zheng閱讀 3,968評論 6 5