C語言課件(函數(shù)).ppt_第1頁
C語言課件(函數(shù)).ppt_第2頁
C語言課件(函數(shù)).ppt_第3頁
C語言課件(函數(shù)).ppt_第4頁
C語言課件(函數(shù)).ppt_第5頁
已閱讀5頁,還剩46頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、,函數(shù),程序的模塊化 函數(shù) 定義 原型 調(diào)用 參數(shù)傳遞 函數(shù)的嵌套調(diào)用 遞歸函數(shù) 程序設(shè)計舉例,C語言程序設(shè)計,簡介,分而治之與程序的模塊化 把一個規(guī)模較大的問題分解成若干個較小的相對獨立的部分,對每一個部分使用一個較小的程序段,即程序模塊(module)來處理。 從較小的程序段或組件來構(gòu)建程序。 這些小片段或組件比原始程序更容易實現(xiàn)和管理。 這些小組件可以被重復(fù)使用。,函數(shù),C語言的函數(shù),在C語言中,函數(shù)(function)是構(gòu)成程序的基本模塊。 一個C程序由一個或多個函數(shù)組成,有且僅有一個主函數(shù),即main()函數(shù)。 每個函數(shù)完成一個相對獨立的且功能明確的任務(wù)。 由主函數(shù)調(diào)用其他函數(shù),其他

2、函數(shù)也可以互相調(diào)用。 同一個函數(shù)可以被一個或多個函數(shù)調(diào)用任意多次。,函數(shù),C語言的函數(shù),C語言的函數(shù)有兩大類: 標準庫函數(shù) 提供了豐富的函數(shù)。 例如 數(shù)學計算:sqrt(),abs() 輸入/輸出:scanf(),printf() 自定義函數(shù) 程序員可以編寫函數(shù)來完成特定的任務(wù)。 應(yīng)該熟悉C系統(tǒng)中的標準函數(shù)庫。 應(yīng)該避免從零開始構(gòu)建一切。,函數(shù),為什么使用函數(shù),函數(shù)使程序模塊化。 程序采用模塊化結(jié)構(gòu)的好處: 分而治之 提高程序開發(fā)的效率。 使程序易于管理。 代碼重用 使用現(xiàn)有的函數(shù)作為構(gòu)件來創(chuàng)建程序。 函數(shù)可以被重復(fù)使用。 抽象 隱藏了實現(xiàn)的細節(jié)。 例如 使用庫函數(shù)(printf()),但并不

3、知道它的具體實現(xiàn)(沒有影響使用)。,函數(shù),案例分析:一個簡單的函數(shù),編寫和使用一個簡單的函數(shù)(cw0801.c) 定義一個函數(shù)square,用來計算任意整數(shù)的平方。 然后,使用該函數(shù)計算從1到10所有整數(shù)的平方。,函數(shù),#include int square(int); void main() int x; for (x=1; x=10; x+) printf(%d , square(x); int square(int y) return y*y; ,聲明函數(shù),使用函數(shù),定義函數(shù),1 4 9 16 25 36 49 64 81 100,函數(shù)的定義,定義函數(shù)的格式 () 函數(shù)名:一個有效的標識

4、符。 函數(shù)類型:返回值的類型說明符。 如果不指定,即缺省,就是 int。 void :表示函數(shù)不返回任何值。 參數(shù)表:聲明參數(shù),多個參數(shù)用逗號分隔。 接收傳遞進來的數(shù)據(jù)。 必須為每個參數(shù)指定數(shù)據(jù)類型。 但 int 可以省略。,函數(shù),函數(shù)頭,函數(shù)體,函數(shù)的定義,定義函數(shù)的格式 () 函數(shù)體:包括聲明語句和可執(zhí)行語句。 在函數(shù)體內(nèi)可以聲明變量。 不能定義函數(shù),即函數(shù)的定義不允許嵌套。 控制返回:結(jié)束執(zhí)行,把程序的控制交還主調(diào)函數(shù),也可以用return返回一個數(shù)值。 return; return ;,函數(shù),無返回值,有返回值,案例分析:函數(shù)的定義,函數(shù)的定義(cw0802.c) 定義函數(shù)找出三個數(shù)中

5、的大數(shù)。,函數(shù),#include int maximum(int, int, int); void main() int a, b, c; printf(“Input three integers: ); scanf(%d%d%d, ,函數(shù)原型,接口(interface),函數(shù)原型,函數(shù)原型 (); 用來對函數(shù)進行聲明。 編譯器使用函數(shù)原型來檢查函數(shù)調(diào)用的合法性。 注意:函數(shù)原型要與函數(shù)的定義一致。 例如 int maximum(int a, int b, int c); int maximum(int, int, int);,函數(shù),函數(shù)原型,函數(shù)原型在程序文件中的位置不同,作用范圍不同。 在

6、所有函數(shù)的外面 在函數(shù)內(nèi)部,函數(shù),main() void funcA() int funcB(int); int funcB(int) ,函數(shù)原型,如果程序中沒有包含函數(shù)原型。 編譯程序會使用該函數(shù)第一次出現(xiàn)的情形來形成自己的函數(shù)原型。 函數(shù)的定義 函數(shù)的調(diào)用 默認情況下,編譯程序假定函數(shù)返回int型的結(jié)果,但不會對參數(shù)進行任何假定。 如果傳遞給函數(shù)的參數(shù)不正確,編譯程序不會檢查到這些錯誤。,函數(shù),函數(shù)原型,函數(shù)原型強迫參數(shù)采用正確的數(shù)據(jù)類型。 舉例 printf(“%.3f”, sqrt(4) ); 函數(shù)原型使編譯程序把整數(shù)值4轉(zhuǎn)換為double型的值4.0 沒有與函數(shù)原型中的參數(shù)類型完全對

7、應(yīng)的參數(shù)值會在調(diào)用函數(shù)之前被轉(zhuǎn)換成合適的數(shù)據(jù)類型。 遵守C語言的提升規(guī)則。,函數(shù),double sqrt(double);,函數(shù)原型與頭文件,頭文件 每個標準庫函數(shù)都有對應(yīng)的頭文件。 包含了標準庫中所有函數(shù)的函數(shù)原型, 以及那些函數(shù)所需的數(shù)據(jù)類型和常量的定義。 使用#include命令把頭文件包含到程序文件中: #include 例如,#include 程序員可以創(chuàng)建自己的頭文件 使用.h擴展名。 使用下面的命令格式包含頭文件: #include “文件名” 例如,#include “abc.h”,函數(shù),函數(shù)調(diào)用,函數(shù)調(diào)用 使用函數(shù),也稱為調(diào)用函數(shù)。,函數(shù),main() int a, b, c

8、; scanf(%d%d, ,1,2,6,int max(int a, int b) int c; c=a=b?a:b; return c; ,3,4,5,1、 2、主調(diào)函數(shù)暫停,保存現(xiàn)場。 3、把實參的值拷貝給形參,控制權(quán)交給函數(shù) max 。 4、,5、被調(diào)函數(shù)執(zhí)行結(jié)束,把函數(shù)值返回給主調(diào)函數(shù),同時把控制權(quán)還給主調(diào)函數(shù)。 6、恢復(fù)現(xiàn)場,主調(diào)函數(shù)繼續(xù)執(zhí)行。 ,參數(shù)傳遞,函數(shù)間的數(shù)據(jù)傳遞方式: 參數(shù) 返回值,函數(shù),int max(int a, int b) return c; main() c=max(a, b); ,參數(shù)傳遞,返回值傳遞,調(diào)用,實參和形參,實參和形參,函數(shù),int max(in

9、t a, int b) int c=a=b?a:b; return c; main() int a, b, c; scanf(“%d%d”, ,形式參數(shù) 簡稱“形參”。在函數(shù)定義時表示可以接受傳遞過來的值。,實際參數(shù) 簡稱“實參”。在函數(shù)調(diào)用時給出。,形參,形參,函數(shù),int max(int a, int b) int c=a=b?a:b; return c; main() int a, b, c; scanf(“%d%d”, ,只有在函數(shù)被調(diào)用、啟動后,才臨時為其分配存儲單元,并接受主調(diào)函數(shù)傳來的數(shù)據(jù)。 在函數(shù)調(diào)用結(jié)束后,形參所占存儲單元被釋放。,實參,實參,函數(shù),int max(int a

10、, int b) int c=a=b?a:b; return c; main() int a, b, c; scanf(“%d%d”, ,實參是函數(shù)調(diào)用時主調(diào)函數(shù)傳送給被調(diào)函數(shù)的形式參數(shù)的實際值。 實參可以是常量、變量和表達式。 實參必須有確定的值。,參數(shù)傳遞,參數(shù)傳遞的順序。,函數(shù),int max(int a, int b) int c=a=b?a:b; return c; main() int x=6, y; y=max(x, x+); printf(“%d”, y); ,當實參表列中有多個實參時,對實參的求值順序并不確定。 VC和BC是按從右往左的順序求值。,b=x+; a=x;,7,在

11、參數(shù)傳遞時,參數(shù)傳遞,參數(shù)傳遞的影響。,函數(shù),int max(int a, int b) int c=a=b?a:b; a+; b+; return c; main() int a=6, b=5, c; c=max(a, b); printf(“%d,%d,%d”,a,b,c); ,實參與形參不共用存儲單元。 參數(shù)傳遞時,把實參的值復(fù)制一份給形參。 形參值的變化不影響實參的值。 所以,形參和實參可以同名。,6,5,6,值傳遞和引用傳遞,函數(shù)間參數(shù)的傳遞有兩種類型: 值傳遞 主調(diào)函數(shù)把實參的值的副本傳遞給被調(diào)函數(shù)的形參。 在被調(diào)函數(shù)內(nèi)改變形參的值不會改變主調(diào)函數(shù)中實參的值。 如果函數(shù)不需要修改參

12、數(shù)的值,就采用這種調(diào)用方式。 引用傳遞 主調(diào)把實參“自身”傳遞給被調(diào)函數(shù)的形參。 在被調(diào)函數(shù)內(nèi)改變形參的值將改變主調(diào)函數(shù)中實參的值。 用于可信的函數(shù)。 在C語言中,所有參數(shù)傳遞都采用值傳遞。,函數(shù),參數(shù)傳遞,實參和形參的類型應(yīng)該相同或賦值兼容。,函數(shù),int max(int a, int b) int c=a=b?a:b; return c; main() int x=6, y=5, z; z=max(x, y); printf(“%d”, z); ,如果x, y是整型,則結(jié)果正確; 如果x, y是字符型,則自動進行類型轉(zhuǎn)換,結(jié)果正確; 如果x, y是短整型,則自動進行類型轉(zhuǎn)換,結(jié)果正確; 如

13、果x或y是實數(shù),則自動進行類型轉(zhuǎn)換,有數(shù)據(jù)丟失,結(jié)果可能不正確。,b=y; a=x;,在參數(shù)傳遞時,函數(shù)的返回值,函數(shù)返回值的類型應(yīng)該與函數(shù)的類型一致。 如果不一致,采用函數(shù)的類型,對返回值進行類型轉(zhuǎn)換。,函數(shù),int max(float a, float b) float c=a=b?a:b; return c; ,main() float x=6.5, y=5.6, z; z = 2*max(x, y); printf(“%f”, z); ,c 的類型? 返回值的類型?,max(x,y) 的類型? 2*max(x,y) 的類型?,函數(shù)的嵌套調(diào)用,嵌套調(diào)用 在調(diào)用一個函數(shù)的過程中又調(diào)用另一個

14、函數(shù),函數(shù),案例分析:函數(shù)的嵌套調(diào)用,計算圓環(huán)的面積 分析 圓環(huán)的面積 = 外圓的面積 內(nèi)圓的面積 可以定義兩個函數(shù) circleArea 計算圓的面積 ringArea 計算圓環(huán)的面積,函數(shù),double circleArea(double r); double ringArea(double r1, double r2);,案例分析:函數(shù)的嵌套調(diào)用,計算圓環(huán)的面積 源代碼(cw0804.c),函數(shù),#include #define PI 3.14 double circleArea(double r); double ringArea(double r1, double r2); void

15、 main() double r1, r2, s; printf(tInput r1, r2: ); scanf(%lf%lf, ,案例分析:函數(shù)的嵌套調(diào)用,計算圓環(huán)的面積 源代碼(續(xù)),函數(shù),double circleArea(double r) return PI*r*r; double ringArea(double r1, double r2) if (r1=r2) return circleArea(r2)-circleArea(r1); else return circleArea(r1)-circleArea(r2); ,Input r1, r2: 1 2 The area is

16、: 9.42,程序設(shè)計舉例:擲骰子,擲骰子 問題 每個玩家擲兩個骰子。每個骰子都有6個面。這些面中包含了1點、2點、3點、4點、5點和6點。當骰子靜止下來之后,計算兩個朝上的面中的點數(shù)和(本次投擲的結(jié)果)。 如果第一次投擲的結(jié)果是7 或11,那么這個玩家就獲勝。 如果第一次投擲的結(jié)果是2、3或12,那么這個玩家就輸了(即莊家獲勝)。 如果第一次投擲的結(jié)果是4、5、6、8、9或10,那么這個結(jié)果就是該玩家的“點數(shù)”。 為了獲勝,玩家必須繼續(xù)擲骰子,直到“擲出了點數(shù)”。在擲出點數(shù)之前,如果玩家擲出了7,那么玩家就輸了。,函數(shù),程序設(shè)計舉例:擲骰子,擲骰子 初始設(shè)計 定義一個函數(shù) rollDice,

17、用來模擬擲一次骰子 產(chǎn)生兩個隨機數(shù)(1.6),返回它們的和(點數(shù)),函數(shù),擲第一次,勝,輸,擲一次,勝,輸,?,程序設(shè)計舉例:擲骰子,擲骰子 細化設(shè)計 定義一個變量保存游戲進展的狀態(tài) gamestatus 0:繼續(xù) 1:勝利(游戲結(jié)束) 2:失?。ㄓ螒蚪Y(jié)束),函數(shù),程序設(shè)計舉例:擲骰子,擲骰子 實現(xiàn)(cw0807.c),函數(shù),#include #include #include int rollDice(void); void main() int gameStatus, sum, myPoint; srand(time(NULL); sum = rollDice();,擲第一次,程序設(shè)計舉例

18、:擲骰子,擲骰子 實現(xiàn),函數(shù),switch(sum) case 7: case 11: gameStatus = 1; break; case 2: case 3: case 12: gameStatus = 2; break; default: gameStatus = 0; myPoint = sum; printf(Point is %dn, myPoint); break; ,擲第一次之后的結(jié)果,程序設(shè)計舉例:擲骰子,擲骰子 實現(xiàn),函數(shù),while (gameStatus = 0) sum = rollDice(); if (sum = myPoint) gameStatus = 1;

19、 else if (sum = 7) gameStatus = 2; if (gameStatus = 1) printf(You wins!); else printf(You loses!); ,繼續(xù)游戲,勝負判斷,程序設(shè)計舉例:擲骰子,擲骰子 實現(xiàn),函數(shù),int rollDice() int dice1, dice2, sum; dice1 = rand()%6 + 1; /第一個骰子的點數(shù) dice2 = rand()%6 + 1; /第二個骰子的點數(shù) sum = dice1 + dice2; printf(You rolled %d + %d = %dn, dice1, dice2,

20、 sum); return sum; ,遞歸函數(shù),遞歸函數(shù) 直接或間接調(diào)用自己的函數(shù)。,函數(shù),案例分析:遞歸函數(shù),用遞歸方法計算n!。 分析 5! = 5 * 4 * 3 * 2 * 1 5! = 5 * 4! 4! = 4 * 3!. 遞歸公式,函數(shù),基本情形,簡化問題,s=1; n=1; while (n=20) s = n * s;,迭代,n! = n * (n-1)!,案例分析:遞歸函數(shù),舉例:用遞歸方法計算n!。 源代碼(cw0805.c),函數(shù),#include long fac(int n) long f; if (n=0|n=1) f=1; else f=n*fac(n-1);

21、 printf(t%d!=%ldn, n, f); return f; void main( ) printf(nt5!=%ldn, fac(5); ,1!=1 2!=2 3!=6 4!=24 5!=120 5!=120,遞歸調(diào)用,案例分析:遞歸函數(shù),舉例:用遞歸方法計算n!。 分析,函數(shù),5!,5*4!,4*3!,3*2!,2*1!,1,120,5*24,4*6,3*2,2*1,1,遞歸調(diào)用,從遞歸調(diào)用返回值,用遞歸方案解決問題小結(jié),用遞歸(函數(shù))方案解決問題 遞歸函數(shù)只知道如何去解最簡單的情形(基本情形) 簡單的返回一個值 把復(fù)雜的問題分成兩部分: 函數(shù)知道如何去做的部分 函數(shù)不知道如何去

22、做的部分 這一部分與原問題相似,且更簡單 函數(shù)可以調(diào)用自己的新形式來解決這個更小的問題(遞歸調(diào)用) 最終遇到基本情形 函數(shù)識別出基本情形,將結(jié)果返回給前一個情形 一系列的結(jié)果按順序返回 直到把最終結(jié)果返回給原始的調(diào)用者(可能是main()函數(shù)),函數(shù),案例分析:遞歸方案,使用遞歸方法計算斐波拉契數(shù)列。 0 1 1 2 3 5 8 分析 從第三個數(shù)開始,每個數(shù)是前兩個數(shù)的和。 第一、二個數(shù)是確定的。 遞歸公式 fib(n) = fib(n-1) + fib(n-2) fib(1) = 0 fib(2) = 1,函數(shù),遞歸與迭代,遞歸與迭代的比較 循環(huán) 迭代:明確使用了循環(huán)結(jié)構(gòu) 遞歸:重復(fù)調(diào)用遞歸

23、函數(shù) 終止條件 迭代:循環(huán)條件不滿足 遞歸:遇到基本情形 都有可能出現(xiàn)無限循環(huán) 如何選擇 迭代:性能好 遞歸:可讀性好,函數(shù),程序設(shè)計舉例:漢諾塔問題,漢諾塔問題 問題 假設(shè)有三個分別命名為X,Y和Z的塔座,在塔座X上插有n個直徑大小各不相同、依從小到大編號為1,2,n的圓盤?,F(xiàn)要求將X軸上的n個圓盤移到塔座Z上,并按同樣的順序疊放。 移動時必須遵循以下規(guī)則: 每次只能移動一個圓盤; 圓盤可以插在X,Y和Z中的任一塔座上; 任何時候都不能將一個較大的圓盤壓在較小的圓盤之上。,函數(shù),程序設(shè)計舉例:漢諾塔問題,漢諾塔問題 分析 n=1時 將圓盤1從塔座X移到塔座Z。,函數(shù),基本情形,程序設(shè)計舉例:漢諾塔問題,漢諾塔問題 分析 n1時,函數(shù),1. 利用塔座Z為輔助塔座,將壓在圓盤n之上的n-1個盤從塔座X移到塔座Y; (與原問題類似) 2. 將圓盤n從塔座X移到塔座Z; 3. 利用塔座X為輔助塔座,將塔座Y上的n-1個圓

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論