C語言的變量存儲分配

      最近看了一些關於C語言中變量存儲機制的資料,覺得還有有一些東西不太理解,自已想做一個整理,這是第一次在在CSDN上發表這樣的帶點原創的技術的文章。

      按照GNU lib C的說法,C語言程序支持兩種變量存儲分配方式,一種是靜態分配方式。靜態分配主要支持靜態變量和全局變量,自打程序開始運行,它們不會被釋放,這個過程由編譯器完成。

還有一種方式是自動分配,它支持自行變量,如函數體的參數和局部變量,當函數執行完,它們釋放掉存儲空間。

 我想大家應該知道還有一種技術叫做動態分配,在運行時才知道在哪存放什麼信息的一種技術,它可以很靈活的在堆中分配空間,這個過程由malloc函數完成。


先來看一段程序:

char *get()

{

char a[]="hello,world";

char *p;

p=a;

return p;

}

int main()

{

char *d=NULL;

d=get();

printf("%s\n",d);

return 0;

}

調用此函數時,並不能得預期的"hello,world";

char *get2()

{

char *a="hello,world";

return a;

}

而這樣就可以了,這是爲什麼呢?

就這涉及到變量的存儲問題了,在get()中,a爲函數內部的字符數組,爲自動變量,它存儲在系統爲它開闢的一段棧上,當調用get()結束後,系統收回了它的存儲空間,其值不存在了,既然不存在了,那麼p也就指向了一個未知區域了。

再來看get2()函數,它利用指針來賦值,a指針本來爲一個整形的變量,它有值,就是常量“hello,world"的地址了,a的值存儲在棧上,而常量"hello,world"則存儲在常量區,(至於爲什麼的要這樣存儲,我還沒有找到根據)這樣即使函數調用結束,也只是銷燬了a的值,常量還是存在的。所以程序能夠正確執行。

這裏還要說明一點,函數是有功能,它也是有值,也即,它也是一個變量,只不過它是有着內部處理功能的變量,在上例程序中,返回值爲char *類型的get()函數顯然是一個全局變量,這樣理解也便於把全局變量,局部變量的概念統一化。

再來看一個程序就明白了:

char ok()

{

char p='a';

return p;

}

int main()

{

char d=ok();

printf("%s\n",d);

return 0;

}

分析ok()函數,裏面的p是局部變量,在main中調用完之後其值會自動銷燬,但是由於return的作用,p的值賦給了這個函數,ok()是全局變量,直到程序結束才銷燬其值。

關於靜態變量:

int fun(int n)

{

static int p=1;

p=p*n;

return p;

}

int main()

{

int i;

for(i=1;i<5;i++)

printf("%d!=%d\n",i,fun(i));

return 0;

}

結果是這樣的:

1!=1

2!=2

3!=6

4!=24

或許你很奇怪每次調用fun函數時都有static int p=1;會把它以前的值覆蓋啊,這就是靜態變量的好處,靜態變量只初始化一次,(至於爲什麼這樣,一直沒查到原因,我很期待有人能回答這個問題)它的值與全局變量一起保存在靜態存儲區,所以其實fun函數每次調用只是在做一句p=p*n;

第一次發技術文章,多有不足之處,誠懇接受各位訪客的指教,謝謝微笑




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章