詳解C 中的自動儲存

2022-09-25 06:51:14 字數 2365 閱讀 5293

c++有3種管理資料記憶體的方式即自動儲存(棧儲存)、靜態儲存和動態儲存(堆儲存)。在不同的方式下,記憶體的分配形式和存在時間的長短都不同。

下面對自動儲存進行說明。

自動儲存(棧儲存)

對於函式的形參、內部宣告的變數及結構變數等,編譯器將在函式執行時為形參自動分配儲存空間,在執行到變數和結構變數等的宣告語句時為其自動分配儲存空間,因此稱其為自動變數(automatic variable),有的教科書也稱其為區域性變數,在函式執行完畢返回時,這些變數將被撤銷,對應的記憶體空間將被釋放。

事實上,自動變數的生存期只侷限於它所在的**塊。所謂**塊,是包含在花括號對中的一段**,函式只是**塊的一種,比較下面兩段**。

**段1

int add(int m,int n)

**段2

int add(int m,int n)

return z;//錯誤

}在**段1中,當函式返回時,變數z被撤銷,對應記憶體空間被釋放,但在**段2中,在if**塊中宣告的變數z,其生存期僅限於if結構的兩個花括號之間,當程式執行到if結構的後花括號時,變數z已被撤銷,其對應的記憶體空間被釋放,此時,再執行「return z;」語句便會出錯。

注意理解**塊的含義十分重要,花括號不是判斷**塊的唯一標準,把**段2中if結構的花括號去掉,**仍然是錯誤的,將「return z;」放在if結構中是正確的用法。

自動變數的生存期是區域性的,這一特性使得程式設計師可以在不同的塊內使用相同的變數名,用不著為使用不同的變數名絞盡腦yqlsqnkxo汁。

1.什麼是「棧」

棧(stack)是一塊儲存區,而且是c++程式使用最頻繁的儲存區,其儲存機理為「filo」,即先進後出(first in,last out)。可以將其想象成乙個裝盤子的桶,最早放入的盤子在桶的底部,最晚放入的盤子在最頂部,取盤子時必須先從後放進去的盤子開始取,這就是所謂的先進後出原則。當乙個**塊(包括函式,視為一種特殊的程式設計客棧**塊)宣告乙個自動變數時,系統便為其在棧中開闢記憶體空間(常稱「壓入」push),該**塊結束後便將自動變數撤銷,釋放記憶體空間(常稱「彈出」pop)。

注意採用「棧」這種機制,c++程式能有效地節省所用記憶體空間。

2.auto關鍵字

auto是c++提供的儲存類宣告符,用於宣告自動變數,除了auto宣告符外,c++還提供了另外3個儲存類宣告符,分別是register(暫存器儲存)、extern(外部儲存)和static(靜態儲存)。在宣告建立變數時,儲存類宣告符應放在資料型別宣告符之前,如下所示。

儲存類宣告符 資料型別 變數名[=初始化表示式]

其中,初始化表示式是可選的,如下列**宣告建立了int型自動變數a,其只在函式demo()執行期間存在,demo()函式執行完畢後,變數a被撤銷,對應記憶體被釋放。

void demo()

在前面給出的示例**在宣告自動變數時並沒有加auto修飾符,實際上,auto常常可以預設,凡是在函式內部(不論是main()函式還是其他函式)的,沒有用其他顯式的儲存型別宣告符,編譯器都認為是auto型自動變數。

3.register關鍵字

除了auto外,還可以通過儲存類宣告符register來宣告自動變數,與auto唯一的不同在於:關鍵字register通知編譯器,使用者希望通過cpu暫存器,而不是「棧」來處理某個變數,從而可以在一定程度上加快該變數的訪問速度。

提示一般來說,www.cppcns.comcpu對暫存器的訪問要快過對記憶體的訪問。

用register宣告的變數常稱為暫存器變數,舉例來說,下列**宣告了int型暫存器變數sum,並將其初始化為9,如下所示。

register int sum=9;

需要注意的是,即使用register宣告了某個變數,編譯器也不一定會程式設計客棧滿足它的要求。因為,cpu暫存器可能被占用或者無法儲存指定型別的資料等,而且,現在的編譯器一般可以自動決定應把哪些變數放在cpu暫存器中,因此,在c++程式中,register關鍵字很少使用。

使用register關鍵字會帶來一定的負面效果,不管是否能滿足要求,編譯器認為register型自動變數是儲存在cpu暫存器中的,而暫存器是沒有記憶體位址的,所以,不能對register型自動變數進行取位址操作,下列**是錯誤的。

void demo()

注意事實上,用auto和register宣告的變數除了儲存位置不同(乙個是「棧」,而另乙個可能是「棧」也可能是cpu暫存器)外,並無其他差異,我們可以將其統稱為自動變數來考慮。

4.自動變數的初始化

可以在宣告自動變數時對其進行初始化,也可以使用任何具有確定值的表示式為自動變數賦值,下列語句都是合法的(假定n為int型自動變數)。

n=2;

n=5*m;//m的值確定

n=add(4,6);

需要特別注意的是,如果沒有在自動變數宣告的同時對其初始化,其初始值是隨機、不可預料的,為避免隨機的初始值給程式帶來麻煩,推薦在宣告自動變數的同時對其顯式初始化。

C 記憶體中型別的儲存典例詳解

我們前面學習了資料在記憶體中的儲存,包括整型,浮點數等等資料型別。這裡我們簡單舉幾個例子,通過這些典例的講解,希望可以對記憶體有乙個更客觀 更深刻的理解。典例 1 include int main 所以輸出 1 1 255 典例 2 include int main char型別變數a列印為無符號整...

C 筆記 自動儲存 靜態儲存和動態儲存

c 有3中管理資料記憶體的方式 自動儲存 靜態儲存和動態儲存,以這三種方式分配的資料物件各不相同。自動儲存。在函式內部定義的常規變數使用自動儲存空間,稱為自動變數,他們在所屬的函式被呼叫時自動產生,在該函式結束時消亡。自動變數是乙個區域性變數,其作用域為包含它的 塊。自動變數通常儲存在棧中。在執行 ...

C 浮點數在記憶體中的儲存詳解

目錄 程式設計客棧我們在碼 的時候,經常遇到過以整數形式存入,浮點數形式輸出 或者浮點數形式存入整數形式輸出。輸出的結果往往讓人意想不到,那麼,為什麼會發生這樣的變化,又是什麼導致發生變化,接下來,就讓我們從儲存內部結構出發,帶你深度解刨!我們以乙個例子來說明一切 include int main ...