一、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語言中依然會有其他的儲存方式和型別的存在。
>>>更多優秀技術博文每日更新
C語言中的記憶體分配
1 段 text 裡面儲存的是可執行程式的二進位制指令,為了防止被意外修改,段一般是唯讀的 2 全域性段 資料段data 儲存被初始化過的全域性變數 靜態變數 3 bss段 靜態資料段 儲存靜態變數 被static修飾過的變數 和末初始化的全域性變數,這段內存在程式執行前會被初始化為0 4 堆 he...
C語言中記憶體分配問題
推薦 c語言中記憶體分配 linux size命令和c程式的儲存空間布局 本大神感覺,上面的鏈結的內容,已經很好的說明了 對於乙個可執行檔案,在linux下可以使用 size命令列出目標檔案各部分佔的位元組數 分為 text段 data段與bss段 參考 linux size命令和c程式的儲存空間布...
C語言中動態記憶體分配
c語言用了蠻久了,最近在寫乙個dsp的程式,發現動態記憶體使用這一塊還是很欠缺,於是又重新看了看c的書,總結一下。之前常見的陣列或結構體內存分配,其長度必須是固定的常數,如 int a 10 等,當需要申請變長陣列時,常規的直接定義就不可以了,如float b n 其中n為變數 好像c99之後可以這...