版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第7章 函數(shù)本章學(xué)習(xí)內(nèi)容 函數(shù)定義、函數(shù)調(diào)用、函數(shù)原型、函數(shù)的參數(shù)傳遞與返回值 遞歸函數(shù)和函數(shù)的遞歸調(diào)用 函數(shù)封裝,函數(shù)復(fù)用,函數(shù)設(shè)計(jì)的基本原則,程序的健壯性 變量的作用域與存儲類型,全局變量、自動(dòng)變量、靜態(tài)變量、寄存器變量 “自頂向下、逐步求精”的模塊化程序設(shè)計(jì)方法 數(shù)學(xué)中的函數(shù)自變量(參數(shù)) 因變量(返回值)函數(shù)名程序設(shè)計(jì)中的函數(shù)程序設(shè)計(jì)中的函數(shù)不局限于計(jì)算計(jì)算類,如打印階乘表的程序判斷推理類,如排序、查找若程序規(guī)模較大,把所有代碼都寫在main函數(shù)中,會使主函數(shù)變得龐大復(fù)雜,閱讀和維護(hù)變得困難程序中要多次實(shí)現(xiàn)某一功能時(shí),需要多次重復(fù)編寫實(shí)現(xiàn)此功能的程序代碼,這使程序冗長不精煉無法多人合作
2、解決的方法: (用模塊化程序設(shè)計(jì)的思路)編寫函數(shù)函數(shù):按照調(diào)用者要求完成特定功能的處理問題的提出-為什么有函數(shù)?什么是模塊化程序設(shè)計(jì)分而治之函數(shù)把較大的任務(wù)分解成若干個(gè)較小的任務(wù),并提煉出公用任務(wù)信息隱藏函數(shù)可把具體操作細(xì)節(jié)對外界隱藏起來使用函數(shù)時(shí),不用知道函數(shù)內(nèi)部,只按照需要和它的參數(shù)形式調(diào)用它即可并行開發(fā)7.2 函數(shù)的定義函數(shù)是C語言中模塊化編程的基本單位可以把每個(gè)函數(shù)看做一個(gè)模塊如把編程比做制造一臺機(jī)器,函數(shù)就好比其零部件:可單獨(dú)設(shè)計(jì),用時(shí)拿出來裝配。也可使用標(biāo)準(zhǔn)產(chǎn)品7.2.1函數(shù)的分類C語言程序由函數(shù)構(gòu)成一個(gè)完整的C程序可以由一個(gè)或多個(gè)函數(shù)組成,但必須有一個(gè)且只有一個(gè)名為main()的
3、函數(shù)。由主函數(shù)調(diào)用其他函數(shù),其它函數(shù)間可以相互調(diào)用。C語言程序的執(zhí)行就是函數(shù)的調(diào)用過程函數(shù)都是平等的,互相獨(dú)立,沒有從屬之分main( )稍微特殊一點(diǎn)點(diǎn)無論main()在什么位置,C程序的執(zhí)行從main ( )函數(shù)開始調(diào)用其他函數(shù)后流程回到main ( )函數(shù)在main ( )函數(shù)中結(jié)束整個(gè)程序運(yùn)行7.2.1函數(shù)的分類(1)從用戶使用角度:庫函數(shù)自定義函數(shù)(2)從函數(shù)返回值角度無返回值:一般用來執(zhí)行指定的一組操作有返回值(返回值應(yīng)用舉例,max函數(shù))(3)從函數(shù)參數(shù)角度無參函數(shù):調(diào)用時(shí),主調(diào)函數(shù)不向被調(diào)函數(shù)傳數(shù)據(jù)有參函數(shù):調(diào)用時(shí)主調(diào)函數(shù)通過參數(shù)向被調(diào)函數(shù)傳數(shù)據(jù)【例】根據(jù)輸入的正整數(shù)n和k,求C
4、(n,k)=n!/(k!*(n-k)!)的值 long fact(int n)/計(jì)算階乘的函數(shù) int i; long f=1L; for(i=1;i=n;i+) f=f*i; return(f); #includelong fact(int n);main() int n,k; long Cn_k; scanf(“%d%d”,&n,&k); Cn_k=fact(n)/(fact(n-k)*fact(k); printf(“C=%ld”,Cn_k);(1)程序中包括兩種函數(shù):一種是系統(tǒng)提供的標(biāo)準(zhǔn)庫函數(shù),如scanf()和printf();另一類是用戶自定義的函數(shù)fact(int n)(2) f
5、act()計(jì)算n階乘,其中n由調(diào)用時(shí)的參數(shù)決定。函數(shù)類型long表示該函數(shù)執(zhí)行結(jié)束后將一個(gè)長整型數(shù)返回給主調(diào)函數(shù)。7.2.2函數(shù)的定義C語言要求函數(shù)使用之前必須先定義函數(shù)定義中指定函數(shù)名字、函數(shù)返回值類型、函數(shù)實(shí)現(xiàn)的功能以及參數(shù)的個(gè)數(shù)與類型,將這些信息通知編譯系統(tǒng)。7.2.2函數(shù)的定義類型 函數(shù)名(類型 參數(shù)1, 類型 參數(shù)2, )聲明語句序列 可執(zhí)行語句序列 return 表達(dá)式;返回值類型函數(shù)名參數(shù)表相當(dāng)于運(yùn)算的操作數(shù)返回運(yùn)算的結(jié)果函數(shù)出口函數(shù)定義的一般形式:類型 函數(shù)名(類型 參數(shù)1, 類型 參數(shù)2, ) 聲明語句序列 可執(zhí)行語句序列 return 表達(dá)式;函數(shù)體的定界符參數(shù)表里的變量(
6、稱為形式參數(shù))也是內(nèi)部變量,及只能在函數(shù)內(nèi)部使用函數(shù)體函數(shù)定義的一般形式:說明(1) 函數(shù)名 函數(shù)名是一個(gè)用戶定義的標(biāo)識符,命名規(guī)則同變量一樣。在同一程序中,不能有同名的函數(shù)。(2) 函數(shù)體 用左、右花括號括起來的部分稱函數(shù)體,它由聲明(變量或者函數(shù))部分和語句部分組成。(3) 函數(shù)類型 定義函數(shù)時(shí)應(yīng)說明函數(shù)類型,函數(shù)類型應(yīng)與return語句中返回值的類型一致。判斷是否素?cái)?shù)的函數(shù)返回類型為?計(jì)算正整數(shù)x!的函數(shù)返回類型為?計(jì)算班里某一門考試的平均分返回類型為?打印200個(gè)空格返回類型為?如果函數(shù)返回值的類型與指定的函數(shù)類型不一致,則以函數(shù)定義類型為準(zhǔn)(按照賦值規(guī)則處理)。如果缺省函數(shù)類型,則系
7、統(tǒng)一律按整型處理。 Ract(int a) return 3.0; sizeof(Ract(2)=? (4)參數(shù)(形參)列表 為了與調(diào)用函數(shù)提供的實(shí)際參數(shù)區(qū)別開,將函數(shù)定義中的參數(shù)表稱為形式參數(shù)表,簡稱形參表。 形參列表列出了參數(shù)類型,名字。多個(gè)參數(shù)用逗號間隔。但是多個(gè)參數(shù)時(shí),對應(yīng)參數(shù)類型不能缺省。(5)函數(shù)定義不允許嵌套函數(shù)的定義,可以放在程序中的任意位置,主函數(shù)main()之前或之后。一個(gè)函數(shù)并不從屬于另一個(gè)函數(shù),各函數(shù)之間是相互獨(dú)立的。在一個(gè)函數(shù)的函數(shù)體內(nèi),不能再定義另一個(gè)函數(shù),即不能嵌套定義。(函數(shù)嵌套定義會導(dǎo)致local function語法錯(cuò)誤)函數(shù)定義的特殊形式:如果不需要指定參
8、數(shù),可以省略參數(shù),或者將參數(shù)部分設(shè)置為void如果不需要通過函數(shù)將計(jì)算結(jié)果返回給使用者,可以將返回類型設(shè)置為voidvoid 函數(shù)名(void)聲明語句序列 可執(zhí)行語句序列 return;函數(shù)無返回值,用void定義返回值類型用void定義參數(shù),表示沒有參數(shù)return語句后無需任何表達(dá)式7.2.2函數(shù)的定義【例7.1a】 計(jì)算整數(shù)n的階乘n! /* 函數(shù)功能: 用迭代法計(jì)算n! 函數(shù)入口參數(shù): 整型變量n表示階乘的階數(shù) 函數(shù)返回值: 返回n!的值*/long Fact(int n) /* 函數(shù)定義 */ int i; long result = 1; for (i=2; iy?x:y; re
9、turn(z); int main() int a,b,c; scanf(“%d,%d”,&a,&b); c=max(a,b); printf(“max is %dn”,c); c=max(a,b); (main函數(shù))int max(int x, int y) (max函數(shù)) int z; z=xy?x:y; return(z); 2a3bxy23實(shí)參形參注意實(shí)參可以是常量、變量、表達(dá)式和函數(shù)調(diào)用。形參和實(shí)參可以同名。形參是局部于該函數(shù)的變量,即使形參和實(shí)參同名,也是兩個(gè)不同的變量,占用不同的內(nèi)存單元,所以同名也互不影響。形式參數(shù)用于函數(shù)體內(nèi)操作(所以不同函數(shù)可以使用同名形參和局部變量) 形參
10、變量只有在被調(diào)用時(shí),才分配內(nèi)存單元;調(diào)用結(jié)束時(shí)即刻釋放所分配的內(nèi)存單元。因此形參只有在該函數(shù)內(nèi)有效。調(diào)用結(jié)束,返回調(diào)用函數(shù)后則不能再使用該形參變量。(和函數(shù)局部變量類似) 實(shí)參對形參的數(shù)據(jù)傳送是單向的,即只能把實(shí)參的值傳送給形參,而不能把形參的值反向地傳送給實(shí)參7.3.1.2 函數(shù)調(diào)用過程函數(shù)定義時(shí)的形參不占內(nèi)存,只有發(fā)生調(diào)用時(shí),形參才被分配臨時(shí)內(nèi)存空間,并接受從實(shí)參傳過來的值。執(zhí)行函數(shù)通過return語句將值帶回主調(diào)函數(shù)調(diào)用結(jié)束,形參單元被釋放。實(shí)參單元仍保留并維持原值,沒有改變。(在執(zhí)行一個(gè)被調(diào)用函數(shù)時(shí),形參的值如果發(fā)生改變,不會改變主調(diào)函數(shù)的實(shí)參的值)考慮交換兩個(gè)整型變量的函數(shù)swap能
11、否成功?7.3.1.3 函數(shù)的返回值1函數(shù)返回值與return語句函數(shù)的返回值是通過函數(shù)中的return語句來獲得的。(1)return語句的一般格式: return ( 返回值表達(dá)式 ); return語句后面的括號可以不要(2)return語句的功能:返回到調(diào)用函數(shù),并將“返回值表達(dá)式”的值帶給調(diào)用函數(shù)。返回值表達(dá)式可以是常量、變量、表達(dá)式和函數(shù)調(diào)用一個(gè)函數(shù)中可以有一個(gè)以上的return語句,執(zhí)行到某個(gè)return語句立刻結(jié)束函數(shù)返回主調(diào)函數(shù)注意:為了明確表示不返回值,用void定義成函數(shù)類型。同時(shí)在函數(shù)定義中,可以有返回語句 return;,也可以不帶返回語句,那么當(dāng)函數(shù)執(zhí)行到最后一個(gè)花
12、括號時(shí),自動(dòng)返回。return語句的作用:結(jié)束被調(diào)函數(shù)的運(yùn)行 double fun(int x,int y) if(xy) return x; 是否正確? x+;y+; 注意:必須保證每個(gè)分支都能返回 (問題:什么情況下,return語句可以缺?。?)注意:函數(shù)只能返回一個(gè)值。函數(shù)返回值類型可以是除數(shù)組以外的任何類型【例】編寫函數(shù),打印輸出x的n次方的值。由于x和n都是可變的,所以應(yīng)該把x和n都作為函數(shù)的參數(shù)。由于不需要返回值,因此函數(shù)類型說明為void型,若取名為power,則求x的n次方函數(shù)可定義為:void power(float x,int n) ; main( ) float x;
13、int n; scanf(“%f%d”,&x,&n); power(x,n); /*函數(shù)調(diào)用*/ void power(float x,int n) /*函數(shù)定義*/ int i; double p=1.0; for (i=1,p=1;i=b?a:b); 7.4 函數(shù)的遞歸調(diào)用和遞歸函數(shù)在調(diào)用一個(gè)函數(shù)的過程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸調(diào)用。字典就是一個(gè)遞歸問題的典型實(shí)例字典中的任何一個(gè)詞匯都是由“其他詞匯”解釋或定義的,但是“其他詞匯”在被定義或解釋時(shí)又會間接或直接地用到那些由它們定義的詞語言的特點(diǎn)之一就在于允許函數(shù)的遞歸調(diào)用。遞歸方法的基本原理將復(fù)雜問題逐步化簡,最終轉(zhuǎn)
14、化為一個(gè)最簡單的問題最簡單問題的解決就意味著整個(gè)問題的解決 【例】 有5個(gè)學(xué)生坐在一起問第5個(gè)學(xué)生多少歲?他說比第4個(gè)學(xué)生大2歲問第4個(gè)學(xué)生歲數(shù),他說比第3個(gè)學(xué)生大2歲問第3個(gè)學(xué)生,又說比第2個(gè)學(xué)生大2歲問第2個(gè)學(xué)生,說比第1個(gè)學(xué)生大2歲最后問第1個(gè)學(xué)生,他說是10歲請問第5個(gè)學(xué)生多大解題思路:要求第個(gè)年齡,就必須先知道第個(gè)年齡要求第個(gè)年齡必須先知道第個(gè)年齡第個(gè)年齡又取決于第個(gè)年齡第個(gè)年齡取決于第個(gè)年齡每個(gè)學(xué)生年齡都比其前個(gè)學(xué)生的年齡大age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10 age(5)=age
15、(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1) =10 age(2) =12 age(3) =14 age(4) =16 age(5) =18 回溯階段 遞推階段 age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1) =10 age(2) =12 age(3) =14 age(4) =16 age(5) =18 回溯階段 遞推階段結(jié)束遞歸的條件#include int main() int age(int n); printf(NO.
16、5,age:%dn,age(5); return 0; int age(int n) int c; if(n=1) c=10; else c=age(n-1)+2; return(c); age(5)輸出age(5)mainc=age(4)+2age函數(shù)n=5c=age(3)+2age函數(shù)n=4c=age(1)+2age函數(shù)n=2c=age(2)+2age函數(shù)n=3c=10age函數(shù)n=1age(1)=10age(2)=12age(3)=14age(4)=16age(5)=1818【例】 用遞歸方法求n!。解題思路:求!可以用遞推方法:即從開始,乘,再乘一直乘到n。遞推法的特點(diǎn)是從一個(gè)已知的事
17、實(shí)(如1!=1)出發(fā),按一定規(guī)律推出下一個(gè)事實(shí)(如2!=1!*2),再從這個(gè)新的已知的事實(shí)出發(fā),再向下推出一個(gè)新的事實(shí)(3!=3*2!)。n!=n*(n-1)!。也可以用遞歸方法遞歸函數(shù)long fact(int n) if (n 0) return -1; else if (n = 0 | n = 1) return 1; else return n * fact(n-1); 【例7.5】計(jì)算n!= n *(n-1)*(n-2)*1 函數(shù)直接或間接調(diào)用自己,稱為遞歸調(diào)用(Recursive Call)求4!的遞歸計(jì)算過程如下圖所示: 第一次調(diào)用函數(shù): fact(4) 24 最終得到結(jié)果24
18、帶結(jié)果24返回 第二次調(diào)用函數(shù): fact(3)*4 6*4 計(jì)算fact(4)的值 帶結(jié)果6返回 第三次調(diào)用函數(shù): fact(2)*3 2*3 計(jì)算fact(3)的值 帶結(jié)果2返回 第四次調(diào)用函數(shù): fact(1)*2 1*2 計(jì)算fact(2)的值 帶結(jié)果1返回 1 遞歸函數(shù)fact(n)的執(zhí)行過程遞歸函數(shù)unsigned long fact(unsigned int n) if (n = 0 | n = 1) return 1;else return n * fact(n-1); 基線情況(base case)一般情況(general case)無需考慮n0了【例7.5】計(jì)算n!= n
19、*(n-1)*(n-2)*1 遞歸函數(shù)遞歸調(diào)用應(yīng)該能夠在有限次數(shù)內(nèi)終止遞歸遞歸調(diào)用若不加以限制,將無限循環(huán)調(diào)用必須在函數(shù)內(nèi)部加控制語句,僅當(dāng)滿足一定條件時(shí),遞歸終止,稱為條件遞歸任何一個(gè)遞歸調(diào)用程序必須包括兩部分遞歸循環(huán)繼續(xù)的過程遞歸調(diào)用結(jié)束的過程 if (遞歸終止條件成立) return 遞歸公式的初值; else return 遞歸函數(shù)調(diào)用返回的結(jié)果值; n!=n(n-1)! (n-1)!=(n-1)(n-2)! (n-2)! (n-3)! 5! 4!=43! 3!=32! 2!=21! 1!=1回推過程遞推過程每個(gè)遞歸函數(shù)必須至少有一個(gè)基線條件一般情況必須最終能簡化為基線條件 遞歸層數(shù)太
20、多易導(dǎo)致??臻g溢出后果很嚴(yán)重,程序被異常中止 fact(5)=5*fact(4)= 120 fact(4)= 4*fact(3)= 24 fact(3)= 3*fact(2)= 6 fact(2)= 2*fact(1)=2 fact(1)=1mainfact(5)fact(4)fact(3)fact(2)fact(1)遞歸與迭代遞歸也可用相應(yīng)的非遞歸迭代實(shí)現(xiàn)。用迭代(即循環(huán))方法編寫的階乘函數(shù)unsigned long Fact(unsigned int n) unsigned long result = 1; unsigned int i; for (i = 1; i b?a:b; retu
21、rn(c); a為局部變量,僅在此函數(shù)內(nèi)有效b為全局變量全局變量( Global Variable )【例7.7】打印計(jì)算Fibonacci數(shù)列每一項(xiàng)時(shí)所需的遞歸調(diào)用次數(shù) 全局變量使函數(shù)間的數(shù)據(jù)交換更容易,更高效,但建議盡量少用,因?yàn)檎l都可改寫它,所以很難確定是誰改寫了它全局變量7.5.2變量的存儲類型指數(shù)據(jù)在內(nèi)存中存儲的方式即編譯器為變量分配內(nèi)存的方式,它決定變量的生存期 存儲類型 數(shù)據(jù)類型 變量名;C程序的存儲類別auto型(自動(dòng)變量)static型(靜態(tài)變量)extern型(外部變量)register型(寄存器變量)靜態(tài)存儲區(qū)中的變量:與程序“共存亡” 動(dòng)態(tài)存儲區(qū)中的變量:與程序塊“共存
22、亡” 寄存器中的變量: 同動(dòng)態(tài)存儲區(qū)變量的生存期決定何時(shí)“生”,何時(shí)“滅”7.5.2變量的存儲類型程序區(qū)靜態(tài)存儲區(qū)動(dòng)態(tài)存儲區(qū)用戶區(qū)將數(shù)據(jù)存放在此區(qū)全局變量全部存放在靜態(tài)存儲區(qū)中函數(shù)形式參數(shù)函數(shù)中定義的沒有用關(guān)鍵字static聲明的變量函數(shù)調(diào)用時(shí)的現(xiàn)場保護(hù)和返回地址等存放在動(dòng)態(tài)存儲區(qū)程序開始執(zhí)行時(shí)給全局變量分配存儲區(qū),程序執(zhí)行完畢就釋放。在程序執(zhí)行過程中占據(jù)固定的存儲單元函數(shù)調(diào)用開始時(shí)分配,函數(shù)結(jié)束時(shí)釋放。在程序執(zhí)行過程中,這種分配和釋放是動(dòng)態(tài)的 auto 數(shù)據(jù)類型 變量名;auto體現(xiàn)在進(jìn)入語句塊時(shí)自動(dòng)申請內(nèi)存,退出時(shí)自動(dòng)釋放內(nèi)存動(dòng)態(tài)局部變量,缺省的存儲類型靜態(tài)變量 static 數(shù)據(jù)類型 變量名;生存期為整個(gè)程序運(yùn)行期間自動(dòng)變量和靜態(tài)變量靜態(tài)局部變量(static局部變量)希望函數(shù)中的局部變量在函數(shù)調(diào)用結(jié)束后不消失而繼續(xù)保留原值,即其占用的存儲
溫馨提示
- 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年中國礦產(chǎn)資源勘查行業(yè)商業(yè)模式創(chuàng)新戰(zhàn)略制定與實(shí)施研究報(bào)告
- 新形勢下塑膠玩具行業(yè)轉(zhuǎn)型升級戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2025-2030年中國電視劇行業(yè)營銷創(chuàng)新戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2025-2030年中國金屬注射成型行業(yè)資本規(guī)劃與股權(quán)融資戰(zhàn)略制定與實(shí)施研究報(bào)告
- 自動(dòng)噴水滅火系統(tǒng)試壓記錄表
- 比較法在圖書館學(xué)研究中的應(yīng)用
- 真絲睡衣體驗(yàn)調(diào)查
- 生活防火知識培訓(xùn)課件
- 2024-2030年中國自動(dòng)血液分析儀行業(yè)市場發(fā)展監(jiān)測及投資潛力預(yù)測報(bào)告
- 2023-2029年中國愛情服務(wù)行業(yè)市場運(yùn)行態(tài)勢及投資戰(zhàn)略規(guī)劃報(bào)告
- 藝術(shù)漆培訓(xùn)課件
- 建德海螺二期施工組織設(shè)計(jì)
- 山東省菏澤市2023-2024學(xué)年高一上學(xué)期期末測試物理試題(解析版)
- 2024年學(xué)校后勤日用品采購合同范本2篇
- 中建中建機(jī)電工程聯(lián)動(dòng)調(diào)試實(shí)施方案范本
- 新《安全生產(chǎn)法》安全培訓(xùn)
- 山東省濟(jì)南市2023-2024學(xué)年高一上學(xué)期1月期末考試 物理 含答案
- 中華人民共和國安全生產(chǎn)法知識培訓(xùn)
- 物業(yè)品質(zhì)提升方案課件
- 《ROHS知識培訓(xùn)》課件
- 服裝行業(yè)倉庫管理流程
評論
0/150
提交評論