第六章模塊化程序設(shè)計與C語言函數(shù)課件_第1頁
第六章模塊化程序設(shè)計與C語言函數(shù)課件_第2頁
第六章模塊化程序設(shè)計與C語言函數(shù)課件_第3頁
第六章模塊化程序設(shè)計與C語言函數(shù)課件_第4頁
第六章模塊化程序設(shè)計與C語言函數(shù)課件_第5頁
已閱讀5頁,還剩61頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第六章 模塊化程序設(shè)計與C語言函數(shù)模塊化程序設(shè)計基礎(chǔ)1函數(shù)的聲明、定義和調(diào)用2程序設(shè)計實例4變量的存儲屬性310/2/2022第六章 模塊化程序設(shè)計與C語言函數(shù)模塊化程序設(shè)計基礎(chǔ)1函數(shù)的6.1.1 模塊化程序設(shè)計1. 模塊化程序設(shè)計基本思想基本思想:將程序按功能分割成小模塊。開發(fā)方法: FTTB,逐步分解,分而治之。特點和作用:模塊獨立,功能單一,結(jié)構(gòu)清晰,接口簡單??刂屏顺绦蛟O(shè)計的復(fù)雜性。提高模塊元件的可靠性??s短開發(fā)周期。避免程序開發(fā)的重復(fù)勞動。易于維護和功能擴充。 FBTT方法與FTTB方法6.1 模塊化程序設(shè)計基礎(chǔ)What to do ?How to do ?10/2/20226.1.

2、1 模塊化程序設(shè)計6.1 模塊化程序設(shè)計基礎(chǔ)What模塊化程序設(shè)計的方法基礎(chǔ)。特點:把復(fù)雜問題的求解過程分步驟進行。面向目標(biāo)。采取先全局、后局部的逐步分解思想。有利于將更多精力集中于較小模塊的局部設(shè)計中。避免了盲目性。降低了系統(tǒng)設(shè)計與實現(xiàn)的整體工作量。FTTB(From Top To Bottom)10/2/2022模塊化程序設(shè)計的方法基礎(chǔ)。FTTB(From Top To 實踐中:FBTT與FTTB結(jié)合來解決問題。在問題求解步驟和方法的確定上用FTTB方法,在將所有模塊構(gòu)成一個整體時用FBTT方法。FBTT(From Bottom To Top)例6-1 以FTTB、逐步求精的模塊化分解思想

3、,分析1948年下半年解放戰(zhàn)爭戰(zhàn)略決戰(zhàn)問題。P125-12610/2/2022實踐中:FBTT與FTTB結(jié)合來解決問題。在問題求解步驟和方例6-2 求1+2+100的和。分析:問題可分為三個部分,對應(yīng)三個模塊:1) 確定求值范圍2) 計算過程3) 輸出結(jié)果給定求和的上界計算i從1到給定上界的和輸出所求的和值用選定方法求和10/2/2022例6-2 求1+2+100的和。給定求和的上界計算i從1 例6-3 分析九九乘法表輸出功能。分析九九表的形狀(例如第一種)。打印九行,每行分成兩個部分:前導(dǎo)空格和九九表的口訣內(nèi)容。右上角九九表輸出九行輸出某行i口訣構(gòu)成:3*3 9 (即i*j=i*j)輸出第i

4、行前導(dǎo)空格輸出第i行口訣輸出第i行的i-1個前導(dǎo)空格口訣輸出第i行第k個前導(dǎo)空格口訣輸出第i行9-i+1個口訣輸出第i行第k個口訣空格口訣與口訣字符結(jié)構(gòu)相同10/2/2022 例6-3 分析九九乘法表輸出功能。右上角九九表輸出九行輸出2. 模塊化程序的基本特征模塊的IPO結(jié)構(gòu):要注意模塊功能的獨立性、完成功能所需的參數(shù)和提供給外界的輸出信息。 模塊的接口問題:唯一的通信渠道。應(yīng)保證接口的單入口和單出口特征。模塊的功能問題:大小要合適;具有較強的獨立性和相對簡單性;內(nèi)部實現(xiàn)方法也應(yīng)按照結(jié)構(gòu)化程序設(shè)計思想進行組織和設(shè)計。10/2/20222. 模塊化程序的基本特征9/24/20226.1.2 C語

5、言對模塊化程序設(shè)計技術(shù)的支持1. 函數(shù)式程序語言結(jié)構(gòu)函數(shù)帶入函數(shù)參數(shù)帶出計算結(jié)果圖6-6 C語言函數(shù)的基本結(jié)構(gòu)10/2/20226.1.2 C語言對模塊化程序設(shè)計技術(shù)的支持1. 函數(shù)式程序float average(float fA,float fB,float fC) float fAve; fAve=(fA+fB+fC)/3; return fAve; /*End of average()*/外部向內(nèi)部傳遞信息內(nèi)部控制信息由內(nèi)部向外傳遞信息1. 允許進行模塊內(nèi)部及外部的信息交換3. 具有編譯預(yù)能力以方便模塊化調(diào)試和移植10/2/2022float average(float fA,floa

6、t f6.2.1 C 語言程序的組織結(jié)構(gòu)6.2 函數(shù)的聲明、定義和調(diào)用結(jié)構(gòu)源程序n函數(shù)1函數(shù)2函數(shù)m源程序i源程序1C程序聲明區(qū)執(zhí)行體10/2/20226.2.1 C 語言程序的組織結(jié)構(gòu)6.2 函數(shù)的聲明、定義和6.2.2 函數(shù)聲明與定義從用戶角度分為:標(biāo)準(zhǔn)函數(shù)(庫函數(shù)):由系統(tǒng)提供。用戶自定義函數(shù):由程序員提供。從函數(shù)形式上分為:無參函數(shù)有參函數(shù)使用庫函數(shù)應(yīng)注意:1) 函數(shù)完成的功能 2) 參數(shù)數(shù)目和順序及各參數(shù)意義和類型 3) 返回值的意義和類型4) 調(diào)用函數(shù)所需的包含文件(頭文件)先聲明、后定義、再引用10/2/20226.2.2 函數(shù)聲明與定義使用庫函數(shù)應(yīng)注意:先聲明、后定義、1. 函

7、數(shù)的聲明(Function Declaration)聲明的作用:告訴編譯器函數(shù)類型、參數(shù)個數(shù)及類型,以便進行類型檢驗,保證調(diào)用的數(shù)據(jù)傳遞的正確性。對被調(diào)用函數(shù)的要求:函數(shù)已經(jīng)被定義,即函數(shù)存在對庫函數(shù),知道庫的頭文件.h對自定義函數(shù),有函數(shù)類型聲明函數(shù)聲明(函數(shù)原型聲明)的一般形式: 函數(shù)類型 函數(shù)名(形參類型1 形參名1,形參類型n 形參名n) ; 或 函數(shù)類型 函數(shù)名() ;P129:函數(shù)的聲明形參數(shù)據(jù)類型和順序很重要必須要用分號結(jié)束10/2/20221. 函數(shù)的聲明(Function Declaration)函數(shù)定義與函數(shù)聲明不同函數(shù)聲明的位置(P133)下列情況,可不作函數(shù)聲明:對ch

8、ar或int型函數(shù)(隱含聲明)函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前有些系統(tǒng)要求函數(shù)聲明指出函數(shù)返值和形參類型,即使對void和int型函數(shù)也要進行函數(shù)說明(如Borland C+)P130-13310/2/2022函數(shù)定義與函數(shù)聲明不同P130-1339/24/2022一個完整形式的函數(shù)聲明/*exam0604a.c:完整形式的函數(shù)聲明*/#include int main(void)float fA=1,fB=2,fC=3;float sum(float fA,float fB,float fC); /*聲明*/printf(sum=%fn,sum(fA,fB,fC); /*調(diào)用*/return 0

9、; /*End of main()*/float sum(float fA,float fB,float fC) /*定義*/return (fA+fB+fC); /*End of sum()*/例6-4 函數(shù)聲明實例。聲明了一個float型函數(shù)sum() sum函數(shù)的定義sum()函數(shù)有三個形式參數(shù)觀察函數(shù)的聲明和定義的區(qū)別10/2/2022一個完整形式的函數(shù)聲明例6-4 函數(shù)聲明實例。聲明了一個fl允許聲明與定義的參數(shù)名字不同#include /*exam0604b.c*/int main(void) float x=1,y=2,z=3;float sum(float x,float y,

10、float z);/*聲明參數(shù)名*/printf(sum=%fn,sum(x+y,y,z);/*實參名*/return 0; /*End of main()*/float sum(float a,float b,float c)/*定義體參數(shù)名*/return (a+b+c); /*End of sum()*/10/2/2022允許聲明與定義的參數(shù)名字不同9/24/2022聲明時可不給參數(shù)名,但類型要一一對應(yīng)#include /*exam0604c.c*/int main(void) float x=1,y=2,z=3;float sum(float,float,float ); /*聲明*/

11、printf(sum=%fn,sum(x,y,z); /*實參*/return 0; /*End of main()*/float sum(float a,float b,float c) return (a+b+c); /*End of sum()*/10/2/2022聲明時可不給參數(shù)名,但類型要一一對應(yīng)9/24/2022/*exam0604d.c*/#include int main(void)float x=1,y=2,z=3;float sum(int a,float b,float c); /*聲明*/printf(sum=%fn,sum(x,y,z); /*調(diào)用*/return 0

12、; /*End of main()*/float sum(float a, float b, float c) /*定義*/return (a+b+c); /*End of sum()*/類型不一致出錯信息:Type mismatch in redeclaration of sum10/2/2022/*exam0604d.c*/類型不一致出錯信息:9/24/*定義時參數(shù)名不能省略*/#include int main(void) float x=1,y=2,z=3;float sum(float a,float b,float c); /*聲明*/printf(sum=%fn,sum(x,y,

13、z); /*調(diào)用*/return 0; /*End of main()*/float sum(float, float,float) /*定義*/return (a+b+c); /*End of sum()*/ 定義時省略了參數(shù)名出錯信息:Argument missing name in function sumUndefined symbol a in function sumUndefined symbol b in function sum Undefined symbol c in function sum10/2/2022/*定義時參數(shù)名不能省略*/定義時省略了參數(shù)名出錯信息:9/2

14、. 函數(shù)定義(Function Definition)是完成模塊功能實現(xiàn)的主要工作。它對應(yīng)一個分程序功能,也稱為函數(shù)體。定義一般格式:合法標(biāo)識符函數(shù)類型 函數(shù)名(類型1 形參1, ,類型n 形參n) 聲明區(qū)域 /*變量或函數(shù)等的聲明*/ 執(zhí)行語句區(qū)域 /*可執(zhí)行命令序列*/ 返回命令 /*retrun*/現(xiàn)代風(fēng)格:函數(shù)體函數(shù)返回值類型。缺省時為int或void10/2/20222. 函數(shù)定義(Function Definition)合法例 有參函數(shù)(現(xiàn)代風(fēng)格)int max(int nX,int nY) int nZ; nZ=nXnY?nX:nY; return(nZ); /*End of m

15、ax()*/例 有參函數(shù)(現(xiàn)代風(fēng)格) int max(int nX, nY) int nZ; nZ=nXnY?nX:nY; return(nZ); /*End of max()*/例 空函數(shù)dummy() /*End of dummy()*/函數(shù)體為空例 無參函數(shù)printStar() printf(*n); /*End of printStar()*/或printStar(void ) printf(*n”); /*End of printStar()*/10/2/2022例 有參函數(shù)(現(xiàn)代風(fēng)格)例 有參函數(shù)(現(xiàn)代風(fēng)格)例 空函函數(shù)類型 函數(shù)名(形參名1,形參名n)數(shù)據(jù)類型1 形參名1;數(shù)據(jù)

16、類型n 形參名n; 語句組早期的函數(shù)定義經(jīng)典方法double sum(n1,n2,d1,d2)double d1,d2;int n1,n2; return (n1+n2+d1+d2); /*End of sum()*/函數(shù)類型形參名列表聲明次序和現(xiàn)代格式的區(qū)別參數(shù)類型10/2/2022函數(shù)類型 函數(shù)名(形參名1,形參名n)早期的函數(shù)定義經(jīng)典#include float average(float val_1,float val_2,float val_3);int main(void) float x=1,y=2,z=3,q=4,t=5;float ave_1,ave_2; /*存放返回結(jié)果*

17、/ave_1=average(x,y,z); printf(ave_1=%fn,ave_1); ave_2=average(x,q,t); printf(ave_2=%fn,ave_2); return 0; /*End of main()*/float average(float val_1,float val_2,float val_3) float ave;ave=(val_1+val_2+val_3)/3.0;return ave; /*End of average()*/文件包含編譯預(yù)處理命令函數(shù)聲明函數(shù)調(diào)用函數(shù)調(diào)用函數(shù)定義10/2/2022#include 文件包含編譯預(yù)處理命令函

18、3. 函數(shù)的返回值返回語句格式:return (表達式); 或 return 表達式; 或 return;功能:使控制從被調(diào)用函數(shù)返回到調(diào)用函數(shù),同時把返值帶給調(diào)用函數(shù)。說明:一個函數(shù)可有多個return語句。若無return語句,遇函數(shù)的時,自動返回調(diào)用函數(shù)。若函數(shù)類型與return語句中表達式值的類型不一致,按前者為準(zhǔn),自動轉(zhuǎn)換函數(shù)調(diào)用轉(zhuǎn)換。void型函數(shù)。例 無返回值函數(shù)。void swap(int x,int y) int temp; temp=x; x=y; y=temp; /*End of swap()*/10/2/20223. 函數(shù)的返回值例 無返回值函數(shù)。9/24/2022pr

19、intStar() printf(*); /*End of printStar*/int main(void) int nA; nA=printStar(); printf(%d,nA); /*End of main()*/例 函數(shù)帶回不確定值。輸出:*5void printStar() printf(*); /*End of printStar*/int main(void) int nA; nA=printStar(); printf(%d,nA); /*End of main()*/編譯錯誤!Error: Not an allowed type in function main10/2/

20、2022printStar()例 函數(shù)帶回不確定值。輸出:*例 函數(shù)返回值類型轉(zhuǎn)換#includeint max(float fA,float fB);int main(void) float fA,fB; int nC; scanf(%f,%f,&fA,&fB); nC=max(fA,fB); printf(Max is %dn,nC); /*End of main()*/int max(float fX, float fY) float fZ; fZ=fXfY?fX:fY; return(fZ); /*End of max()*/返回值要自動轉(zhuǎn)換成整型!10/2/2022例 函數(shù)返回值類型

21、轉(zhuǎn)換#include返回6.2.3 函數(shù)的調(diào)用 參數(shù)是函數(shù)調(diào)用時的信息交換載體,其傳遞是函數(shù)調(diào)用過程的重要環(huán)節(jié)。 C語言函數(shù)調(diào)用分為傳值調(diào)用和傳地址調(diào)用(第九章)兩種。1. 函數(shù)的傳值調(diào)用調(diào)用方法:函數(shù)名(實參表)說明:實參與形參個數(shù)相等,類型一致,按順序一一對應(yīng)10/2/20226.2.3 函數(shù)的調(diào)用 參數(shù)是函數(shù)調(diào)用時的信息float sum(float fA,float fB,float fC) return sum; /*End of sum()*/函數(shù)的IO信息路徑10/2/2022float sum(float fA,float fB,fl注意函數(shù)參數(shù)求值順序:自右向左。#inclu

22、deint f(int nA,int nB);int main(void) int i=2,nP; nP=f(i,+i); printf(%d,%d,nP,i); return 0; /*End of main()*/int f(int nA, int nB) int nC; if (nAnB) nC=1; else if (nA=nB) nC=0; else nC=-1; return(nC); /*End of f()*/運行結(jié)果:0,3#includeint f(int nA,int nB);int main(void) int i=2,nP; nP=f(i, i+); printf(%

23、d,nP); return 0; /*End of main()*/int f(int nA, int nB) int nC; if (nAnB) nC=1; else if (nA=nB) nC=0; else nC=-1; return(nC); /*End of f()*/運行結(jié)果:1,310/2/2022注意函數(shù)參數(shù)求值順序:自右向左。#includey?x:y; return(z); /*End of max()*/例 比較兩個數(shù)并輸出大者。#includeint max(int x,int y);int main(void) int a,b,c; scanf(%d,%d,&a,&b

24、); c=max(a,b); printf(Max is %d,c); /*End of main()*/int max(int x, int y) int z; z=xy?x:y; return(z); /*End of max()*/形參實參10/2/2022形參與實參c=max(a,b);main()max()int說明:實參必須有確定的值形參必須指定類型形參與實參類型一致,個數(shù)相同若形參與實參類型不一致,自動按形參類型轉(zhuǎn)換函數(shù)調(diào)用轉(zhuǎn)換形參在調(diào)用前不占內(nèi)存;調(diào)用執(zhí)行時為形參分配內(nèi)存;調(diào)用結(jié)束,釋放空間。其存儲空間是不固定的且值是不可繼承的實參是特定存儲空間中的值,在調(diào)用期間值不會發(fā)生變化

25、且存儲空間相對固定10/2/2022說明:9/24/2022例6-7 形參和實參的虛實結(jié)合實例。#include float average(float val_1,float val_2,float val_3) float ave;ave=(val_1+val_2+val_3)/3.0;return ave; /*End of average()*/int main(void) float x=1,y=2,z=3,q=4,t=5; float ave_1,ave_2; ave_1=average(x,y,z); printf(ave_1=%fn,ave_1); ave_2=average(

26、x,q,t); printf(ave_2=%fn,ave_2); return 0; /*End of main()*/65470654746548665490654946547865482 1.000000 2.000000 3.0000004.0000005.000000*xytave_1ave_2zq*val_2val_1val_31.0000002.0000003.0000002.0000001.0000004.0000005.0000003.33333310/2/2022例6-7 形參和實參的虛實結(jié)合實例。654706547465參數(shù)傳遞方式值傳遞方式:函數(shù)調(diào)用時為形參分配單元,并將

27、實參值復(fù)制到形參中;調(diào)用結(jié)束時形參單元被釋放,實參單元仍保留并維持原值值傳遞特點:形參與實參占用不同的內(nèi)存單元。單向傳遞。10/2/2022參數(shù)傳遞方式9/24/20221020 x:y:調(diào)用前:調(diào)用后:1020 x:y:例6-8 交換兩個數(shù)。#include void swap(int a,int b);int main(void) int x=10,y=20; printf(x=%d,y=%dn,x,y); printf(swapped:n); swap(x,y); printf(x=%d,y=%dn,x,y); /*End of main()*/void swap(int a,int b

28、) int temp; temp=a; a=b; b=temp; /*End of swap()*/調(diào)用:1020a:b:1020 x:y:swap():1020 x:y:2010a:b:temp這里可以看:到x,y的值并沒有發(fā)生變化,想要交換主函數(shù)中的變量x和y的值,該如何處理呢?10/2/20221020 x:y:調(diào)用前:調(diào)用后:1020 x:y:例6-8 地址傳遞方式:函數(shù)調(diào)用時,將實參的存儲地址作為參數(shù)值傳遞給形參的參數(shù)傳遞方式。實質(zhì)上也是值傳遞,不過穿的是形參的地址值,而不是形參所在存儲空間中的數(shù)據(jù)值。傳地址值的特點:形參與實參占用(指向)同樣的存儲單元“雙向”傳遞實參和形參必須是地

29、址10/2/2022地址傳遞方式:函數(shù)調(diào)用時,將實參的存儲地址作為參數(shù)值傳遞給形例 交換兩個數(shù)x59y調(diào)前:xp159y調(diào)swap:&x&yp2x95y交換:p1&x&yp2x95y返回:void swap(int *p1,int *p2) int p; p=*p1; *p1=*p2; *p2=p; /*End of swap()*/int main(void) int x,y; scanf(%d,%d,&x,&y); printf(x=%d,y=%dn,x,y); printf(swapped:n); swap(&x,&y); printf(x=%d,y=%dn,x,y); return 0

30、; /*End of main()*/10/2/2022例 交換兩個數(shù)x59y調(diào)前:xp159y調(diào)swap:&x&2. 函數(shù)嵌套調(diào)用函數(shù)定義不可嵌套,但調(diào)用可以嵌套main()調(diào)用函數(shù)f1return 0;f1函數(shù)f2函數(shù)調(diào)用函數(shù)f210/2/20222. 函數(shù)嵌套調(diào)用main()調(diào)用函數(shù)f1return 0;例6-10 計算一個數(shù)的絕對值平方根。float absoluteValue(float x); float squareRoot(float x);float absoluteValue(float x) if (x=epsilon) guessValue=(x/guessValue+

31、guessValue)/2.0; return guessValue; /*End of square()*/int main(void) printf(SquareRoot(2.0)=%fn,squareRoot(2.0);return 0; /*End of main()*/main()squareRoot(2.0)return 0;squareRoot()absoluteValue()x=absoluteValue(x)guessValue=absoluteValue(x/guessValue+guessValue)/2.0)return guessValue;return x;retu

32、rn x;10/2/2022例6-10 計算一個數(shù)的絕對值平方根。main()squar3. 函數(shù)的遞歸調(diào)用*函數(shù)直接或間接調(diào)用自己的調(diào)用f()調(diào)f()調(diào)f2()調(diào)f1()f1()f2()int f(int nX) int nY,nZ; nZ=f(nY); . return(2*nZ);int f1(int nX) int nY,nZ; nZ=f2(nY); . return (2*nZ);int f2(int nT) int nA,nC; nC=f1(nA); . return (3+nC);說明C語言對遞歸函數(shù)的自調(diào)用次數(shù)沒有限制每調(diào)用函數(shù)一次,系統(tǒng)將在內(nèi)存堆棧區(qū)分配空間,用于存放函數(shù)變量

33、、返回值等信息。所以遞歸次數(shù)過多可能引起堆棧溢出10/2/20223. 函數(shù)的遞歸調(diào)用*f()調(diào)f()調(diào)f2()調(diào)f1()f1例6-11 直接遞歸求n的階乘。int fact(int num) if (num0) /*n0時繼續(xù)求n!*/ nTemp=fact(n); printf(The %d!=%dn,n,nTemp); else printf(n must be greater than zero!n); return 0; /*End of main()*/10/2/2022例6-11 直接遞歸求n的階乘。int fact(int nint main(void) nTemp=fact(

34、4); /*main()*/int fact(4) if (num=1) return 1; else return 4*fact(3); /*fact()*/int fact(3) if (num=1) return 1; else return 3*fact(2); /*fact()*/int fact(1) if (num=1) return 1; else return 1*fact(0); /*fact()*/int fact(2) if (num=1) return 1; else return 2*fact(1); /*fact()*/2*1=23*2=64*6=24nTemp=

35、24n=4時fact()的執(zhí)行過程:10/2/2022int main(void)int fact(4) int例6-12 間接遞歸求n的階乘。例6-13 Hanoi塔問題。10/2/2022例6-12 間接遞歸求n的階乘。例6-13 Hanoi塔問題6.3 變量的存儲屬性變量屬性研究的內(nèi)容:可操作屬性(數(shù)據(jù)類型屬性)存儲屬性(數(shù)據(jù)在存儲空間的分配與有效性屬性)可改變屬性(值型變量還是指針型變量)訪問屬性(直接訪問還是間接訪問) 可操作屬性在第二章作過詳細討論,訪問屬性及值的可改變屬性將在第九章討論。10/2/20226.3 變量的存儲屬性變量屬性研究的內(nèi)容:9/24/20226.3.1 變量

36、的存儲屬性和可操作屬性 由第二章的變量討論知道,變量是對存放數(shù)據(jù)的存儲空間及其值的一種抽象。變量聲明、定義和使用的注意事項: 變量的存儲數(shù)據(jù)類型問題。不同數(shù)據(jù)類型的存放格式各不相同,有效取值范圍及能夠進行的操作也有區(qū)別,它們是變量的操作屬性; 變量的有效作用范圍、所用存儲器類別、有效作用時間段(生成周期)和存儲數(shù)據(jù)類別等構(gòu)成了變量的存儲屬性內(nèi)容。引入10/2/20226.3.1 變量的存儲屬性和可操作屬性 由第二C語言系統(tǒng)的內(nèi)存映像堆棧區(qū)域(Stack)堆區(qū)域(Heap)全局變量區(qū)域(Global)C程序代碼(Code)變量的4種存儲屬性類型說明修飾符auto自動變量(動態(tài)變量)static靜

37、態(tài)變量register寄存器變量(動態(tài)變量)extern外部變量10/2/2022C語言系統(tǒng)的內(nèi)存映像堆棧區(qū)域(Stack)堆區(qū)域(Heap)int average(int n1,int n2,int n3) int nX,nY;int nX,nY;int nX,nY;int main(void) int nX,nY;6.3.2 變量在語言程序代碼中的位置屬性在函數(shù)內(nèi)部出現(xiàn)在分程序中出現(xiàn)在函數(shù)體外部出現(xiàn)在main()函數(shù)中出現(xiàn)函數(shù)參數(shù)作為函數(shù)返回值總結(jié):局部變量參數(shù)變量全局變量外部變量10/2/2022int average(int n1,int n2,int 6.3.3 變量的生成周期及有效

38、作用范圍按生存周期臨時變量全程變量局部的全局的局部的1. 臨時存儲變量及其有效作用范圍臨時變量在程序執(zhí)行時進行空間分配且局部有效,也稱動態(tài)變量。特點:在執(zhí)行的某一時刻動態(tài)建立,在另外一個時刻被動態(tài)撤銷或回收。從位置上看,除了在函數(shù)體外聲明外,沒有static或extern修飾的都是臨時變量。例如:函數(shù)的形參變量、函數(shù)或分程序內(nèi)部所聲明的寄存器變量和自動變量都屬于動態(tài)變量。10/2/20226.3.3 變量的生成周期及有效作用范圍按生存周期臨時變量動態(tài)變量分為:自動變量和寄存器變量自動變量聲明格式如下:auto 數(shù)據(jù)類型 變量名=常量表達式,; auto修飾可有可無。 函數(shù)體內(nèi)部聲明的變量、函數(shù)

39、參數(shù)變量和其它分程序中聲明的變量都屬于自動變量。 自動變量在程序段執(zhí)行時臨時建立和分配存儲空間,離開時自動撤銷以便資源被其他它序段重用。自動變量在聲明它的分程序中有效10/2/2022動態(tài)變量分為:自動變量和寄存器變量自動變量自動變量在聲明它的void prt(int n1,int n2) int nX,nY; printf(prts source n1=%d n2=%dn,n1,n2); nX=n1+10,nY=n2+10; printf(prt()s nX=%d nY=%dn,nX,nY); n1+;n2+; printf(prt()s modified n1=%d n2=%dn,n1,n

40、2); return; /*End of prt()*/int main(void) int nX=10,nY=20; printf(Before call:nX=%d nY=%dn,nX,nY); prt(nX,nY); printf(After call:nX=%d nY=%dn,nX,nY); return 0; /*End of main()*/Before call:nX=10 nY=20prt()s source: n1=10 n2=20prt()s nX=20 nY=30prt()s modified n1=11 n2=21After call:nX=10 nY=20prt()內(nèi)

41、的自動變量main()內(nèi)的自動變量可見:main()中的nX,nY調(diào)用prt()前后的值未發(fā)生變化例6-14 自動變量的局部有效性。思考形參n1,n2和實參nX,nY值的變化情況,體會函數(shù)調(diào)用時值傳遞的特點10/2/2022void prt(int n1,int n2) Befor例如:例14中main()的nX,nY及prt()中的nX, nY的存儲空間分布與同名屏蔽問題。FFD4FFD6FFC8FFCA1020nXnY2030nYnXmain()中的nX,nY變量的地址和值prt()中的nX,nY變量地址和值地址地址內(nèi)、外層同名變量的自動屏蔽值值自動變量在賦初值之前的值不確定多次調(diào)用函數(shù)時

42、,自動變量值不保留10/2/2022例如:例14中main()的nX,nY及prt()中的nX,例6-15 自動變量賦值之前的不確定性。int main(void)int num1,num2,num3; /*聲明但不初始化*/float value1,value2;char ch;double dValue;printf(num1=%d num2=%d um3=%dn,num1,num2,num3);printf(value1=%f value2=%fn,value1,value2);printf(dValue=%lfn,dValue);printf(ch=%cn,ch);return 0;

43、/*End of main()*/第三次運行結(jié)果:num1=-44 num2=27617 num3=-48value1=0.000000 value2=0.000000dValue=0.000000ch=第一次運行結(jié)果:num1=104 num2=27 num3=-48value1=0.000000 value2=0.000000dValue=0.000000ch=第二次運行結(jié)果:num1=774 num2=0 num3=-48value1=0.000000 value2=0.000000dValue=0.000000ch=可見:對整型自動變量在不給初始值時它是不確定的10/2/2022例6-

44、15 自動變量賦值之前的不確定性。第三次運行結(jié)果:第一例6-16 函數(shù)的多次調(diào)用之間自動變量沒有繼承性。#include /*自動變量繼承性測試*/int inheritance_test(int num1, int num2)int nX,nY; /*nX,nY為觀察對象*/printf(Before modified:nX=%d nY=%dn,nX,nY);nX=num1-num2;nY=num1+num2; /*修正nX,nY*/printf(After modified:nX=%d nY=%dn,nX,nY);return 0; /*inheritance_test()*/int ma

45、in(void)int i;for(i=1;i5;i+) inheritance_test(i*i, i+i); /*5次調(diào)用*/return 0; /*End of main()*/Before modified:nX=1 nY=2444After modified:nX=-1 nY=3Before modified:nX=2 nY=2444After modified:nX=0 nY=8Before modified:nX=3 nY=2444After modified:nX=3 nY=15Before modified:nX=4 nY=2444After modified:nX=8 nY

46、=24結(jié)果分析:第一次調(diào)用后:nX=-1,nY=3;第二次調(diào)用計算賦值前,nX=2,nY=2444。它們與上次調(diào)用時最后計算結(jié)果完全不同,表明上次計算結(jié)果沒有被保留下來。后續(xù)調(diào)用與此相似。nX和nY的隨機性與具體編譯器及執(zhí)行環(huán)境有關(guān)。10/2/2022例6-16 函數(shù)的多次調(diào)用之間自動變量沒有繼承性。Befor寄存器變量聲明格式如下:register 數(shù)據(jù)類型 變量名=常量表達式,;以寄存器方式存放,而不是主存儲器。主要的優(yōu)勢是快,但寄存器數(shù)量資源有限。Register只能修飾局部變量和函數(shù)形參變量。例6-16 寄存器變量實例。(P151)10/2/2022寄存器變量例6-16 寄存器變量實例

47、。(P151)9/24/2. 全程存儲變量全程變量(Gloabal (life period)Variable):變量所占存儲空間在整個程序執(zhí)行期間都有效程變量分為:靜態(tài)全程變量和外部全程變量全程性與全局性的區(qū)別:全程性指的是變量的生存周期性或時間屬性;全局性和局部性指的是變量在代碼段中的有效作用范圍或空間屬性。10/2/20222. 全程存儲變量全程變量(Gloabal (life pe靜態(tài)變量聲明格式如下:static 數(shù)據(jù)類型 變量名=常量表達式,;在編譯時分配空間,且在程序執(zhí)行期間都不變。從執(zhí)行開始直到整個程序結(jié)束。是函數(shù)或文件中的永久變量,分為靜態(tài)局部變量和靜態(tài)全局變量。聲明在函數(shù)、

48、分程序或文件內(nèi)部的靜態(tài)變量在外部不可見。但多次調(diào)用時值可以繼承,以實現(xiàn)局部變量的繼承性。必須初始化且用常量表達式。不顯式初始化時,編譯時的自動初始化的規(guī)定是:整型數(shù)據(jù)初值為0,浮點型數(shù)據(jù)值為0.0,字符數(shù)據(jù)為空格 。10/2/2022靜態(tài)變量9/24/2022例6-18 靜態(tài)局部變量和自動變量的可繼承性對比。#include int main(void) void increment(void); increment(); increment(); increment(); return 0; /*End of main()*/void increment(void) int n=0; /*a

49、uto*/ n+; printf(n=%dn,n); return; /*End of increment()*/#include int main(void) void increment(void); increment(); increment(); increment(); return 0; /*End of main()*/void increment(void) static int n=0; /*auto*/ n+; printf(n=%dn,n); return; /*End of increment()*/運行結(jié)果:n=1n=1n=1運行結(jié)果:n=1n=2n=3n無繼承性n

50、有繼承性10/2/2022例6-18 靜態(tài)局部變量和自動變量的可繼承性對比。#incl例6-19 靜態(tài)局部變量的隱式初始化。#include void prt(void) /*輸出靜態(tài)局部變量的值*/static int num; /*聲明局部靜態(tài)變量但不作顯式初始化*/static float val;static char ch;static long lNum;static double dVal;static long unsigned luNum;printf(num=%d, val=%f, ch=%c, ch=%dn,num,val,ch,ch);printf(lNum=%ld,

51、dVal=%lf, luNum=%lun,lNum,dVal,luNum);return; /*End of prt()*/int main(void)prt();return 0; /*End of main()*/運行測試結(jié)果:num=0, val=0.000000, ch= ,ch=0lNum=0, dVal=0.000000, luNum=0注意:1) 沒有對靜態(tài)局部變量顯式初始化時,系統(tǒng)自行完成初始化。2) 在主函數(shù)中引用prt()的靜態(tài)變量時,編譯器將提示“Undefined symbol of num in function main”錯誤。它表明prt()中的靜態(tài)局部變量在分程

52、序外部是不可見的,不能在外部進行引用。10/2/2022例6-19 靜態(tài)局部變量的隱式初始化。運行測試結(jié)果:注意:1例6-20 靜態(tài)局部變量的有效作用范圍測試。#include void prt(void) static int nX=1; printf(In prt() before nX+=2:nX=%dn,nX); nX+=2; printf(In prt() after nX+=2:nX=%dn,nX); return; /*End of prt()*/int main(void) static int nX=10; printf(Before 1st prt() call:nX=%d

53、n,nX); prt();nX+; printf(After 1st prt() call:nX=%dn,nX); printf(Before 2nd prt() call:nX=%dn,nX); prt();nX+; printf(After 2nd prt() call:nX=%dn,nX); return 0; /*End of main()*/運行測試結(jié)果:Before 1st prt() call:nX=10In prt() before nX+=2:nX=1In prt() after nX+=2:nX=3After 1st prt() call:nX=11Before 2nd p

54、rt() call:nX=11In prt() before nX+=2:nX=3In prt() after nX+=2:nX=5After 2nd prt() call:nX=12注意: prt()內(nèi)對nX的修改有繼承性,但作用范圍只能在prt()內(nèi),它影響不主函數(shù)中的nX。這正是模塊化設(shè)計技術(shù)需要的特性。10/2/2022例6-20 靜態(tài)局部變量的有效作用范圍測試。運行測試結(jié)果:注全局變量(外部變量)聲明:聲明位置在函數(shù)體外部。整個程序可見,它可以被任何代碼段引用。程序執(zhí)行期間一直占用所分配存儲空。必須進行聲明初始化。否則,系統(tǒng)將自動初始化。初始化規(guī)定同靜態(tài)變量。基本作用域從聲明處直到所在文件末尾。所有外部變量不能重名,否則,編譯器將報告錯誤信息“Redeclaration of 變量名”。但可以和函數(shù)體內(nèi)的自動變量、參數(shù)變量以及其它類型的非外部變量重名。此時系統(tǒng)自動采用屏蔽技術(shù)進行重名處理。int nX,nY;int main(void)int nZ;float q;void f1()int nW;float f2()圖6-2

溫馨提示

  • 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. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論