第6章函數(shù)與宏定義.ppt_第1頁
第6章函數(shù)與宏定義.ppt_第2頁
第6章函數(shù)與宏定義.ppt_第3頁
第6章函數(shù)與宏定義.ppt_第4頁
第6章函數(shù)與宏定義.ppt_第5頁
已閱讀5頁,還剩44頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、03:34,1/49,第六章 函數(shù)與宏定義,6.1 函數(shù)概念,6.2 變量作用域和存儲類型,6.3 內(nèi)部函數(shù)與外部函數(shù),6.4 遞歸函數(shù)設(shè)計和調(diào)用,6.6 綜合范例,03:34,2/49,6.1 函數(shù)概念,C語言允許把問題設(shè)計成一個一個的模塊,程序通過調(diào)用模塊功能來解決問題。這些模塊通常都是通過函數(shù)來實現(xiàn)的,又可稱其為函數(shù)模塊。,C語言中,函數(shù)可分為兩類 :,一類是由系統(tǒng)定義的標(biāo)準(zhǔn)函數(shù),又稱為庫函數(shù),其函數(shù)聲明一般是放在系統(tǒng)的include目錄下以.h為后綴的頭文件中,如在程序中要用到某個庫函數(shù),必須在調(diào)用該函數(shù)之前用#include命令將庫函數(shù)信息包含到本程序中。,另一類函數(shù)是自定義函數(shù) ,

2、兩種形式:,第一種:函數(shù)聲明、函數(shù)調(diào)用、函數(shù)定義。 第二種:函數(shù)定義、函數(shù)調(diào)用。,03:34,3/49, 6.1.1 函數(shù)定義,函數(shù)定義的一般形式可以有兩種。,形式一:,存儲類型符 返回值類型符 函數(shù)名(形參說明表) 函數(shù)語句體 ,形式二:,存儲類型符 返回值類型型符 函數(shù)名(形參表) 形參說明; 函數(shù)語句體 ,03:34,4/49,說明:,1存儲類型符指的是函數(shù)的作用范圍,它只有兩種形式:static和extern。 static說明函數(shù)只能作用于其所在的源文件,用static說明的函數(shù)又稱為內(nèi)部函數(shù)。 extern說明函數(shù)可被其它源文件中的函數(shù)調(diào)用,用extern說明的函數(shù),又稱為外部函數(shù)

3、。 缺省情況為extern。,2返回值類型符指的是函數(shù)體語句執(zhí)行完成后,函數(shù)返回的值的類型,如int, float, char等等,若函數(shù)無返回值,則用空類型void來定義函數(shù)的返回值。 缺省情況為int型。,03:34,5/49,3函數(shù)名由任何合法的標(biāo)識符構(gòu)成。建議將函數(shù)名的命名與函數(shù)內(nèi)容有一定關(guān)系。,4在第一種函數(shù)定義的形式中,形參說明表是一系列用逗號分開的每個形參變量說明。 如:int x, int y, int z 這表示形參變量有三個:x, y, z。它們的類型都是int型。 在第二種函數(shù)定義的形式中,形參表是一系列用逗號分開的形參變量。如:x, y, z,5函數(shù)語句體是放在一對花括

4、號 中,由局部數(shù)據(jù)類型描述和功能實現(xiàn)兩部分組成。,03:34,6/49,6函數(shù)返回語句的形式有以下兩種: 函數(shù)無返回值的情況:return; 函數(shù)有返回值的情況:return(表達式的值); 在第種情況下要注意“表達式的值”的類型必須與函數(shù)返回值的類型相一致。,例如:求兩個任意整數(shù)的絕對值的和,用函數(shù)abs_sum()實現(xiàn)。,/*直接調(diào)用庫函數(shù)來計算m和n的絕對值 */ int abs_sum(int m, int n) return (abs(m)+abs(n); /*函數(shù)abs()是在頭文件math.h中聲明的*/,03:34,7/49,函數(shù)定義如下: int abs_sum(int m,

5、 int n) if (m0) m=-m; if(n0) n=-n; return(m+n); ,6.1.2 函數(shù)聲明和調(diào)用,一函數(shù)的聲明 函數(shù)聲明的一般形式:,存儲類型符 返回值類型符 函數(shù)名(形參說明表); 如:int abs-sun(int m, int n);,03:34,8/49,二函數(shù)調(diào)用 函數(shù)調(diào)用是通過函數(shù)調(diào)用語句來實現(xiàn)的,分兩種形式:,無返回值的情況: 函數(shù)名(實參表); 有返回值的情況: 變量名函數(shù)名(實參表); 該變量名的類型必須與函數(shù)的返回值類型相同。,函數(shù)調(diào)用時都會去執(zhí)行函數(shù)語句中的內(nèi)容,函數(shù)執(zhí)行完畢后,回到函數(shù)的調(diào)用處,繼續(xù)執(zhí)行下面的語句。,03:34,9/49,6.

6、1.3 函數(shù)的傳值方式,函數(shù)的傳值方式: 采用實參表將每一個實參的值相應(yīng)地傳遞給每一個形參變量,形參變量在接收到實參表傳過來的值時,會在內(nèi)存臨時開辟新的空間,以保留形參變量的值,當(dāng)函數(shù)執(zhí)行完畢時,這些臨時開辟的內(nèi)存空間會被釋放,并且形參的值在函數(shù)中不論是否發(fā)生變化,都不會影響到實參變量的值的變化,這就是函數(shù)的傳值方式。,自定義函數(shù)在程序中的使用順序有兩種形式:, 先進行函數(shù)聲明,再進行函數(shù)調(diào)用,函數(shù)定義放在函數(shù)調(diào)用之后。函數(shù)聲明在函數(shù)調(diào)用之前。 函數(shù)定義放在函數(shù)調(diào)用之前。,03:34,10/49,【例6-1】 編程序,通過調(diào)用函數(shù)abs-sum(),求任意兩個整數(shù)的絕對值的和。,/*exam6

7、_1.c 調(diào)用函數(shù)求兩整數(shù)絕對值的和*/ #include int abs_sum(int m,int n); main() int x,y,z; scanf(%d%d, ,程序運行結(jié)果: 7 12 sum is 19,03:34,11/49,用傳值方式調(diào)用函數(shù)時,實參也可以是函數(shù)調(diào)用語句,【例6-2】求任意三個數(shù)的絕對值的和。,/*exam6_2.c 調(diào)用函數(shù)求三個整數(shù)絕對值的和*/ #include int abs_sum(int m,int n); main() int x,y,z,sum; scanf(%d%d%d, ,程序運行結(jié)果: 7 12 5 sum is 24,03:34,12

8、/49,注意:,對于有返回值的函數(shù),調(diào)用時若沒有把它賦給某個變量,仍然是可以的,只是函數(shù)的返回值有可能會被丟失。,【例6-3】 求任意兩數(shù)的乘積。,自定義一個函數(shù)mul(),用于求兩數(shù)的乘積,程序: /*exam6_3.c 求兩個數(shù)的乘積*/ #include float mul(float a,float b); main() float x,y,z; scanf(%f %f, /* */,03:34,13/49,x=x*2; y=y*2; printf(z=%f,mul(%f,%f)=%fn,z,x,y,mul(x,y); /* */ float mul(float a,float b)

9、return a*b; ,程序運行結(jié)果: 5 6 z=30.000000,mul(30.000000,-8.000000)=-240.000000,03:34,14/49,程序說明:,注釋處調(diào)用函數(shù)后的返回值賦給變量z。,注釋處調(diào)用函數(shù)后的返回值沒有賦給任何變量,函數(shù)的返回值被丟失。,注釋處調(diào)用函數(shù)后的返回值成為了printf()函數(shù)的參數(shù)。,03:34,15/49,6.2 變量作用域和存儲類型,一變量的作用域,變量的作用域:指的是變量的有效范圍,針對變量不同的作用域,可把變量分為局部變量和全局變量。,局部變量:在函數(shù)內(nèi)部或某個控制塊的內(nèi)部定義的變量為局部變量,局部變量的有效范圍只限于本函數(shù)內(nèi)

10、部,退出函數(shù),該變量自動失效。,全局變量:在函數(shù)外面定義的變量稱為全局變量,全局變量的作用域是從該變量定義的位置開始,直到源文件結(jié)束。在同一文件中的所有函數(shù)都可以引用全局變量。,03:34,16/49,局部變量和全局變量的作用域如圖所示:,03:34,17/49,【例6-4】 變量作用域應(yīng)用舉例,閱讀下面的程序,注意區(qū)分局部變量和全局變量的作用域。,/*exam6_4.c 變量作用域舉例*/ #include void a( void ); void b( void ); void c( void ); int x = 1; main() int x = 5; printf(local x i

11、n outer scope of main is %dn, x );,03:34,18/49, int x = 7; printf( local x in inner scope of main is %dn, x ); printf( local x in outer scope of main is %dn, x ); a(); b(); c(); a(); b(); c();,前三次輸出結(jié)果: local x in outer scope of main is 5 local x in inner scope of main is 7 local x in outer scope of

12、main is 5,03:34,19/49,printf( local x in main is %dn, x ); getchar(); return 0; void a( void ) int x = 25; printf( nlocal x in a is %d after entering an, x ); +x; printf( local x in a is %d before exiting an, x ); ,03:34,20/49,void b( void ) static int x = 50; printf( nlocal static x is %d on enteri

13、ng bn, x ); +x; printf( local static x is %d on exiting bn, x ); void c( void ) printf( nglobal x is %d on entering cn, x ); x *= 10; printf( global x is %d on exiting cn, x ); ,03:34,21/49,程序運行結(jié)果: 后6次函數(shù)調(diào)用,local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 50 o

14、n entering b local static x is 51 on exiting b global x is 1 on entering c global x is 10 on exiting c local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 51 on entering b local static x is 52 on exiting b global x is 10 on entering c global x is 100 on exiting

15、c,最后一次輸出: local x in main is 5,03:34,22/49,二變量的存儲類型,變量的存儲類型:指的是變量的存儲屬性,它說明變量占用存儲空間的區(qū)域。,在內(nèi)存中,供用戶使用的存儲區(qū)由程序區(qū)、靜態(tài)存儲區(qū)和動態(tài)存儲區(qū)三部分組成。,變量的存儲類型有四種:auto型、register型、static型和extern型。,auto型變量存儲在內(nèi)存的動態(tài)存儲區(qū)。 register型變量保存在寄存器中。 static型變量和extern型變量存儲在靜態(tài)存儲器。,03:34,23/49,局部變量的存儲類型缺省值為auto型 。 全局變量的存儲類型缺省值為extern型 。,auto型變量

16、和register型變量只用于定義局部變量。 static型變量即可定義成局部變量,又可定義成全局變量。,【例6-5】 設(shè)計一個函數(shù):long fac(int n),可用來計算15的階乘。,分析:可在函數(shù)中定義一個static型變量,用來保存上次的計算結(jié)果。,03:34,24/49,/*exam6_5.c 用static型變量保留上次階乘的值*/ #include long fac(int n) static int f=1; f=f*n; return f; main() int i; for(i=1;i=5;i+) printf(%d!=%ldn,i,fac(i); ,程序運行結(jié)果: 1!

17、=1 2!=2 3!=6 4!=24 5!=120,局部變量f被定義成static型的,因此,它只在該函數(shù)第1次被調(diào)用的時候初始化其值為1,以后再調(diào)用該函數(shù)時,不再進行初始化,而是使用上一次調(diào)用的值。,03:34,25/49,6.3 內(nèi)部函數(shù)與外部函數(shù),一內(nèi)部函數(shù),若函數(shù)的存儲類型為static型,則稱其為內(nèi)部函數(shù)或稱靜態(tài)函數(shù),它表示在同一個程序中(由多個源文件組成),該函數(shù)只能在一個文件中存在,在其它文件中不可使用。,如:static int fun-name(); 內(nèi)部函數(shù)只能被其所在的源文件調(diào)用。,二外部函數(shù),若函數(shù)的存儲類型定義為extern型,則稱其為外部函數(shù),它表示該函數(shù)能被其它源

18、文件調(diào)用。函數(shù)的缺省存儲類型為extern型。,注意:在需要用到外部函數(shù)的文件中,其函數(shù)聲明必須用extern進行說明。,03:34,26/49,例如:有兩個源文件file1.c和file2.c如下所示:,/* file1.c 調(diào)用外部函數(shù)*/ # include int mod(int a, int b); extern int add (int m, int n); /*外部函數(shù)聲明* main() int x, y, result; scanf (“%d%d”, ,03:34,27/49,int mod(int a, int b) return(a%d); /* file2.c外部函數(shù)*

19、/ extern int add(int m, int n) return(m+n); ,說明:,1在文件1(file1.c)中的函數(shù)聲明: int mod(int a, int b); 實際上相當(dāng)于:extern int mod(int a, int b);,03:34,28/49,2在文件2(file2.c)中的函數(shù)定義: extern int add(int m, int n) return(m+n); 實際上相當(dāng)于:int add(int m, int n) return(m+n); ,3由多個源文件組成一個程序時,main()函數(shù)只能出現(xiàn)在一個源文件中。,03:34,29/49,4多

20、個源文件的連接方式有三種:,將各源文件分別編譯成目標(biāo)文件,得到多個目標(biāo)文件(.obj后綴),然后用連接命令(tlink)把多個.obj文件連接起來,在Turbo c上用如下命令: tlink file1.obj+file2.obj+filen.obj 生成一個file1.exe的可執(zhí)行文件。,建立項目文件(.prj后綴),具體操作可參閱各種C編譯手冊。,使用文件包含命令。,03:34,30/49,6.4 遞歸函數(shù)設(shè)計和調(diào)用,C語言中一個函數(shù)中的語句可以是對另一個函數(shù)的調(diào)用。,函數(shù)嵌套調(diào)用圖例:,調(diào)用過程按圖中箭頭所示的方向和順序進行,屬于一種線性調(diào)用關(guān)系,每次調(diào)用后,最終返回到原調(diào)用點,繼續(xù)執(zhí)

21、行以下語句。,03:34,31/49,C語言中還允許在函數(shù)中調(diào)用自身,或函數(shù)之間相互調(diào)用,這種調(diào)用方式稱之為遞歸。遞歸又分為直接遞歸調(diào)用和間接遞歸調(diào)用。,直接遞歸調(diào)用;函數(shù)直接調(diào)用自身。,間接遞歸調(diào)用:函數(shù)互相調(diào)用對方。,直接遞歸:,int temp (int x) int y, z; z=temp(y); ,03:34,32/49,間接遞歸:,顯然,遞歸有可能陷入無限遞歸狀態(tài),最終導(dǎo)致錯誤發(fā)生。因此,設(shè)計一個遞歸問題必須具備兩個條件:,1后一部分與原始問題類似。 2后一問題是原始問題的簡化。,03:34,33/49,【例6-6】 編程,從鍵盤輸入一個正整數(shù)n,求n!。,n!的數(shù)字表達式為:

22、n!=,定義一個求n!的函數(shù):long fac(int n) long fac(int n) long result; if (n= = 0 | n= =1) result =1; else result=n*fac(n-1); return(result); ,03:34,34/49,完整程序如下:,/*exam6_6.c 用遞歸法求n!*/ #include long fac(int n) long result; if(n=0|n=1) result=1; else result=n*fac(n-1); return result; main() int x; long f;,03:34

23、,35/49,scanf(%d, ,程序運行結(jié)果: 6 6!=720,03:34,36/49,【例6-7】 求Fibonacci數(shù)列第i項的值。 Fibonacci數(shù)列:0, 1, 1, 2, 3, 5, 8, 13, 21,其數(shù)字表達式為: fibonacci(0)=0 fibonacci(1)=1 fibonacci(n)=fibonacci(n-1)+fibonacci(n-2) (n1),設(shè)計一個函數(shù):long fibonacci (int n)用于計算數(shù)列中第n項的值,,03:34,37/49,程序如下所示:,/*exam6_7.c 求第n項Fibonacci數(shù)列的值*/ #incl

24、ude long fibonacci(int n); main() int x=0; long result; do result=fibonacci(x); printf(fibonacci(%d)=%ldn,x,result); scanf(%d, ,03:34,38/49,long fibonacci(int n) if(n=0|n=1) return n; else return fibonacci(n-1)+fibonacci(n-2); ,程序運行結(jié)果: fibonacci(0)=0 3 fibonacci(3)=2 4 fibonacci(4)=3 6,03:34,39/49,以

25、x=4為例,下圖說明了fibonacci函數(shù)是怎樣計算fibonacci(4)的。圖中把fibonacci簡寫成f。,03:34,40/49,6.6 綜合范例,【例6-12】 在屏幕上畫一個1818大小的棋盤。,程序如下:,/*exam6_12.c 在屏幕上畫一個棋盤*/ #include #include #include /*定義畫棋盤所需的制表符*/ #define LU 0 xda /*左上角*/ #define RU 0 xbf /*右上角*/ #define LD 0 xc0 /*左下角*/ #define RD 0 xd9 /*右下角*/ #define L 0 xc3 /*左邊

26、*/ #define R 0 xb4 /*右邊*/,03:34,41/49,#define U 0 xc2 /*上邊*/ #define D 0 xc1 /*下邊*/ #define CROSS 0 xc5 /*十字叉*/ /*棋盤左上角坐標(biāo)*/ #define MAP_X 5 #define MAP_Y 5 void draw_cross(int x,int y); void draw_map(); main() textmode(C40); draw_map(); ,03:34,42/49,/*函數(shù)定義:*/ void draw_map() /*畫棋盤*/ int i,j; for(i=0;i19;i+) for(j=0;j19;j+) draw_cross(i,j); void draw_cross(int x,int y) gotoxy(x+MAP_X,y+MAP_Y); textcolor(GREEN); if(x=0 ,03:34,43/49,if(x=0 ,03:34,44/49,if(x=0) putch(L); /*畫左邊*/ return; if(x=18) putch(R); /*畫右邊*/ return; if(y=0) putch(U); /*畫上邊*/ return;

溫馨提示

  • 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

提交評論