第三章 模塊化程序設(shè)計_第1頁
第三章 模塊化程序設(shè)計_第2頁
第三章 模塊化程序設(shè)計_第3頁
第三章 模塊化程序設(shè)計_第4頁
第三章 模塊化程序設(shè)計_第5頁
已閱讀5頁,還剩54頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第三章第三章 模塊化程序設(shè)計模塊化程序設(shè)計2/59第三章第三章 模塊化程序設(shè)計模塊化程序設(shè)計n3.1 模塊化程序設(shè)計的方法與特點模塊化程序設(shè)計的方法與特點 n3.2 函數(shù)的定義函數(shù)的定義n3.3 無返回值函數(shù)的定義與調(diào)用無返回值函數(shù)的定義與調(diào)用 n3.4 有返回值函數(shù)的定義與調(diào)用有返回值函數(shù)的定義與調(diào)用 n3.5 函數(shù)嵌套調(diào)用和函數(shù)聲明函數(shù)嵌套調(diào)用和函數(shù)聲明 n3.6 函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用n3.7 庫函數(shù)的使用庫函數(shù)的使用n3.8 全局變量和局部變量全局變量和局部變量 n3.9 指針和指針作為函數(shù)參數(shù)指針和指針作為函數(shù)參數(shù) n3.10 返回指針值的函數(shù)返回指針值的函數(shù) n3.11 函數(shù)

2、的指針函數(shù)的指針n3.12 典型例題典型例題3/593.1 模塊化程序設(shè)計的方法和特點模塊化程序設(shè)計的方法和特點n什么是模塊化程序設(shè)計?什么是模塊化程序設(shè)計?模塊化程序設(shè)計就是將一個復雜的大問題,分解為一個個模塊化程序設(shè)計就是將一個復雜的大問題,分解為一個個獨立的簡單的小問題獨立的簡單的小問題(即模塊即模塊),分別解決簡單的小問題,分別解決簡單的小問題,進而解決復雜的大問題。進而解決復雜的大問題。n在在C語言中,這些獨立的簡單的語言中,這些獨立的簡單的模塊就是函數(shù)模塊就是函數(shù)。 模塊分解的方法模塊分解的方法 功能分解法功能分解法 - - 基礎(chǔ)基礎(chǔ)面向?qū)ο蠓嫦驅(qū)ο蠓?- - 主流主流n功能分解

3、是一個自頂向下、逐步求精的過程。功能分解是一個自頂向下、逐步求精的過程。 n模塊劃分的原則是:高聚合、低耦合。模塊劃分的原則是:高聚合、低耦合。 4/59n模塊化程序設(shè)計的特點:模塊化程序設(shè)計的特點:q模塊相對獨立,功能單一模塊相對獨立,功能單一q編寫相對簡單,可以獨立編寫調(diào)試編寫相對簡單,可以獨立編寫調(diào)試q可集體開發(fā),縮短開發(fā)周期。不同的模塊可以由不同的可集體開發(fā),縮短開發(fā)周期。不同的模塊可以由不同的人員開發(fā),最終能夠合成完整的程序人員開發(fā),最終能夠合成完整的程序q開發(fā)出的模塊,可在不同的應用程序中多次使用,減少開發(fā)出的模塊,可在不同的應用程序中多次使用,減少重復勞動,提高開發(fā)效率重復勞動,

4、提高開發(fā)效率q測試、更新以模塊為單位進行而不會影響其他模塊測試、更新以模塊為單位進行而不會影響其他模塊5/59n階乘的實現(xiàn):階乘的實現(xiàn): x = 1;for (i=1; i=k; i+)x = x * i;例例1:計算:計算!kmn 6/59#include void main()int i, k, m, n;float x, y, z;scanf(%d%d%d, &k, &m, &n);x = 1; for (i=1; i=k; i+)x = x * i;y = 1; for (i=1; i=m; i+)y = y * i;z = 1;for (i=1; i=n; i

5、+)z = z * i;printf(%fn, x/(y+z);void main( )int k, m, n;float x, y, z;scanf(%d%d%d, &k, &m, &n);x = factorial(k);y = factorial(m);z = factorial(n);printf(%fn, x/(y+z);#include float factorial(int n)int i;float f = 1;for (i=1; i=n; i+)f = f * i;return f;EG301_1.CEG301_2.C7/59void main( )i

6、nt k, m, n;float x, y, z;scanf(%d%d%d, &k, &m, &n);x = factorial(k);y = factorial(m);z = factorial(n);printf(%fn, x/(y+z);定義格式定義格式: : 函數(shù)類型函數(shù)類型 函數(shù)名函數(shù)名( (形式參數(shù)表形式參數(shù)表) ) 函數(shù)體函數(shù)體; ; 其中其中形式參數(shù)表形式參數(shù)表為為: : 類型名類型名 形式參數(shù)形式參數(shù)1,1,類型名類型名 形式參數(shù)形式參數(shù)2,2,#include float factorial(int n)int i;float f = 1;for (

7、i=1; i=n; i+)f = f * i;return f;函數(shù)調(diào)用形式為函數(shù)調(diào)用形式為: : 函數(shù)名函數(shù)名( (實際參數(shù)表實際參數(shù)表) );!kmn 3.2 函數(shù)的定義函數(shù)的定義8/593.3 無返回值函數(shù)的定義與調(diào)用無返回值函數(shù)的定義與調(diào)用n例:顯示如下:例:顯示如下:*good*定義格式定義格式: : void void 函數(shù)名函數(shù)名( (形式參數(shù)表形式參數(shù)表) ) 函數(shù)體函數(shù)體; ; #include void list( ) printf(“*n”); void main( ) list( ) ; printf(“ good n”); list ( );9/59#include

8、void swap(int a, int b) int t; t=a; a=b; b=t; printf(“交換后:交換后:%d,%dn”, a, b);n例例2:交換兩個數(shù)的值。:交換兩個數(shù)的值。void main( ) int x5, y10; printf(“交換前:交換前:%d %dn”, x,y); swap(x, y);printf(“函數(shù)調(diào)用結(jié)束后:函數(shù)調(diào)用結(jié)束后:%d %dn”, x, y);EG302.C10/59n說明:說明:q當函數(shù)被調(diào)用時,形式參數(shù)才被分配存儲空間,在當函數(shù)被調(diào)用時,形式參數(shù)才被分配存儲空間,在調(diào)用結(jié)束后,形參所占的空間將被釋放;調(diào)用結(jié)束后,形參所占的空

9、間將被釋放;q實際參數(shù)可以是常量,變量或表達式;實際參數(shù)可以是常量,變量或表達式;q實際參數(shù)和形式參數(shù)個數(shù)一致,類型一致,順序一實際參數(shù)和形式參數(shù)個數(shù)一致,類型一致,順序一致;致;q實參對形參的數(shù)據(jù)傳遞是實參對形參的數(shù)據(jù)傳遞是“值傳遞值傳遞”,即,即單向傳遞單向傳遞。11/593.4 有返回值函數(shù)的定義與調(diào)用有返回值函數(shù)的定義與調(diào)用n 通過通過函數(shù)調(diào)用函數(shù)調(diào)用使主調(diào)函數(shù)能得到一個確定的值,該值就是使主調(diào)函數(shù)能得到一個確定的值,該值就是函數(shù)的函數(shù)的返回值返回值。n 函數(shù)的返回值通過函數(shù)中函數(shù)的返回值通過函數(shù)中return語句獲得。語句獲得。qreturn的作用:的作用:1、使流程返回主調(diào)函數(shù);、

10、使流程返回主調(diào)函數(shù); 2、將函數(shù)值返回到主調(diào)函數(shù)中、將函數(shù)值返回到主調(diào)函數(shù)中n 函數(shù)類型決定函數(shù)返回值的類型。函數(shù)類型決定函數(shù)返回值的類型。q一般函數(shù)值的類型和一般函數(shù)值的類型和return語句中表達式的類型應一致,如果二語句中表達式的類型應一致,如果二者不一致,則以函數(shù)值的類型為準者不一致,則以函數(shù)值的類型為準n 一個函數(shù)允許有一個或多個一個函數(shù)允許有一個或多個return語句語句q每個每個return后的表達式類型要相同;當執(zhí)行到其中任何一個后的表達式類型要相同;當執(zhí)行到其中任何一個return語句時會立即返回主調(diào)函數(shù)語句時會立即返回主調(diào)函數(shù)12/59#include int leap(i

11、nt year) int s;if (year%4=0 & year%100!=0) | (year%400=0)s = 1;elses = 0;return s; /* 或或 return (s);*/如果使用多個如果使用多個return語句怎么語句怎么寫?寫?n例例3:判斷閏年:判斷閏年void main()int y, t;scanf(“%d”, &y);t = leap(y);if (t = 1)printf(“%d 年是閏年年是閏年n”, y);elseprintf(“%d 年不是閏年年不是閏年n”, y);EG303.C13/59#include #include

12、int isprime(int m) int i, k; k=sqrt(m); for(i=2; i=k; i+) if(m%i=0) return (0); return (1);n例例4:輸入一個正整數(shù),判斷該數(shù)是否為素數(shù)。:輸入一個正整數(shù),判斷該數(shù)是否為素數(shù)。void main()int num, t;scanf(“%d”, &num);t = isprime(num);if (t=1)printf(“%d is a primen”, num);else printf(“%d is not a primen”, num);EG304.C14/59n例例5:求兩個數(shù)的最大公約數(shù)和最

13、小公倍數(shù)。:求兩個數(shù)的最大公約數(shù)和最小公倍數(shù)。q求最大公約數(shù)的方法:輾轉(zhuǎn)相除法求最大公約數(shù)的方法:輾轉(zhuǎn)相除法n給出兩個數(shù),如果兩數(shù)相除的余數(shù)不是給出兩個數(shù),如果兩數(shù)相除的余數(shù)不是0,則除數(shù)作,則除數(shù)作為新的被除數(shù),余數(shù)作為新的除數(shù),繼續(xù)相除,當為新的被除數(shù),余數(shù)作為新的除數(shù),繼續(xù)相除,當兩數(shù)相除的余數(shù)是兩數(shù)相除的余數(shù)是0時結(jié)束,此時除數(shù)就是最大公約時結(jié)束,此時除數(shù)就是最大公約數(shù)。數(shù)。 q最小公倍數(shù)的方法:用兩數(shù)的乘積除以最大公約數(shù)最小公倍數(shù)的方法:用兩數(shù)的乘積除以最大公約數(shù)例例:a=25 ; b=15; s=a%b=10; a=b; (a=15) b=s; (b=10) s=a%b=5; a=

14、b; (a=10) b=s; (b=5) s=a%b=0; b就是最大公約數(shù);就是最大公約數(shù); 最小公倍數(shù):最小公倍數(shù): 25*15/5=7515/59n求最大公約數(shù)的函數(shù)為:求最大公約數(shù)的函數(shù)為:int gys(int a, int b) /*a為被除數(shù)為被除數(shù), b為除數(shù)為除數(shù)*/ int s; /* s存放余數(shù)存放余數(shù)*/s=a%b; while(s!=0) a=b;b=s;s=a%b; return (b);while(s=a%b)!=0) a=b;b=s;16/59n方法一:完整程序的實現(xiàn)如下:方法一:完整程序的實現(xiàn)如下:#include int gys(int a, int b)

15、void main( ) int p, q, r, z ; printf(please input 2 numbers: ); scanf(%d%d, &p, &q); r=gys(p, q); printf(“Greatest common divisor is %dn, r); z=p*q/r; printf(least common multiple is %dn, z );EG305_1.C17/59n方法二:編寫求最小公倍數(shù)的函數(shù)。方法二:編寫求最小公倍數(shù)的函數(shù)。#include int gys(int a, int b) int gbs(int a, int b,

16、int h) /*h為最大公約數(shù)為最大公約數(shù)*/ return (a*b/h); void main( ) int p, q, r ; printf(please input 2 numbers: ); scanf(%d%d, &p, &q); r=gys(p, q); printf(“Greatest common divisor is %dn, r); printf(lease common multiple is %dn, gbs(p, q, r);EG305_2.C18/59n函數(shù)調(diào)用的一般形式:函數(shù)調(diào)用的一般形式:函數(shù)名函數(shù)名( 實參列表實參列表 ) ;n說明說明q形

17、式參數(shù):形式參數(shù):定義函數(shù)定義函數(shù)時寫在函數(shù)名后括號內(nèi)的變量,形時寫在函數(shù)名后括號內(nèi)的變量,形參前必須有數(shù)據(jù)類型參前必須有數(shù)據(jù)類型 int gys(int a, int b) q實際參數(shù):實際參數(shù):調(diào)用函數(shù)調(diào)用函數(shù)時寫在函數(shù)名后括號內(nèi)的變量,實時寫在函數(shù)名后括號內(nèi)的變量,實參僅寫變量名參僅寫變量名 r=gys(p, q)q實參列表可包含多個實參,各個實參之間用逗號分隔實參列表可包含多個實參,各個實參之間用逗號分隔q實參與形參的個數(shù)應相等,類型一致,順序一一對應實參與形參的個數(shù)應相等,類型一致,順序一一對應q調(diào)用無參函數(shù)時格式為:調(diào)用無參函數(shù)時格式為:函數(shù)名函數(shù)名( ); 注意注意( )不能省略

18、不能省略19/59n函數(shù)調(diào)用的方式函數(shù)調(diào)用的方式q 函數(shù)語句函數(shù)語句swap(x, y);q 函數(shù)表達式函數(shù)表達式 r=gys(p, q);q 函數(shù)參數(shù)函數(shù)參數(shù) printf(“gbs is %dn, gbs(p, q, r);n函數(shù)的調(diào)用過程:函數(shù)的調(diào)用過程: q形參與實參各自占有一個獨立的存儲空間形參與實參各自占有一個獨立的存儲空間q形參的存儲空間在函數(shù)被調(diào)用時才分配形參的存儲空間在函數(shù)被調(diào)用時才分配 q函數(shù)返回時,形參占據(jù)的臨時存儲區(qū)被撤消函數(shù)返回時,形參占據(jù)的臨時存儲區(qū)被撤消q注意:函數(shù)中對形參變量的操作不會影響到實參注意:函數(shù)中對形參變量的操作不會影響到實參20/593.5 函數(shù)嵌套

19、調(diào)用和函數(shù)聲明函數(shù)嵌套調(diào)用和函數(shù)聲明n函數(shù)的嵌套調(diào)用是指在被調(diào)用函數(shù)的執(zhí)行過程函數(shù)的嵌套調(diào)用是指在被調(diào)用函數(shù)的執(zhí)行過程中又調(diào)用另一個函數(shù)。中又調(diào)用另一個函數(shù)。void main( ) : fun( ) ; : void fun( void ) : g( ) ; : main函數(shù)函數(shù)fun函數(shù)函數(shù)g函數(shù)函數(shù)調(diào)用調(diào)用調(diào)用調(diào)用嵌套嵌套調(diào)用調(diào)用21/59例例: : 函數(shù)的嵌套調(diào)用函數(shù)的嵌套調(diào)用#include void fa ( ) putchar( a ) ; void fb ( ) fa( ) ; putchar( t ) ; void main ( ) putchar( c ); fb( ) ;

20、 main輸出輸出c調(diào)用調(diào)用fb結(jié)束結(jié)束fb調(diào)用調(diào)用fa輸出輸出tfa輸出輸出a結(jié)束結(jié)束結(jié)束結(jié)束輸出結(jié)果輸出結(jié)果: cat22/59n例例5:求最小公倍數(shù):求最小公倍數(shù)int gbs(int a, int b, int h) /*h為最大公約數(shù)為最大公約數(shù)*/ return (a*b/h); int gbs(int a, int b) return (a*b/gys(a, b); 23/59例例6 編程求編程求 ,輸入,輸入k和和n的值的值nkx=1x分析分析: 假設(shè)輸入假設(shè)輸入k=3,n=5,即求,即求13+23+33+43+53 可分為以下可分為以下4步求解:步求解: 輸入輸入n和和k的值

21、的值 乘方運算,即計算乘方運算,即計算xk 求和運算,即計算求和運算,即計算1k+2k+nk 輸出結(jié)果輸出結(jié)果需要編寫三個函數(shù):乘方函數(shù)、求和函數(shù)、需要編寫三個函數(shù):乘方函數(shù)、求和函數(shù)、main 函數(shù)函數(shù) 注意:注意: main函數(shù)調(diào)用求和函數(shù),而求和函數(shù)又調(diào)用乘方函數(shù)函數(shù)調(diào)用求和函數(shù),而求和函數(shù)又調(diào)用乘方函數(shù) main函數(shù)中將函數(shù)中將n和和k作為實際參數(shù),把它們的值傳給求和函作為實際參數(shù),把它們的值傳給求和函數(shù)數(shù) 24/59void main( ) /*主函數(shù)主函數(shù)*/ int k, n; float sum; /* 為什么用為什么用float型定義變量?型定義變量?*/ printf(in

22、put:k,n ); /*提示信息提示信息*/ scanf(%d%d, &k, &n); sum=sop(n, k); printf(%.0fn, sum); 25/59/*求和函數(shù)求和函數(shù)*/float sop( int m, int t) int i; float sum, p; sum=0; for (i=1; i=m; i+ ) p=power(i, t); sum=sum+p; return (sum) ; /*乘方函數(shù)乘方函數(shù)*/float power(int p, int q) int i; float product; product=1; for(i=1; i

23、=q; i+) product=product*p; return (product); 26/59void main( ) int k, n; float sum; printf(“input n,k: ); scanf(%d%d, &n, &k); sum=sop(n, k); printf(%.0fn, sum); float sop( int m, int t) int i; float sum, p; sum=0; for (i=1; i=m; i+ ) p=power(i, t); sum=sum+p; return (sum) ; float power(int

24、p, int q) int i; float product; product=1; for(i=1; i=q; i+) product=product*p; return(product); #include例例6 6的完整程序:的完整程序:參數(shù)值的傳遞過程參數(shù)值的傳遞過程:main sop power n m k t q i pEG306.C27/59n函數(shù)聲明函數(shù)聲明q在調(diào)用函數(shù)前,一般要對函數(shù)事先作出聲明在調(diào)用函數(shù)前,一般要對函數(shù)事先作出聲明q聲明有利于編譯系統(tǒng)對函數(shù)調(diào)用的合法性進行檢查,如函數(shù)類型、參數(shù)個聲明有利于編譯系統(tǒng)對函數(shù)調(diào)用的合法性進行檢查,如函數(shù)類型、參數(shù)個數(shù)及類型等數(shù)及類

25、型等q聲明格式:聲明格式: 函數(shù)類型函數(shù)類型 函數(shù)名函數(shù)名 ( 形參表形參表 ) ;n函數(shù)聲明的注意事項:函數(shù)聲明的注意事項:q函數(shù)聲明末尾要加分號;函數(shù)聲明末尾要加分號;q形參表中可以只寫數(shù)據(jù)類型;形參表中可以只寫數(shù)據(jù)類型; 如如 int f( int , float);q形參的先后次序和函數(shù)定義時的次序應一致形參的先后次序和函數(shù)定義時的次序應一致q當被調(diào)函數(shù)的定義寫在主調(diào)函數(shù)之前時,允許省略函數(shù)聲明當被調(diào)函數(shù)的定義寫在主調(diào)函數(shù)之前時,允許省略函數(shù)聲明q建議將程序中用到的函數(shù)都在程序的前面加以聲明建議將程序中用到的函數(shù)都在程序的前面加以聲明n聲明的位置聲明的位置q在主調(diào)函數(shù)中聲明,只能被該函

26、數(shù)調(diào)用在主調(diào)函數(shù)中聲明,只能被該函數(shù)調(diào)用q在所有函數(shù)外部聲明,可以被在所有函數(shù)外部聲明,可以被main函數(shù)和其他函數(shù)調(diào)用函數(shù)和其他函數(shù)調(diào)用28/59本章開頭的例子:本章開頭的例子:#include float factorial(int n)int i;float f = 1;for (i=1; i=n; i+)f = f * i;return f;void main()int k, m, n;float x, y, z;scanf(%d%d%d, &k, &m, &n);x = factorial(k);y = factorial(m);z = factorial(n

27、);printf(%fn, x/(y+z);改變兩個函數(shù)的前后次序:改變兩個函數(shù)的前后次序:#include void main()int k, m, n;float x, y, z;scanf(%d%d%d, &k, &m, &n);x = factorial(k);y = factorial(m);z = factorial(n);printf(%fn, x/(y+z);float factorial(int n)int i;float f = 1;for (i=1; i=n; i+)f = f * i;return f;函數(shù)聲明函數(shù)聲明float factoria

28、l(int);29/59例例7 7:求:求1 1n n之間所有素數(shù)的和。之間所有素數(shù)的和。分析:分析: 該問題的主體結(jié)構(gòu)還是求和運算,而參與求和的數(shù)該問題的主體結(jié)構(gòu)還是求和運算,而參與求和的數(shù)是是1 1n n之間的素數(shù)。之間的素數(shù)。 可以分可以分3 3步求解:步求解: 輸入輸入n n的值的值 求和運算求和運算 輸出結(jié)果輸出結(jié)果求和計算時先要判斷當前的數(shù)是否為素數(shù),把判求和計算時先要判斷當前的數(shù)是否為素數(shù),把判斷素數(shù)編成一個函數(shù)在求和計算中調(diào)用這個函數(shù)斷素數(shù)編成一個函數(shù)在求和計算中調(diào)用這個函數(shù)30/59long sum(int);int isprime(int);例例7 7的完整程序:的完整程序

29、:int isprime(int m) int i, k; k=sqrt(m); for(i=2; i=k; i+) if(m%i=0) return (0); return (1);void main( ) int n; long s; scanf(%d, &n); s=sum(n); printf(%ld, s);long sum(int n) int i; long s=0; for(i=1; i=n; i+) if ( isprime(i)=1 ) s=s+i; return (s);#include #include 函數(shù)聲明函數(shù)聲明(外部外部)EG307.C31/593.6

30、 函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用n概念:函數(shù)直接或間接的調(diào)用自身叫函數(shù)的遞歸調(diào)用概念:函數(shù)直接或間接的調(diào)用自身叫函數(shù)的遞歸調(diào)用f( )調(diào)調(diào)f調(diào)調(diào)f2調(diào)調(diào)f1f1( )f2( )int f(int x) int y,z; z=f(y); . return(2*z);int f1(int x) int y,z; z=f2(y); . return(2*z);int f2(int t) int a,c; c=f1(a); . return(3+c);32/59n用遞歸求解問題的特點用遞歸求解問題的特點q存在遞歸的終止條件存在遞歸的終止條件q存在導致問題求解的遞歸方式存在導致問題求解的遞歸方式n使用遞歸

31、的優(yōu)缺點使用遞歸的優(yōu)缺點q優(yōu)點:程序簡潔,代碼緊湊優(yōu)點:程序簡潔,代碼緊湊q缺點:每調(diào)用函數(shù)一次,在內(nèi)存堆棧區(qū)分配空間,用于缺點:每調(diào)用函數(shù)一次,在內(nèi)存堆棧區(qū)分配空間,用于存放函數(shù)變量、返回值等信息,所以遞歸次數(shù)過多,可存放函數(shù)變量、返回值等信息,所以遞歸次數(shù)過多,可能引起堆棧溢出,且時間效率較差能引起堆棧溢出,且時間效率較差33/59n例例8:求:求n的階乘的階乘#include /*非遞歸的方式非遞歸的方式*/float fac(int n) float f; int i; f=1; for (i =1;i=n;i+) f=f*i; return (f);void main( ) int

32、n; float y; printf(Input a integer number:); scanf(%d,&n); y=fac(n); printf(%d! =%.0f, n, y);#include /*遞歸方式遞歸方式*/#include float fac(int n) float f; if(n0) exit(0); else if(n=0|n=1) f=1; else f=fac(n-1)*n; return(f);void main( ) float y; int n; printf(Input a integer number:); scanf(%d,&n);

33、y=fac(n); printf(%d! =%.0f, n, y);) 1()!1() 1 , 0(1!nnnnn遞歸的終止條件遞歸的終止條件遞歸方式遞歸方式EG308.C34/59main函數(shù)函數(shù)輸入輸入m 3y=fac(m)輸出輸出y 6調(diào)用調(diào)用facmn 3 因因 3!=1或或0 f=3*fac(3-1)返回返回f=6調(diào)用調(diào)用facmn 2返回返回f=2返回返回f=1 因因 2!=1或或0 f=2*fac(2-1)調(diào)用調(diào)用facmn 1因因1=1 f=1結(jié)束結(jié)束例例8 8的遞歸調(diào)用過程:的遞歸調(diào)用過程:35/593.7 庫函數(shù)的使用庫函數(shù)的使用n使用庫函數(shù)應注意:使用庫函數(shù)應注意:q函數(shù)

34、功能函數(shù)功能q函數(shù)參數(shù)的數(shù)目和順序,及各參數(shù)意義和類型函數(shù)參數(shù)的數(shù)目和順序,及各參數(shù)意義和類型q函數(shù)返回值意義和類型函數(shù)返回值意義和類型q需要使用函數(shù)所在的包含文件,若包含的頭文件多需要使用函數(shù)所在的包含文件,若包含的頭文件多于一個,則每個于一個,則每個#include需單獨占一行需單獨占一行36/593.8 全局變量和局部變量全局變量和局部變量n局部變量局部變量(內(nèi)部變量內(nèi)部變量) q指在一個函數(shù)內(nèi)部定義的變量,它只在本函數(shù)的范圍內(nèi)指在一個函數(shù)內(nèi)部定義的變量,它只在本函數(shù)的范圍內(nèi)有效,在此函數(shù)之外不能使用這些變量有效,在此函數(shù)之外不能使用這些變量q說明:說明:nmain函數(shù)中定義的變量也是局

35、部變量,只在函數(shù)中定義的變量也是局部變量,只在main函數(shù)中有效函數(shù)中有效n不同函數(shù)中同名變量,占不同內(nèi)存單元,互不干擾不同函數(shù)中同名變量,占不同內(nèi)存單元,互不干擾n函數(shù)的形式參數(shù)也是局部變量函數(shù)的形式參數(shù)也是局部變量n可在復合語句中定義變量,它們只在復合語句的內(nèi)部有效可在復合語句中定義變量,它們只在復合語句的內(nèi)部有效n全局變量全局變量(外部變量外部變量) q在所有函數(shù)之外定義的變量在所有函數(shù)之外定義的變量q它的有效范圍從定義變量的位置開始到本源文件結(jié)束它的有效范圍從定義變量的位置開始到本源文件結(jié)束37/59#include int p=1 , q=5 ;float f1( int a ) f

36、loat r ; :char s;int f2( int a , int b ) int sum ; :float m , n ;void main( ) float x , y , a ; :全局變量全局變量s s的的有效范圍有效范圍全局變量全局變量p p和和q q的有效范圍的有效范圍全局變量全局變量m m和和n n的有效范圍的有效范圍a,r等為局部變量等為局部變量38/59n全局變量的使用增加了函數(shù)間數(shù)據(jù)聯(lián)系的渠道,由于在同一文件中的全局變量的使用增加了函數(shù)間數(shù)據(jù)聯(lián)系的渠道,由于在同一文件中的所有函數(shù)都能使用全局變量,所以可以利用全局變量從函數(shù)中得到一所有函數(shù)都能使用全局變量,所以可以利用

37、全局變量從函數(shù)中得到一個以上的返回值,而使用個以上的返回值,而使用return只能返回一個值。只能返回一個值。例例9 9:求某班成績的平均分:求某班成績的平均分, , 最高分和最低分。最高分和最低分。#include float max=0, min=100 ; float average( int n ); void main( ) int m; float ave2 ; printf(“input m:”); scanf(“% %d”,&m); ave2=average(m); printf(“ave=% %6.2fn”, ave2); printf(“max=% %6.2fn”,

38、 max); printf(“min=% %6.2fn”, min); float average( int n ) int i; float s, ave1, sum=0; for(i=1; imax) max=s; if (smin) min=s; sum=sum+s; ave1=sum/n; return (ave1); EG309.C39/59n建議不要過多的使用全局變量建議不要過多的使用全局變量q全局變量在程序的執(zhí)行過程中一直占用存儲單元全局變量在程序的執(zhí)行過程中一直占用存儲單元q它使函數(shù)的通用性降低它使函數(shù)的通用性降低 q它會降低程序的清晰性它會降低程序的清晰性n若全局變量與局部變

39、量同名,則全局變量被屏蔽若全局變量與局部變量同名,則全局變量被屏蔽#include int a=3, b=5;max(int a, int b) int c; c=ab?a:b; return(c);void main( ) int a=8; printf(max=%d,max(a,b);運行結(jié)果:運行結(jié)果:max=8#include int x=10; void f( ) int x=1; x=x+1; printf(“x=%dn”, x );void main( ) x=x+1; printf(“x=%dn”, x); f( ); 運行結(jié)果運行結(jié)果:x=11x=2 40/59n變量的存儲類

40、別變量的存儲類別 q變量的存儲方式變量的存儲方式n從變量的作用域(即從空間)角度來分,可分為局從變量的作用域(即從空間)角度來分,可分為局部變量、全局變量。部變量、全局變量。n從變量存在的時間(即變量生存期)角度來分,可從變量存在的時間(即變量生存期)角度來分,可分為:分為:動態(tài)存儲變量、靜態(tài)存儲變量動態(tài)存儲變量、靜態(tài)存儲變量。n動態(tài)存儲變量:用動態(tài)存儲方式存儲的變量。動態(tài)存儲變量:用動態(tài)存儲方式存儲的變量。q特點是函數(shù)開始調(diào)用時為變量分配存儲空間,函特點是函數(shù)開始調(diào)用時為變量分配存儲空間,函數(shù)結(jié)束時釋放這些空間。數(shù)結(jié)束時釋放這些空間。n靜態(tài)存儲變量:用靜態(tài)存儲方式存儲的變量。靜態(tài)存儲變量:用

41、靜態(tài)存儲方式存儲的變量。q特點是在靜態(tài)存儲區(qū)分配存儲單元,整個程序運特點是在靜態(tài)存儲區(qū)分配存儲單元,整個程序運行期間都不釋放,在程序結(jié)束時才釋放空間。行期間都不釋放,在程序結(jié)束時才釋放空間。41/59n變量的存儲類別變量的存儲類別 q變量的存儲類型變量的存儲類型nauto (自動的自動的):如果局部變量不作存儲類型說明,:如果局部變量不作存儲類型說明,均為動態(tài)存儲變量均為動態(tài)存儲變量nregister (寄存器的寄存器的):可以提高:可以提高“存取存取”速度,因為速度,因為從寄存器存取數(shù)據(jù)比從內(nèi)存存取數(shù)據(jù)快從寄存器存取數(shù)據(jù)比從內(nèi)存存取數(shù)據(jù)快nstatic (靜態(tài)的靜態(tài)的):它的存儲空間在程序的

42、運行期間都它的存儲空間在程序的運行期間都固定不變。該類變量在其函數(shù)調(diào)用結(jié)束后仍然保留固定不變。該類變量在其函數(shù)調(diào)用結(jié)束后仍然保留著變量的值,調(diào)用該函數(shù),靜態(tài)局部變量中仍保留著變量的值,調(diào)用該函數(shù),靜態(tài)局部變量中仍保留上次調(diào)用結(jié)束時的值。上次調(diào)用結(jié)束時的值。nextern (外部的外部的):可以擴展全局變量的作用域,或引:可以擴展全局變量的作用域,或引用其它文件的全局變量用其它文件的全局變量42/59例例10:靜態(tài)變量和動態(tài)變量的對比:靜態(tài)變量和動態(tài)變量的對比#include void f(int c) int a=0; static int b=0; a+; b+; printf(% %d:

43、a=% %d, b=% %dn, c, a, b);void main( ) int i; for (i=1; i=3; i+) f( i );mainficab1 2 310 101 2 3ca021ca031輸出結(jié)果輸出結(jié)果:1: a=1, b=12: a=1, b=23: a=1, b=3EG310.C43/593.9 指針和指針作為函數(shù)參數(shù)指針和指針作為函數(shù)參數(shù)n地址地址q在計算機中,把內(nèi)存區(qū)劃分為一個一個的存儲單元,每個單在計算機中,把內(nèi)存區(qū)劃分為一個一個的存儲單元,每個單元為一個字節(jié)(位),它們都有一個編號,這個編號就是元為一個字節(jié)(位),它們都有一個編號,這個編號就是內(nèi)存單元的地

44、址內(nèi)存單元的地址。n變量的地址變量的地址q每個變量在內(nèi)存中都占有一定字節(jié)數(shù)的存儲單元。程序編譯每個變量在內(nèi)存中都占有一定字節(jié)數(shù)的存儲單元。程序編譯時,根據(jù)程序中定義的變量類型,在內(nèi)存中為其分配了相應時,根據(jù)程序中定義的變量類型,在內(nèi)存中為其分配了相應字節(jié)數(shù)的存儲空間。字節(jié)數(shù)的存儲空間。q變量在內(nèi)存中所占存儲空間的首地址,稱變量的地址。該地變量在內(nèi)存中所占存儲空間的首地址,稱變量的地址。該地址存儲的內(nèi)容,就是變量的數(shù)值址存儲的內(nèi)容,就是變量的數(shù)值(變量的內(nèi)容變量的內(nèi)容)。44/59n變量的訪問方式變量的訪問方式q直接訪問:通過變量名或變量名所對應的地址訪問變量直接訪問:通過變量名或變量名所對應的

45、地址訪問變量的存儲區(qū),存取其值。的存儲區(qū),存取其值。 int x; x=3; printf(“x=%dn”, x);內(nèi)容內(nèi)容變量變量 地址地址3 x 20002000 p 3010q間接訪問:將一個變量的地址存放在另一個變量中,使間接訪問:將一個變量的地址存放在另一個變量中,使用時先找到后者的地址,再從中取出前者的地址。用時先找到后者的地址,再從中取出前者的地址。另一變量的地址另一變量的地址指針變量指針變量 地址地址45/59n指針變量的概念指針變量的概念q存放變量地址的變量,它用來存放變量地址的變量,它用來指向指向另一個變量。另一個變量。某個變量的地址某個變量的地址指針變量:存放變量的地址指

46、針變量:存放變量的地址指向指向3 x 20002000 p 3010另一變量的地址另一變量的地址指針變量指針變量 地址地址n指針的概念指針的概念q由于通過地址能找到所需的變量單元,地址象一根針一樣由于通過地址能找到所需的變量單元,地址象一根針一樣“指向指向”該變量單元。所以將地址形象的稱為:該變量單元。所以將地址形象的稱為:“指針指針”。46/59n指針變量的定義指針變量的定義 基類型名基類型名 *指針變量名;指針變量名;例:例:int *p; p是整型指針,指向整型變是整型指針,指向整型變量量 float *q; q是指向?qū)嵭妥兞康闹羔樧兞渴侵赶驅(qū)嵭妥兞康闹羔樧兞?char *r;n說明說明

47、q類型名是指針變量指向的變量的數(shù)據(jù)類型類型名是指針變量指向的變量的數(shù)據(jù)類型q在變量定義時,在變量定義時, * 號表示該變量是指針變量,不可號表示該變量是指針變量,不可省省 q注意:指針變量名是注意:指針變量名是p,而不是,而不是*p。47/59n指針變量的賦值指針變量的賦值q定義指針變量時進行定義指針變量時進行初始化初始化,或使用,或使用賦值語句賦值語句。n兩個運算符兩個運算符q:取地址運算符。:取地址運算符。 可作用于一般變量或指針變量可作用于一般變量或指針變量q * :指針運算符。:指針運算符。 只能作用于指針變量只能作用于指針變量q它們優(yōu)化級相同,滿足右結(jié)合。它們優(yōu)化級相同,滿足右結(jié)合。

48、例:例:int *p, x; x = 3; p = &x; 把把x的地址賦給的地址賦給p,即,即p指向指向x&x3px通過通過p取取x值:值: *p, 表示表示p所指向的變量所指向的變量x的值的值*p或:或:int x, *p=&x;48/59n使用指針變量時,需注意的幾個問題:使用指針變量時,需注意的幾個問題:q只能用同類型變量的地址給指針變量賦值只能用同類型變量的地址給指針變量賦值 例:例:int x, *p; p=&x; int x; float *p; p=&x; 錯錯q使用指針變量前,一定要使其指向一個確定的變量使用指針變量前,一定要使其指向一

49、個確定的變量 例:例:int *p; *p = 10; 錯錯qp=&x; *p = 10; p所指向的變量,所指向的變量, 把把*p看作一個整體看作一個整體qp與與*p不同:不同:np是指針變量,是指針變量,p的值是的值是p所指向的變量的地址所指向的變量的地址 n*p 是是p 所指向的變量,所指向的變量,*p的值是的值是p所指向的變量的值所指向的變量的值q引用指針變量時的引用指針變量時的 * 與定義指針變量時的與定義指針變量時的 * 不同,定義變量不同,定義變量時的時的 * 只是表示其后的變量是指針變量只是表示其后的變量是指針變量q當當p = &a ; *p與與a相同相同; 則

50、有:則有:&*p &(*p) &a p 是地址是地址 *&a *(&a) *p a 是變量是變量49/59例例11:指針變量的賦值操作:指針變量的賦值操作#include void main() int a, b; int *p1, *p2;a=100; b=10;p1=&a;p2=&b;printf(“%d,%dn”, a, b);printf(“%d,%dn”, *p1,*p2);10010abp1p2&a&b*p1*p2EG311.C50/59例例12-1:#include void main() int a, b;

51、 int *p1, *p2;a=100; b=10;p1 = &a;p2 = p1;p1 = &b;printf(“%d,%dn”, a, b);printf(“%d,%dn”, *p1,*p2);10010abp1p2&a&a&b輸出結(jié)果:輸出結(jié)果:100, 1010, 100EG312_1.C51/59例例12-2:指針變量的初始化操作:指針變量的初始化操作#include void main() int a=100, b=10; int *p1=&a, *p2=&b, *t;printf(“%d,%dn”, *p1, *p2);t

52、= p1; p1 = p2; p2 = t;printf(“%d,%dn”, *p1,*p2);10010abp1p2&a&b&at&b&aEG312_2.C52/59例例12-3:#include void main() int a=100, b=10; int *p1=&a, *p2=&b, t;printf(“%d,%dn”, *p1, *p2);t = *p1; *p1 = *p2; *p2 = t;printf(“%d,%dn”, *p1,*p2);10010abp1p2&a&b100t10100EG312_3.C53/59n指針作為函數(shù)參數(shù)指針作為函數(shù)參數(shù)#include void swap(int a, int b) int t; t=a; a=b; b=t; /*printf(“交換后:交換后:%d,%d

溫馨提示

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

最新文檔

評論

0/150

提交評論