娓娓道來c指標 (2)記憶體配置

來源:互聯網
上載者:User

標籤:記憶體配置   全域變數   局部變數   靜態變數   malloc   

                            (2)記憶體配置

c語言中描述變數的時候常用的兩個用語

1.範圍:也叫可見域,指的是變數的作用範圍。在哪個範圍內,該變數是可見的、可以使用的。

2.生存期:也叫儲存期,指的是變數從建立到銷毀的存留時間段。

範圍和存在域是兩個不同的概念,比如在程式的某個位置,某變數存在(記憶體中分配了地址)但不可見(不可使用)。

範圍

從範圍看,變數分為以下三種:

1.全域變數

在c語言中,把在任何函數之外聲明的變數稱為全域變數。一般情況下,全域變數在任何地方都是可見的。當然也有例外,比如在語句塊{}內聲明了一個同名的局部變數,則該全域變數會暫時不可見。

//全域變數int foo = 5;void fun(){printf(" fun()->foo...%d\n", foo);}int main(){int bar = 3;printf("main()->foo...%d\n", foo);printf("main()->bar...%d\n", bar);{//局部變數,屏蔽同名全域變數fooint foo = 6;printf("    {}->foo...%d\n", foo);//局部變數,屏蔽同名局部變數barint bar = 4;printf("    {}->bar...%d\n", bar);}fun();return 0;}
運行


從運行結果可以看出全域變數的可見範圍。當然,如果在全域變數未被聲明之前就試圖使用它,則也會出錯。(這與規則:“未聲明,不可使用”有關。)

除此之外,c中的設計思想是:一個全域變數也是一個預設的外部變數(extern)。也就是說,一個全域變數不僅在本檔案中是全域可見的,在別的檔案中也是可見的。如

//1.cint foo;
在另一個檔案中有

//2.cint foo;
編譯報錯:foo被重複定義,命名衝突。

這種預設行為被廣為詬病,不少人認為,變數的可見域預設下應僅限於當前檔案,需要擴大時,應該由程式員自己控制。並且對於函數,也有同樣的預設行為。

如何防止這種行為?

(1)若是確實需要使用一個同名的變數,則可對已存在的同名全域變數用static修飾,使之成為靜態全域變數。這樣它的可見域,就僅限於它所在的檔案之內。如

//1.cstatic int foo; //可見域被限制於本檔案內
在另一個檔案中重新聲明 int foo; 沒有問題。

(2)不定義新的,直接使用別的檔案中的全域變數。文法是 extern int foo; 關鍵字 extern 是外部的意思,表明變數 foo,已在別的地方定義,這裡只是在使用之前,作一個聲明而已,不是重複定義。當然不作此聲明也是停用,這再次體現了:可見,但不一定可用。


2.檔案內部的靜態變數

這就是上文中說的靜態全域變數。


3.局部變數

在函數中,或更直接的說是在語句塊{}內定義的變數,是局部變數。它的可見域僅限於語句塊內,在其它地方無法引用。局部變數在函數被調用時由系統分配儲存區,在不同的函數中同名的變數實際上在記憶體中占不同的單元,因此在不同的函數中可以定義相同名字的局部變數。如函數的形參,main函數中定義的變數都是局部變數。

對範圍進行總結

c語言中存在三種範圍

(1)塊範圍
自動變數(auto、register)和內部靜態變數(static)具有塊範圍,在一個塊內聲明的變數,其範圍從聲明點開始,到該塊結束為止。函數定義中聲明的形參,其範圍限定在該函數體內,與其他函數中聲明的同名變數不是一回事,允許在不同的函數中使用相同的變數名,編譯器將為這些變數分配不同的儲存單元,不會衝突。
(2)檔案範圍
外部靜態變數(static)具有檔案範圍,從聲明點開始到檔案末尾,此處所指的檔案是編譯基本單位—c檔案。
(3)全域(程式)範圍
全域變數(extern)具有全域範圍,只要在使用前對其進行聲明,便可在程式(由若干個檔案組成)的任意位置使用全域變數。


生存期從生存期看,分為以下三種:

1.靜態變數(static variable)

全域變數和指定static的局部變數,都具有靜態儲存期。它們從程式開始一直到程式結束都存在,故被統稱為靜態變數。


2.自動變數(auto variable)

沒有被指定為static的局部變數和寄存器變數(register variable)都是自動變數。函數的形參及代碼塊中定義的變數都屬於auto變數,這是C語言中應用最廣的一種變數,這類變數是棧分配的,是動態分配儲存空間的。舉函數形參為例,當調用該函數時,為形參分配儲存空間,當函數調用結束時,就自動釋放這些儲存空間。對代碼塊中定義的變數(包含函數中定義的變數),當執行到變數聲明語句時,系統為這些auto變數分配空間,當程式流程離開代碼塊時,這些變數被自動撤銷,其佔用的記憶體空間被釋放。


3.堆變數

通過malloc()函數分配記憶體地區的變數被放在堆中,故稱為堆變數。並且似乎這個“堆”和資料結構中的堆沒有什麼聯絡,只是一種稱呼而已。這種變數需要手動釋放記憶體地區:free(變數名),也就是說它從建立時起就一直存在直到使用free()釋放為止。當然,即使最後忘了釋放,如今的作業系統也會在程式結束後釋放為它分配的記憶體。不過仍然建議:誰建立,誰釋放。




相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.