




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第八章 函數1、熟練掌握函數的定義;2、對函數的參數和函數的值要深刻理解; 3、學會函數的調用;4、靈活掌握函數變量的類型及存儲類別;本章要求: 函函 數數 函函 數數 概概 念念 函函 數數 調調 用用 應應 用用 舉舉 例例 遞遞 歸歸 調調 用用全局變量與局部變量全局變量與局部變量 動態與靜態存儲變量動態與靜態存儲變量內部與外部函數內部與外部函數 第八章 函數8 8. 1 8. 1 概述概述 8. 8.函數定義的一般形式函數定義的一般形式 8. 8.函數參數和函數的值函數參數和函數的值 8. 8.函數的調用函數的調用 8. 8.函數的嵌套調用函數的嵌套調用 8. 8.函數的遞歸調用函數的
2、遞歸調用 8. 8.數組作為函數參數數組作為函數參數 8. 8 8. 8 局部變量和全局變量局部變量和全局變量 8. 8.變量的存儲類別變量的存儲類別 8.10 8.10 內部函數和外部函數內部函數和外部函數本章要求:本章要求:1、熟練掌握函數的定義;、熟練掌握函數的定義;2、對函數的參數和函數的值要深刻理、對函數的參數和函數的值要深刻理 解;解; 3、學會函數的調用;、學會函數的調用;4、靈活掌握函數變量的類型及存儲類、靈活掌握函數變量的類型及存儲類 別;別; 一個程序可由一個主函數和若干個其他函一個程序可由一個主函數和若干個其他函數構成。數構成。在高級語。在高級語言中用子程序實現模塊的功能
3、言中用子程序實現模塊的功能, , 子程序由函數來子程序由函數來完成。完成。 C C是模塊化程序設計語言是模塊化程序設計語言源 程 序 文 件 1預 編 譯 命 令說 明 部 分執 行 部 分函 數 1函 數 n源 程 序 文 件 i源 程 序 文 件 nC程 序C C程序結構程序結構&C C是是函數式函數式語言語言&必須有且只能有一個名為必須有且只能有一個名為mainmain的主函數的主函數&C C程序的執行總是程序的執行總是從從mainmain函數開始,在函數開始,在mainmain中結束中結束&函數函數不能嵌套定義不能嵌套定義, ,可以嵌套調用可以嵌套調用模
4、塊化程序設計模塊化程序設計v基本思想:將一個大的程序按功能分割成一些小模塊基本思想:將一個大的程序按功能分割成一些小模塊v特點:特點:l各模塊相對獨立、功能單一、結構清晰、接口簡單各模塊相對獨立、功能單一、結構清晰、接口簡單l控制了程序設計的復雜性控制了程序設計的復雜性l提高元件的可靠性提高元件的可靠性l縮短開發周期縮短開發周期l避免程序開發的重復勞動避免程序開發的重復勞動l易于維護和功能擴充易于維護和功能擴充v開發方法開發方法: : 函數分類函數分類 從用戶角度從用戶角度標準函數(庫函數):由系統提標準函數(庫函數):由系統提供供用戶自定義函數用戶自定義函數 從函數形式從函數形式無參函數無參
5、函數有參函數有參函數:1)1) 由系統提供,用戶無須定義,也不必在由系統提供,用戶無須定義,也不必在程序中作類型說明,只需在程序前包含有該函數原型的頭文程序中作類型說明,只需在程序前包含有該函數原型的頭文件即可在程序中直接調用。在前面各章的例題中反復用到件即可在程序中直接調用。在前面各章的例題中反復用到printf、scanf、getchar、putchar、gets、puts、strcat等等函數均屬此類。函數均屬此類。應注意:應注意:1 1、函數功能、函數功能2 2、函數參數的數目和順序,及各參數的意義和類型、函數參數的數目和順序,及各參數的意義和類型3 3、函數返回值的意義和類型、函數返
6、回值的意義和類型4 4、需要使用的包含文件、需要使用的包含文件 標準函數一般均是系統提供,因此程序質量應是最高的,即速標準函數一般均是系統提供,因此程序質量應是最高的,即速度快、精度高且占內存少,調用方便。度快、精度高且占內存少,調用方便。C 中庫函數按功能分類:中庫函數按功能分類: 編程中常遇到完成某個功能的程序段出現多次,為使程編程中常遇到完成某個功能的程序段出現多次,為使程序更簡化;常遇到大家均要用到的功能,為了減少不必要的序更簡化;常遇到大家均要用到的功能,為了減少不必要的重復編程使程序質量提高。在計算機高級語言中,引入函數重復編程使程序質量提高。在計算機高級語言中,引入函數(或子程序
7、、過程),稱為(或子程序、過程),稱為標準函數標準函數,C中稱中稱庫函數庫函數。 函數函數 頭文件頭文件 輸入、輸出函數輸入、輸出函數 stdio.h 數學函數數學函數 math.h 字符和字符串函數字符和字符串函數 string.h 動態分配函數動態分配函數 malloc.h 圖形函數圖形函數 graphics.h語言不僅提供了語言不僅提供了極為豐富的庫函數極為豐富的庫函數( (如如Turbo CTurbo C,MS CMS C都提供了三百多個都提供了三百多個庫函數庫函數) ),還允許,還允許用戶建立自己定義用戶建立自己定義的函數。用戶可把的函數。用戶可把自己的算法編成一自己的算法編成一個個
8、相對獨立的函個個相對獨立的函數模塊,然后用調數模塊,然后用調用的方法來使用函用的方法來使用函數。可以說程序數。可以說程序的全部工作都是由的全部工作都是由各式各樣的函數完各式各樣的函數完成的,所以也把成的,所以也把語言稱為函數式語語言稱為函數式語言。言。2)2) 由用戶按需要寫的函數。由用戶按需要寫的函數。Void main( )Void main( ) int max( int a, int b ); int max( int a, int b ); int x, y, z; int x, y, z; printf(input two numbers:n); printf(input two
9、numbers:n); scanf(%d%d, &x, &y); scanf(%d%d, &x, &y); z=max(x, y);z=max(x, y); printf(maxmum=%d, z); printf(maxmum=%d, z); 函數說明與函數定義中的函數函數說明與函數定義中的函數頭部分相同,但是末尾要加分號頭部分相同,但是末尾要加分號 int max( int a, int b )int max( int a, int b ) if (ab) return a; else return b;【 1)1) 函數定義、函數說明及函數調用中均函數定義
10、、函數說明及函數調用中均不帶參數。主調函數和被調函數之間不進行參數傳送。此不帶參數。主調函數和被調函數之間不進行參數傳送。此類類,可以返回或不返回,可以返回或不返回函數值。函數值。2)2) 也稱為帶參函數。在函數定義及函數也稱為帶參函數。在函數定義及函數說明時都有參數,稱為形式參數說明時都有參數,稱為形式參數( (簡稱為形參簡稱為形參) )。在函數調。在函數調用時也必須給出參數,稱為實際參數用時也必須給出參數,稱為實際參數( (簡稱為實參簡稱為實參) )。進行。進行。通過參數向被調用函數傳遞數據。void Hello( ) void main( ) :無參函數:無參函數:函數定義、函數說明及函
11、數調用中均函數定義、函數說明及函數調用中均不帶參數不帶參數。主調函數和被調函數之間主調函數和被調函數之間不進行參數傳送不進行參數傳送。無參函數無參函數一個函數調用的簡單例子一個函數調用的簡單例子(無參)# include void main() printstar(); *調用printstar函數* print_message(); /*調用print_message函數*/ printstar(); *調用printstar函數*/ *定義printstar函數* printf(* * * * * * * * * * * * * * * *n); *定義print_message函數* p
12、rintf(How do you do!n); 運行情況如下:運行情況如下:* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *How do you do!How do you do!* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *【補補例例2】調用函數,輸出若干個】調用函數,輸出若干個 “ * ” 每行輸出每行輸出10個個“* *”,共輸出三行。,共輸出三行。 void myprint ( ) int i ; for (i=1; i=10;
13、i+) printf (* ) ; printf (n ) ; void main ( ) myprint ( ) ; myprint ( ) ; myprint ( ) ; 無參函數無參函數 *#include 輸出一行輸出一行10個個“*” 有參函數:有參函數:在函數定義及函數說明時都在函數定義及函數說明時都有參數有參數,稱為形式參,稱為形式參數數(簡稱為形參簡稱為形參)。在函數調用時也必須給出參數,稱為實際。在函數調用時也必須給出參數,稱為實際參數參數(簡稱為實參簡稱為實參)。進行函數調用時,主調函數。進行函數調用時,主調函數將把實參的將把實參的值傳送給形參值傳送給形參,供被調函數使用。
14、,供被調函數使用。void main( ) int a, b, c; scanf(%d,%d, &a, &b); c=c=max (a , b ) ;max (a , b ) ; printf(Max is %d, c ) ;max ( int x , int y)max ( int x , int y) int z; z=xy? x: y ; return( z ); void main( ) int x, y, z; scanf(%d,%d, &x, &y); z=xy? x: y ; printf(Max is %d, z ) ;:【補補例例2】調用函數,
15、輸出若干個】調用函數,輸出若干個“*” 每行輸出每行輸出 n 個個“* *”,共輸出三行。,共輸出三行。 void myprint_n (int n) int i ; for (i=1; i=n; i+) printf (* ) ; printf (n ) ; void main ( ) myprint_n(5); myprint_n(10); myprint_n(15); 有參函數有參函數 *#include 輸出一行輸出一行n個個“*” 【補例【補例3】計算】計算xy的值的值 請注意:請注意:C語言中語言中 解法解法1:調用庫函數:調用庫函數pow ,計算,計算xy 計算計算xy 調用庫函
16、數調用庫函數必須加此行必須加此行 pow要求要求x和和y為為double Input data: 2.0 3.0 2.000000的的3.000000次方是次方是 8.000000解法解法2:調用自編函數:調用自編函數mypow,計算,計算xy若庫中未提供求若庫中未提供求xy的函數,的函數,則用戶先編寫后再使用則用戶先編寫后再使用 #include #include double mypow ( double x, double y ) int i; double z ;z = 1.0;for ( i = 1; i b) return a; else return b; 形形參參: 形參出現在
17、函數定義中,形參出現在函數定義中,形參變量只有在被調用形參變量只有在被調用時才分配內存單元,在調用結束時,時才分配內存單元,在調用結束時,立立刻釋放所分配刻釋放所分配的內存單元。因此,形參只有在函數內部有效。函數的內存單元。因此,形參只有在函數內部有效。函數調用結束返回主調函數后則不能再使用該形參變量調用結束返回主調函數后則不能再使用該形參變量。 實實參參:max(,)實參和形參在數量上,類型上,順序上應嚴格一致實參和形參在數量上,類型上,順序上應嚴格一致否則會發生否則會發生”類型不匹配類型不匹配”的錯誤。的錯誤。 主調函數和被調用函數之間有主調函數和被調用函數之間有的關系。的關系。在不同的函
18、數之間傳遞數據,可以使用的方法有:在不同的函數之間傳遞數據,可以使用的方法有:通過形式參數和實際參數通過形式參數和實際參數用用returnreturn語句返回計算結果語句返回計算結果外部變量外部變量#include void main( ) int max(int int max(int ,int int ) ); /* 對對max函數的聲明函數的聲明 */ int aint a,b b,c c; scanf (scanf (,a a,b)b); printfprintf( ,c c );); int max(int ,int ) *定義有參函數定義有參函數max * int int ; ?
19、; returnreturn();(); 運行情況如下:運行情況如下:, 通過函數調用,可使兩個函數中的數據發生聯系。通過函數調用,可使兩個函數中的數據發生聯系。void main() int n; scanf(%d, &n); s(n); printf(n=%dn, n );int s(int n) int i; for(i=n-1; i=1; i-) n=n+i; printf(n=%dn, n); 運行結果:運行結果:n=5050 n=100形參的值形參的值實參的值實參的值100s=0;for(i=1; iy? x: y ; return( z ); void main( ) i
20、nt x, y, z; scanf(%d,%d, &x, &y); z=xy? x: y ; printf(Max is %d, z ) ;:1 1、值傳遞、值傳遞方式方式l方式:方式: 函數調用時函數調用時, ,為形參分配單元為形參分配單元, ,并將實參的值并將實參的值復制復制到形到形參中參中, ,既實參將值直接賦給形參(變量)既實參將值直接賦給形參(變量) ;調用結束,形參;調用結束,形參單元被釋放,實參單元仍保留并維持原值。單元被釋放,實參單元仍保留并維持原值。 l特點:特點:u形參與實參占用形參與實參占用不同不同的內存單元的內存單元u稱做稱做單方向值調用單方向值調用-單
21、向單向傳遞傳遞實參變量對形參變量的數據傳遞有兩種方式:實參變量對形參變量的數據傳遞有兩種方式: 實參和形參在數量上,類型上,順序上應嚴格一致實參和形參在數量上,類型上,順序上應嚴格一致補例補例 交換兩個數交換兩個數void swap(int a,int b) int temp; temp=a; a=b; b=temp; printf(“a=%dtb=%dn, a, b ); Void main( ) int x=7,y=11; printf(x=%d, y=%dn, x, y ); printf(swapped:n); swap(x,y); printf(x=%d,ty=%dn, x, y )
22、;調用交調用交1.C711x:y:調用前:調用前:調用調用:711a:b:711x:y:swap:711x:y:117a:b:temp調用結束:調用結束:711x:y:調用之前調用之前x7y11x = 7 , y = 11printf (x = %d , y = %dn , x , y ) ;x7y11調用開始調用開始實參實參形參形參abx = 7 , y = 11711開辟開辟x7y11實參實參形參形參abx = 7 , y = 11711711temp = a ; a= b ; b = temp ;a = 11 , b = 7x7y11調用完畢調用完畢實參實參形參形參abx = 7 , y
23、 = 11711釋放釋放x = 7 , y = 11“按值按值”單向傳遞單向傳遞 printf (x = %d , y = %dn , x , y ) ;2 2、地址傳遞(暫略)、地址傳遞(暫略)l方式:方式: 函數調用時,將數據的函數調用時,將數據的存儲地址存儲地址作為參數傳遞作為參數傳遞給形參給形參,表示被調函數和主調函數操作的是同一批表示被調函數和主調函數操作的是同一批內存單元內容內存單元內容l特點:特點:u形參與實參占用形參與實參占用同樣同樣的存儲單元的存儲單元u形參的值發生改變,帶回主調函數形參的值發生改變,帶回主調函數-“雙向雙向”傳遞傳遞u實參和形參必須是實參和形參必須是地址地址
24、常量或變量常量或變量swap (int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p;main() int a,b; scanf(%d,%d,&a,&b); printf(“a=%d,b=%dn”,a,b); printf(“swapped:n”); swap(&a, &b); printf(”a=%d,b=%dn,a,b);例例 交換兩個數交換兩個數a59b調前:調前:a59b調調swap:p1&a&bp2a95b交換:交換:p1&a&bp2a95b返回:返回:略返回值返回值: 函數的值是
25、指函數被調用之后,函數的值是指函數被調用之后,執行函數執行函數體中的程序段所取得的并返回給主調函數的值。體中的程序段所取得的并返回給主調函數的值。如如; ; 調用正弦函數取得調用正弦函數取得, 例例8.中,中,max(,)的值是,(,)的值是,max(,)的值是(,)的值是5。賦值語句將這個函數值賦。賦值語句將這個函數值賦給變量。給變量。 調用調用等。等。 : return(表達式表達式); return 表達式;表達式; return;使程序控制從被調用函數返回到調用函數中,使程序控制從被調用函數返回到調用函數中,同時同時 把返值帶給調用函數把返值帶給調用函數例例 無返回值函數無返回值函數v
26、oid swap(int x, int y ) int temp; temp=x; x=y; y=temp; 返回語句返回語句說明說明: (1 1)函數的返回值是通過函數中的函數的返回值是通過函數中的returnreturn語句獲得的。語句獲得的。 一個函數中可以有一個以上的一個函數中可以有一個以上的語句,執行到哪一個語句,執行到哪一個 語句,哪一個語句起作用。語句,哪一個語句起作用。 語句后面的括弧也可以不要語句后面的括弧也可以不要例如例如: : “;” 等價于等價于 “;” 后面的值可以是一個表達式。后面的值可以是一個表達式。例如例如: : 若無若無 語句,遇語句,遇“ ”時,自動返回調用
27、函數時,自動返回調用函數(2 2)函數的返回值應當屬于某一個確定的類型,在定函數的返回值應當屬于某一個確定的類型,在定 義函數時指定函數返回值的類型。義函數時指定函數返回值的類型。例如例如: 下面是下面是3個函數的首行:個函數的首行: int max(float ,float ) /* 函數值為整型 */ char letter(char c1,char c2) /* 函數值為字符型 */ double min(int ,int ) /* 函數值為雙精度型 */ 注意:注意: 若函數類型與若函數類型與語句中表達式值的類語句中表達式值的類型不一致,按函數類型為準,自動轉換型不一致,按函數類型為準
28、,自動轉換-函數調函數調用轉換用轉換(3 3)對于不帶回值的函數,應當用對于不帶回值的函數,應當用“void”定義函定義函 數為數為“無類型無類型”(或稱(或稱“空類型空類型”)。此時)。此時在函在函 數體中不得出現數體中不得出現return語句。語句。 return、break、exit、contiune的作用:的作用: return 語句語句 退出調用函數退出調用函數 break 語句語句 退出退出switch語句體或本層循環語句體或本層循環 exit 結束整個程序執行結束整個程序執行 contiune 語句語句 return( (表達式)表達式)僅僅返回一個值返回一個值;若不返回任何值可
29、不要若不返回任何值可不要 return ( ); 凡函數未說明返回值類型均以凡函數未說明返回值類型均以 int 處理;處理; 例例 8.3 返回值類型與函數類型不同返回值類型與函數類型不同# include void main() int max(float ,float ); float ,; int c; scanf(,); c(,); printf( ,c); max(float ,float ) ; /* z為實型變量 */ ? ; return(z); , Max is Max is 說明說明: :如果是調用無參函數,則如果是調用無參函數,則“實參表列實參表列”可以沒可以沒 有,但括
30、弧不能省略。有,但括弧不能省略。實參與形參實參與形參個數相等個數相等,類型一致類型一致,按順序一一按順序一一 對應對應實參表求值順序,因系統而定實參表求值順序,因系統而定(Turbo C 自右向左自右向左)例例 8.4 實參求值的順序實參求值的順序#include void main() int f( int a, int b ); /* 函數聲明 */ int i=2,p; p=f( i, +i ); /* 函數調用 */ printf(%dn, p ); int f( int a, int b) /* 函數定義 */ int c; if(ab) c=1; else if(a=b) c=0;
31、 else c=-1; return(c); 如果按自左至右順序求實如果按自左至右順序求實參的值,則函數調用相當參的值,則函數調用相當于(,)于(,) 如果按自右至左順序求實如果按自右至左順序求實參的值,則函數調用相當參的值,則函數調用相當于(于(3,),) 對于函數調用對于函數調用 int i=2, p;p=f( i, +i ); 函數調用的一般形式加上分號即構成函函數調用的一般形式加上分號即構成函數語句。數語句。 如:如: printf(“ %sn”, “BBI”);作為表達式中的一項出現作為表達式中的一項出現在表達式中,以函數返回值參與表達式的運算。在表達式中,以函數返回值參與表達式的運
32、算。 如:如: y= max(a, b) + 100;函數作為另一個函數函數作為另一個函數調用的實際參數出現。調用的實際參數出現。 如:如: printf(“ %d n”, max(s, b) ) ; 如:如: y= max( max(a, b), c );首先被調用的函數必須是已經存在的函數(是庫函數首先被調用的函數必須是已經存在的函數(是庫函數或用戶自己定義的函數)。但光有這一條件還不夠。或用戶自己定義的函數)。但光有這一條件還不夠。如果如果,還應該在本文件開頭用,還應該在本文件開頭用#include 命令將調用有關庫函數時所需用到的信息命令將調用有關庫函數時所需用到的信息“包含包含”到本
33、到本文件中來。文件中來。 如果使用用戶自己定義的函數,而該函數的位置在調用如果使用用戶自己定義的函數,而該函數的位置在調用它的函數(即主調函數)的后面,應該在主調函數中它的函數(即主調函數)的后面,應該在主調函數中函數原型的一般形式為函數原型的一般形式為: : 聲明的作用是把函數名、函數參數的個數和參數聲明的作用是把函數名、函數參數的個數和參數類型等信息通知編譯系統,以便在遇到函數調用時,類型等信息通知編譯系統,以便在遇到函數調用時,編譯系統能正確識別函數并檢查調用是否合法。編譯系統能正確識別函數并檢查調用是否合法。1.2.返回值是返回值是非非整型和字符型整型和字符型且函數定義在主調且函數定義
34、在主調 函數之后時,均須在主調函數里加說明。函數之后時,均須在主調函數里加說明。 格格 式:式: 或為:或為: float max( float a, float b );float max( float a, float b );或寫為或寫為: : float max( float, float ); float max( float, float );這便于編譯系統進行檢錯,以防止可能出現的錯誤這便于編譯系統進行檢錯,以防止可能出現的錯誤 聲明的作用是把函數名、函數參數的個數和參數聲明的作用是把函數名、函數參數的個數和參數類型等信息通知編譯系統,以便在遇到函數調用時,類型等信息通知編譯系統
35、,以便在遇到函數調用時,編譯系統能正確識別函數并檢查調用是否合法。編譯系統能正確識別函數并檢查調用是否合法。(與函數定義不同(與函數定義不同)注意:注意: 函數的函數的“定義定義”和和“聲明聲明”的區別:的區別:l 是指對是指對函數功能的確立函數功能的確立,包括指定函數名,包括指定函數名,函數值類型、形參及其類型、函數體等,它是一個完函數值類型、形參及其類型、函數體等,它是一個完整的、獨立的函數單位。整的、獨立的函數單位。l 的的作用則是把函數的名字、函數類型以及作用則是把函數的名字、函數類型以及形參的類型、個數和順序通知編譯系統,以便在調用形參的類型、個數和順序通知編譯系統,以便在調用該函數
36、時系統按此進行對照檢查。該函數時系統按此進行對照檢查。 void main() float a,b; int c; scanf(%f,%f,&a,&b); c=max(a,b); printf(Max is %dn,c);max(float x, float y) float z; z=xy?x:y; return(z);int型函數可不作函數說明型函數可不作函數說明例例 函數說明舉例函數說明舉例float add(float x, float y) float z; z=x+y; return(z);main() float a,b,c; scanf(%f,%f, &
37、a, &b); c=add(a, b); printf(sum is %f, c );被調函數出現在主調函數被調函數出現在主調函數之前,不必函數說明之前,不必函數說明void main( ) float add(float, float); /*function declaration*/ float a, b, c; scanf(%f, %f, &a, &b); c=add(a, b); printf(sum is %f, c);float add(float x, float y) float z; z=x+y; return(z);float add(); 在函數
38、外預先說明了各個函在函數外預先說明了各個函數的類型,則在以后的各主調數的類型,則在以后的各主調函數中,可不再對被調函數作函數中,可不再對被調函數作說明。說明。 例例8. 58. 5 對被調用的函數作聲明對被調用的函數作聲明# include void main() float a,b,c; scanf(f,f,a,b); cadd(a,b); printf(sum is f n,c);float add(float ,float ) *函數首部* float ; /* 函數體 */ z; return(z); 定義在后 例例8 8 對被調用的函數作聲對被調用的函數作聲明明# include f
39、loat add(float ,float ) *函數首部函數首部* float ; /* 函數體函數體 */ z; return(z);); void main()() float a,b,c; scanf(f,f,a,b);); cadd(a,b); printf(sum is f n,c);); 定義在前形式參數:函數名后面括號中的變量名稱為“形式參數”(簡稱“形參形參”)。實際參數:主調函數中調用一個函數時,函數名后面括號中的參數(可以是一個表達式)稱為“實際參數”(簡稱“實參實參”)。函數返回值:return后面的括號中的值作為函數帶回的值(稱函數返回值函數返回值)。 形式參數和實際
40、參數形式參數和實際參數 語言中不允許作嵌套的函數定義。因此各函數之間是平語言中不允許作嵌套的函數定義。因此各函數之間是平行的,不存在上一級函數和下一級函數的問題。但語言允許行的,不存在上一級函數和下一級函數的問題。但語言允許在一個函數的定義中出現對另一個函數的調用。這樣就出現了在一個函數的定義中出現對另一個函數的調用。這樣就出現了函數的嵌套調用函數的嵌套調用, , 即在被調函數中又調用其它函數。即在被調函數中又調用其它函數。例例 8. 用弦截法求方程用弦截法求方程 f(x)=x3-5x2+16x-80=0 f(x)=x3-5x2+16x-80=0 的根的根 取兩個不同點x1, x2, 如果 f
41、(x1) 和 f(x2) 符號相反, 則(x1, x2) 區間內必有一個根。如果f(x1)與f(x2)同符號, 則應改變 x1, x2, 直到 f(x1)、f(x2) 異號為止。注意 x1、x2 的值不應差太大, 以保證(x1, x2) 區間內只有一個根。 連接( x1, f(x1) )和 (x2, f(x2) )兩點, 此線(即弦)交x軸于x。 若 f(x)與 f(x1)同符號, 則根必在( x, x2 )區間內, 此時將 x 作為新的 x1。如果 f(x) 與 f(x2) 同符號, 則表示根在( x1, x )區間內, 將 x 作為新的 x2。 重復步驟 (2) 和 (3) , 直到 f(
42、x) 為止, 為一個很小的數, 例如 10-6。此時認為 f(x)0 。 取兩個不同點取兩個不同點x1, x2, 如果如果 f(x1) 和和 f(x2) 符號相反符號相反, 則則(x1, x2) 區間內必有一個根。如果區間內必有一個根。如果f(x1)與與f(x2)同符號同符號, 則應則應改變改變 x1, x2, 直到直到 f(x1)、f(x2) 異號為止。注意異號為止。注意 x1、x2 的的值不應差太大值不應差太大, 以保證以保證(x1, x2) 區間內只有一個根。區間內只有一個根。 連接連接( x1, f(x1) )和和 (x2, f(x2) )兩點兩點, 此線此線(即弦即弦)交交x軸于軸于
43、x。方法:方法: 若若 f(x)與與 f(x1)同符號同符號, 則根必在則根必在( x, x2 )區間內區間內, 此時此時將將 x 作為新的作為新的 x1。如果。如果 f(x) 與與 f(x2) 同符號同符號, 則表示根在則表示根在( x1, x )區間內區間內, 將將 x 作為新的作為新的 x2。 重復步驟重復步驟 (2) 和和 (3) , 直到直到 f(x) 為止為止, 為一個為一個很小的數很小的數, 例如例如 10-6。此時認為。此時認為 f(x)0 。N-S流程圖流程圖 實現各部分功能的幾個函數實現各部分功能的幾個函數: :用函數用函數 f(x) 代表代表 x 的函數的函數: x3-5
44、x2+16x-80。2. 用函數調用用函數調用 xpoint ( x1, x2) 來求來求 (x1, f(x1) )和和 ( x2, f(x2) )的連線與的連線與 x軸的交點軸的交點x 的坐標。的坐標。3. 用函數調用用函數調用 root ( x1, x2) 來求來求 (x1, x2) 區間的區間的 那個實根。顯然那個實根。顯然, 執行執行 root 函數過程中要用到函函數過程中要用到函 數數 xpoint, 而執行而執行 xpoint 函數過程中要用到函數過程中要用到 f 函數。函數。 include include float f(float x) float y;return(y);
45、/ * 定 義 函 數 , 以 實 現 f(x) x3-5x2+16x-80 * y=(x-5.0)*x+16.0)* x-80.0;float xpoint (float x1,float x2) *定義xpoint函數,求出弦與x軸交點 */ float y; y=( x1* f(x2)-x2*f(x1) ) (f(x2)- f(x1); return (y); float root(float x1,float x2) /* 定義root函數,求近似根 */ float x,y,y1; y1 f(x1); do while(fabs(y)0.0001); return( x) void
46、main( ) *主函數主函數 */ float x1,x2,f1,f2,x; do printf( ,:); scanf(,x1,x2); f1 f(x1); f2 f(x2); while(f1* f2); xroot( x1, x2 ); printf(“ root of equation is .n”,x );運行情況如下:input ,:, root of equation is 5.0000補例補例1 求三個數中求三個數中最大數最大數和和最小數最小數的的差值差值#include int dif( int x, int y, int z ); int max( int x, int
47、y, int z ); int min( int x, int y, int z);void main() int a,b,c,d; scanf(%d%d%d, &a,&b,&c); d=dif( a, b, c ); printf(Max-Min=%dn, d ); main( )調用函數調用函數dif輸出輸出結束結束dif函數函數max函數函數調用函數調用函數max調用函數調用函數minmin函數函數【補例補例2】編寫函數】編寫函數mysum,用以求,用以求 其中其中 f ( i ) = i +5 niif0)( return i+5; scanf(%d,&
48、n);printf(%d,%dn,n, mysum ( n );void main( ) int n ;int mysum ( int n ) int i , s = 0 ;for ( i=0; i=n ; i+ )s = s + myf(i);return s ;int myf(int i)int mysum ( int n ) ; int myf ( int i ) ;niif0)()(if for(i=0;i 1) 用用遞歸遞歸方法求方法求n! n!= = (n-1)! * * n按公式可編程如下:按公式可編程如下:if (n0)printf(“n1)【例【例8. 8】用遞歸法計算用遞歸
49、法計算n!【例【例8.7】有個人坐在一起,問第個人多少歲?他說有個人坐在一起,問第個人多少歲?他說比第個人大歲。問第個人歲數,他說比第個人比第個人大歲。問第個人歲數,他說比第個人大歲。問第個人,又說比第個人大歲。問第大歲。問第個人,又說比第個人大歲。問第個人,說比第個人大歲。最后問第個人,他說是個人,說比第個人大歲。最后問第個人,他說是歲。請問第個人多大。歲。請問第個人多大。 age(5)= age (4)+2age(4)= age (3)+2age(3)= age (2)+2age(2)= age (1)+2age(1)= 10用數學公式表述如下:age(n)= 10 ()age(n-1)+
50、2 ()有有5人,每人的年齡均是前一個人年齡人,每人的年齡均是前一個人年齡+2,問第五個人的年齡,問第五個人的年齡?第第5人人 第第4人人 第第3人人 第第2人人 第第1人人 (第(第5人年人年 齡是第齡是第 4人年齡人年齡+2, 第第4人人 年齡是第年齡是第3人年齡人年齡 +2, 依次類推。)依次類推。)( 第第1人年齡是人年齡是10則第二人年則第二人年齡是齡是12.) age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10 回推回推 遞推遞推歸遞公式:歸遞公式:age(n)=10 (n=1) age(n)=
51、 age(n-1)+2 (n1) (當第一個人年齡確定,其它人年齡可知)(當第一個人年齡確定,其它人年齡可知) int age(int n) void main( ) int c; int num; if (n= =1) c=10; scanf(“%d”, &num); else c=age(n-1) +2; printf(“age is %dn” , ); return ( c); age(4)+2 age(1)+2c=10age(5)=18 age(4)=16 age(1)=10輸出輸出age(5)main( ) 用一個主函數調用age函數,求得第5人的年齡。*求年齡的遞歸函數*運
52、行結果如下:運行結果如下: 18 【例【例8-9】Hanoi塔問題塔問題 一塊板上有三根針,一塊板上有三根針,A A,B B,C C。A A針上套有針上套有6464個大小不等個大小不等的圓盤,大的在下,小的在上。要把這的圓盤,大的在下,小的在上。要把這6464個圓盤從個圓盤從A A針移動針移動C C針上,每次只能移動一個圓盤,移動可以借助針上,每次只能移動一個圓盤,移動可以借助B B針進行。但針進行。但在任何時候,任何針上的圓盤都必須保持大盤在下,小盤在在任何時候,任何針上的圓盤都必須保持大盤在下,小盤在上。求移動的步驟。上。求移動的步驟。ABC略略如果如果n=1n=1,則將圓盤從則將圓盤從A
53、 A直接移動到直接移動到C C。如果如果n=2n=2,則:則: 1.1.將將A A上的上的n-1(n-1(等于等于1)1)個圓盤移到個圓盤移到B B上;上; 2.2.再將再將A A上的一個圓盤移到上的一個圓盤移到C C上;上; 3.3.最后將最后將B B上的上的n-1(n-1(等于等于1)1)個圓盤移到個圓盤移到C C上。上。如果如果n=3n=3,則:則: A. A. 將將A A上的上的n-1(n-1(等于等于2 2,令其為,令其為n)n)個圓盤移到個圓盤移到B(B(借助于借助于C)C),步驟如下:步驟如下: (1)(1)將將A A上的上的n-1(n-1(等于等于1)1)個圓盤移到個圓盤移到C
54、 C上。上。 (2)(2)將將A A上的一個圓盤移到上的一個圓盤移到B B。 (3)(3)將將C C上的上的n-1(n-1(等于等于1)1)個圓盤移到個圓盤移到B B。 B. B. 將將A A上的一個圓盤移到上的一個圓盤移到C C。 C. C. 將將B B上的上的n-1(n-1(等于等于2 2,令其為,令其為n)n)個圓盤移到個圓盤移到C(C(借助借助A)A),步,步驟如下:驟如下: (1)(1)將將B B上的上的n-1(n-1(等于等于1)1)個圓盤移到個圓盤移到A A。 (2)(2)將將B B上的一個盤子移到上的一個盤子移到C C。 (3)(3)將將A A上的上的n-1(n-1(等于等于1
55、)1)個圓盤移到個圓盤移到C C。 到此,完成了三個圓盤的移動過程。到此,完成了三個圓盤的移動過程。略略 從上面分析可以看出,當從上面分析可以看出,當n n大于等于大于等于2 2時,移動的時,移動的過程可分解為三個步驟:過程可分解為三個步驟:第一步第一步 把把A A上的上的n-1n-1個圓盤移到個圓盤移到B B上;上;第二步第二步 把把A A上的一個圓盤移到上的一個圓盤移到C C上;上;第三步第三步 把把B B上的上的n-1n-1個圓盤移到個圓盤移到C C上;其中第一步和上;其中第一步和第三步是類同的。第三步是類同的。 當當n=3n=3時,第一步和第三步又分解為類同的三步,時,第一步和第三步又
56、分解為類同的三步,即把即把n-1n-1個圓盤從一個針移到另一個針上,這里的個圓盤從一個針移到另一個針上,這里的n=n-1n=n-1。 顯然這是一個遞歸過程,據此算法可編程顯然這是一個遞歸過程,據此算法可編程如下:如下:略略由上面的分析可知:將個盤子從座移到座可以分解為以下3個步驟: 1.1.將上個盤借助座先移到座上。將上個盤借助座先移到座上。2.2.把座上剩下的一個盤移到座上。把座上剩下的一個盤移到座上。3.3.將個盤從座借助于座移到座上。將個盤從座借助于座移到座上。ABC略略程序如下程序如下:#include void main() void hanoi( int n, char one,
57、char two, char three ); /* 對hanoi函數的聲明 */ int m; printf( input the number of diskes:“ ); scanf( “%d”, &m); printf( The step to moveing %d diskes:n, m ); hanoi( m , A, B ,C ); 略略void hanoi(int n, char one, char two, char three) /*定義hanoi函數,將個盤從one座借助two座,移到three座 */ void move( char x, char y ); /
58、* 對move函數的聲明 */ if(n=1) move( one ,three); else hanoi( n-1, one, three, two); move( one, three ); hanoi( n-1, two, one, three ); void move(char x,char y) /* 定義move函數 */ printf(“%c-%cn, x, y) ; 略略運行情況如下:運行情況如下:input the number of diskes:3 The steps to noving 3 diskes: 略略 數組可以作為函數的參數使用,進行數據傳送。數數組可以作為函
59、數的參數使用,進行數據傳送。數組用作函數參數有兩種形式,組用作函數參數有兩種形式,是把數組元素是把數組元素( (下標變下標變量量) )作為實參使用;作為實參使用;是把數組名作為函數的形參和是把數組名作為函數的形參和實參使用。實參使用。數數 數組元素就是下標變量,它與普通變量并無區別。數組元素就是下標變量,它與普通變量并無區別。因此它作為函數實參使用與普通變量是完全相同的,在發因此它作為函數實參使用與普通變量是完全相同的,在發生函數調用時,把作為實參的數組元素的值傳送給形參,生函數調用時,把作為實參的數組元素的值傳送給形參,實現單向的值傳送。實現單向的值傳送。 711x:y:調用前:調用前:調用
60、結束:調用結束:711x:y:例例 交換兩個數交換兩個數void main() int x=7,y=11; printf(x=%d, y=%dn,x,y); printf(swapped:n); swap(x,y); printf(x=%d,ty=%dn,x,y);swap(int a,int b) int temp; temp=a; a=b; b=temp; printf(“a=%dtb=%dn,a,b);調用:調用:711a:b:711x:y:swap:711x:y:117a:b:temp普通變量作參數普通變量作參數例例 交換兩個數交換兩個數Void main() int x2=7, 11; printf(swapped:n); swap (x0, x1 ); printf(“x0=%d x1=%d , x0, x1);Void swap(int a,int b)int temp; temp=a; a=b; b=temp; printf(“a=
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年汽車租賃合同范本
- 2025年租車帶司機服務合同模板
- 2025標準個人租房租賃合同樣本
- 2025財產委托管理合同模板
- 2025包裝盒生產合同模板
- 2025年土地流轉合同樣本
- 2025訂購綠化苗木合同模板
- 2025物業管理服務合同范本
- 2025合同能源托管協議范本
- 2025咖啡店承包合同協議書
- 美國加征關稅從多個角度全方位解讀關稅課件
- 期中(試題)-2024-2025學年人教精通版(2024)英語三年級下冊
- 一例脂肪液化切口的護理
- 2025-2030中國煤焦油雜酚油行業市場發展趨勢與前景展望戰略研究報告
- 2025屆嘉興市高三語文二模作文解析:智慧不會感到孤獨
- 2025中考英語熱點話題閱讀《哪吒2魔童鬧海》
- 定額〔2025〕1號文-關于發布2018版電力建設工程概預算定額2024年度價格水平調整的通知
- 《思想政治教育方法論》考研(第3版)鄭永廷配套考試題庫及答案【含名校真題、典型題】
- UL9540A標準中文版-2019儲能系統UL中文版標準
- 一種基于STM32的智能門鎖系統的設計-畢業論文
- 末端產品介紹
評論
0/150
提交評論