最近看了一些關於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;
第一次發技術文章,多有不足之處,誠懇接受各位訪客的指教,謝謝。