合工大計算機學院 程序設計 04第四章 函數(shù).ppt
第四章函數(shù),函數(shù)的聲明與調(diào)用參數(shù)傳遞方式標識符的作用域變量的生存期遞歸程序設計C+語言常用庫函數(shù),4.1C+語言的函數(shù)一、函數(shù)的建立與使用,函數(shù)的建立函數(shù)聲明:定義函數(shù)的名字、執(zhí)行的語句序列、傳遞和使用的數(shù)據(jù)參數(shù)、返回值等;函數(shù)的使用函數(shù)調(diào)用:指明函數(shù)去“做什么”;函數(shù)調(diào)用的控制流程:如右圖,函數(shù)調(diào)用程序(主調(diào)函數(shù)),調(diào)用F,調(diào)用F,被調(diào)用函數(shù)F,例1:,#includefloatmax(floatx,floaty)floatz;/求兩個數(shù)的最大值if(x>=y)z=x;elsez=y;returnz;intmain()floati,j,k;/用戶輸入的三個數(shù)floattemp;/臨時最大者cout>i>>j>>k;/用戶輸入三個數(shù)/找出最大數(shù)存放在temp中temp=max(i,j);/main()是主調(diào)函數(shù),max()是被調(diào)函數(shù)temp=max(temp,k);/輸出找到的最大數(shù)cout<<"Themaximumnumberis"<<temp<y?x:y;若函數(shù)定義時沒有說明函數(shù)類型,則缺省認為函數(shù)返回類型是intmain()若函數(shù)無返回值,則應明確定義函數(shù)類型為voidvoidhandle(),函數(shù)名是標識符函數(shù)名后一定要有一對圓括號(),這是函數(shù)的標志,使函數(shù)與其他標識符名區(qū)分開來形式參數(shù)用于接收從主調(diào)函數(shù)傳給這個函數(shù)的數(shù)據(jù)一般形式:(數(shù)據(jù)類型變量1,數(shù)據(jù)類型變量2,)形參個數(shù)不受限制函數(shù)體聲明部分:用于聲明在函數(shù)中使用到的變量語句部分:在函數(shù)中用于實現(xiàn)某項任務的語句序列空函數(shù):函數(shù)體為空(沒有語句,但不能省略),二、函數(shù)調(diào)用,函數(shù)調(diào)用的一般形式:當作表達式使用函數(shù)名(實際參數(shù)表)實際參數(shù)出現(xiàn)在函數(shù)調(diào)用表達式中,是函數(shù)調(diào)用時,實際使用的參數(shù)一般形式:(表達式1,表達式2,)實際參數(shù)表是用逗號分隔的表達式列表,其中每一個表達式稱為實際參數(shù),有時也簡稱為實參。在函數(shù)調(diào)用時,需要將實際參數(shù)的值傳送給對應位置的形式參數(shù)實際參數(shù)與形式參數(shù)必須一一對應,位置、個數(shù)以及數(shù)據(jù)類型都匹配例:p82程序4.1.1,2.函數(shù)調(diào)用表達式,函數(shù)調(diào)用作為一個表達式,其類型是函數(shù)返回值的類型函數(shù)調(diào)用可用于任何表達式可以出現(xiàn)的地方例1:if(max(i,j)i>>j>>k;temp=max(i,j);temp=max(temp,k);cout=y)z=x;elsez=y;returnz;,floatmax(floatx,floaty);,函數(shù)原型:floatmax(floatx,floaty);floatmax(float,float);floatmax(floatt,floatk);,4.3參數(shù)傳遞,一、參數(shù)傳遞方式主調(diào)函數(shù)與被調(diào)函數(shù)的數(shù)據(jù)交換:由參數(shù)傳遞與返回值實現(xiàn)按值調(diào)用:單項的參數(shù)傳遞按引用調(diào)用:雙向的參數(shù)傳遞二、按值調(diào)用(傳值,按拷貝調(diào)用)單向的,實際參數(shù)>形式參數(shù),傳遞的是參數(shù)的值例:p91程序4.3.1#includecout<<"iis"<<i<<"n"intsquare(intx)cout<<"jis"<<j<<"n"/求一個整數(shù)的平方return0;x=x*x;returnx;intmain()inti,j;i=8;j=square(i);,8,64,64,64,三、缺省參數(shù),C+語言允許在函數(shù)原型或函數(shù)定義中為形式參數(shù)指定缺省值,具有缺省值的形式參數(shù)稱缺省形參用初值表達式定義缺省值缺省行參必須從右邊開始定義intfunc(inta,floatb,intc=0);若在函數(shù)調(diào)用時指定了形式參數(shù)對應的實際參數(shù),則形式參數(shù)使用實際參數(shù)的值,否則未指定相應的實際參數(shù)則形式參數(shù)使用缺省值。,例2:,#include#include/給出函數(shù)原型doubledistance(doublex1,doubley1,doublex2=0,doubley2=0);intmain()cout<<"(1,2)to(0,0)is"<<distance(1,2)<<"n"cout<<"(-1.5,2)to(1.5,-2)is"<<distance(-1.5,2,1.5,-2)<<"n"return0;/計算兩點之間的距離doubledistance(doublex1,doubley1,doublex2,doubley2)doublex,y;x=x2-x1;y=y2-y1;returnsqrt(x*x)+(y*y);,4.4生存期與作用域一、變量的兩個性質,生存期:(從時間角度考慮)變量的生存期是指在程序運行過程中變量占存儲空間的時限作用域:(從空間角度考慮)指在變量占用存儲空間的時間內(nèi)變量的名字能被引用的區(qū)域,即變量名作用的有效范圍。在變量的作用域中變量必然存在在變量的生存期中變量不一定有效,二、全局變量和局部變量,局部變量:在一個塊語句內(nèi)部定義的變量作用域:本塊語句中。塊語句嵌套時,內(nèi)層的同名變量有效,而外層的同名變量被屏蔽。不同函數(shù)中使用同名變量,代表不同對象,互不相干例:voidfunc(intx)形式參數(shù)x的作用域inty=x+1;外層變量y的作用域inty=x+2;內(nèi)層變量y的作用域intz=x+3;內(nèi)層變量z的作用域y=y*y;z=z*z;cout<<x<<”<<y<<”<<z<<”n”;intz=x+4;外層變量z的作用域y=y+y;z=z+z;cout<<x<<”<<y<<”<<z<<”n”;,生存期:局部變量是當程序的控制流程進入定義該變量的塊語句時,才為其分配一塊臨時的存儲空間,當程序的控制流程退出該程序塊時,臨時占用的存儲空間被釋放。初始化:無顯式初始化式,其初值是一個不確定的值。顯示初始化時,每次流程進入塊函數(shù)時,分配內(nèi)存空間,都重新對局部變量初始化,2.全局變量:在函數(shù)之外定義的變量,作用域:從定義變量開始到本源程序文件結束。生存期:全局變量在整個程序的運行期中都存在初始化:無顯式初始化式,其初值會被清0。顯示初始化時,對全局變量的初始化在編譯時一次完成。同名的全局變量與局部變量:在局部變量的作用域內(nèi),全局變量被屏蔽,直接使用該名字,用的是局部變量,但可用:作用域運算符引用同名全局變量,例:,inty=8;voidfunc(intx)inty=x+1;:y=:y*y;cout<<y<<”<<:y<<”n”;intmain()func(3);cout<<y<<”n”;return0;,三、變量的存儲類別,1.存儲方式從生存期(時間)來分,有兩種存儲方式靜態(tài)存儲方式:在程序運行期間占用固定存儲空間動態(tài)存儲方式:運行時,根據(jù)需要動態(tài)分配存儲空間內(nèi)存中,供用戶使用的存儲空間:變量的定義:數(shù)據(jù)存儲類別數(shù)據(jù)類型變量名(=初值);,程序區(qū),靜態(tài)存儲區(qū),動態(tài)存儲區(qū),2.數(shù)據(jù)存儲類別,例:,#includevoidgrow()intage=30;age=age+1;cout<<"Myageis"<<age<<"n"return;intmain()for(inti=1;i<=3;i=i+1)grow();return0;age不是靜態(tài)變量的運行結果:age是靜態(tài)局部變量的運行結果:Myageis31Myageis31Myageis31Myageis32Myageis31Myageis33,static,4.5遞歸程序設計,在函數(shù)定義中,一個函數(shù)直接或間接地調(diào)用自己,稱遞歸調(diào)用,這類函數(shù)為遞歸函數(shù)。1)直接遞歸2)間接遞歸f(intx)f1()f2()f(x-1);f2();f1();遞歸調(diào)用是無終止的自身調(diào)用,因此在遞歸函數(shù)中應該用if語句或其它分支語句,判斷當某些條件成立時結束遞歸調(diào)用,例:,/功能:使用遞歸程序計算Fibonacci序列。#includeintfibonacci(intn)intresult;if(n<2)result=1;elseresult=fibonacci(n-1)+fibonacci(n-2);returnresult;intmain()intloop;/循環(huán)變量/輸出Fibonacci序列的前6個數(shù)for(loop=0;loop<=5;loop=loop+1)cout<<fibonacci(loop)<<""cout<<"n"return0;,intfibonacci(intn)intresult,i,pre1,pre2;result=1;i=2;pre2=1;while(i<=n)pre1=pre2;pre2=result;result=pre1+pre2;i+;returnresult;,設n為5,則有:F(5)=F(3)+F(4)=F(1)+F(2)+F(2)+F(3)=F(1)+F(0)+F(1)+F(0)+F(1)+F(1)+F(2)=F(1)+F(0)+F(1)+F(0)+F(1)+F(1)+F(0)+F(1)=1+1+1+1+1+1+1+1=8,分析如下:,例:梵塔問題,盤按由小到大的順序標上號碼1n。開始時n個盤全套在A柱上,且小的放在大的上面,如圖4.6.1所示。游戲要求按下列規(guī)則將所有的盤從A柱移到C柱,在移動過程中可以借助另一個B柱。規(guī)則1:每次只能移動柱最上面的一個盤;規(guī)則2:任何盤都不得放在比它小的盤上。ABC12n,遞歸思路:把A上的n個盤運到C上先把n-1個盤從A搬到B,借助C把A上剩下的最大的一個盤搬到C再把n-1個盤從B搬到C,借助A當n=1時,直接從A搬到C即可,程序,#include/將disk_num個盤從from柱移到to柱,可以借助aux柱voidmove_tower(intdisk_num,charfrom,charto,charaux)if(disk_num=1)/僅有一個盤時,直接從from柱移到to柱cout<<"Movedisk1from"<<from<<"to"<<to<<"n"else/將disk_num-1個盤從from柱移到aux柱,借助于to柱move_tower(disk_num-1,from,aux,to);/將最下的盤從from柱移到to柱cout<<"Movedisk"<<disk_num<<"from"<<from<<"to"<<to<<"n"/將disk_num-1個盤從aux柱移到to柱,借助于from柱move_tower(disk_num-1,aux,to,from);return;intmain()move_tower(4,A,C,B);return0;,