1. 程式人生 > >C語言中記憶體分配

C語言中記憶體分配

一、static在C語言裡面可以用來修飾變數,也可以用來修飾函式。

1、 先看用來修飾變數的時候。變數在C語言裡面可分為存在全域性資料區、棧和堆裡。

其實我們平時所說的堆疊是棧而不是堆,不要弄混。

例如:在file.c中

int a ;

int main()

{

int b ;

int *c = (int *)malloc(sizeof(int));

}

a是全域性變數,

b是棧變數,

c是堆變數。

2、static對全域性變數的修飾,可以認為是限制了只能是本檔案引用此變數。有的程式是由許多.c檔案構成。彼此可以互相引用變數,但加入static修飾之後,只能被本檔案中函式引用此變數。

3、static對棧變數的修飾,可以認為棧變數的生命週期延長到程式執行結束時。一般來說,棧變數的生命週期由OS管理,在退棧的過程中,棧變數的生命也就結束了。但加入static修飾之後,變數已經不再儲存在棧中,而是和全域性變數一起儲存。同時,離開定義它的函式後不能使用,但如再次呼叫定義它的函式時,它又可繼續使用,而且儲存了上一次被呼叫後留下的值。

4、static對函式的修飾與對全域性變數的修飾相似,只能被本檔案中的函式呼叫,而不能被同一程式其它檔案中的函式呼叫。

例如:

檔案a.c

static int i; //只在a檔案中用

int j; //在工程裡用

static void init() //只在a檔案中用

{

}

void callme() //在工程中用

{

static int sum;

}

上面的全域性變數i和init()函式只能用在a.c檔案中,全域性變數sum的作用域只在callme()函式裡。變數j和函式callme()的作用域擴充到整個工程檔案。所以可以在下面的b.c中用extern關鍵字呼叫。extern告訴編譯器這個變數或者函式在其他檔案裡已經被定義了。

檔案b.c

extern int j; //呼叫a檔案裡的

extern void callme(); //呼叫a檔案裡的

int main()

{

...

}

而且static會有下面的幾個特點:

1、若全域性變數僅在單個C檔案中訪問,則可以將這個變數修改為靜態全域性變數,以降低模組間的耦合度;

2、若全域性變數僅由單個函式訪問,則可以將這個變數改為該函式的靜態區域性變數,以降低模組間的耦合度;

三、區域性變數和全域性變數

從作用域角度將變數分為區域性變數和全域性變數。它們採取的儲存類別如下:

區域性變數:

①自動變數,即動態區域性變數(離開函式,值就消失)。

②靜態區域性變數(離開函式,值仍保留)。

③暫存器變數(離開函式,值就消失)。

④形式引數可以定義為自動變數或暫存器變數。

全域性變數:

①靜態全域性變數(只限本程式檔案使用)。

②全域性變數(即非靜態的全域性變數,允許其它程式檔案引用)。

從變數存在時間可將變數儲存分為動態儲存和靜態儲存。靜態儲存是在整個程式執行時都存在,而動態儲存則是在呼叫函式時臨時分配儲存單元。

動態儲存:

①自動變數(函式內有效)。

②暫存器變數(函式內有效)。

③形式引數。

靜態儲存:

①靜態區域性變數(函式內有效)。

②靜態全域性變數(本程式檔案內有效)。

③全域性變數(整個程式可引用)。

從變數存放的位置可將變數儲存區分為靜態儲存區和動態儲存區:

靜態儲存區:

①靜態區域性變數。

②靜態全域性變數。

③全域性變數(可被同一程式其它檔案引用)。

動態儲存區:自動變數和形式引數。

CPU暫存器:暫存器變數。

當然,本文討論的對於變數的記憶體儲存分配只是一部分,在C語言中依然會有其他的儲存方式和型別的存在。