有這樣一道筆試題逻住,包括百度支子、中興在內(nèi)的很多公司都曾在筆試面試中出過該題目:
請回答全局變量和局部變量在內(nèi)存中是否有區(qū)別创肥?如果有,是什么區(qū)別值朋?
該題目的解析如下:
答:有區(qū)別叹侄。全局變量保存在內(nèi)存的全局存儲區(qū)中,占用靜態(tài)的存儲單元昨登;局部變量保存在棧中趾代,只有在所在函數(shù)被調(diào)用時才動態(tài)地為變量分配存儲單元。
該題目考查的知識點(diǎn)是變量的存儲類型及性質(zhì)丰辣。C語言經(jīng)過編譯之后將內(nèi)存分為以下幾個區(qū)域:
(1)棧(stack):由編譯器進(jìn)行管理撒强,自動分配和釋放,存放函數(shù)調(diào)用過程中的各種參數(shù)笙什、局部變量飘哨、返回值以及函數(shù)返回地址。操作方式類似數(shù)據(jù)結(jié)構(gòu)中的棧琐凭。
(2)堆(heap):用于程序動態(tài)申請分配和釋放空間芽隆。C語言中的malloc和free,C++中的new和delete均是在堆中進(jìn)行的统屈。正常情況下摆马,程序員申請的空間在使用結(jié)束后應(yīng)該釋放,若程序員沒有釋放空間鸿吆,則程序結(jié)束時系統(tǒng)自動回收囤采。注意:這里的“堆”并不是數(shù)據(jù)結(jié)構(gòu)中的“堆”。
(3)全局(靜態(tài))存儲區(qū):分為DATA段和BSS段惩淳。DATA段(全局初始化區(qū))存放初始化的全局變量和靜態(tài)變量蕉毯;BSS段(全局未初始化區(qū))存放未初始化的全局變量和靜態(tài)變量乓搬。程序運(yùn)行結(jié)束時自動釋放。其中BBS段在程序執(zhí)行之前會被系統(tǒng)自動清0代虾,所以未初始化的全局變量和靜態(tài)變量在程序執(zhí)行之前已經(jīng)為0进肯。
(4)文字常量區(qū):存放常量字符串。程序結(jié)束后由系統(tǒng)釋放棉磨。
(5)程序代碼區(qū):存放程序的二進(jìn)制代碼江掩。
顯然,C語言中的全局變量和局部變量在內(nèi)存中是有區(qū)別的乘瓤。C語言中的全局變量包括外部變量和靜態(tài)變量环形,均是保存在全局存儲區(qū)中,占用永久性的存儲單元衙傀;局部變量抬吟,即自動變量,保存在棧中统抬,只有在所在函數(shù)被調(diào)用時才由系統(tǒng)動態(tài)在棧中分配臨時性的存儲單元火本。
有興趣的讀者可以運(yùn)行下面的程序,分析一下運(yùn)行結(jié)果聪建。
include <stdio.h>
include <stdlib.h>
int k1 = 1;
int k2;
static int k3 = 2;
static int k4;
int main( )
{ staticint m1=2, m2;
inti=1;
charp;
charstr[10] = "hello";
charq = "hello";
p= (char *)malloc( 100 );
free(p);
printf("棧區(qū)-變量地址 i:%p\n", &i);
printf(" p:%p\n", &p);
printf(" str:%p\n", str);
printf(" q:%p\n", &q);
printf("堆區(qū)地址-動態(tài)申請:%p\n", p);
printf("全局外部有初值 k1:%p\n", &k1);
printf(" 外部無初值 k2:%p\n", &k2);
printf("靜態(tài)外部有初值 k3:%p\n", &k3);
printf(" 外靜無初值 k4:%p\n", &k4);
printf(" 內(nèi)靜態(tài)有初值 m1:%p\n", &m1);
printf(" 內(nèi)靜態(tài)無初值 m2:%p\n", &m2);
printf("文字常量地址 :%p, %s\n",q, q);
printf("程序區(qū)地址 :%p\n",&main);
return0;
}
更多技術(shù)文章請關(guān)注微信公眾號:開點(diǎn)工作室(ID:kaidiancs)