編程變數存儲空間
第2章 變數和數據存儲
C語言的強大功能之一是可以靈活地定義數據的存儲方式。C語言從兩個方面控制變數的性質:作用域(scope)和生存期(lifetime)。作用域是指可以存取變數的代碼范圍,生存期是指可以存取變數的時間范圍。
作明告用域有三種:
1. extern(外部的) 這是在函數外部定義的變數的預設存儲方式。extern變數的作用域是整個程序。
2.static(靜態的) 在函數外部說明為static的變數的作用域為從檔畢定義點到該文件尾部;在函數內部說明為static的變數的作用域為從定義點到該局部程序塊尾部。
3.auto(自動的) 這是在函數內部說明的變數的預設存儲方式。auto變數的作用域為從定義點到該局部程序塊尾部。
變數的生存期也有三種,但它們不象作用域那樣有預定義的關鍵字名稱。第一種是extern和static變數的生存期,它從main()函數被調用之前開始,到程序退出時為止。第二種是函數參數和auto變數的生存期,它從函數調用時開始,到函數返回時為止。第三種是動態分配的數據的生存期,它從程序調用malloc()或calloc()為數據分配存儲空間時開始,到程序調用free()或程序退出時為止。
2.1 變數存儲在內存(memory)中的什麼地方?
變數可以存儲在內存中的不同地方,這依賴於它們的生存期。在函數外部定義的變數(全局變數或靜態外部變數)和在函數內部定義的static變數,其生存期就是程序運行的全過程,這些變數被存儲在數據段(datasegment)中。數據段是在內存中為這些變數留出的一段大小固定的空間,它分為兩部分,一部分用來存放初始化變數,另一部分用來存放未初始化變數。
在函數內部定義的auto變數(沒有用關鍵字static定義的變數)的生存期從程序開始執行其所在的程序塊代碼時開始,到程序離開該程序塊時為止。作為函數參數的變數只在調用該函數期間存在。這些變數被存儲在棧(stack)中。棧是內存中的一段空間,開始很小,以後逐漸自動增大,直到達到某個預定義的界限。在象DOS這樣的沒有虛擬內存(virtual memory)的系統中,這個界限由系統決定,並且通常非常大,因此程序員不必擔心用盡棧空間。關於虛擬內存 的討論,請參見2.3。
第三種(也是最後一種)內存空間實際上並不存儲變數,但是可以用來存儲變數所指向的數據。如果把調用malloc()函數的結果賦行槐芹給一個指針變數,那麼這個指針變數將包含一塊動態分配的內存的地址,這塊內存位於一段名為「堆(heap)」的內存空間中。堆開始時也很小,但當程序員調用malloc()或calloc()等內存分配函數時它就會增大。堆可以和數據段或棧共用一個內存段(memorysegment),也可以有它自己的內存段,這完全取決於編譯選項和操作系統。
與棧相似,堆也有一個增長界限,並且決定這個界限的規則與棧相同。
請參見:
1.1 什麼是局部程序塊(10calblock)?
2.2 變數必須初始化嗎?
2.3 什麼是頁抖動(pagethrashing)?
7.20 什麼是棧(stack)?
7.21 什麼是堆(heap)7 .
2.2 變數必須初始化嗎?
不。使用變數之前應該給變數一個值,一個好的編譯程序將幫助你發現那些還沒有被給定一個值就被使用的變數。不過,變數不一定需要初始化。在函數外部定義的變數或者在函數內部用static關鍵字定義的變數(被定義在數據段中的那些變數,見2.1)在沒有明確地被程序初始化之前都已被系統初始化為0了。在函數內部或程序塊內部定義的不帶static關鍵字的變數都是自動變數,如果你沒有明確地初始化這些變數,它們就會具有未定義值。如果你沒有初始化一個自動變數,在使用它之前你就必須保證先給它賦值。
調用malloc()函數從堆中分配到的空間也包含未定義的數據,因此在使用它之前必須先進行初始化,但調用calloc()函數分配到的空間在分配時就已經被初始化為0了。
請參見:
1.1 什麼是局部程序塊(10calblock)?
7.20 什麼是棧(stack)?
7.21 什麼是堆(heap)?
2.3 什麼是頁抖動(pagethrashing)?
有些操作系統(如UNIX和增強模式下的Windows)使用虛擬內存,這是一種使機器的作業地址空間大於實際內存的技術,它是通過用磁碟空間模擬RAM(random—access memory)來實現的。
B. 程序的局部變數 全局變數 動態申請數據分別存儲在什麼地方
程序的局部變數全局變數動態申請數據分別存儲在棧里。
普通局部變數在堆棧空間上分配,當局部變數的函數被多次調用時,局部變數每次在堆棧上的位置都不相同。還可以在堆上動態分配局部變數(malloc),但是要記住在耗盡堆空間後釋放zd。
內存分配上的棧空間時要注意內存的,不能分配太多的內存。如果堆棧中的空間小於請求的空間大小,則系統將顯示堆棧溢出並給出相應的異常信息。但堆不同,堆可分配空間很大。
(2)編程變數存儲空間擴展閱讀:
注意事項:
對局部變數進行分類
1.位置:編譯器將靜態局部變數放在全局存儲區域中。數據,因此盡管它是本地的,但它存在於程序的整個生命周期中(它在定義時產生,並隨著程序的結束而結束)。
2.訪問許可權:靜態局部變數只能由其作用域內的變數或函數訪問。也就是說,盡管它將存在於程序的整個生命周期中,但是其他函數和源文件不能訪問它,因為它是靜態的。
3.值:如果用戶沒有初始化靜態局部變數,編譯器會自動將其賦值為0,每次調用靜態局部變數時都會使用最後一次調用後的值。
C. C語言中 局部變數和全局變數都是存儲在什麼區
C語言中局部變數存在棧里,全局變數存靜態存儲區。
局部變數在棧空間上分配,這個局部變數所在的函數被多次調用時,每次調用這個局部變數在棧上的位置都不一定相同。局部變數也可以在堆上動態分配,但是記得使用完這個堆空間後要釋放之。
全局變數全部存放在靜態存儲區,在程序開始執行時給全局變數分配存儲區,程序行完畢就釋放。在程序執行過程中它們占據固定的存儲單元,而不動態地進行分配和釋放;
(3)編程變數存儲空間擴展閱讀
C語言中局部變數和全局變數示例:
#include<stdio.h>
#include<malloc.h>
staticints1=0,s2=0,s3=0;//靜態變數放在靜態區
intg1=0,g2=0,g3=0;//全局變數放在靜態區
voidmain()
{
staticints4=0,s5=0,s6=0;<spanstyle="font-family:Arial,Helvetica,simsun,u5b8bu4f53;"></span>//靜態變數
inta1=0,a2=0,a3=0;<spanstyle="font-family:Arial,Helvetica,simsun,u5b8bu4f53;"></span>//局部變數放在棧區
charc1[]="aabb";//局部變數放在棧區
char*c2="aabb";//字元常量放在靜態區
char*m1=(char*)malloc(1);//堆區
char*m2=(char*)malloc(1);//堆區
char*m3=(char*)malloc(1);//堆區
printf("動態數據區 ");
printf("a1 a2 a3 ",&a1,&a2,&a3);
printf("c1 ",c1);
printf("m1 m2 m3 ",&m1,&m2,&m3);
printf("靜態數據區 ");
printf("s1 s2 s3 ",&s1,&s2,&s3);
printf("g1 g2 g3 ",&g1,&g2,&g3);
printf("s4 s5 s6 ",&s4,&s5,&s6);
printf("c2 ",c2);
}
D. C語言中全局變數存放在內存空間中那個位置
在 C 語言中,內存分配方式有以下三種形式:
1、從靜態存儲區域分配
由編譯器自動分配和釋放,在程序編譯的時候就已經分配好內存,這塊內存在程序的整個運行期間都存在,直到整個程序運行結束時才被釋放,如全局變數與 static 變數。
2、在棧上分配
同樣由編譯器自動分配和釋放,在函數執行時,函數內部的局部變數都可以在棧上創建,函數執行結束時,這些存儲單元將則被自動釋放。
需要注意的是,棧內存分配運算內置於處理器的指令集中,它的運行效率一般很高,但是分配的內存容量有限。
3、從堆上分配
也稱為動態內存分配,由程序員手動完成申請和釋放。程序在運行的時,由程序員使用內存分配函數(如 malloc 函數)來申請內存,使用完之後再由程序員自己負責使用內存釋放函數(如 free 函數)來釋放內存。
需要注意的是,如果在堆上分配了內存空間,就必須及時釋放它,否則將會導致運行的程序出現內存泄漏等錯誤。
在 C 語言中,不同類型變數的存儲位置和作用域也有所不同。
全局變數
從靜態存儲區域分配,其作用域是全局作用域,也就是整個程序的生命周期內都可以使用。如果程序是由多個源文件構成的,那麼全局變數只要在一個文件中定義,就可以在其他所有的文件中使用,但必須在其他文件中通過使用extern關鍵字來聲明該全局變數。
全局靜態變數
從靜態存儲區域分配,其生命周期也是與整個程序同在的,從程序開始到結束一直起作用。與全局變數不同的是,全局靜態變數作用域只在定義它的一個源文件內,其他源文件不能使用。
局部變數
從棧上分配,其作用域只是在局部函數內,在定義該變數的函數內,只要出了該函數,該局部變數就不再起作用,也即該變數的生命周期和該函數同在。
局部靜態變數
從靜態存儲區域分配,其在第一次初始化後就一直存在直到程序結束。該變數的特點是其作用域只在定義它的函數內可見,出了該函數就不可見了。
E. c語言中編譯系統和操作系統誰為變數分配相應的存儲空間
編譯系統將程序編譯成可皮敬卜執行代碼
操作系統執行程序,按照可執行代碼需求為程序燃穗分配代碼空間、常量空間、變數空間稿含、堆棧空間,然後執行程序。