C08作用域和存儲類別_第1頁
C08作用域和存儲類別_第2頁
C08作用域和存儲類別_第3頁
C08作用域和存儲類別_第4頁
C08作用域和存儲類別_第5頁
已閱讀5頁,還剩30頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、1第八章 用戶標識符的作用域和存儲類 教學(xué)目標教學(xué)目標掌握作用域與的概念;了解動態(tài)存儲區(qū)與靜態(tài)存儲區(qū)的概念;掌握4種存儲類別(auto,register,static,extern);掌握局部變量的作用域、及其使用特點;掌握的作用域、及其使用特點;了解函數(shù)的存儲分類(extern ,static)。 基本要求基本要求 能夠熟練地閱讀有關(guān)的應(yīng)用程序,能夠利用不同的存儲屬性來靈活地編寫有關(guān)的應(yīng)用程序。28.1 局部變量、全局變量和存儲分類 在C語言中,由用戶命名的標識符都有一個有效的作用域。所謂“作用域”是指程序中的某一部分,只有在這一部分中,該標識符才是有定義的,即只有在這個域中才能使用該標識符

2、。 例如,在某一函數(shù)內(nèi)定義的變量,只能在該函數(shù)內(nèi)進行使用。顯然,變量的作用域與其定義語句在程序中出現(xiàn)的位置有直接的關(guān)系,由此可以將變量劃分為局部變量和全局變量。1. 用戶標識符的作用域作用域3定義:在函數(shù)內(nèi)定義的變量, 只在本函數(shù)內(nèi)有效。說明:在main函數(shù)中定義的變量只能在main函數(shù)內(nèi)有效;不同函數(shù)中的同名變量,占不同的內(nèi)存單元。函數(shù)的形參屬于局部變量;可以定義只在某個復(fù)合語句內(nèi)有效的局部變量。float f1(int a) int b,c; .char f2(int x,int y) int i,j; main() int m,n; .a,b,c有效x,y,i,j有效m,n有效2. 局部

3、變量(也稱內(nèi)部變量)4例 不同函數(shù)中同名變量main() int a,b; a=3; b=4; printf(main:a=%d,b=%dn,a,b); sub(); printf(main:a=%d,b=%dn,a,b);sub() int a,b; a=6; b=7; printf(sub:a=%d,b=%dn,a,b);例 復(fù)合語句中的變量#define N 5main() int i; int aN=1,2,3,4,5; for(i=0;iN/2;i+) int temp;temp=ai;ai=aN-i-1;aN-i-1=temp; for(i=0;iN;i+) printf(%d ,

4、ai);局部變量示例5 若要在本文件中使用同一程序的其它文件中定義的全局變量,必需要對該變量進行外部變量聲明。 外部變量聲明聲明的方法的方法: extern 數(shù)據(jù)類型 變量表;定義:在函數(shù)外定義,可為本文件內(nèi)的所有函數(shù)共用。有效范圍:從定義變量的位置開始到本源文件結(jié)束,及有extern聲明的其它源文件。3.3.全局變量全局變量( (也稱也稱外部變量外部變量) ) 外部變量定義 外部變量聲明u次數(shù): 只能1次 可說明多次u位置: 所有函數(shù)之外 函數(shù)內(nèi)或函數(shù)外u分配內(nèi)存: 分配內(nèi)存,可初始化 不分配內(nèi)存,不可初始化外部變量定義與外部變量聲明聲明的區(qū)別的區(qū)別:6全全局變量示例int a , b;ma

5、in() a=3; b=4; printf(main:a=%d,b=%dn,a,b); sub(); printf(main:a=%d,b=%dn,a,b);sub() int a ; a=6; b=7; printf(sub:a=%d,b=%dn,a,b); 若外部變量與局部變量同名,則外部變量被屏蔽。 盡量少用全局變量Y全局變量在程序全部執(zhí)行過程中始終占用存儲單元;Y降低了函數(shù)的通用性、可靠性,可移植性;Y降低了程序清晰性,容易出錯。 運行結(jié)果: main:a=3,b=4 sub:a=6,b=7 main:a=3,b=77變量的屬性變量的屬性 數(shù)據(jù)類型:變量所持有的數(shù)據(jù)的性質(zhì)(操作屬性)

6、存儲屬性存儲屬性:存儲器類型:寄存器、靜態(tài)存儲區(qū)、動態(tài)存儲區(qū)生存期:變量在某一時刻存在-靜態(tài)變量與動態(tài)變量作用域:變量在某區(qū)域內(nèi)有效-局部變量與全局變量指定變量的存儲類型時所要用的關(guān)鍵字 auto -自動型(缺省值缺省值) register-寄存器型 static -靜態(tài)型 extern -外部型變量定義格式: 存儲類型 數(shù)據(jù)類型 變量表;如: int sum; auto int a,b,c; register int i; static float x,y;4. 變量的變量的存儲屬性存儲屬性8 靜態(tài)存儲靜態(tài)存儲:程序運行期間分配固定地存儲空間 動態(tài)存儲動態(tài)存儲:程序運行期間根據(jù)需要動態(tài)地分配

7、存儲空間 寄存器寄存器:程序運行期間動態(tài)地占用CPU的內(nèi)部寄存器5. 變量的變量的存儲類型存儲類型程序代碼區(qū)靜態(tài)存儲區(qū)動態(tài)存儲區(qū)全局變量、靜態(tài)局部變量形參變量動態(tài)局部變量(auto、register)函數(shù)調(diào)用現(xiàn)場保護和返回地址等計算機計算機內(nèi)存內(nèi)存分分系統(tǒng)區(qū)系統(tǒng)區(qū)和和用戶區(qū)用戶區(qū)操作系統(tǒng)區(qū)9靜態(tài)變量的生存期生存期: 從程序程序開始執(zhí)行到整個程序運行結(jié)束程序運行結(jié)束。動態(tài)變量的生存期生存期: 從包含該變量定義的函數(shù)函數(shù)開始執(zhí)行至該函該函數(shù)執(zhí)行結(jié)束。數(shù)執(zhí)行結(jié)束。6. 變量的變量的生存期生存期10int a;main( ) . . f2; . f1; .f1( ) auto int b; f2; .

8、f2( ) static int c; c作用域b作用域a作用域mainf2f1mainf1f2maina生存期:b生存期:例:例:變量的作用域與生存期c生存期:11靜態(tài)動態(tài)存儲方式程序整個運行期間函數(shù)調(diào)用開始至結(jié)束生存期編譯時賦初值,只賦一次每次函數(shù)調(diào)用時賦初值自動賦初值0或空字符不確定未賦初值靜態(tài)存儲區(qū)動態(tài)區(qū)存儲區(qū)寄存器局部變量外部變量作用域定義變量的函數(shù)或復(fù)合語句內(nèi)本文件多個文件局部變量默認為auto型register型變量個數(shù)受限,且不能為long, double, float型static局部變量具有全局壽命和局部可見性static局部變量具有可繼承性extern不是變量定義,可擴展

9、外部變量作用域registerstatic局部autostatic外部外部存儲類別小結(jié):變量的存儲類型、作用域與生存期128.2 局部變量及其作用域和生存期 1. auto變量 在函數(shù)內(nèi)部(或復(fù)合語句內(nèi))定義變量時,若使用auto(或缺省) ,稱為“動態(tài)局部變量” 內(nèi)。 如在一函數(shù)中有定義:auto int a; 或 int a; 則整型變量a是一個自動類的局部變量。 auto變量的特點:1. 由于自動類局部變量的存儲單元是在進入這些局部變量所在的函數(shù)體(或復(fù)合語句)時分配,退出所在的函數(shù)體(或復(fù)合語句)時釋放,所以這些變量的生存期是“短期” 。2. 多次進入同一函數(shù)體(或復(fù)合語句)時,自動類

10、局部變量所分配的存儲位置可能不同。所以,未賦初值的自動變量其值為一個隨機值。3不同函數(shù)中使用同名變量不會相互影響。 13main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);auto變量的應(yīng)用示例(1/8) void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);內(nèi)存.main:a20002001200220032004200520062007動動態(tài)態(tài)存存儲儲區(qū)區(qū)main()void f(in

11、t x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b14內(nèi)存.main: a20002001200220032004200520062007動動態(tài)態(tài)存存儲儲區(qū)區(qū)main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b1020void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x

12、,y,t);auto變量的應(yīng)用示例(2/8)15內(nèi)存.main: a2000200120022003200420052006200720082009動動態(tài)態(tài)存存儲儲區(qū)區(qū)main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b1020void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);f: xf: yf: tauto變量的應(yīng)用示例(3/8)16內(nèi)存.main: a20002001

13、20022003200420052006200720082009動動態(tài)態(tài)存存儲儲區(qū)區(qū)main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b1020void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);102030f: xf: yf: tx=10,y=20,x+y=30auto變量的應(yīng)用示例(4/8)17內(nèi)存.main: a2000200120022003200420052006

14、200720082009動動態(tài)態(tài)存存儲儲區(qū)區(qū)main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b1020void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);x=10,y=20,x+y=30main: tauto變量的應(yīng)用示例(5/8)18內(nèi)存.main: a2000200120022003200420052006200720082009動動態(tài)態(tài)存存儲儲區(qū)區(qū)main()voi

15、d f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b2010void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);x=10,y=20,x+y=3010main: tauto變量的應(yīng)用示例(6/8)19內(nèi)存.main: a2000200120022003200420052006200720082009動動態(tài)態(tài)存存儲儲區(qū)區(qū)main()void f(int x,int y); int a , b;

16、a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b1020void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);f: xf: yf: tx=10,y=20,x+y=30auto變量的應(yīng)用示例(7/8)20void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);x=10,y=20,x+y=30內(nèi)存.main: a200020012002200320042005200620072

17、0082009動動態(tài)態(tài)存存儲儲區(qū)區(qū)main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b1020201030f: xf: yf: tx=10,y=20,x+y=30 x=20,y=10,x+y=30主函數(shù)運行結(jié)束時,內(nèi)存中所有的變量均被釋放auto變量的應(yīng)用示例(8/8)21 寄存器變量也是自動類變量。這種變量的值是保留在CPU內(nèi)部的寄存器中。 特點:程序運行速度快。主要針對過去的計算機速度慢。2. register變量說明1一個計算機系統(tǒng)中的寄存器數(shù)

18、目是有限的,因此只能定義少量的寄存器變量。當(dāng)程序中的寄存器變量較多時,或編譯程序認為指定的變量不適合放在寄存器中時,將自動按auto變量來處理。因此,register說明只是對編譯程序的一種建議。2由于register變量的值是放在寄存器內(nèi)而不是放在內(nèi)存中,因此register變量沒有地址,也就不能對它進行求地址運算。3為了提高寄存器的利用率,register變量應(yīng)盡量做到即定義即使用,用完就釋放。4有些編譯程序不理采寄存器變量的定義,直接將其當(dāng)auto變量來處理。 運算速度慢、訪問內(nèi)存速度慢223. 靜態(tài)存儲的局部變量 說明:1.靜態(tài)局部變量的作用域仍是從定義點到函數(shù)體(或復(fù)合語句)結(jié)束。即

19、仍具有作用域的局部特性。2.在整個程序運行期間,靜態(tài)局部變量在內(nèi)存的靜態(tài)存儲區(qū)中將長期占用存儲單元并保留其值(即便是函數(shù)運行結(jié)束),其生存期為“長期”,一直到程序運行結(jié)束。但要注意此變量及其值不能被其它函數(shù)使用。3.靜態(tài)局部變量的初值是在編譯期間賦予的(一次性的),在程序運行期間不再賦予初值。 對未賦初值的靜態(tài)局部變量,C編譯程序自動給它賦初值0。 在函數(shù)體(或復(fù)合語句)內(nèi)部,用static說明的變量,稱為靜態(tài)局部變量,存放在內(nèi)存的靜態(tài)存儲區(qū)。23例8.2 靜態(tài)局部變量與動態(tài)局部變量的比較 f()auto int b=0; /*或int b=0; */ b+; return b;g()stat

20、ic int c=0;/*或static int c;*/ c+; return c;main()int i; for(i=1;i4;i+) printf(%d%d%dn,i,f(),g();運行結(jié)果為:111212313 內(nèi)存.20002001200220032004動動態(tài)態(tài)存存儲儲區(qū)區(qū)main: if: b靜態(tài)存靜態(tài)存儲區(qū)儲區(qū)g: c24靜態(tài)局部變量使用的情形(例8.3) 需要保留函數(shù)上一次調(diào)用結(jié)束時的變量值。 注意:使用靜態(tài)局部變量要長期占用存儲空間,而且當(dāng)調(diào)用次數(shù)多時,難以確定靜態(tài)局部變量的當(dāng)前值。并且,不同的編譯系統(tǒng)對靜態(tài)局部變量的處理方法不盡相同。因此,如不必要,盡量不要使用靜態(tài)局

21、部變量。 例8.3 在函數(shù)中使用靜態(tài)局部變量來計算1到5的階乘值。int fac(int n)static int f=1; f=f*n; return f; main()int i; for(i=1;i=5;i+) printf(%d!=%dn,i,fac(i);程序運行結(jié)果為:1!=12!=23!=64!=245!=120258.3 全局變量及其作用域和生存期 全局變量只有靜態(tài)一種類別,放在靜態(tài)存儲區(qū)。1. 全局變量的作用域和生存期 全局變量是可以在函數(shù)外部任意位置上定義的變量,它的作用域是從定義點到整個源文件結(jié)束。 說明: (1)全局變量為函數(shù)之間的數(shù)據(jù)傳遞提供了一條通道。由于同一文件的

22、所有函數(shù)都能引用全局變量的值,如果在一個函數(shù)中改變了某全局變量的值,就能影響使用該全局變量的其它函數(shù),相當(dāng)于各個函數(shù)間有了直接傳遞的通道。(2)全局變量的生存期是整個程序的運行期間,即“長期”。(3)若全局變量與某一函數(shù)中的局部變量同名,則在該函數(shù)中,全局變量被屏蔽,使用局部變量。 26int max,min;float f(int a10) int i,sum=a0; float aver; max=a0; min=a0; for(i=1;imax) max=ai; if(aimin) min=ai); aver=sum/10.0; return aver; main()int x10,j;

23、 float average; for(j=0;j10;j+) scanf(%d,&xj); average=f(x);printf(max=%d,min=%d,average=%fn,max,min,average); 例例8.4 編一函數(shù)求出編一函數(shù)求出10個整數(shù)的最大值、最小值和平均值。個整數(shù)的最大值、最小值和平均值。27int i;main() void prt(); for(i=0;i5;i+) prt();void prt() for(i=0;i5;i+) printf( %c, *); printf(n);運行結(jié)果:*例例 外部變量副作用外部變量副作用282. 全局變量作

24、用域的擴展 (1) 當(dāng)全局變量定義在后,引用它的函數(shù)在前時,應(yīng)該在引用它的函數(shù)中用extern對此全局變量進行聲明,使其作用域從extern聲明處起,延伸到該函數(shù)末尾。也可將extern寫在函數(shù)之外,使其作用域延伸至文件末尾。 (2) 當(dāng)一個程序由多個文件組成時,每個文件都是一個獨立的編譯單位。如果多個文件中都需要用同一個全局變量,這時若在每個文件中都定義一個同名的全局變量,則單獨編譯各個文件時不會產(chǎn)生錯誤,編譯程序?qū)炊x分別為它們分配存儲空間;但當(dāng)連接時,將產(chǎn)生同一變量的重復(fù)定義的錯誤。 解決辦法是:在其中一個文件中定義的全局變量,在其它文件中用extern進行說明,說明這些全局變量已在某

25、一編譯單位中定義過,通知編譯程序不必再為它們開辟存儲單元,只是將作用域進一步擴展到本編譯單位中。 29main( )void gx(),gy(); extern int x,y; gx();gy(); void gx( )int x,y;void gy( ) x,y的原作用域擴展后新增的作用域extern int x,y; main() void gx() int x,y; void gy() x,y的作用域擴展后 x,y的作用域例:在同文件中擴展全局變量的作用域30/*/int x,y;main( )f1();f2(); f3(); f1( ) x=111; x,y的作用域/*/extern

26、 int x;f2( ) printf(%dn,x); /*111*/ f3( ) x+; printf(%dn,x); /*112*/ 例:在不同文件中擴展全局變量的作用域擴展后x的作用域31/*xt10210a.c*/#include int x=10;int y=10;void add(void) y=x+10; x*=2;void main() extern void sub(); x+=5; add(); sub();printf(x=%d,y=%dn,x,y);/*xt10210b.c*/void sub(void) extern int x; x-=5;習(xí)題:在不同文件中擴展全局變

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論