C語言程序設計課件-第5章_第1頁
C語言程序設計課件-第5章_第2頁
C語言程序設計課件-第5章_第3頁
C語言程序設計課件-第5章_第4頁
C語言程序設計課件-第5章_第5頁
已閱讀5頁,還剩57頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

C語言程序設計TheCProgrammingLanguage華中科技大學計算機學院

曹計昌8/5/20231華中科技大學計算機學院C語言程序設計TheCProgrammingLangu第5章函數(shù)與程序結(jié)構(gòu)本章內(nèi)容:構(gòu)化編程和C程序的一般結(jié)構(gòu)。函數(shù)的機制:包括函數(shù)定義、函數(shù)聲明、函數(shù)調(diào)用、變量的存儲類型、參數(shù)數(shù)目可變的函數(shù)等。遞歸與回溯:包括解釋遞歸與回溯的概念、遞歸函數(shù)設計,以及遞歸調(diào)用。多文件程序設計。8/5/20232華中科技大學計算機學院第5章函數(shù)與程序結(jié)構(gòu)本章內(nèi)容:7/31/20232華中5.1C程序的一般結(jié)構(gòu)5.1.1結(jié)構(gòu)化程序設計結(jié)構(gòu)化編程是一種解決問題的策略,它包括如下2條編程標準:(1)程序中的控制流應該盡可能簡單。(2)應該自頂向下地設計程序結(jié)構(gòu)。自頂向下設計也稱為逐步細化,即把一個問題按功能分解為若干子問題,如果子問題還較復雜,可將其繼續(xù)分解,直到分解成為容易求解的子問題為止。分解而來的每個子問題被稱為模塊,C中提供的函數(shù)機制完成每個模塊的編程任務,即用函數(shù)編寫由分解而來的子問題的代碼。8/5/20233華中科技大學計算機學院5.1C程序的一般結(jié)構(gòu)5.1.1結(jié)構(gòu)化程序設計7/3例顯示從1到10的整數(shù)冪。***************************************ATABLEOFPOWERS***************************************IntSquareCubeQuarticQuintic111112481632392781243416642561024525125625312563621612967776749343240116807864512409632768981729656159049101001000100001000008/5/20234華中科技大學計算機學院例顯示從1到10的整數(shù)冪。**************自頂向下的分解問題:(1)顯示標題(2)顯示表頭(3)分列整齊地顯示整數(shù)1到10的2至5次冪每個子問題都能作為函數(shù)直接被編寫成代碼,在main中調(diào)用這些函數(shù),解決總的問題。8/5/20235華中科技大學計算機學院自頂向下的分解問題:(1)顯示標題7/31/20235華中#include<stdio.h>voidprn_banner(void);/*prn_banner的函數(shù)原型*/voidprn_headings(void);/*prn_headings的函數(shù)原型*/doublepower(intx,intn);/*power的函數(shù)原型*/voidmain(void){inti,j;prn_banner();/*顯示標題*/prn_headings();/*顯示表頭*/for(i=1;i<=10;i++){printf("%5d",i);for(j=2;j<=5;j++)printf("%10.0f",power(i,j));/*ij*/printf("\n");}}main函數(shù):8/5/20236華中科技大學計算機學院#include<stdio.h>main函數(shù):7/31/2結(jié)構(gòu)化程序設計的益處使程序編制方便,易于管理、修改和調(diào)試。增強了程序的可讀性、可維護性和可擴充性,方便于多人分工合作完成程序的編制。函數(shù)可以公用,避免在程序中使用重復的代碼。提高軟件的可重用性,軟件的可重用性是轉(zhuǎn)向面向?qū)ο蟪绦蛟O計的重要因素。8/5/20237華中科技大學計算機學院結(jié)構(gòu)化程序設計的益處使程序編制方便,易于管理、修改和調(diào)試。75.1.2C程序的一般結(jié)構(gòu)C程序由一或多個函數(shù)組成,這些函數(shù)可以編輯成多個C源文件,每一個C源文件含有一個或多個函數(shù)定義。各C源文件中要用到的一些外部變量說明、枚舉類型聲明、結(jié)構(gòu)類型聲明、函數(shù)原型和編譯預處理指令等可編輯成一個.h頭文件,然后在每個C文件中包含該頭文件。每個源文件可單獨編譯生成目標文件,組成一個C程序的所有源文件都被編譯之后,由連接程序?qū)⒏髂繕宋募械哪繕撕瘮?shù)和系統(tǒng)標準函數(shù)庫的函數(shù)裝配成一個可執(zhí)行C程序。除main以外的其它函數(shù)分兩類,一類是由系統(tǒng)提供的標準函數(shù)。另一類是需要由程序員自己編寫的函數(shù)(“自定義函數(shù)”)。8/5/20238華中科技大學計算機學院5.1.2C程序的一般結(jié)構(gòu)C程序由一或多個函數(shù)組成,這5.2函數(shù)的定義與函數(shù)的聲明程序中若要使用自定義函數(shù)實現(xiàn)所需的功能,需要做三件事:①按語法規(guī)則編寫完成指定任務的函數(shù),即定義函數(shù);②有些情況下在調(diào)用函數(shù)之前要進行函數(shù)聲明;③在需要使用函數(shù)時調(diào)用函數(shù)8/5/20239華中科技大學計算機學院5.2函數(shù)的定義與函數(shù)的聲明程序中若要使用自定義5.2.1函數(shù)的定義函數(shù)定義的一般形式為:類型名函數(shù)名(參數(shù)列表){聲明部分語句部分}無返回值,類型名用void。無參數(shù),參數(shù)列表void(可缺省不寫)8/5/202310華中科技大學計算機學院5.2.1函數(shù)的定義函數(shù)定義的一般形式為:7/31/2函數(shù)定義的例子/*函數(shù)prn_banner:顯示標題*/voidprn_banner(void)/*同于voidprn_banner()

*/{printf("\n%s%s%s\n","*******************************\n","*ATABLEOFPOWERS*\n","*******************************\n");}8/5/202311華中科技大學計算機學院函數(shù)定義的例子/*函數(shù)prn_banner:顯示標題未指明函數(shù)返回值的類型,默認為int/*函數(shù)prn_headings:顯示表頭*/voidprn_headings()/*不同于prn_headings(

)*/{printf("\n%5s%10s%10s%10s%10s\n","Int","Square","Cube","Quartic","Quintic");}8/5/202312華中科技大學計算機學院未指明函數(shù)返回值的類型,默認為int/*函數(shù)prn_必須明確地列出每一個參數(shù)的類型。

函數(shù)定義中的參數(shù)稱為形式參數(shù)(形參)/*函數(shù)power:計算xn,n>0*/doublepower(intx,intn)/*不能為

doublepower(intx,n)*/{inti;doublep;for(i=1,p=1;i<=n;i++)p*=x;returnp;}8/5/202313華中科技大學計算機學院必須明確地列出每一個參數(shù)的類型。

函數(shù)定義中的參數(shù)稱為形式參5.2.2return語句return語句可以是如下兩種形式之一:(1)return;/*void函數(shù)*/(2)return表達式;/*非void函數(shù)*/void函數(shù)也可以不包含return語句。如果沒有return語句,當執(zhí)行到函數(shù)結(jié)束的右花括號時,控制返回到調(diào)用處,把這種情況稱為離開結(jié)束。

表達式值的類型應該與函數(shù)定義的返回值類型一致,如果不相同,就把表達式值的類型自動轉(zhuǎn)換為函數(shù)返回值的類型。

8/5/202314華中科技大學計算機學院5.2.2return語句return語句可以是如下兩函數(shù)返回的值,程序可以使用它,

也可以不使用它while(…){getchar();/*返回值不被使用*/c=getchar();/*返回值被使用*/…}8/5/202315華中科技大學計算機學院函數(shù)返回的值,程序可以使用它,

也可以不使用它while(…一旦return被執(zhí)行,控制立即返回到調(diào)用處,其后的代碼不可能被執(zhí)行/*is_prime:如果n是素數(shù),則返回1;否則,返回0*/intis_prime(intn)/*等價于is_prime(intn)*/{intk,limit;if(n==2)return1;if(!(n%2))return0;limit=n/2;for(k=3;k<=limit;k+=2)if(!(n%k))return0;return1;}8/5/202316華中科技大學計算機學院一旦return被執(zhí)行,控制立即返回到調(diào)用處,其后的代碼不可5.2.3函數(shù)的聲明1.函數(shù)定義起函數(shù)聲明的作用函數(shù)定義在前,調(diào)用函數(shù)在后。例:#include<stdio.h>voidprn_banner(void){…}voidprn_headings(void){…}doublepower(intx,intn){…}voidmain(void){…}8/5/202317華中科技大學計算機學院5.2.3函數(shù)的聲明1.函數(shù)定義起函數(shù)聲明的作用7/2.函數(shù)原型函數(shù)定義出現(xiàn)在函數(shù)調(diào)用后被調(diào)用函數(shù)在其它文件中定義必須在函數(shù)調(diào)用之前給出函數(shù)原型。8/5/202318華中科技大學計算機學院2.函數(shù)原型函數(shù)定義出現(xiàn)在函數(shù)調(diào)用后7/31/2023函數(shù)原型的一般形式

類型名函數(shù)名(參數(shù)類型表);參數(shù)類型表通常是用逗號隔開的形參類型列表,而形參名可以省略。例如,

doublepower(int,int);

等價于doublepower(intx,intn);無參函數(shù)的函數(shù)原型參數(shù)表必須指定為void8/5/202319華中科技大學計算機學院函數(shù)原型的一般形式類型名函數(shù)名(參數(shù)類型函數(shù)原型的作用函數(shù)原型告訴編譯器函數(shù)返回值的數(shù)據(jù)類型,傳遞給函數(shù)的參數(shù)個數(shù)、參數(shù)類型和參數(shù)順序。編譯器用函數(shù)原型校驗函數(shù)調(diào)用,強制轉(zhuǎn)換傳遞的參數(shù)類型,從而避免錯誤的函數(shù)調(diào)用導致的致命運行錯誤或微妙而難以檢測的非致命邏輯錯誤。例如,

printf("%.1f\n",sqrt(4));(1)包含了math.h,輸出2.0*/(2)沒有包含math.h,函數(shù)調(diào)用sqrt(4)不會產(chǎn)生正確的值。8/5/202320華中科技大學計算機學院函數(shù)原型的作用函數(shù)原型告訴編譯器函數(shù)返回值的數(shù)據(jù)類型,3.遺漏函數(shù)原型編譯器首次遇到?jīng)]有聲明的函數(shù)調(diào)用時,將構(gòu)造一個缺省聲明并繼續(xù)編譯:intf();/*函數(shù)是int類型,但不給出參數(shù)表信息*/(1)函數(shù)類型不是int,給出一個錯誤提示:

Typemismatchinredeclarationof'f‘(2)函數(shù)類型是int,就不給出錯誤提示。編譯器對參數(shù)類型不作檢查,把正確類型的參數(shù)傳遞給函數(shù)是程序員的責任。假設函數(shù)f只有一個類型為int的參數(shù),函數(shù)調(diào)用f(2)會產(chǎn)生正確的值,而函數(shù)調(diào)用f(2.5)將產(chǎn)生錯誤的運行結(jié)果。8/5/202321華中科技大學計算機學院3.遺漏函數(shù)原型編譯器首次遇到?jīng)]有聲明的函數(shù)調(diào)用時,良好的編程風格在函數(shù)調(diào)用之前必須給出它的函數(shù)定義、函數(shù)原型或兩者都給出。引入標準頭文件的主要原因是它含有函數(shù)原型。8/5/202322華中科技大學計算機學院良好的編程風格在函數(shù)調(diào)用之前必須給出它的函數(shù)定義、函數(shù)原型5.3函數(shù)調(diào)用與參數(shù)傳遞5.3.1函數(shù)調(diào)用1.函數(shù)調(diào)用的形式

函數(shù)名(實參列表)實參是一個表達式,對于無函數(shù),調(diào)用形式:

函數(shù)名()

8/5/202323華中科技大學計算機學院5.3函數(shù)調(diào)用與參數(shù)傳遞5.3.1函數(shù)調(diào)用7/31函數(shù)調(diào)用在程序中出現(xiàn)的形式(1)作為表達式語句出現(xiàn)。prn_headings();putchar(c);(2)作為表達式中的一個操作數(shù)出現(xiàn)。例如:c=getchar()sum+=power(i,j);(3)作為函數(shù)調(diào)用的一個實參出現(xiàn),即嵌套調(diào)用。printf("%10.0f",power(i,j));putchar(getchar());8/5/202324華中科技大學計算機學院函數(shù)調(diào)用在程序中出現(xiàn)的形式(1)作為表達式語句出現(xiàn)。7/32.函數(shù)調(diào)用的執(zhí)行過程#include<stdio.h>intmax(int,int);voidmain(void){intm,a=3,b=4;m=max(a,b);printf("%d",m);}intmax(intx,inty){if(x>y)returnx;elsereturny;}8/5/202325華中科技大學計算機學院2.函數(shù)調(diào)用的執(zhí)行過程#include<stdio.h>3.實參的求值順序?qū)崊⒌那笾淀樞蛴删唧w實現(xiàn)確定,有的按從左至右的順序計算,有的按從右至左的順序計算a=1;max(a,a++)----從左至右:max(1,1)----從右至左:max(2,1)(多數(shù))為了保證程序清晰、可移植,應避免使用會引起副作用的實參表達式.實參的求值順序C語言采用從右至左規(guī)則8/5/202326華中科技大學計算機學院3.實參的求值順序?qū)崊⒌那笾淀樞蛴删唧w實現(xiàn)確定,有的按從左至實參的求值順序C語言采用從右至左規(guī)則#include"stdio.h"voidmain(void){intx=1;printf("%d\t%d\t%d\n",x,x++,x);}運行結(jié)果:2118/5/202327華中科技大學計算機學院實參的求值順序C語言采用從右至左規(guī)則#include"st5.3.2參數(shù)的值傳遞參數(shù)的傳遞方式是“值傳遞”,實參的值單向傳遞給相應的形參。如果實參、形參都是x,被調(diào)用函數(shù)不能改變實參x的值。8/5/202328華中科技大學計算機學院5.3.2參數(shù)的值傳遞參數(shù)的傳遞方式是“值傳遞”,實參的例說明值傳遞概念的程序#include<stdio.h>longfac(int);voidmain(){intn=4;printf("%d\n",n);/*輸出4*/printf("%ld\n",fac(n));/*輸出24*/printf("%d\n",n);/*輸出4*/}longfac(intn)/*計算n的階乘*/{longf=1;for(;n>0;--n)f*=n;/*main中的n值未改變*/printf("%d\n",n);/*輸出0*/return(f);}8/5/202329華中科技大學計算機學院例說明值傳遞概念的程序#include<stdio5.4作用域作用域:程序正文中可以使用該標識符的那部分程序段。根據(jù)作用域,變量有兩類:局部變量:在函數(shù)內(nèi)部定義的變量,作用域是定義該變量的程序塊,程序塊是帶有說明的復合語句(包括函數(shù)體)。不同函數(shù)可同名,同一函數(shù)內(nèi)不同程序塊可同名。形式參數(shù)是局部變量。外部變量:在函數(shù)外部定義的變量,其作用域從其定義處開始一直到其所在文件的末尾,可由程序中的部分或所有函數(shù)共享。8/5/202330華中科技大學計算機學院5.4作用域作用域:程序正文中可以使用該標識符的關(guān)鍵字extern的作用intsp=0;/*sp是外部變量,main,push和pop均可訪問*/voidmain(){…}/*val不能用在main中*/doubleval[MAXVAL];/*val是外部數(shù)組*/voidpush(doublef){…}doublepop(void){…}利用extern對外部變量進行聲明可以擴大其作用域,使得外部變量在定義之前可以使用,以及其它源文件中的函數(shù)也可以使用。例如voidmain(){externdoubleval[MAXVAL];……}8/5/202331華中科技大學計算機學院關(guān)鍵字extern的作用intsp=0;/*sp是外部外部變量的聲明和定義的區(qū)別外部變量的聲明用于通報變量的類型(引用性聲明)外部變量的定義除此以外還引起存儲分配(定義性聲明)intsp;這是外部變量的定義,一方面說明了sp類型為int,另一方面系統(tǒng)還要為其分配2B的存儲單元。而externintsp;這是外部變量的聲明,僅僅說明了sp類型為int,不會為其分配存儲單元。外部變量只能定義一次,而外部變量的聲明可以出現(xiàn)多次。外部變量的初始化只能出現(xiàn)在其定義中。8/5/202332華中科技大學計算機學院外部變量的聲明和定義的區(qū)別外部變量的聲明用于通報變量的類型5.5存儲類型變量和函數(shù)都有兩個屬性:數(shù)據(jù)類型和存儲類型。函數(shù)的存儲類型決定函數(shù)的作用域,可使用的關(guān)鍵字有extern和static(5.9節(jié))。變量的存儲類型決定變量的作用域、存儲分配方式、生命周期和初始化方式,可使用的關(guān)鍵字有:auto、extern、static和register。

存儲分配方式:在何時、何處給變量分配存儲單元;

生命周期:變量在內(nèi)存中的存在期;

初始化方式:在定義變量時如果未顯示初始化,是否有缺省初值,如果有顯示初始化,賦初值操作如何執(zhí)行(執(zhí)行一次還是執(zhí)行多次)。8/5/202333華中科技大學計算機學院5.5存儲類型變量和函數(shù)都有兩個屬性:數(shù)據(jù)類型和存儲類型5.5.1存儲類型auto局部變量的缺省存儲類型是auto,稱自動變量autointa;/*等價于inta;也等價于autoa;*/

作用域:局部于定義它的塊,從塊內(nèi)定義之后直到該塊結(jié)束有效。存儲分配方式:動態(tài)分配方式,即在程序運行過程中分配和回收存儲單元。生命周期:短暫的,只存在于該塊的執(zhí)行期間。初始化方式:定義時沒有顯示初始化,其初值是不確定的;有顯示初始化,則每次進入塊時都要執(zhí)行一次賦初值操作。8/5/202334華中科技大學計算機學院5.5.1存儲類型auto局部變量的缺省存儲類型是au例塊多重嵌套時自動變量的作用域#include<stdio.h>voidmain(void){inta=2,b=4;printf("a=%d,b=%d\n",a,b);{inta;a=3;b=5;printf("a=%d,b=%d\n",a,b);}printf("a=%d,b=%d\n",a,b);}內(nèi)外層有同名變量時,外層變量不可見.輸出:a=2,b=4a=3,b=5a=2,b=58/5/202335華中科技大學計算機學院例塊多重嵌套時自動變量的作用域#include<stdi5.5.2存儲類型extern外部變量的存儲類型是extern,但在定義時(定義性聲明)不使用關(guān)鍵字extern。外部變量的作用域:從定義之后直到該源文件結(jié)束的所有函數(shù),通過用extern做聲明,外部變量的作用域可以擴大到整個程序的所有文件。存儲分配方式:靜態(tài)分配方式,即程序運行之前,系統(tǒng)就為外部變量在靜態(tài)區(qū)分配存儲單元,整個程序運行結(jié)束后所占用的存儲單元才被收回。生命周期:永久的,存在于整個程序的執(zhí)行期間。

初始化方式:定義時沒有顯示初始化,初值0;有顯示初始化,只執(zhí)行一次賦初值操作。

8/5/202336華中科技大學計算機學院5.5.2存儲類型extern外部變量的存儲類型是ext例說明外部變量的缺省初值和作用域#include<stdio.h>intn;/*外部變量,等價于intn=0*/intf1(void){n++;returnn;}voidf2(intx){n=x;}voidmain(void){inti;printf("globalnis%donenteringmain\n",n);f2(10);for(i=0;i<3;i++)printf("%6d",f1());printf("\nglobalnis%donexitingmain\n",n);}globalnis0onenteringmain111213globalnis13onexitingmain8/5/202337華中科技大學計算機學院例說明外部變量的缺省初值和作用域#include<std例關(guān)鍵字extern的用法文件file1.c的內(nèi)容為:#include<stdio.h>intn;/*定義外部變量*/intf1(void);/*f1的函數(shù)原型*/voidf2(int);/*f2的函數(shù)原型*/voidmain(void){inti;printf("globalnis%donenteringmain\n",n);f2(10);for(i=0;i<3;i++)printf("%6d",f1());printf("\nglobalnis%donexitingmain\n",n);}8/5/202338華中科技大學計算機學院例關(guān)鍵字extern的用法文件file1.c的內(nèi)容為:文件file2.c的內(nèi)容為externintn;/*外部變量n的聲明*/intf1(void){n++;returnn;}voidf2(intx){n=x;}8/5/202339華中科技大學計算機學院文件file2.c的內(nèi)容為externintn;5.5.3存儲類型static關(guān)鍵字static有兩個重要而截然不同的用法:(1)用于定義局部變量,稱為靜態(tài)局部變量。(2)用于定義外部變量,稱為靜態(tài)外部變量。

存儲分配方式:靜態(tài)分配方式

生命周期:永久的,

缺省初值:0,只執(zhí)行一次靜態(tài)局部變量和自動變量有根本性的區(qū)別。靜態(tài)外部變量和外部變量區(qū)別:作用域不同。8/5/202340華中科技大學計算機學院5.5.3存儲類型static關(guān)鍵字static有兩個1.靜態(tài)局部變量作用域:和自動變量一樣靜態(tài)局部變量的值有連續(xù)性.#include<stdio.h>longfac(int);/*函數(shù)原型*/voidmain(void){inti;for(i=1;i<5;i++)printf("%d!=%ld\n",i,fac(i));}longfac(intn){staticlongf=1;/*靜態(tài)局部變量只初始化1次*/f*=n;returnf;}1!=12!=23!=64!=248/5/202341華中科技大學計算機學院1.靜態(tài)局部變量作用域:和自動變量一樣1!=17/將f定義為自動變量,輸出結(jié)果如何?#include<stdio.h>longfac(int);/*函數(shù)原型*/voidmain(void){inti;for(i=1;i<5;i++)printf("%d!=%ld\n",i,fac(i));}longfac(intn){longf=1;/*局部變量*/f*=n;returnf;}1!=12!=23!=34!=48/5/202342華中科技大學計算機學院將f定義為自動變量,輸出結(jié)果如何?#include<stdi2.靜態(tài)外部變量靜態(tài)外部變量和外部變量的唯一區(qū)別是作用域的限制。靜態(tài)外部變量只能作用于定義它的文件,其它文件中的函數(shù)不能使用,外部變量用extern聲明后可以作用于其它文件。使用靜態(tài)外部變量的好處在于:當多人分別編寫一個程序的不同文件時,可以按照需要命名變量而不必考慮是否會與其它文件中的變量同名,保證文件的獨立性。8/5/202343華中科技大學計算機學院2.靜態(tài)外部變量靜態(tài)外部變量和外部變量的唯一區(qū)別是作用域的5.5.4存儲類型register用來定義局部變量,register建議編譯器把該變量存儲在計算機的高速硬件寄存器中,除此之外,其余特性和自動變量完全相同。使用register的目的是為了提高程序的執(zhí)行速度。程序中最頻繁訪問的變量,可聲明為register,。不可多必要時使用。8/5/202344華中科技大學計算機學院5.5.4存儲類型register用來定義局部變量,r5.6參數(shù)數(shù)目可變的函數(shù)printf和scanf就是典型的參數(shù)數(shù)目可變的函數(shù)。intprintf(constchar*format,…);函數(shù)調(diào)用時,實參可以有1至多個。定義參數(shù)數(shù)目可變的函數(shù),要用到可變參數(shù)頭文件stdarg.h中定義的宏和類型。參閱:P148(1)-(4)8/5/202345華中科技大學計算機學院5.6參數(shù)數(shù)目可變的函數(shù)printf和scan例5.9函數(shù)average的第1個參數(shù)是要被求平均值的數(shù)據(jù)的個數(shù)。#include<stdio.h>#include<stdarg.h>doubleaverage(int,…);/*函數(shù)原型*/voidmain(void){doublea=1.5,b=2.6,c=3.7,d=4.8;printf("a=%.1f,b=%.1f,c=%.1f,d=%.1f\n",a,b,c,d);printf("Theaverageofaandbis%.2f\n",average(2,a,b));printf("Theaverageofa、bandcis%.2f\n",average(3,a,b,c));

printf("Theaverageofa,b,canddis%.2f\n",average(4,a,b,c,d));}doubleaverage(inti,…){doublesum=0;intk;

va_listap;

/*用va_list類型的對象ap來處理不定參數(shù)部分*/

va_start(ap,i);

/*用va_start初始化ap,使ap指向第一個不定參數(shù)*/for(k=1;k<=i;k++)sum+=va_arg(ap,double);/*用va_start反復從可變參數(shù)列表中檢索到每一個不定參數(shù)的值*/

va_end(ap);

/*使程序能夠從可變參數(shù)列表的函數(shù)中正常返回*/return(sum/i);}8/5/202346華中科技大學計算機學院例5.9函數(shù)average的第1個參數(shù)是要被求平均值的數(shù)據(jù)可變參數(shù)有多種數(shù)據(jù)類型doubleaverage(int,...);voidmain(void){doublea=1.5,b=2.6,c=3.7,d=4.8;printf("a=%.1f,b=%.1f,c=%.1f,d=%.1f\n",a,b,c,d);printf("Theaverageofaandbis%.2f\n",average(2,a,b,10));printf("Theaverageofa,bandcis%.2f\n",average(3,a,b,c,20));printf("Theaverageofa,b,canddis%.2f\n",average(4,a,b,c,d,30));}doubleaverage(inti,...){doublesum=0;intk;va_listap;va_start(ap,i);for(k=1;k<=i;k++)sum+=va_arg(ap,double);

k=va_arg(ap,int);printf("%d\n",k);va_end(ap);return(sum/i);}8/5/202347華中科技大學計算機學院可變參數(shù)有多種數(shù)據(jù)類型doubleaverage(int5.7遞歸5.7.1遞歸函數(shù)與遞歸調(diào)用#include<stdio.h>voidprn_int(intn){if(n>0){printf("%d",n);prn_int(n-1);/*遞歸調(diào)用*/}}voidmain(void){prn_int(10);}遞歸調(diào)用:函數(shù)直接調(diào)用自己或通過另一函數(shù)間接調(diào)用自己的函數(shù)調(diào)用方式遞歸函數(shù):函數(shù)定義中含有遞歸調(diào)用的函數(shù)8/5/202348華中科技大學計算機學院5.7遞歸5.7.1遞歸函數(shù)與遞歸調(diào)用void用遞歸代替循環(huán)(ex5_10b.c)#include"stdio.h"voidrecursive_add(inta,intb){ if(b<=10){ a=a+b; printf("b=%d,sum=%d\n",b,a); b++; recursive_add(a,b); }}intloop_add(inta,intb){ a=a+b; printf("b=%d,sum=%d\n",b,a); returna;}voidmain(void){inta,b; printf("\nrecursiveadd\n"); recursive_add(0,1); printf("\nloopadd\n"); for(a=0,b=1;b<=10;b++) a=loop_add(a,b);}一般而言,循環(huán)結(jié)構(gòu)都可以用遞歸的方法來實現(xiàn).8/5/202349華中科技大學計算機學院用遞歸代替循環(huán)(ex5_10b.c)#include"st遞歸的兩個要素(1)遞歸結(jié)束條件。也就是所描述問題的最簡單情況,遞歸如果沒有結(jié)束條件,遞歸過程將永不終止,即無窮遞歸(和無限循環(huán)類似)。(2)遞歸定義。為了描述問題的某一狀態(tài),必須用到它的上一狀態(tài),而描述上一狀態(tài),又必須用到它的上一狀態(tài),……,這種用自已來定義自己的方法,稱為遞歸定義。遞歸定義必須能使問題越來越簡單,使問題向結(jié)束條件轉(zhuǎn)化。8/5/202350華中科技大學計算機學院遞歸的兩個要素(1)遞歸結(jié)束條件。也就是所描述問題的最簡單遞歸算法解決三類問題(1)數(shù)據(jù)的定義形式按遞歸定義。例如,n!=n*(n-1)!;0!=1。f(n)=f(n-1)+f(n-2);f(1)=1;f(2)=1。(2)數(shù)據(jù)的結(jié)構(gòu)形式是按遞歸定義的。如樹的遍歷,圖的搜索等。(3)問題解法按遞歸算法實現(xiàn)。例如回溯法8/5/202351華中科技大學計算機學院遞歸算法解決三類問題(1)數(shù)據(jù)的定義形式按遞歸定義。例如,5.7.2遞歸的執(zhí)行過程以求n!為例longfac(intn){if(n==0||==1)return1;elsereturn(n*fac(n-1));}n!=1(n=0,1)n(n–1)!(n>1)8/5/202352華中科技大學計算機學院5.7.2遞歸的執(zhí)行過程以求n!為例n!=1main(){

fac(4);}

fac(4){4fac(3);}fac(3){3fac(2);}

fac(1){return1;}fac(2){2fac(1);}簡化算法不節(jié)省存儲空間,運行效率也不高8/5/202353華中科技大學計算機學院main()fac(4)fac(3)fac(1)fac(例5.12編寫一個遞歸函數(shù)計算Fibonacci數(shù)列的第n項(p152)。/*Recursivefibonacci:Computethenitem*/longfibonacci(longn){if(n==1||n==2)return1;elsereturnfibonacci(n-1)+fibonacci(n-2);}8/5/202354華中科技大學計算機學院例5.12編寫一個遞歸函數(shù)計算Fibonacci數(shù)列的第n這種遞歸方式有損于運行效率隨著n值的增大,對fibonacci的調(diào)用次數(shù)將急劇增多。例如,n=5,需調(diào)用9次;n=10,需調(diào)用109次;n=20,需調(diào)用13529次。計算數(shù)列的下一個數(shù)時,花費的時間會越來越長。編寫一個主函數(shù),在主函數(shù)中調(diào)用此函數(shù)計算Fibonacci數(shù)列。另外,可以調(diào)用time.h庫中的函數(shù)time來計算出數(shù)列的20項、30項、40項等需要花費的時間,并輸出此時間。8

溫馨提示

  • 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

提交評論