C++復合類型 (CPP Chapter4)

基于基本類型和浮點類型創建(C語言:派生類型)

1.數組(簡介)

1.數組聲明?? ·存儲在每個元素中的值的類型? ·數組名 ? ·數組中的元素量

??????????????????? typeName? arrayName[arraySize];

2.數組初始化 C++11初始化? ·可省略等號·大括號不包含任何東西所有元素置為零·列表初始化禁止窄縮轉換

3.C++標準模板庫(STL)提供了一種數組代替品——模板類vector

2.字符串

C++處理字符串的方式有兩種,第一種來自C語言,C-風格字符串,另一種基于string類庫的方法

1.初始化??? ·數組初始化 '\0'? ·字符串常量(字符串字面值)

2.處理字符串的函數根據空字符的位置,而不是數組長度來進行處理,C++對字符串長度沒有限制

?? sizeof運算符指出整個數組的長度,strlen()函數返回的是存儲在數組中的字符串的長度,而不是數組本身的長度,此外,strlen()只計算可見的字符串,不把空字符計算在內

3. cin使用空白來確定字符串的結束位置,這意味著cin 在獲取字符串輸入時只讀取一個單詞 (cin的高級特性)

4.面向行的輸入:getline()

??? istream類,getline()函數讀取整行,它使用通過回車鍵輸入的換行符來確定輸入結尾?

??? 調用: cin.getline()

??? 參數:有兩個參數,第一個參數用來存儲輸入行的數組的名稱,第二個參數是要讀取的字符數。getline成員函數在讀取指定數目的字符或遇到換行符時停止讀取

???? getline()函數每次讀取一行,它通過換行符來確定行尾,但不保存換行符。相反,在存儲字符串時,它用空字符來替換換行符

5.面向行的輸入:get()

??? istream類,該函數有幾種變體,其中一種變體的工作方式與getline相似,接受的參數相同,解釋參數的方式也相同,但是不在讀取并丟棄換行符,而是將其留在輸入隊列中。如果不使用幫助get()不能跨過該換行符

?? 另一種變體,不帶參數的cin.get(),調用讀取下一個字符(處理換行符)

?? 另一種使用方式是將兩個類成員函數拼接起來(合并)

?? cin.get(name. Arsize).get();

?? cin.get(name, Arsize).getline(name2, Arsize);

?? cin.get(name, Arsize)返回一個cin對象,該對象隨后將被用來調用get()函數

?? C++允許函數有多個版本,條件是這些版本的參數列表不同——函數重載

6.老式實現沒有getline(),get()使輸入更仔細,例如,假設用get()將一行讀入數組中,如何知道停止讀取的原因是 由于已經讀取了整行,而不是由于數組已填滿。查看下一個輸入字符,如果是換行符,說明已經讀取了整行,否則,說明該行中還有其他輸入。(17章updateing)getline()使用簡單,但get()使得檢查錯誤更簡單些

7.空行和其他問題(5章,6章, 17章updating)?? p81

?? 當getline()或get()讀取空行時,將發生什么

?? 當get()讀取空行后將設置失效位(failbit)這意味著接下來的輸入將被阻斷,但可以用cin.clear()恢復輸入

?? 另一個問題是,輸入行包含的字符數比指定的多,getline()和get()將把余下的字符留在輸入隊列之中,而getline()還會設置失效位,并關閉后面的輸入

8.混合輸入字符串和數字

??? 混合輸入數字和面向行的字符串會導致問題,讀取數字后,回車鍵生成的換行符留在了輸入隊列中,讀取面向行的字符串前應先讀取并丟棄換行符

??? cin.get();

??? cin.get(ch);

3.String類 (簡介)

?????? 使用string類的對象來存儲字符串,string類使用比數組簡單,提供了將字符串作為一種數據類型的表示方法。使用string類要在頭文件中包含頭文件string,string類位于名稱空間std中

1.與C-風格字符串異同

??? ·可以使用C-風格字符串來初始化string對象

??? ·可以使用cin將鍵盤輸入存儲到string對象中,cout來顯示string對象

??? ·可以使用數組表示法來訪問存儲法來訪問存儲在string對象中的字符

??? ·最主要區別是,可以將string對象聲明為簡單變量,而不是數組,類設計讓程序可以自動處理string的大小。這使得與使用數組相比,使用string對象更方便,也更安全。從理論上說,可以將char數組視為一組用于存儲一個字符串的char存儲單元,而string類變量是一個表示字符串的實體

2.C++11字符串初始化

??? 允許將列表初始化用于C-風格字符串和string對象

??? string str1? {"Hello World!"};

3.string類的操作

??? 不能將一個數組賦給另一個數組,但是可以將一個string對象賦給另一個string對象

??? 可使用+/+=拼接兩個string對象

??? C-風格字符串???? 頭文件cstring提供C語言庫中的函數

??????????????????? strcpy(charr1, charr2);??? //copy charr2 to charr1

??????????????????? strcat(charr1, charr2);??? //append contents of charr2 to char1

??????????????????? strncpy(charr1, charr2, n);

??????????????????? strncat(charr1, charr2, n);

??????????????????? 后兩個函數接收指出目標數組最大允許長度的第三個參數,因此更為安全

?????????????????? string類具有自動調整大小的功能,能夠避免覆蓋相鄰內存,數據破壞的事情發生

?????????????????? string str1;

?????????????????? char charr[20];

?????????????????? int len1 = str1.size();????????????????????? //類方法,方法是一個函數,只能通過其所屬類的對象進行調用

?????????????????? int len2 = strlen(charr1);???????????? //常規函數,接收一個C-風格字符串為參數,返回字符數

4.string類I/O

??? 未初始化的數組的內容是未定義的,未被初始化的string對象的長度被自動設置為零。

??? cin.getline(charr, 20);

??? getline(cin,? str1);???? /*不是一個類方法,istream中有處理double、int和其他基本類型的類方法,但沒有處理string對象的類方法。將cin作為參數,指出到哪里去查找輸入。沒有指出字符串長度的參數,因為string對象根據字符串的長度自動調整自己的大小。*/

?? cin >> x;????? //使用istream類的一個成員函數

?? cin >> str;??? //使用string類的一個友元函數?? (updating)

5.其他形式的字符串字面值

?? wchar_t? title[] = L''Chief Astrogator";????????????????? //wchar前綴?? L

?? char16_t name[]? = u"Felonia? Ripova";??????????????? //char16_t前綴? u

?? char32_t? car[]? =? U"Humber Super Snipe";??????? // char32_t前綴? U

? (unfinshed)

4.結構(簡介)

?? 結構是一種比數組更靈活的數據格式,因為同一個結構可以存儲多種類型的數據。

?? 結構是用戶定義的類型,而結構聲明定義了這種類型的數據屬性。定義了類型后,便可以創建這種類型的變量。創建結構包括兩步,首先,定義結構描述——它描述并標記了能夠存儲在結構中的各種數據類型。然后按照描述創建結構變量(結構數據對象)。

?? struct? inflatable

?? {

???????? char name[];????????????????? //結構的成員 , 聲明語句

???????? float volume;

???????? double? price;

?? };

inflatable?? hat;??????? //inflatable類型的變量

C++允許在聲明結構變量時省略關鍵字struct,在C++中結構標記的用法與基本類型名相同。訪問成員函數的方式是從訪問結構成員變量(eg : hat.volume)的方式衍生而來的。

C++不提倡使用外部變量,但提倡使用外部結構聲明,另外,在外部聲明符號變量通常更合理

1.初始化

?? 和數組一樣,使用由逗號分割值列表,并將這些值用花括號擴起。

?? C++結構初始化??? 等號可選,其次,如果大括號內未包含任何東西,各個成員都將被設置為零,C-風格字符串每個字節都被設置為零,最后,不允許縮窄轉換

?? 如果編譯器支持對以string對象作為成員的結構進行初始化,可以使用string對象而不是字符數組(std::string? str)

2.其他結構屬性

?? C++使用戶自定義的類型與內置類型盡可能相似。

?? 可以將結構作為參數傳遞給函數,可以返回一個結構。

?? 可以使用賦值運算符將結構賦給另一個同類型的結構,即使成員是數組,這種賦值被稱為成員賦值

?? (傳遞返回結構)

??? 可以同時完成定義結構和創建結構變量的工作,只需將變量名放在結束括號的后面即可。

?? ? struct? inflatable

?? {

???????? char name[];?????????????????

???????? float volume;

???????? double? price;

?? }hat,? key;????????????????????? //two variable

可以初始化這樣創建的變量

??? struct? inflatable

?? {

???????? char name[];?????????????????

???????? float volume;

???????? double? price;

?? }hat? =??

{

??????? "Key",

????? ?? 6.0,

????? ?? 8.7,

};?????????????

還可以聲明沒有名稱的結構類型,方法是省略名稱,同時定義一種結構類型和一個這種類型的變量。

struct

?? {

???????? char name[];?????????????????

???????? float volume;

???????? double? price;

?? } key;

這樣將創建一個名為key的結構變量,可以使用成員運算符來訪問它的成員,但這種類型沒有名稱,因此以后無法創建這種類型的變量。 ?????????????

與C結構不同,C++結構除了成員變量之外,還可以有成員函數,但這些高級特性通常被用于類中,而不是結構中。(Updating)

3.結構數組

可以創建元素為結構的數組

初始化:結合初始化數組和初始化結構的規則

4.結構中的位字段

與C語言一樣,C++也允許指定占用特定位數的結構成員,這使得創建與某個硬件設備上的寄存器對應的數據結構非常方便。字段的類型應為整型或枚舉。冒號后面是一個整數,指定了使用的位數。可以使用沒有名稱的字段來提供間距,每個成員都被稱為位字段。

struct? torgle

{

unsigned int? SN :?? 4;

unsigned? int :? 4;???????? //4bits? unused

bool?? goodIn? :?? 1;

}

可使用標準的結構表示法來訪問位字段。

位字段通常用在低級編程中,一般來說,可以使用整型和按位運算符來代替這種方式。(附錄E?? updating)

5.共用體

共用體(union)是一種數據格式,它能存儲不同的數據類型,但只能同時存儲其中的一種類型。

union? one

{

int?? int_val ;

long?? long_val;

double?? double_val;

};

one? pail;

pail.int_val ? = ? 35;

cout << pail.int_val;

pail.double_val? =? 98.75;

cout<<pail.double_val;

共用體的長度為其最大成員的長度,共用體的用途之一是,當數據項使用兩種或更多格式但不會同時使用時,可節省空間。

匿名共用體沒有名稱,其成員將成為位于相同地址處的變量

struct? widget

{

char?? brand[];

int?? type;

union

??? {

??????????? long??? id_num;

??????????? double? id_char[];

??? };

};

widget prize;

if(prize.type?? ==?? 1)

?????????? cin>>prize.id_num;

?else

?????????? cin>>prize.id_char;

共用體常用于節省內存,此外,共用體常用于操作系統數據結構或硬件數據結構。

6.枚舉

C++的enum提供了另一種創建符號常量的方式,這種方式可以代替const,它還允許定義新類型,但必須按嚴格的限制執行。

enum spectrum {red,? orange,? yellow,? greeen, blue,? violet,? indigo,? ultraviolet};

這條語句中,spectrum成為新類型的名稱:枚舉,將red,yellow等作為符號常量,他們對應整數值0-7,這些常量叫做枚舉量。在默認的情況下,將整數值賦給枚舉量,第一個枚舉量的值為0,第二個為1,以此類推可以通過顯式的指定整數值來覆蓋默認值,在不進行強制性類型轉化的情況下,只能將定義枚舉時使用的枚舉量賦給這種枚舉的變量。spectrum變量只有八個可能的值,為了獲得最大程度的可移植性,應將把非enmu值賦給enum變量視為錯誤(有些編譯器出現錯誤,有些編譯器警告)。

對于枚舉,只定義了賦值運算符,沒有為枚舉定義算術運算。(有些實現沒有這種限制,這有可能導致反類型限制)

spectrum?? band;

band = blue;

枚舉量是整型,可被提升為int類型,但int類型不能自動轉化為枚舉類型。(可將枚舉賦給int,但不能把int類型賦給枚舉類型,有些實現沒有這種限制)枚舉可以轉換為int類型,因此可以在算數表達式中同時使用枚舉和常規整數,盡管并沒有為枚舉本身定義算數運算。

band? =? orange? +? red;?? //? not? valid.? 相當于將一個int類型賦給枚舉量

如果int值有效,則可以通過強制類型轉換,將它賦給枚舉變量:

band? = spectrum(3);

如果將一個不適當的值進行強制類型轉換,結果是不確定的,這么做不會出錯,但結果不可用。

枚舉常被用來定義相關的符號常量,而不是新的類型,如果只打算使用常量,而不創建枚舉類型的變量,則可省略枚舉類型的名稱

enum{ red,? orange,? yellow,? greeen, blue,? violet,? indigo,? ultraviolet }

1.設置枚舉量的值

??? 可以使用賦值運算符來顯式地設置枚舉量的值,指定的值必須是整數,也可以只顯式地定義其中一些枚舉量的值,后面沒有被初始化的枚舉量的值將比其前面的枚舉量大1,可以創建多個值相同的枚舉量。在C++早期版本中只能將int值(或提升成int的值)賦給枚舉量,但這種限制取消了,因此可以使用long甚至longlong類型的值。

2.枚舉的取值范圍

??? 最初對于枚舉來說,只有聲明中指出的那些值是有效的,然而,C++現在通過強制類型轉換,增加了可賦給枚舉變量的合法值。每個枚舉變量都有取值范圍(range),通過強制類型轉換,可以將取值范圍內的任何整數值賦給枚舉變量,即使這個值不是枚舉值。

???? 取值范圍如下

???? 上限:找到枚舉量的最大值,找到大于這個最大值的、最小的2的冪,將它減去1,得到的便是取值范圍的上限

????? 下限:找到枚舉量的最小值,如果它不小于0,則取值下限為0;否則,與上限方式相同,但加上負號;

????? 選擇用多少空間來存儲枚舉由編譯器決定,對于取值范圍較小的枚舉,使用一個字節或更小的空間,而對于包含long類型值的枚舉,則使用4個字節。

3.

??? C++11擴展了枚舉,增加了作用域內枚舉


7.指針(指針、數組、自由存儲空間)

(此部分內容整合進C++專項中,C++數組和C++指針。)

計算機程序在存儲數據中必須跟蹤的三種基本屬性:

·信息存儲在何處

·存儲的值為多少

·存儲的值是什么類型

定義一個簡單變量時,聲明語句指出了值的類型和符號名,還讓程序為值分配內存,并在內部跟蹤該內存單元。使用常規變量時,值是指定的量,而地址為派生量。使用指針策略時,將地址視為指定的量,而將值視為派生量。指針是C++內存管理編程理念的核心。

指針與C++基本原理:??????????? 面向對象編程與傳統的過程性編程的區別在于,OOP強調的是在運行階段而不是編譯階段做決策。運行階段決策提供了靈活性。在運行階段做決策并非OOP獨有的,但使用C++編寫這樣的代碼比使用C簡單。

例如:為數組分配內存時,聲明數組,指定數組長度為編譯階段決策;使用OOP時,在運行階段決定數組的長度。為使用這種方法,語言必須允許在程序運行時創建數組,C++采用的方法是,使用關鍵字new請求正確數量的內存以及使用指針跟蹤新分配的內存的位置。

1.聲明和初始化指針

?? typename? *?? pointerName;

??? int*? ptr;???????????????????? //在C++中,int*是一種類型——指向int的指針

??? int* ptr1,? ptr2;??????? //創建一個指針,和一個int變量。對每個指針變量名,都需要使用一個*

??? 和數組一樣,指針都是基于其他類型的

??? 在聲明語句中初始化指針,被初始化的時指針,而不是它指向的值

??? int higgens = 5;

??? int*? ptr? =? &higgens;

??? 指針的危險:???? 在C++中創建指針時,計算機將分配用來儲存地址的內存,但不會分配用來存儲指針所指向的數據的內存。使用指針時,先初始化,再解引用。

??? 指針不是整型,雖然計算機通常把地址當作整數來處理。不能簡單地將整數賦給指針,要將數字值作為地址來使用,應通過強制類型轉換將數字轉換為適當的地址類型:

???? int*? ptr;

???? ptr = (int*) 0xB8000000;

???? ptr是int值的地址并不意味著ptr本身的類型是int

2.使用new來分配內存(使用指針來管理運行階段的內存空間分配)

??? 指針真正的用武之地在于 : 在運行階段分配未命名的內存以存儲值。在這種情況下,只能通過指針來訪問內存

??? 在C語言中,可以用庫函數malloc()來分配內存;在C++仍然可以這樣做,但還有更好的方法——new運算符

? ? 在運行階段為一個int值分配未命名的內存,并使用指針來訪問這個值。要告訴new需要為哪種數據類型分配內存;new將找到一個長度正確的內存塊,并返回其地址,將該地址賦給一個指針。

??? typeName*? pointer_name? =? new ? typeName;????????? //為一個數據對象獲得并指定分配內存的通用格式

??? 該pointer指向一個數據對象,"數據對象"比"變量"更通用,它指的是為數據項分配的內存塊。

??? 處理數據對象的指針方法使程序在管理內存方面有更大的控制權。

??? new分配的內存塊通常與常規變量聲明分配的內存塊不同,常規聲明的變量都存儲在被稱為棧(stack)的內存區域中;而new從被稱為堆(heap)或自由存儲區(free store)的內存區域分配內存。

??? 計算機可能會由于沒有足夠的內存而無法滿足new的請求,這種情況下,new通常會引發異常(錯誤處理),在較老的實現中,new將返回0. 在C++中,值為0的指針被稱為空指針(null? pointer)。C++確保空指針不會指向任何有效的數據,因此它常被用來表示運算符或函數失敗,如果成功,將返回一個有用的指針。可檢測處理分配內存失敗。

3.使用delete釋放內存

??? 當需要內存時,可以使用new來請求,這只是C++內存管理數據包中有魅力的一個方面,另一個方面是delete運算符,它使得在使用完內存后,能夠將其歸還給內存池這是通向最有效的使用內存的關鍵一步。歸還獲釋放的內存可供程序的其他部分使用。

????? in*? ps? =?? new? int;

????? delete ps;

???? · 這將釋放ps指向的內存,但不會刪除指針ps本身。

???? ·要配對的使用new和delete,否則將發生內存泄漏,也就是說,被分配的內存再也無法使用了。如果內存泄漏嚴重,則程序將由于不斷尋找更多內存而終止。

????? ·不要釋放已經釋放的內存塊,C++標準指出,這樣做的結果是不確定的,這意味著什么情況都有可能發生。

????? ·不能使用delete來釋放聲明變量所獲得的內存

????? ·只能用delete來釋放使用new分配的內存。然而,對空指針使用delete是安全的

????? ·使用delete的關鍵在于,將它用于new分配的內存。這并不意味著要使用用于new的指針,而是用于new的地址

????? ·不要創建兩個指向同一個內存塊的指針,這將增加錯誤地刪除同一個內存塊兩次的可能性

4.使用new來創建動態數組

????? 通常,對于大型數據(如數組,字符串和結構),應使用new。

???? 編譯時給數組分配內存被稱為靜態聯編,但使用new時,如果在運行階段需要數組,則創建它,如果不需要,則不創建。還可以在程序運行時選擇數組的長度,這被稱為動態聯編。這種數組被稱為動態數組。

1.使用new創建動態數組

??? int*? psome? = new? int[100];

??? new運算符返回第一個元素的地址

??? 當程序使用完new分配的內存塊時,應使用delete釋放它們

??? delete[]?? psome;???????????????????? //格式匹配

??? psome是指向一個int的指針,必須讓程序跟蹤內存塊中的元素個數,以便以后使用delete[]運算符時能正確的釋放這些內存。但這些信息不是公用的,例如,不能使用sizeof運算符來確定動態分配的數組包含的字節數

??? type_name?? *??? pointer_name?? =?? new?? type_name [num_elements];?? //通用格式

2.使用動態數組

??? 將指針名當作數組使用 ??

??? C和C++內部都用指針來處理數組

??? 不能修改數組名的值,但是指針是變量,因此可以修改它的值。

5.指針、數組和指針算數

指針和數組基本等價的原因在于指針算數(pointer-arithmetic)和C++內部處理數組的方式。

在多數情況下,C++將數組名解釋為數組第一個元素的地址。

指針變量加1,其增加的值等于指向的類型占用的字節數

通常,使用數組表示法(包括使用指針),C++將執行以下轉換:

???????? arrayname[i]??? becomes? *(arrayname + i)

???????? pointername[i] ?? becomes ? *(arrayname + i)

因此,在很多情況下,可以相同的方式使用指針名和數組名。對于它們,可以使用數組方括號表示法,也可以使用解除引用運算符。在多數表達式中,它們都表示地址。區別之一是,可以修改指針的值,而數組名是常量。另一個區別是,對數組應用sizeof運算符得到的是數組的長度,而對指針應用sizeof得到的是指針的長度,即使指針指向的是一個數組,這種情況下,C++不會將數組名解釋為地址。

數組的地址:????? 數組名被解釋為其第一個元素的地址,而對數組名應用地址運算符時,得到的是整個數組的地址。

int? tell[10];

cout ? << ? tell ? <<? endl; ? ? ? ? ? ? //displays? &tell[0]

cout?? <<? &tell? <<? endl;?????????? // displays? address of whole? array

int (*pas)[10] = &tell;?????????????? //pas? points? to? array? of 10? int

int*? pas[10]??????????????????????????????? //an? array? of? pointer to?? int

1.對指針解除引用

?? 對指針解除引用意味著獲得指針指向的值,對指針應用間接值運算符,另一種對指針解除引用的方法是使用數組表示法,千萬不能對未被初始化為適當地址的指針解除引用。

2.指針算數

??? C++允許將指針和整數相加,加1的結果等于原來的地址值加上指向的對象占用的總字節數。還可以將一個指針減去另一個指針,獲得兩個指針的差。僅當兩個指針指向同一個數組時,這種運算才有意義。

3.數組的動態聯編和靜態聯編

?? 靜態聯編:使用數組聲明來創建數組,即數組的長度在編譯時設置

?? 動態聯編:使用new[]運算符創建數組,運行時分配空間,其長度也在運行時設置。使用完這種數組,應使用delete[]釋放其占用的內存。

4.數字表示法和指針表示法

6.指針和字符串

1.

數組和指針的特殊關系可以擴展到C-風格字符串

在C++中,用引號括起的字符串像數組名一樣,也是第一個元素的地址

對于數組中的字符串,用引號括起的字符串常量以及指針所描述的字符串,處理的方式是一樣的,都將傳遞它們的地址

字符串字面值是常量,有些編譯器將字符串字面值視為只讀常量,可以訪問,但不能修改,如果試圖修改,將導致運行階段錯誤。最好使用const關鍵字(const指針)

有些編譯器只使用字符串字面值的一個副本來表示程序中所有的該字面值,C++不能保證字符串字面值被唯一的存儲。如果是以上情況,將值讀入一個字符串,可能會影響被認為是獨立的為位于其他地方的字符串。

在將字符串讀入程序時,應使用已分配的內存地址。該地址可以是數組名,也可以是new初始化的指針,不要使用字符串常量或未被初始化的指針來接收輸入。為避免這些問題,可以使用一個足夠大的char數組或使用std::string對象

2.如何獲得字符串的副本

首先,需要分配內存來存儲該字符串,可以通過聲明另一個數組或者使用new來完成。

ps = new? char[strlen(array) + 1];???????????????? //不會浪費空間

不能將array直接賦給ps,這樣只能修改存儲在ps中的地址,從而失去程序訪問新分配內存的唯一途徑,需要使用庫函數strcpy():

strcpy(ps,? array);

獲得array的兩個獨立副本,new在離animal數組很遠的地方找到了所需的內存空間。

strcpy/strncpy

7.使用new創建動態結構

在運行時創建數組優于在編譯時創建數組,對于結構也是如此。通過使用new,可以創建動態結構

將new用于結構由兩步構成:創建結構和訪問其成員。

創建動態結構時,不能將成員運算符句點用于結構名,因為這種結構沒有名稱,只知道它的地址。

C++專門為這種情況提供了一個運算符:箭頭成員運算符(->),可用于指向結構的指針。

另一種訪問結構成員的方法是,如果ps是指向結構的指針,則*ps就是被指向的值——結構本身,因此(*ps).price是該結構的price成員。C++的運算符優先規則要求使用括號。

8.自動存儲、靜態存儲和動態存儲

根據用于分配內存的方法,C++有三種管理數據內存的方式:自動存儲、靜態存儲和動態存儲(自由存儲存儲空間、堆),C++11新增了第四種類型——線程存儲。(9章)

1.自動存儲

在函數內部定義的常規變量使用自動存儲空間,被稱為自動變量,這意味著它們在所屬的函數被調用的時候產生,在該函數結束是消亡。實際上,自動變量是一個局部變量,其作用域為包含它的代碼塊。

自動變量通常存儲在中。這意味著執行代碼塊時,其中的變量將依次加入到棧中,而在離開代碼塊時,將按相反的順序釋放這些變量,這被稱為先進后出。因此,在程序執行的過程中,棧將不斷的增大和縮小。

2.靜態存儲

靜態存儲是整個程序執行期間都存在的存儲方式。是變量成為靜態的方式由兩種:一種是在函數外面定義它;另一種是使用關鍵字static。

在K&RC中,只能初始化靜態數組和靜態結構,而C++Release2.0及后續版本和ANSIC中,也可以初始化自動數組和自動結構。然而,有些C++實現還不支持對自動數組和自動結構的初始化。

自動存儲和靜態存儲的關鍵在于,這些方法嚴格地限制了變量的壽命。

3.動態存儲

new和delete提供了一種比自動和靜態變量更靈活的方法。它們管理了一個內存池,這在C++中被成為自由存儲空間或堆。該內存池同用于靜態變量和自動變量的內存是分開的。數據的聲明周期不完全受程序或函數的生存時間控制。與使用常規變量相比,使用new和delete讓程序員對程序如何使用內存有更大的控制權。然而,內存管理也更加復雜了。在棧中,自動添加和刪除機制使得占用的內存總是連續的,但new和delete的相互影響可能導致占用的自由存儲區不連續,這使得跟蹤新分配內存的位置更困難。

4.棧、堆和內存泄漏

8.類型組合

9.數組的代替品

模板類vector/array(C++11)

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

推薦閱讀更多精彩內容

  • 淺談C++常用輸入輸出 在編寫C++程序的時候,經常因為輸入輸出頭疼,所以在這里做一個小結,記錄一下常用的輸入輸出...
    MinoyJet閱讀 3,758評論 0 6
  • 第一章 計算機與C++編程簡介 C++程序6個階段編程 ->預處理->編譯->連接->裝入->執行1.程序在編譯器...
    rogertan30閱讀 3,928評論 0 1
  • C/C++輸入輸出流總結 前兩天寫C++實習作業,突然發現I/O是那么的陌生,打了好長時間的文件都沒有打開,今天終...
    LuckTime閱讀 1,747評論 0 6
  • 一、Java 簡介 Java是由Sun Microsystems公司于1995年5月推出的Java面向對象程序設計...
    子非魚_t_閱讀 4,225評論 1 44
  • 希望你能快點長大,在我還能等待你的日子里,我喜歡和你嬉鬧,喜歡和你瘋耍,但我卻知道最終會選擇的不是一位玩伴,我需要...
    免辣閱讀 153評論 0 0