存儲方式
C語言根據(jù)變量的生存周期來區(qū)分奕污,分為靜態(tài)存儲方式和動態(tài)存儲方式姓蜂。
- 靜態(tài)存儲方式:在程序運行期間分配固定存儲空間的方式按厘。靜態(tài)存儲區(qū)存放了在整個程序執(zhí)行過程中都存在的變量,如全局變量覆糟。
- 動態(tài)存儲方式:在程序運行期間根據(jù)需要進行動態(tài)的分配存儲空間的方式。動態(tài)存儲區(qū)中存放的變量是根據(jù)程序運行的需要而建立和釋放的遮咖,通常包括:函數(shù)形式參數(shù)滩字、自動變量、函數(shù)調(diào)用時的現(xiàn)場保護和返回地址等御吞。
在內(nèi)存中的用戶存儲空間分為:程序區(qū)麦箍、靜態(tài)存儲區(qū)、動態(tài)存儲區(qū)陶珠。
存儲類別
C語言中的存儲類別分為四類:自動(auto)挟裂、靜待(static)、寄存器(register)揍诽、外部的(extern)诀蓉。
1栗竖、auto 自動變量 --局部變量
auto定義的變量為自動變量,auto可以省略渠啤,auto不寫則隱含定為“自動存儲類別”狐肢,屬于動態(tài)存儲方式。
函數(shù)的形參沥曹、在函數(shù)中定義的局部變量(包含在符合語句中定義的局部變量)份名,都是自動變量auto。存儲在內(nèi)存的動態(tài)存儲區(qū)中妓美。
int funny (int a) { /*定義函數(shù)僵腺,a為參數(shù)/形參*/
auto int b ,c; /*定義b,c自動變量*/
/*....*/
}
2、static 靜態(tài)變量
static修飾的是靜態(tài)變量壶栋,如果定義在函數(shù)內(nèi)部辰如,稱之為靜態(tài)局部變量;如果定義在函數(shù)外部委刘,稱之為靜態(tài)外部變量丧没。
靜態(tài)變量都存儲于靜態(tài)存儲區(qū)。
- 靜態(tài)局部變量
1锡移、靜態(tài)局部變量在編譯時賦初值呕童,第一次賦值有效,以后在調(diào)用時淆珊,直接使用上一次調(diào)用的值而不需要重新賦值夺饲。
2、靜態(tài)局部變量屬于靜態(tài)存儲類別施符,在靜態(tài)存儲區(qū)內(nèi)分配存儲單元往声,在程序整個運行期間都不釋放。
3戳吝、如果在定義局部變量時不賦初值的話浩销,則靜態(tài)變量在編譯時自動賦初值0(對數(shù)值型變量)或空字符(對字符變量)。
void funny (int a) {
static int index = 1;
index += 1;
printf("funny :%d\n",index);
}
int main(int argc, const char * argv[]) {
for (int i = 0; i < 5; i ++) {
funny(10);
}
printf("********\n");
funny(0);
return 0;
}
打印結(jié)果:
funny :2
funny :3
funny :4
funny :5
funny :6
********
funny :7
- 靜態(tài)外部變量/靜態(tài)全局變量
全局變量都是放在靜態(tài)存儲區(qū)中的听哭。一般來說慢洋,外部變量是在函數(shù)外定義的全局變量,它的作用域是從變量定義處開始陆盘,到本程序文件末尾普筹。
靜態(tài)外部變量,是為了使某些變量只限于被本文件引用隘马,而不能被其他文件引用太防。
1、static int a酸员,變量只可以在當前文件中使用蜒车,
2讳嘱、int a,只是全局變量醇王,可以在整個工程中使用呢燥,其他文件引用時需要extern關鍵字聲明
test.c
static int staticInt_test = 100;
int pInt_test = 200;
/*-----------------------*/
main.c
int main(int argc, const char * argv[]) {
extern int pInt_test;/*可以通過extern關鍵字聲明,之后可以直接使用test.c中聲明的變量 */
printf("test:%d\n",pInt_test); /*打印結(jié)果:200*/
extern int staticInt_test ;/*如果聲明的是全局靜態(tài)變量寓娩,這里在編譯時會報錯叛氨,找不到對應變量。*/
printf("test static:%d\n",staticInt_test); /* 報錯 */
return 0;
}
static對局部變量和全局變量的作用不同棘伴,對局部變臉來說它使變量由動態(tài)存儲方式改為靜態(tài)存儲方式寞埠。對全局變量來說,它使變量局部化(局部于本文件)焊夸,但仍為靜態(tài)存儲方式仁连。
從作用域角度看,凡有static聲明的阱穗,其作用域都是局限的饭冬,或者都是局限于本函數(shù)內(nèi)(靜態(tài)局部變量),或者局限于本文件內(nèi)(靜態(tài)外部變量)揪阶。
3昌抠、register 寄存器變量
為提高效率,C語言允許將局部變量的值放在CPU的寄存器中鲁僚,這種變量叫“寄存器變量”炊苫,關鍵字register聲明。
void funny () {
register int i,sum = 0;//定義為寄存器變量
}
只有局部自動變量和形式參數(shù)可以作為寄存器變量冰沙;一個計算機系統(tǒng)中的寄存器數(shù)據(jù)有限侨艾,不能定義任意多個寄存器變量,局部靜態(tài)變量不能定義為寄存器變量拓挥。
4唠梨、extern 外部變量
extern聲明的變量是外部變量,表示把該變量的作用域擴展到此位置侥啤。外部變量的含義是某函數(shù)可以調(diào)用在該函數(shù)之后定義的變量当叭。也可以調(diào)用其他文件中聲明的外部變量。
- 在一個文件內(nèi)擴展外部變量的作用域
int main(int argc, const char * argv[]) {
extern int count;
printf("%d\n",count);
return 0;
}
int count = 100;
打印結(jié)果:
100
/** 如果不作聲明愿棋,將報錯"Use of undeclared identifier 'count'" **/
- 將外部變量的作用域擴展到其他文件科展,即在一個文件中引用另一個文件已經(jīng)定義的外部變量
test.c
int pInt_test = 200;
/*-----------------------*/
main.c
int main(int argc, const char * argv[]) {
extern int pInt_test;
/*通過extern關鍵字聲明均牢,之后可以直接使用test.c中聲明的變量 */
printf("test:%d\n",pInt_test);
/*打印結(jié)果:200*/
return 0;
}
-
作用
1糠雨、在一個文件中擴展外部變量的作用域
2、在一個文件中引用給另一個文件中已經(jīng)定義的外部變量徘跪。
部分概念說明
數(shù)據(jù)存放的6中形式:
- 1甘邀、程序代碼區(qū)--存放程序編譯后的可執(zhí)行代碼
- 2琅攘、靜態(tài)區(qū)(全局區(qū))--全局變量和靜態(tài)變量的存儲是放在一起的,初始化的全局變量和初始化的靜態(tài)變量在同一區(qū)域松邪,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域坞琴。程序結(jié)束后由系統(tǒng)釋放
- 3、常量區(qū)--常量存放位置逗抑,程序結(jié)束后由系統(tǒng)釋放
- 4剧辐、堆區(qū)--一般由程序分配和釋放,如果程序不釋放邮府,程序結(jié)束時可能由操作系統(tǒng)回收(程序不正常結(jié)束則無法回收)
- 5荧关、棧區(qū)--由編譯器自動分配并且釋放,一般存放函數(shù)的參數(shù)褂傀、局部變量等
- 6忍啤、寄存器區(qū)--有限容量的高速存儲區(qū),直接建立在中央處理器內(nèi)部仙辟,用來暫存指令同波、數(shù)據(jù)和地址,一般用來保存棧頂指針叠国、指令指針和現(xiàn)在正在被運行的指令未檩。由于存儲區(qū)其實是在中央處理器內(nèi)部建立,不在內(nèi)存中煎饼,因此不能將其劃分到內(nèi)存中讹挎。這里與內(nèi)存的功能大致相同,都用來暫存數(shù)據(jù)吆玖。
---這部分說明來自博客
全局變量筒溃、局部變量
程序的編譯單位是源程序文件,一個原文家可以包含一個或若干個函數(shù)沾乘。在函數(shù)內(nèi)定義的變量是局部變量怜奖,在函數(shù)之外定義的變量稱為外部變量,外部變量是全局變量(也稱全程變量)翅阵。
全局變量可以為本文件中其他函數(shù)所共用歪玲,他的有效范圍為從定義變量的位置到本源文件結(jié)束。
建議不再必要時不要使用全局變量:1掷匠、全局變量在程序執(zhí)行的全部過程中都占用存儲單元滥崩,而不是僅在需要時才開辟單元;2讹语、使函數(shù)通用性降低钙皮;3、全局變量過多,降低程序的清晰性短条,難以清晰判斷出每個瞬間各個外部變量的值导匣。
作用域、生存期
一個變量的屬性可以從兩個方面分析茸时,一個是作用域贡定,一個事變量值存在時間的長短,即生存期可都。前者是從空間角度缓待,后者是從時間角度。二者有聯(lián)系渠牲,但不是同一回事命斧。
如果一個變量在某個文件或函數(shù)范圍內(nèi)是有效的,就稱該范圍為該變量的作用域嘱兼。在該作用域內(nèi)可以引用該變量国葬。
如果一個變量值在某一時刻是存在的,則認為這一時刻屬于該變量的生存期芹壕,或稱該變量在此時刻存在汇四。
存儲類別小結(jié)
1、從作用域角度分踢涌,有局部變量和全局變量
2通孽、從變量存在的時間(生存期)區(qū)分,有動態(tài)存儲和靜態(tài)存儲兩種類型
3睁壁、從變量值存儲位置區(qū)分