版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第六章函數(shù)目錄/Contents函數(shù)定義、函數(shù)調(diào)用、函數(shù)原型、函數(shù)的參數(shù)傳遞與返回值函數(shù)封裝,函數(shù)復(fù)用,函數(shù)設(shè)計的基本原則,程序的健壯性遞歸函數(shù)和函數(shù)的遞歸調(diào)用變量的作用域與存儲類型,全局變量、自動變量、靜態(tài)變量、寄存器變量模塊化程序設(shè)計方法◆當(dāng)一個程序的代碼量達(dá)到數(shù)千行以上時,所有的代碼都放在main函數(shù)中嗎?如何進(jìn)行團(tuán)隊合作?◆所有代碼放在一個文件中,如何進(jìn)行團(tuán)隊合作?◆調(diào)試良好的代碼如何被其他程序使用呢?◆當(dāng)一個問題的規(guī)模很大時,應(yīng)該采用什么樣的方法來解決它呢?問題的提出模塊化程序設(shè)計思想分而治之函數(shù)把較大的任務(wù)分解成若干個較小的任務(wù),并提煉出公用任務(wù)信息隱藏設(shè)計良好的函數(shù)可把具體操作細(xì)節(jié)對外界隱藏起來,從而使整個程序結(jié)構(gòu)清楚使用函數(shù)時,用戶不用知道函數(shù)內(nèi)部是如何運(yùn)作的,只按照我們的需要和它的參數(shù)形式調(diào)用它即可函數(shù)的定義■函數(shù)是C語言中模塊化程序設(shè)計的最小單位,用來實現(xiàn)各種不同的功能。每個函數(shù)可看作是一個程序模塊?!瞿K化程序設(shè)計如同制造機(jī)器,函數(shù)相當(dāng)于機(jī)器的“零部件”
-先將這些“零部件”單獨(dú)設(shè)計、調(diào)試和測試好,接著進(jìn)行組裝,最后進(jìn)行綜合測試。
-這些“零部件”既可以是自己設(shè)計的,也可以是別人設(shè)計好的,還可以是現(xiàn)成的標(biāo)準(zhǔn)產(chǎn)品?!鋈舾蓚€函數(shù)可以合成一個“模塊”■一個C程序由一個或若干個源文件組成■一個源文件由一個或多個函數(shù)組成函數(shù)的定義■一般來說,函數(shù)是各自獨(dú)立、平等的,沒有高低貴賤之分。
-main()稍稍特殊一點(diǎn),
-程序的執(zhí)行從main()的入口地址開始-在函數(shù)體中順序、循環(huán)、遞歸、迭代地調(diào)用各個函數(shù),調(diào)用其他函數(shù)后程序執(zhí)行流程返回main函數(shù)
-在main()的出口結(jié)束程序的運(yùn)行函數(shù)的分類■標(biāo)準(zhǔn)庫函數(shù)
-ANSI/ISOC定義的標(biāo)準(zhǔn)庫函數(shù)符合標(biāo)準(zhǔn)的C語言編譯器必須提供這些函數(shù)函數(shù)的行為也要符合ANSI/ISOC的定義-第三方庫函數(shù)由其他廠商自行開發(fā)的C語言函數(shù)庫不在標(biāo)準(zhǔn)范圍內(nèi),能擴(kuò)充C語言的功能(圖形、網(wǎng)絡(luò)、數(shù)據(jù)庫等)■自定義函數(shù)
-自己定義的函數(shù)包裝后,也可成為函數(shù)庫,供別人使用函數(shù)的分類返回值類型
函數(shù)名(類型形式參數(shù)1,類型形式參數(shù)2,…)←函數(shù)頭部{
聲明語句序列
執(zhí)行語句序列}函數(shù)的定義函數(shù)體函數(shù)體的定界符void函數(shù)名(void)←函數(shù)頭部{
聲明語句序列
執(zhí)行語句序列}函數(shù)體函數(shù)定義【例6.1】
編寫一個函數(shù)計算整數(shù)x的n次冪
。/*函數(shù)功能:用迭代法計算x的n次冪。
函數(shù)參數(shù):整型變量x表示底數(shù),整型變量n表示冪指數(shù)。
函數(shù)返回值:返回x的n次冪的值。*/longPower(intx,intn) /*函數(shù)定義*/{ inti; longresult=1; for(i=0;i<n;i++) { result=result*x;/*計算x的n次冪*/ } returnresult;/*將result的值作為函數(shù)的返回值返回*/}返回值類型函數(shù)名說明函數(shù)的功能形參表,函數(shù)入口函數(shù)內(nèi)部可以定義只能自己使用的變量,稱內(nèi)部變量返回值作為函數(shù)調(diào)用表達(dá)式的值函數(shù)調(diào)用◆有返回值時:◆無返回值時函數(shù)名(實參表列);
返回值=函數(shù)名(實參表列);函數(shù)調(diào)用#include<stdio.h>intmain(){intp,q;longret;printf("pleaseinputtwointegers:");scanf("%d%d",&p,&q);ret=Power(p,q);printf("ret=%ld",ret);return0;}函數(shù)原型聲明#include<stdio.h>longPower(intx,intn);intmain(){intp,q;longret;printf("pleaseinputtwointegers:");scanf("%d%d",&p,&q);ret=Power(p,q);printf("ret=%ld",ret);return0;}末尾有一個分號,聲明時不要省略形參和返回值的類型longPower(intx,intn){ inti; longresult=1; for(i=0;i<n;i++) { result=result*x; } returnresult;}函數(shù)定義函數(shù)定義指函數(shù)功能的確立指定函數(shù)名、函數(shù)類型、形參及類型、函數(shù)體等是完整獨(dú)立的單位
函數(shù)聲明是對函數(shù)名、返回值類型、形參類型的說明不包括函數(shù)體是一條語句,以分號結(jié)束,只起一個聲明作用函數(shù)聲明與函數(shù)定義的區(qū)別函數(shù)封裝與防御性編程■函數(shù)封裝(Encapsulation)使得外界對函數(shù)的影響僅限于入口參數(shù),而函數(shù)對外界的影響僅限于一個返回值?!纠?.2】
試編寫一個函數(shù),從鍵盤輸入整數(shù)n,計算n!,并編寫測試程序。longFac(intn){ inti; longresult=1; for(i=2;i<=n;i++) { result=result*i; } returnresult;}#include<stdio.h>longFac(intn);intmain(){ intm; longret; printf("pleaseinputm:"); scanf("%d",&m); ret=Fac(m); /*調(diào)用階乘計算函數(shù)*/ printf("%d!=%ld",m,ret); /*輸出語句*/ return0;}防御性編程■函數(shù)具有遇到不正確使用或非法數(shù)據(jù)輸入時保護(hù)自己避免出錯的能力。在函數(shù)的入口處增加對入口參數(shù)的合法性檢查,是一種增強(qiáng)程序健壯性的有效方法。/*用迭代法計算n的階乘*/longFac(intn){ inti; longresult=1; if(n<0) { printf("inputdataerror!\n"); } else { for(i=2;i<=n;i++) { result=result*i; } returnresult; }}#include<stdio.h>longFac(intn);intmain(){ intm; longret; printf("pleaseinputm:"); scanf("%d",&m); ret=Fac(m); if(ret==-1) printf("inputdataerror!\n"); else printf(“%d!=%ld",m,ret); return0;}/*用迭代法計算n的階乘*/longFac(intn){ inti; longresult=1; if(n<0) { return-1; } else { for(i=2;i<=n;i++) { result=result*i; } returnresult; }}防御性編程#include<stdio.h>unsignedlongFac(unsignedintn);intmain(){ intm; longret; printf("pleaseinputm:"); scanf("%d",&m); ret=Fac(m); if(ret==-1) printf("inputdataerror!\n"); else printf(“%d!=%ld",m,ret); return0;}/*用迭代法計算n的階乘*/unsignedlongFac(unsignedintn){ unsignedinti; unsignedlongresult=1; if(n<0) { return-1; } else { for(i=2;i<=n;i++) { result=result*i; } returnresult; }}傳入負(fù)數(shù)的實參時Fac()會返回-1嗎?存在死代碼的原因何在?防御性編程如何修改程序去除冗余代碼?如何保證不會傳入負(fù)數(shù)實參?#include<stdio.h>unsignedlongFac(unsignedintn);intmain(){ intm; longret; printf("pleaseinputm:"); scanf("%d",&m); ret=Fac(m); if(ret==-1) printf("inputdataerror!\n"); else printf(“%d!=%ld",m,ret); return0;}unsignedlongFac(unsignedintn){ unsignedinti; unsignedlongresult=1; for(i=2;i<=n;i++) { result=result*i; } returnresult;}運(yùn)行結(jié)果:pleaseinputm(m>0):-1pleaseinputm(m>0):55!=120防御性編程【例6.3】
編寫程序,實現(xiàn)組合數(shù)的計算。unsignedlongFac(unsignedintn){ unsignedinti; unsignedlongresult=1; for(i=2;i<=n;i++) { result=result*i; } returnresult;}#include<stdio.h>unsignedlongFac(unsignedintn);intmain(){intm,k;unsignedlongret;do{printf("pleaseinputm,k(m>=k>0):");scanf("%d%d",&m,&k);}while(m<k||m<=0||k<0);ret=Fac(m)/(Fac(k)*Fac(m-k));printf("ret=%lu\n",ret);return0;}函數(shù)設(shè)計原則①函數(shù)的規(guī)模要?。虎诤瘮?shù)的功能要單一,不要設(shè)計多功能的函數(shù);③在函數(shù)的接口中清楚地定義函數(shù)的行為;④在函數(shù)的入口處,對參數(shù)的有效性進(jìn)行檢查;⑤應(yīng)檢查某些敏感性操作;⑥不能主觀地認(rèn)為調(diào)用一個函數(shù)總會成功,要考慮如果調(diào)用失敗,應(yīng)該如何處理。函數(shù)嵌套調(diào)用嵌套調(diào)用:在調(diào)用一個函數(shù)的過程中,又調(diào)用另一個函數(shù)C語言規(guī)定函數(shù)不能嵌套定義,但可以嵌套調(diào)用,函數(shù)是相互平行的遞歸函數(shù)■目標(biāo):將A上的盤子全部移到B上■規(guī)則:每次只能移動一個盤子,不允許大盤子放在小盤子上第一步:A→B
第二步:A→CABCn=3【例6.4】漢諾塔問題遞歸函數(shù)ABC
第三步:B→C第四步:A→Bn=3遞歸函數(shù)ABC
第五步:C→A第六步:C→Bn=3遞歸函數(shù)ABCn更大些怎么辦?
第七步:A→Bn=3遞歸函數(shù)第1步:將問題簡化假設(shè)A桿上只有2個圓盤,即漢諾塔有2層,n=2將1號圓盤從A移到C將2號圓盤從A移到B將1號圓盤從C移到BABC第2步:對于一個有n(n>1)個圓盤的漢諾塔,將n個圓盤分為兩部分:上面n-1個圓盤和最下面的n號圓盤。將“上面n-1個圓盤”看成一個整體將n-1個圓盤從A移到C將n號圓盤從A移到B將n-1個圓盤從C移到BACB遞歸函數(shù)遞歸函數(shù)設(shè)計2個函數(shù):將n個圓盤借助C從A移到B
將一個圓盤從A移到B
ACB將n-1個圓盤從A移到C將n號圓盤從A移到B將n-1個圓盤從C移到BHanoi(intn,chara,charb,charcMove(intn,chara,charb);step1Hanoi(n-1,a,c,b)step2Move(n,a,b)Step3Hanoi(n-1,c,b,a)遞歸函數(shù)遞歸方法的基本原理將一個復(fù)雜問題逐步分解并最終簡化為一個顯而易見的小問題這個小問題的解決,意味著整個復(fù)雜問題的解決
遞歸函數(shù)遞歸函數(shù)【例6.5】
編寫程序,用遞歸法計算整數(shù)x的n次冪xn。longPower(intx,intn) /*函數(shù)定義*/{if(n==0)return1;elsereturnx*Power(x,n-1);}一般情況基線情況遞歸函數(shù)遞歸調(diào)用應(yīng)該能夠在有限次數(shù)內(nèi)終止遞歸遞歸調(diào)用若不加以限制,將無限循環(huán)調(diào)用必須在函數(shù)內(nèi)部加控制語句,僅當(dāng)滿足一定條件時,遞歸終止,稱為條件遞歸任何一個遞歸調(diào)用程序必須包括兩部分遞歸循環(huán)繼續(xù)的過程遞歸調(diào)用結(jié)束的過程
if(遞歸終止條件成立)
return遞歸公式的初值;elsereturn遞歸函數(shù)調(diào)用返回的結(jié)果值;
遞歸函數(shù)每個遞歸函數(shù)必須至少有一個基線條件一般情況必須最終能簡化為基線條件遞歸層數(shù)太多易導(dǎo)致棧空間溢出后果很嚴(yán)重,程序被異常中止優(yōu)點(diǎn):從編程角度來看,比較直觀、精煉,邏輯清楚符合人的思維習(xí)慣,逼近數(shù)學(xué)公式的表示尤其適合非數(shù)值計算領(lǐng)域hanoi塔,騎士游歷、八皇后問題(回溯法)缺點(diǎn):增加了函數(shù)調(diào)用的開銷,每次調(diào)用都需要進(jìn)行參數(shù)傳遞、現(xiàn)場保護(hù)等耗費(fèi)更多的時間和棧空間應(yīng)盡量用迭代形式替代遞歸形式遞歸與迭代的比較變量的作用域與存儲類型什么是變量的作用域?指在源程序中定義變量的位置及其能被讀寫訪問的范圍分為局部變量全局變量局部變量指在函數(shù)或語句塊內(nèi)定義的變量形參也是局部變量特點(diǎn)生存期是該語句塊,進(jìn)入語句塊時獲得內(nèi)存,僅能由語句塊內(nèi)語句訪問,退出語句塊時釋放內(nèi)存,不再有效定義時不會自動初始化,除非程序員指定初值并列語句塊各自定義的同名變量互不干擾形參和實參可以同名在所有函數(shù)之外定義的變量生存期是整個程序,從程序運(yùn)行起占據(jù)內(nèi)存,程序運(yùn)行過程中可隨時訪問,程序退出時釋放內(nèi)存有效范圍是從定義變量的位置開始到本程序結(jié)束全局變量變量的存儲類型指數(shù)據(jù)在內(nèi)存中存儲的方式即編譯器為變量分配內(nèi)存的方式,它決定變量的生存期變量定義格式:存儲類型數(shù)據(jù)類型變量名;C語言的存儲類別auto型(自動變量)static型(靜態(tài)變量)extern型(外部變量)register型(寄存器變量)變量的存儲類型■變量的生成期:決定何時“生”,何時“滅”靜態(tài)存儲區(qū)中的變量:與程序“共存亡”動態(tài)存儲區(qū)中的變量:與所在函數(shù)“共存亡”寄存器中的變量:同動態(tài)存儲區(qū)自動變量與靜態(tài)變量auto
數(shù)據(jù)類型變量名;auto體現(xiàn)在進(jìn)入函數(shù)/語句塊時自動申請內(nèi)存,退出時自動釋放內(nèi)存動態(tài)局部變量,缺省的存儲類型靜態(tài)變量static
數(shù)據(jù)類型變量名;在語句塊/函數(shù)內(nèi)聲明的靜態(tài)局部變量,其生存期為整個程序生存期為整個程序運(yùn)行期間自動變量與靜態(tài)變量#include<stdio.h>intf(inta);intmain(){ inta=2,i; for(i=0;i<3;i++) { printf("%d\t",F(a)); } printf("\n"); return0;}intF(inta){ autointb=0; staticintc=3; b++; c++; returna+b+c;}靜態(tài)變量僅初始化一次,變量的值可保存到下次進(jìn)入函數(shù),使函數(shù)具有記憶功能運(yùn)行結(jié)果:789自動變量與靜態(tài)變量#include<stdio.h>intf(inta);intmain(){ inta=2,i; for(i=0;i<3;i++) { printf("%d\t",F(a)); } printf("\n"); return0;}intF(inta){ autointb=0; intc=3; b++; c++; returna+b+c;}運(yùn)行結(jié)果:777靜態(tài)局部變量和全局變量自動初始化為0值。自動變量不初始化時,值是隨機(jī)值寄存器變量寄存器CPU內(nèi)部容量有限、但速度極快的存儲器
register
類型名變量名;
使用頻率比較高的變量聲明為register
,可使程序更小、執(zhí)行速度更快現(xiàn)代編譯器有能力自動把普通變量優(yōu)化為寄存器變量,并且可以忽略用戶的指定所以一般無需特別聲明變量為register
變量的作用域與存儲類型小結(jié)全局變量靜態(tài)外部變量(只限本文件使用)外部變量
(非靜態(tài)外部變量允許其他文件引用)局部變量
自動變量,(離開函數(shù),值就消失)寄存器變量(離開函數(shù),值就消失)定義點(diǎn)之前使用,需用extern聲明靜態(tài)局部變量(離開函數(shù),值仍保留)動態(tài)局部變量模塊化程序設(shè)計功能分解自頂向下、逐步求精的過程模塊分解的基本原則保證模塊的相對獨(dú)立性——高聚合、低耦合模塊的實現(xiàn)細(xì)節(jié)對外不可見——信息隱藏外部:關(guān)心做什么;內(nèi)部:關(guān)心怎么做設(shè)計好模塊接口接口指羅列出一個模塊的所有的與外部打交道的變量等定義好后不要輕易改動在模塊開頭(文件的開頭)進(jìn)行函數(shù)聲明模塊化程序設(shè)計逐步求精(StepwiseRefinement)由不斷的自底向上修正所補(bǔ)充的自頂向下(Top-down)的程序設(shè)計方法模塊化程序設(shè)計模塊各司其職每個模塊只負(fù)責(zé)一件事情,它可以更專心便于進(jìn)行單個模塊的設(shè)計、開發(fā)、調(diào)試、測試和維護(hù)等工作一個模塊一個模塊地完成,最后再將它們集成開發(fā)人員各司其職按模塊分配任務(wù),職責(zé)明確并行開發(fā),縮短開發(fā)時間什么時候需要模塊化?某一功能,如果重復(fù)實現(xiàn)3遍以上,即應(yīng)考慮模塊化,將它寫成通用函數(shù),并向小組成員發(fā)布模塊化程序設(shè)計模塊化的優(yōu)點(diǎn)——復(fù)用構(gòu)建新的軟件系統(tǒng)可以不必每次從零做起,直接使用已有的經(jīng)過反復(fù)驗證的軟構(gòu)件,組裝或加以合理修改后成為新的系統(tǒng),提高軟件生產(chǎn)率和程序質(zhì)量在其他函數(shù)的基礎(chǔ)上構(gòu)造程序拿來拿去主義,指盡可能復(fù)用其他人現(xiàn)成的模塊不是人類懶惰的表現(xiàn),而是智慧的表現(xiàn)一般要靠日積月累才能建立可以被復(fù)用的軟件庫前期投入多,缺乏近期效益,大部分公司都注重近期效益,是為了生存,所以軟件復(fù)用對公司來說不是最高優(yōu)先級【例6.6】模塊化設(shè)計拋硬幣游戲猜硬幣正反面,10次猜不對就猜下一個數(shù)模塊分解過程開始結(jié)束初始化退出處理主功能為程序運(yùn)行所做的準(zhǔn)備工作在退出前要做的事情,如打印結(jié)果、資源釋放等自底向上自頂向下的模塊化程序設(shè)計模塊化設(shè)計拋硬幣游戲開始結(jié)束生成硬幣猜正反面intmain(){intcoin;charreply;srand((unsigned)time
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 ISO 16281:2025 EN Rolling bearings - Methods for calculating the modified reference rating life for universally loaded rolling bearings
- 箱子材料成型課程設(shè)計
- 生物數(shù)字化課程設(shè)計
- 公司薪酬福利管理制度
- 發(fā)展集團(tuán)財務(wù)管理管控規(guī)章制度匯編
- 研究生幼兒游戲課程設(shè)計
- 繼電器電路控制課程設(shè)計
- 住院部護(hù)理工作總結(jié)
- 泰拳系統(tǒng)課程設(shè)計案例
- 2025年高考?xì)v史一輪復(fù)習(xí)之經(jīng)濟(jì)發(fā)展與社會進(jìn)步
- 2022版義務(wù)教育物理課程標(biāo)準(zhǔn)
- 數(shù)字資產(chǎn)管理與優(yōu)化考核試卷
- 期末測試-2024-2025學(xué)年語文四年級上冊統(tǒng)編版
- 教案-“枚舉法”信息技術(shù)(信息科技)
- 2024年內(nèi)部審計年度工作計劃范文(六篇)
- 四川省成都市2021-2022學(xué)年物理高一下期末學(xué)業(yè)質(zhì)量監(jiān)測模擬試題含解析
- 光伏發(fā)電系統(tǒng)租賃合同范本
- 新教科版六年級上冊科學(xué)全冊知識點(diǎn)(期末總復(fù)習(xí)資料)
- 綠色建筑工程監(jiān)理實施細(xì)則
- 2024年安全員b證繼續(xù)教育考試
- 科研倫理與學(xué)術(shù)規(guī)范期末考試試題
評論
0/150
提交評論