c語言中需要記憶體來存放資料。而記憶體主要分為兩類:靜態儲存區和動態儲存區;
1.靜態儲存區分為:唯讀資料(readonly data)區、讀寫資料(rw data)區、未初始化區(bss)。它們都是在程式編譯連線階段確定的,在程式執行的階段不會改變。
2.動態儲存區分為堆和棧。都是程式執行的過程中動態分配的,大小也隨之動態變化。從記憶體管理的實現的角度看來,堆使用的鍊錶實現的,而棧使用的是線性儲存的方法。
棧:棧是先進後出,實際的操作中,棧記憶體可以有滿棧和空棧的情況,滿棧的情況下,棧指標當前的位子是已經使用的的棧區域;空棧的情況是,棧指標當前的位子是沒有使用的棧區域,所以兩種情況的出入棧,指標和資料的操作先後順序是不同的。
滿棧時:入棧,是先移動指標,在放入資料;出棧則是先出資料,在移動指標;
空棧時:入棧,是先放入資料,在移動指標。出棧則是先移動指標,在出資料;
c語言必須注意的幾個問題:
1.記憶體洩露:申請一塊記憶體,但沒有釋放,程式結束也沒**,導致其他程式不能使用
2.野指標:指乙個記憶體指標已經被釋放free或者realloc,但指標依然在使用。避免野指標的情況,將記憶體的指標置為null,並在程式使用的時候判斷該記憶體是否為null,如為空,則認為該記憶體已經釋放,不對記憶體進行訪問。
3.非法釋放記憶體:原則上講只有被malloc(),calloc()或realloc()分配並通過返回值返回返回的記憶體才能被釋放,否則釋放除此以外的記憶體都是非法的。即使有乙個指標是*p是malloc,那麼對p1=p++,這個時候free(p1)也是不合法的,但free(p)確實可以的。同樣釋放函式中的區域性變數也是非法的.還有一種情況是,對乙個堆記憶體釋放兩次也是錯誤的用法。因為free()函式是不能釋放未分配的堆記憶體。在程式使用free釋放記憶體之後,應該將指標置為null,free乙個null位址是沒有問題的。
1. static 變數
靜態變數的型別 說明符是static。 靜態變數當然是屬於靜態儲存方式,但是屬於靜態儲存方式的量不一定就是靜態變數。 例如外部變數雖屬於靜態 儲存方式,但不一定是靜態變數,必須由 static加以定義後才能成為靜態外部變數,或稱靜態全域性變數。
2.靜態區域性變數
靜態區域性變數屬於靜態儲存方式,它具有以下特點:
(1)靜態區域性變數在函式內定義 它的生存期為整個源程式,但是其作用域仍與自動變數相同,只能在定義該變數的函式內使用該變數。退出該函式後, 儘管該變數還繼續存在,但不能使用它。
(2)允許對構造類靜態區域性量賦初值 例如陣列,若未賦以初值,則由系統自動賦以0值。
(3)對基本型別的靜態區域性變數若在說明時未賦以初值,則系統自動賦予0值。而對自動變數不賦初值,則其值是不定的。 根據靜態區域性變數的特點, 可以 看出它是一種生存期為整個源程式的量。雖然離開定義它的函式後不能使用,但如再次呼叫定義它的函式時,它又可繼續使用, 而且儲存了前次被呼叫後留下的 值。 因此,當多次呼叫乙個函式且要求在呼叫之間保留某些變數的值時,可考慮採用靜態區域性變數。雖然用全域性變數也可以達到上述目的,但全域性變數有時會造成 意外的***,因此仍以採用區域性靜態變數為宜。
3.靜態全域性變數
全域性變數(外部變數)的說明之前再冠以static 就構 成了靜態的全域性變數。全域性變數本身就是靜態儲存方式, 靜態全域性變數當然也是靜態儲存方式。 這兩者在儲存方式上並無不同。這兩者的區別雖在於非靜態全域性 變數的作用域是整個源程式, 當乙個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是有效的。 而靜態全域性變數則限制了其作用域, 即只在 定義該變數的原始檔內有效, 在同一源程式的其它原始檔中不能使用它。由於靜態全域性變數的作用域侷限於乙個原始檔內,只能為該原始檔內的函式公用, 因此 可以避免在其它原始檔中引起錯誤。從以上分析可以看出,把區域性變數改變為靜態變數後是改變了它的儲存方式即改變了它的生存期。把全域性變數改變為靜態變數 後是改變了它的作用域, 限制了它的使用範圍
。因此static 這個說明符在不同的地方所起的作用是不同的。
4.static函式
內部函式和外部函式:當乙個源程式由多個原始檔組成時,c語言根據函式能否被其它原始檔中的函式呼叫,將函式分為內部函式和外部函式。
(1) 內部函式(又稱靜態函式)
如果在乙個原始檔中定義的函式,只能被本檔案中的函式呼叫,而不能被同一程式其它檔案中的函式呼叫,這種函式稱為內部函式。定義乙個內部函式,只需在函式型別前再加乙個「static」關鍵字即可,如下所示:
static 函式型別 函式名(函式引數表)
關鍵字「static」,譯成中文就是「靜態的」,所以內部函式又稱靜態函式。但此處「static」的含義不是指儲存方式,而是指對函式的作用域僅侷限於本檔案。使用內部函式的好處是:不同的人編寫不同的函式時,不用擔心自己定義的函式,是否會與其它檔案中的函式同名,因為同名也沒有關係。
2 外部函式
外部函式的定義:在定義函式時,如果沒有加關鍵字「static」,或冠以關鍵字「extern」,表示此函式是外部函式:
[extern] 函式型別 函式名(函式引數表)
呼叫外部函式時,需要對其進行說明:
[extern] 函式型別 函式名(引數型別表)[,函式名2(引數型別表2)……];
[案例]外部函式應用。
(1)檔案mainf.c
main()
(2)檔案subf1.c
……extern void input(……) /*定義外部函式*/
(3)檔案subf2.c
……extern void process(……) /*定義外部 函式*/
(4)檔案subf3.c
……extern void output(……) /*定義外部函式*/
全域性變數 靜態全域性變數 靜態區域性變數 區域性變數
全域性和靜態變數都在堆裡。這句話應該錯了,應該是放在常量資料段 全域性變數的作用範圍是整個程式 如果程式是多個檔案,必須在其他的檔案中說明 靜態變數的作用範圍要看靜態變數的位置,如果在函式裡,則作用範圍 就是這個函式。靜態全域性變數,只在本檔案可以用,雖然整個程式包含多個檔案,但靜態全域性變數只能用...
全域性變數 靜態全域性變數 靜態區域性變數 區域性變數
全域性和靜態變數都在堆裡。全域性變數的作用範圍是整個程式 如果程式是多個檔案,必須在其他的檔案中說明 靜態變數的作用範圍要看靜態變數的位置,如果在函式裡,則作用範圍 就是這個函式。靜態全域性變數,只在本檔案可以用,雖然整個程式包含多個檔案,但靜態全域性變數只能用在定義它的那個檔案裡,卻不能用在程式中...
全域性變數 靜態全域性變數區域性變數 靜態區域性變數
對於乙個完整的程式,在記憶體中的分布情況如下圖 區 low address 全域性資料區 堆區 棧區 high address 一般程式把新產生的動態資料存放在堆區,函式內部的自動變數存放在棧區。自動變數一般會隨著函式的退出而釋放空間,靜態資料 即使是函式內部的靜態區域性變數 也存放在全域性資料區。...