摘 要: C語言中變量在內存中的存儲情況一直是C語言學習的重點和難點,這些變量都是存放在RAM中的可編程內存中。為了更清楚地了解各種變量的存儲情況,具體討論了RAM中可編程內存各個分區的特點和作用,根據C語言中各種變量的特性,得出各種變量在內存中相應的存儲位置。
關鍵詞: RAM; 可編程內存; 存儲位置; 變量
中圖分類號:TP312 文獻標志碼:A 文章編號:1006-8228(2015)10-53-03
Abstract: The storage of the variables in C language has been the focus and difficulty of the C language learning. These variables are stored in the programmable memory of RAM. In order to get a better understanding of the storage of various variables, this paper discusses the characteristics and functions of the programmable memory partitions, and according to the characteristics of various variables in C language, gets the variables' corresponding storage location in memory.
Key words: RAM; programmable memory; storage location; variable
0 引言
內存一般采用半導體存儲單元,包括RAM(隨機存儲器)、ROM(只讀存儲器)和CACHE(高度緩存)。ROM中存儲的東西,只能讀出,不能寫入,即是不可以改變的,而且斷電后里面的東西不會丟失。ROM中存放的是固定的程序和數據,比如基本輸入/輸出程序、系統設置信息、開機后自檢程序和系統自啟動程序,也就是平時所說的BIOS。BIOS是固化到ROM芯片上的一組程序。RAM中存儲的東西可以隨機讀寫,但斷電后不保存。計算機中的內存條是RAM,我們平時處理文件、玩游戲等,數據就是臨時保存在RAM中的,如果不及時保存,斷電重新啟動后這些數據就都不存在了。
本文具體討論一個RAM,以及RAM在C語言中的使用情況。
1 RAM的可編程內存
RAM隨機存儲器通常作為操作系統或其他正在運行的程序的臨時數據存儲媒介。C語言中使用到的內存為可編程內存,可編程內存可分為以下三個部分:靜態存儲區(static)、棧區(stack)和堆區(heap)。棧區和堆區也統稱動態存儲區。根據他們的功能不同,C對它們的使用方式也不同。
1.1 靜態存儲區
程序在編譯的時候進行分配,這塊內存在程序的整個運行期間都存在,直到程序運行結束。所以這部分內存主要存放全局數據、靜態變量、常量。
1.2 棧區
由編譯器自動分配和釋放。函數中的局部變量存放在棧區,函數調用時分配相應的空間,函數調用結束后系統自動釋放該部分的空間。注意:是函數調用后即釋放,而不是程序運行結束后釋放。
1.3 堆區
也稱為動態內存分配區,是程序在運行時使用malloc函數申請所需要大小的內存空間。動態內存分配和回收是由程序員人為決定的,當我們不再需要時就用free釋放該部分內存,以免造成內存的泄漏。
1.4 各個分區小結
總之,對于堆區、棧區和靜態存儲區它們之間最大的不同在于生命周期,棧的生命周期很短暫,需要時開辟,使用完后自動回收;堆區生命周期較為“自由”,需要時動態開辟,不需要時用free釋放,但若不釋放會被一直占用;靜態存儲區生命周期最長,從程序開始到運行結束一直存在,可以認為靜態存儲區的生命周期與程序“共生死”。所以程序中使用的各種數據我們可以給它們找到歸宿了:全局變量和靜態變量肯定存放在靜態存儲區,局部變量、函數參數放在棧區,動態分配內存的變量放在堆區[3]。
下面通過例1來說明各種變量所占的存儲區。
由例1及圖1可見,全局變量和靜態變量的地址是連續的,它們存放在靜態存儲區。局部變量的地址與全局變量和靜態變量的地址沒任何關系,它們存放在棧區[4]。用戶開辟的空間在堆區。注意:printf(\"%x\n\",p1)和printf(\"%x\n\",p1),p1表示p1這個變量的存儲地址,由于這個變量是局部變量,所以p1在棧區。而這個變量中的內容也是一個地址,即新開辟的空間的地址,即p1,它是在堆中動態分配的空間,由圖1可知,動態開辟的空間不連續,但從它們的高位地址來看都是屬于同一個區——堆區。
2 變量的存儲類別
C語言中的變量是不是就只有全局變量、靜態變量和局部變量呢?這種說法不準確。按照變量的作用域劃分可以分為局部變量和全局變量。局部變量一般是存放在內存的棧區的,全局變量存放在靜態存儲區的。那靜態變量存放在靜態存儲區又是怎樣理解的呢?C中的變量有兩個基本屬性:數據類型和存儲類別。數據類型指的是基本類型int,float,char等。而存儲類別才是指數據在內存中的存儲方式。C中變量按存儲類別分有四種:auto(自動)、static(靜態)、register(寄存器)、extern(外部)[1]。我們從存儲類別的角度分析一下C中的變量所占的內存分區。
2.1 auto(自動)變量
auto變量只用于定義函數中的局部變量,平時可以省略,它存放在內存的棧區。在程序運行時分配,分配和釋放由系統自動完成。函數中的形參、函數中定義的變量、復合語句中定義的變量都是這種變量。如例2所示:
例2:
int f([auto]int a) //①
{
[auto] int b,c; //②
……
}
①處的a和②處的b,c都是auto變量,都屬于局部變量,存放在棧區。
2.2 static(靜態)變量
static可以定義全局變量,也可以定義局部變量。static變量在編譯時分配存儲空間,程序運行結束存儲空間才被釋放,稱為永久存儲[2]。故程序運行期間自始至終占用分配的空間。所以staic型的全局變量和局部變量都存放在內存的靜態存儲區,可參考例3。
例3:
static int m; //①m為static型的全局變量,存儲在靜態存儲區
int f(int a) //②a為auto型的函數形參,存儲在棧區
{
static int b; //③b為static型的局部變量,存儲在靜態存儲區
……
}
2.3 register(寄存器)變量
將使用頻繁的局部變量存儲在CPU的寄存器中,這樣可以提高執行效率。這樣的局部變量可以定義為register型的變量。
例4:
long fac(long n)
{
register long int i,f=1; //①i使用多次,用register定義,存放在寄存器中
for(i=1; i<=n; i++)
f=f*i
}
2.4 extern(外部)變量
extern可以用在變量前,也可以用在函數前。用在變量前表示只是在此處聲明一下,該變量已經在別的地方定義,目的是擴展變量的作用范圍。其實extern變量就是非靜態的全局變量,存放在內存的靜態存儲區。例5說明了extern的作用。
例5:
void main()
{
int max(int,int);
extern A,B;// ①外部變量聲明,定義在后面
printf(“%d\n”,max(A,B)); //②因為已經聲明了A,B,此處可以
使用。不然要先定義再使用
}
int A=10,B=20; //③全局變量定義(用extern在①處聲明)
int max(int x,int y)
{
int z;
z=x>y?x:y;
return z;
}
通過以上例子,我們可以從不同的角度對存儲類別做歸納:圖2是從變量作用域角度出發,歸納不同存儲類別的變量所占用的存儲空間;圖3是從可編程內存的各存儲區角度出發歸納存放各種不同存儲類別的變量。
3 結束語
C語言是計算機類學生和從業人員必掌握的語言之一,但對于C語言中變量存儲問題方面的研究一直很少,而且也都是從變量分類角度討論存儲情況,傳統C語言的教材在對變量分類時基本都是按作用域和存儲類別分類,而變量在這兩種分類中有交叉。因此,從變量存儲情況的“根本”出發,由底而上地從內存存儲區入手,討論變量的存儲及內存的分配將對C語言的學習者有很大幫助。同時變量的存儲問題還有很多地方值得研究,比如變量的讀取、內存的釋放等,今后還將繼續做進一步研究。
參考文獻:
[1] 譚浩強.C程序設計第三版[M].清華大學出版社,2005.
[2] 李學剛.C語言程序設計[M].高等教育出版社,2013.
[3] 田淑清.全國計算機等級考試二級教程[M].高等教育出版社,2013.
[4] 李學剛.數據結構(C語言描述)[M].高等教育出版社,2013.
[5] 洽汗·合孜爾.C語言程序設計(第三版)[M].中國鐵道出版社,2010.