版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
面向?qū)ο蟪绦蛟O(shè)計(jì)復(fù)習(xí)輔導(dǎo)(三)—函數(shù)徐孝凱一個(gè)C++語言程序由若干個(gè)程序文獻(xiàn)和頭文獻(xiàn)所組成,每個(gè)頭文獻(xiàn)中通常帶有用戶類型的定義、符號(hào)常量的定義、函數(shù)的聲明等內(nèi)容,每個(gè)程序文獻(xiàn)由若干個(gè)函數(shù)定義所組成,其中必有一個(gè)并且只有一個(gè)程序文獻(xiàn)中包具有主函數(shù)main,稱此程序文獻(xiàn)為主程序文獻(xiàn)。函數(shù)是C++程序中的基本功能模塊和執(zhí)行單元,這一章專門討論函數(shù)的定義和調(diào)用,變品的作用域和生存期等內(nèi)容。一、函數(shù)的定義(一)定義格式〈類型名〉〈函數(shù)名)([<參數(shù)表>])〈函數(shù)體〉<類型名)為系統(tǒng)或用戶已定義的一種數(shù)據(jù)類型,它是函數(shù)執(zhí)行過程中通過roturn語句規(guī)定返回的值的類型,又稱為該函數(shù)的類型。當(dāng)一個(gè)函數(shù)不需要通過return語句返回一個(gè)值時(shí),稱為無返回值函數(shù)或無類型函數(shù),此時(shí)需要使用保存字void作為類型名。當(dāng)類型名為int時(shí),可以省略不寫,但為了清楚起見,還是寫明為好。〈函數(shù)名〉是用戶為函數(shù)所起的名字,它是一個(gè)標(biāo)記符,應(yīng)符合C++標(biāo)記符的一般命名規(guī)則,用戶通過使用這個(gè)函數(shù)名和實(shí)參表可以調(diào)用該函數(shù)?!磪?shù)表》又稱形式參數(shù)表,它包具有任意多個(gè)(含0個(gè),即沒有)參數(shù)說明項(xiàng),當(dāng)多于一個(gè)時(shí)其前后兩個(gè)參數(shù)說明項(xiàng)之間必須用逗號(hào)分開。每個(gè)參數(shù)說明項(xiàng)由一種已定義的數(shù)據(jù)類型和一個(gè)變量標(biāo)記符組成,該變量標(biāo)記符成為該函數(shù)的形式參數(shù),簡稱形參,形參前面給出的數(shù)據(jù)類型稱為該形參的類型。一個(gè)函數(shù)定義中的V參數(shù)表)可以被省略,表白該函數(shù)為無參函數(shù),若<參數(shù)表〉用void取代,則也表白是無參函數(shù),若〈參數(shù)表〉不為空,同時(shí)又不是保存字void,則稱為帶參函數(shù)。置接著向下執(zhí)行。當(dāng)return語句帶有表達(dá)式時(shí),又分為兩種情況,一種是函數(shù)類型為非引用類型,則計(jì)算出return表達(dá)式的值,并把它保存起來,以便返回后訪問它參與相應(yīng)的運(yùn)算;另一種情況是函數(shù)的類型為引用類型,則return中的表達(dá)式必須是一個(gè)左值,并且不能是本函數(shù)中的局部變量(關(guān)于局部變量的概念留在下一節(jié)討論),執(zhí)行return語句時(shí)就返回這個(gè)左值,也可以說函數(shù)的返回值是該左值的一個(gè)引用。因此,返回為引用的函數(shù)調(diào)用表達(dá)式既可作為右值乂可作為左值使用,但非引用類型的函數(shù)表達(dá)式只能作為右值使用。例如:int&fl4(inta[],intn)(。intk=0;for(inti=l;i<n;i++)。。if(a[i]>a[k])k=i;°returna[k];)該函數(shù)的功能是從一維整型數(shù)組a[n]中求出具有最大值的元素并引用返回。當(dāng)調(diào)用該函數(shù)時(shí),其函數(shù)表達(dá)式既可以作為右值,從而取出a[k]的值,乂可以作為左值,從而向a[k]賦予新值。如:#include<iostream.h>int&f14(inta口,intn)(intk=0;for(inti=l;i<n;i++)。if(a[i]>a[k])k=i;oreturna[k];ointb[8]={25,37,18,69,54,73,62,31};。cout?fl4(b,8)?endl;f14(b,5)=86;。for(inti=0;i<8;i++)cout<<b[i]?zocout<<endl;)該程序的運(yùn)營結(jié)果如下,請(qǐng)讀者自行分析。732537188654736231通常把函數(shù)定義為引用的情況較少出現(xiàn),而定義為非引用(即普通類型和指針類型)的情況則常見。(三)函數(shù)調(diào)用舉例程序1:#inc1ude<iostrearn.h>ntxkl(intn);voidmainO(cout<v”輸入i個(gè)正整數(shù):“;intm;cin?m;3intsum=xkl(m)+xk1(2*m+l);ocout<<sum<<en(11;}intxk1(intn),for(i=l;i<=n;i++)s+=i;returns;)該程序包含一個(gè)主函數(shù)和一個(gè)xkl函數(shù),在程序開始給出了一條xkl函數(shù)的原型語句,使得xkl函數(shù)無論在什么地方定義,在此程序文獻(xiàn)中的所有函數(shù)都可以合法地調(diào)用它。注意:主函數(shù)不需要使用相應(yīng)的函數(shù)原型語句加以聲明,由于C++規(guī)定不允許任何函數(shù)調(diào)用它,它只由操作系統(tǒng)調(diào)用并返回操作系統(tǒng)。函數(shù)xkl的功能是求出自然數(shù)1至n之和,這個(gè)和就是s的最后值,由return語句把它返回。在主函數(shù)中一方面為m輸入一個(gè)自然數(shù),接著用m去調(diào)用xkl函數(shù)返回1至m之間的所有自然數(shù)之和,再用2*m+l去調(diào)用xkl函數(shù)返回1至2*m+l之間的所有自然數(shù)之和,把這兩個(gè)和加起來賦給變量sum,最后輸出sum的值。假定從鍵盤上為m輸入的止整數(shù)為5,則進(jìn)行xk1(m)調(diào)用時(shí)把m的值5傳送給n,接著執(zhí)行函數(shù)體后返回s的值為15,進(jìn)行xkl(2*m+l)調(diào)用時(shí)把2*m+l的值11傳送給n,接著執(zhí)行函數(shù)體后返回s的值為66,它們的和81被作為初值賦給sum,最后輸出的sum值為81。程序2:ttinclude<iostream.h>voidxk2(int&a,intb);voidmain()(intx=12,y=18;ocout?"x=z,?x<<,"y=H?y?end1;xk2(x,y);。cout<<"x=*?x<<*1?^y=H<<y?endl;voidxk2(int&a,intb)cout?"a="?a?*Y<"b=〃VVbVVend1;a=a+b;b=a+b;cout?z,a="?a?z'??,b="?b?end1;)該程序包含一個(gè)主函數(shù)和一個(gè)xk2函數(shù),xk2函數(shù)使用了兩個(gè)形參,一個(gè)是整型引用變量a,另一個(gè)是整型變量b。在主函數(shù)中使用xkl(x,y)調(diào)用時(shí),將使形參a成為實(shí)參x的別名,在函數(shù)體中對(duì)a的訪問就是對(duì)主函數(shù)中x的訪問,此調(diào)用同時(shí)把y的值傳送給形參b,在函數(shù)體中對(duì)形參b的操作是與相應(yīng)的實(shí)參y無關(guān)的,由于它們使用各自的存儲(chǔ)空間。該程序的運(yùn)營結(jié)果為:x=12y=l8a=l2b=J8a=30b=48x=30y=18程序3:#inc1ude<iostream.h>voidxk3(int*a,int*b);voidxk4(int&a,int&b);voidmain()(intx=5,y=10;cout?"x="<<x?*'<<"y="VVy<Xendl;xk3(&x,&y);cout?"x="V<x?'J?"y=?y?endl;xk4(x,y);。cout?*x=*<<x<</Y<〃y="<<y<<endl;)voidxk3(int*a,int*b)(intc=*a;*a=*b;*b=c;)voidxk4(int&a,int&b)(。intc=a;a=b;b=c;}該程序中的xk3函數(shù)用于互換a和b分別指向的兩個(gè)對(duì)象的值,主函數(shù)使用xk3(&x,&y)調(diào)用時(shí),分別把x和y的地址賦給形參a和b,所以實(shí)際互換的是主函數(shù)中x和y的值;xk4函數(shù)用于直接互換a和b的值,由于a和b都是引用參數(shù),所以在主函數(shù)使用xk4(x,y)調(diào)用時(shí),執(zhí)行xk4函數(shù)實(shí)際互換的是相應(yīng)實(shí)參變量x和y的值此程序的運(yùn)營結(jié)果為:x=5y=l0x=10y=5x=5y=10上述的xk3和xk4具有完全相同的功能,但由于在xk3中使用的是指針參數(shù),傳送給它的實(shí)參也必須是對(duì)象的地址,在函數(shù)體中訪問指針?biāo)赶虻膶?duì)象必須進(jìn)行間接訪問運(yùn)算,所以,定義和調(diào)用xk3不如定義和調(diào)用xk4直觀和簡便。程序4:#inc1ude<iostream.h>constintN=8;intxk5(inta[],intn);voidmain(){intb[N]={1,7,2,6,4,5,3,-2);3intml=xk5(b,8);。intm2=xk5(&b[2],5);。intm3=xk5(b+3,3):cout?m1<<>'<<m2V<'>?m3<<end1;}intxk5(inta[],intn)(。inti,f=l;for(i=0;i<n;i++)f*=a[i];〃或?qū)懗蒮*=*a++;。returnf;)該函數(shù)包含一個(gè)主函數(shù)和一個(gè)xk5函數(shù),xk5函數(shù)的功能是求出一維整型數(shù)組a[n]中所有元素之積并返回。在主函數(shù)中第一次調(diào)用xk5函數(shù)時(shí),把數(shù)組b的首地址傳送給a,把數(shù)組b的長度8傳送給n,執(zhí)行函數(shù)體對(duì)數(shù)組a的操作事實(shí)上就是對(duì)主函數(shù)中數(shù)組b的操作,由于它們同時(shí)指向數(shù)組b的存儲(chǔ)空間;第二次調(diào)用xk5函數(shù)是把數(shù)組b中b[2]元素的地址傳送給a,把整數(shù)5傳送給n,執(zhí)行函數(shù)體對(duì)數(shù)組a[n]的操作事實(shí)上是對(duì)數(shù)組b中b[2]至b[6]之間元素的操作;第三次調(diào)用xk5函數(shù)是把數(shù)組b中b[3]元素的地址傳送給a,把整數(shù)3傳送給n,執(zhí)行函數(shù)體對(duì)數(shù)組a[n]的操作事實(shí)上是對(duì)數(shù)組b中b[3]至b[5]之間元素的操作。該程序的運(yùn)營結(jié)果為:-10080720120程序5:#inc1ude<iostream.H>char*xk6(char*sp,char*dp);voidmain()(。chara[15]="abcadecaxybcw;3charb[15];。char*cl=xk6(a,b);ocout<<c1<<Z>?a<<,><<b<<endl;char*c2=xk6(a+4,b);cout〈Vcl<V'1<<a<<**?b<<end1;)char*xk6(char*sp,char*dp)(。if(*sp=='\0'){*dp=,\O,;returndp;}°inti=0,j;for(char*p=sp;*p;p++){//掃描sp所指字符串中的每個(gè)字符位置3°for(j=0;j<i;j++)if(*p==dp[j])break;〃當(dāng)*p與dp[0]至dp[i-1]之間的o//任一元素相同則比較過程結(jié)束°if(j>=i)dp[i++]=*p;//若dp數(shù)組的前i個(gè)元素均不等于*p,則把*P寫入dp[i]元素中)dp[i]=\0*;〃寫入字符串結(jié)束符returndp;}xk6函數(shù)的功能是把sp所指向的字符串,去掉反復(fù)字符后拷貝到dp所指向的字符數(shù)組中,并返|可dp指針。在主函數(shù)中第一次調(diào)用xk6函數(shù)時(shí),分別以a和b作為實(shí)參,第二次調(diào)用時(shí)分別以a+4(艮*⑷的地址)和b作為實(shí)參。該程序運(yùn)營后的輸出結(jié)果為:abcdexywabcadecaxybcwabcdexywdecaxybwabcadecaxybcwdecaxybw程序6:#include<iostream.H>int*xk7(int*&al,int*a2);int*xk7(intal,int*a2){。coutwhenenterxk7:*al,*a2=z*?*a1<<",^<<*a2<<endl;al=newint(2**al+4);oa2=newint(2**a2—1);。cout<<,,whenleavexk7:*al,*a2="V<*al<<",”<<*a2V<endl;returna2;)voidmain(){intx=10,y=25;int*xp=&x,*yp=&y;cout?wboforecallxk7:*xp,*yp="<V*xp<<”,,,<<*yp<<ondl;int*ip=xk7(xp,yp);cout<<?,aftercallxk7:*xp,*yp="<V*xpV<",”<<*ypV〈end1;cout〈V〃*ip=*<<*ip<<endl;deletexp;//xp指向的是在執(zhí)行xk7函數(shù)時(shí)動(dòng)態(tài)分派的對(duì)象*aldeleteip;〃ip指向的是在執(zhí)行xk7函數(shù)時(shí)動(dòng)態(tài)分派的對(duì)象*a2)在xk7函數(shù)的定義中,把形參al定義為整型指針的引用,把a(bǔ)2定義為整型指針,當(dāng)在主函數(shù)中運(yùn)用xk7(xp,yp)表達(dá)式調(diào)用該函數(shù)時(shí),al就成為xp的別名,訪問a1就等于訪問主函數(shù)中的xp,而a2同yp具有各自獨(dú)立的存儲(chǔ)空間,a2的初值為yp的值,在xk7函數(shù)中對(duì)a2的訪問(指直接訪問)與yp無關(guān)。此程序運(yùn)營結(jié)果為:boforecallxk7:*xp,*yp=10,25whenenterxk7:*al,*a2=10,25whenleavexk7:*al,*a2=24,49aftercallxk7:*xp,*yp=24,25*ip=49三、變量的作用域在一個(gè)C++程序中,對(duì)于每個(gè)變量必須遵循先定義后使用的原則。根據(jù)變量定義的位置不同將使它具有不同的作用域。一個(gè)變量離開了它的作用域,在定義時(shí)為它分派的存儲(chǔ)空間就被系統(tǒng)自動(dòng)回收了,因此該變最也就不存在了。(一)作用域分類變量的作用域具有四種類別:全局作用域、文獻(xiàn)作用域、函數(shù)作用域和塊作用域。具有全局作用域的變量稱為全局變量,具有塊作用域的變量稱為局部變量。.全局作用域當(dāng)一個(gè)變量在一個(gè)程序文獻(xiàn)的所有函數(shù)定義之外(并且通常在所有函數(shù)定義之前)定義時(shí),則該變量具有全局作用域,即該變量在整個(gè)程序涉及的所有文獻(xiàn)中都有效,都是可見的,都是可以訪問的。當(dāng)一個(gè)全局變量不是在本程序文獻(xiàn)中定義時(shí),若要在本程序文獻(xiàn)中使用,則必須在本文獻(xiàn)開始進(jìn)行聲明,聲明格式為:extern〈類型名〉〈變量名〉,<變量名>,...;它與變量定義語句格式類似,其區(qū)別是:不能對(duì)變量進(jìn)行初始化,并且要在整個(gè)語句前加上extern保存字。當(dāng)用戶定義?個(gè)全局變量時(shí),若沒有對(duì)其初始化,則編譯時(shí)會(huì)自動(dòng)把它初始化為0。.文獻(xiàn)作用域當(dāng)一個(gè)變量定義語句出現(xiàn)在一個(gè)程序文獻(xiàn)中的所有函數(shù)定義之外,并且該語句前帶有static保存字時(shí),則該語句定義的所有變量都具有文獻(xiàn)作用域,,即在整個(gè)程序文獻(xiàn)中有效,但在其他文獻(xiàn)中是無效的,不可見的。若在定義文獻(xiàn)作用域變量時(shí)沒有初始化,則編譯時(shí)會(huì)自動(dòng)把它初始化為0。.函數(shù)作用域在每個(gè)函數(shù)中使用的語句標(biāo)號(hào)具有函數(shù)作用域,即它在本函數(shù)中有效,供本函數(shù)中的gol。語句跳轉(zhuǎn)使用。由于語句標(biāo)號(hào)不是變量,應(yīng)當(dāng)說函數(shù)作用域不屬于變量的一種作用域。4,塊作用域當(dāng)一個(gè)變量是在一個(gè)函數(shù)體內(nèi)定義時(shí);則稱它具有塊作用域,其作用域范圍是從定義點(diǎn)開始,直到該塊結(jié)束(即所在復(fù)合語句的右花括號(hào))為止。具有塊作用域的變量稱為局部變量,若局部變量沒有被初始化,則系統(tǒng)也不會(huì)對(duì)它初始化,它的初值是不擬定的。對(duì)于在函數(shù)體中使用的變量定義語句,若在其前面加上static保存字,則稱所定義的變最為靜態(tài)局部變量,若靜態(tài)局部變量沒有被初始化,則編譯時(shí)會(huì)被自動(dòng)初始化為00對(duì)于非靜態(tài)局部變量,每次執(zhí)行到它的定義語句時(shí),都會(huì)為它分派相應(yīng)的存儲(chǔ)空間,并對(duì)帶初值表達(dá)式的變量進(jìn)行初始化;而對(duì)于靜態(tài)局部變量,只是在整個(gè)程序執(zhí)行過程中第一次執(zhí)行到它的定義語句時(shí)為其分派相應(yīng)的存儲(chǔ)空間,并進(jìn)行初始化,以后再執(zhí)行到它時(shí)什么都不會(huì)做,相稱于第一次執(zhí)行后就刪除了該語句?!春瘮?shù)體》是一條復(fù)合語句,它以左花括號(hào)開始,到右花括號(hào)結(jié)束,中間為一條或若干條C++語句。在一個(gè)函數(shù)的參數(shù)表中,每個(gè)參數(shù)可認(rèn)為任一種數(shù)據(jù)類型,涉及普通類型、指針類型、數(shù)組類型、引用類型等,一個(gè)函數(shù)的返回值可以是除數(shù)組類型之外的任何類型,涉及普通類型、指針類型和引用類型等。此外,當(dāng)不需要返回值時(shí),應(yīng)把函數(shù)定義為void類型。(二)定義格式舉例(1)voidfl(){...}(2)voidf2(intx)}intf3(intx,int*p){...}char*f4(chara[])(...)(5)intf5(int&x,doubled){...}int&f6(intb[10],intn)(...)voidf7(f1oatc[][N],intm,float&max)}boolf8(ElemType*&bt,E1emType&item){...}在第一條函數(shù)定義中,函數(shù)名為門,函數(shù)類型為void,參數(shù)表為空,此函數(shù)是一個(gè)無參無類型函數(shù)。若在fl后面的圓括號(hào)內(nèi)寫入保存字void,也表達(dá)為無參函數(shù)。在第二條函數(shù)定義中,僅帶有一個(gè)類型為int的形參變量x,該函數(shù)沒有返回值。在第三條函數(shù)定義中,函數(shù)名為f3,函數(shù)類型為int,函數(shù)參數(shù)為x和p,其中x為int型普通參數(shù),p為int*型指針參數(shù)。在第四條函數(shù)定義中,函數(shù)名為f4,函數(shù)類型為char*,即字符指針類型,參數(shù)表中包含一個(gè)一維字符數(shù)組參數(shù)。注意:在定義任何類型的一維數(shù)組參數(shù)時(shí),不需要給出維的尺寸,當(dāng)然給出也是允許的,但沒有任何意義。在第五條函數(shù)定義中,函數(shù)名為「5,返回類型為int,該函數(shù)帶有兩個(gè)形參,一個(gè)為整型引用變量x,另一個(gè)為雙精度變量d。在第六條函數(shù)定義中,函數(shù)名為f6,函數(shù)類型為int&,即整型引用,該函數(shù)帶有兩個(gè)形參,一個(gè)是整型數(shù)組b,另一個(gè)是整型變量n。在這里定義形參數(shù)組b所給出的維的尺任一函數(shù)定義中的每個(gè)形參也具有塊作用域,這個(gè)塊是作為函數(shù)體的復(fù)合語句,當(dāng)離開函數(shù)體后它就不存在了,函數(shù)調(diào)用時(shí)為它分派的存儲(chǔ)空間也就被系統(tǒng)自動(dòng)回收了,當(dāng)然引用參數(shù)相應(yīng)的存儲(chǔ)空間不會(huì)被回收。由于每個(gè)形參具有塊作用域,所以它也是局部變量。在C++程序中定義的符號(hào)常量也同變量同樣具有全局、文獻(xiàn)和局部這三種作用域。當(dāng)符號(hào)常量定義語句出現(xiàn)在所有函數(shù)定義之外,并且在前面帶有extern保存字時(shí),則所定義的常量具有全局作用域,若在前面帶有static關(guān)鍵字或什么都沒有,則所定義的常量具有文獻(xiàn)作用域。若符號(hào)常量定義語句出現(xiàn)在?個(gè)函數(shù)體內(nèi),則定義的符號(hào)常量具有局部作用域。一個(gè)C++程序中的所有函數(shù)的函數(shù)名都具有全局作用域,所以在程序中所含的任何文獻(xiàn)內(nèi)都可以使用任一函數(shù)名構(gòu)成函數(shù)調(diào)用表達(dá)式,執(zhí)行相應(yīng)的函數(shù)。具有同一作用域的任何標(biāo)記符,不管它表達(dá)什么對(duì)象(如常量、變量、函數(shù)、類型等)都不允許重名,若重名系統(tǒng)就無法唯一擬定它的含義九由于每一個(gè)復(fù)合語句就是一個(gè)塊,所以在不同復(fù)合語句中定義的對(duì)象具有不同的塊作用域,也稱為具有不同的作用域,其對(duì)象名允許重名,由于系統(tǒng)可以區(qū)分它們。(二)程序舉例程序7:程序主文獻(xiàn)7.cpp#inc1ude<iostream.h>intxk8(intn);//函數(shù)xk8的原型聲明intxk9(intn);〃函數(shù)xk9的原型聲明intAA=5;//定義全局變量AAexternconstintBB=8;〃定義全局常量BBstaticintCC=12;//定義文獻(xiàn)域變量CCconstintl)D=23;〃定義文獻(xiàn)域常量D[)voidmain()intx=15;〃x的作用域?yàn)橹骱瘮?shù)體cout?"x*x="?xk8(x)?endl;cout<<*mainFi1e:AA,BB=//<<AA<<,,'<<BB?end1;cout<<"mainFi1e:CC,DD="?CC<<’,'<<DIK<end1;cout<<xk9(16)<<endl;)intxk9(intn)//n的作用域?yàn)閤k9函數(shù)體{intx=10://x的作用域?yàn)閤k9函數(shù)體cout?"Xk9:x="?X?end1;returnn*x;}程序次文獻(xiàn)7T.cpp#inc1ude<iostrearn.h>intxk8(intn);〃函數(shù)xk8的原型聲明externintAA;//全局變量AA的聲明externconstintBB;〃全局常量BB的聲明staticintCC=120;〃定義文獻(xiàn)域變量CCconstintDD=230;//定義文獻(xiàn)域常量DDintxk8(intn)//n的作用域?yàn)閤k8函數(shù)體(cout??,attachFile:AA,BB="<<AA?*,*?BB?end1;cout?"attachFile:CC,DD=〃V<CC<V','<VDD<Vend1;returnn*n;此程序包含兩個(gè)程序文獻(xiàn),定義有各種類型的變量和常量,其中AA為全局變量,BB為全局常量,CC為各自的文獻(xiàn)域變量,DD為各自的文獻(xiàn)域常量,主函數(shù)中的x為作用于主函數(shù)的局部變量,xk9函數(shù)中的x為作用于該函數(shù)的局部變量,xk8和xk9函數(shù)的各自參數(shù)表中的形參n是作用于各自函數(shù)的局部變量。為了在程序次文獻(xiàn)77.cpP中可以使用程序主文獻(xiàn)7.cpp中定義的全局變量AA和全局常量BB,必須在該文獻(xiàn)開始對(duì)他們進(jìn)行聲明。當(dāng)上機(jī)輸入和運(yùn)營該程序時(shí)\可以先建立程序主文獻(xiàn)d6-7.cpp并編譯通過,再建立程序次文獻(xiàn)7—1.cpp并編譯通過,然后把它們連接起來生成可執(zhí)行文獻(xiàn)7.exe。該程序的運(yùn)營結(jié)果為:attachFile:AA,BB=5,8attachFi1e:CC,DD=120,230x*x=225mainFi1e:AA,BB=5,8mainFile:CC,DD=12,23xk9:x=10160請(qǐng)讀者結(jié)合上述程序分析結(jié)果的對(duì)的性。程序8:#inc1ude<iostream.h>constintN=10;voidmain()(inta[N]={3,8,12,20,15,6,7,24,8,19};for(inti=0;iVN/2;i++){o?intx=a[i];a[i]=a[N-i-1];a[N-i-1]=x,for(i=0;i<N;i++)cout<<a[i]?z';cout<<endl;)在這個(gè)程序中,N為文獻(xiàn)域常量,a和i分別為主函數(shù)體復(fù)合語句塊內(nèi)的局部數(shù)組和變量,它們的作用域從定義點(diǎn)開始到主函數(shù)結(jié)束,x為for循環(huán)體復(fù)合語句塊內(nèi)的局部變量,它的作用域從定義點(diǎn)開始到for循環(huán)體結(jié)束。在主函數(shù)中,一方面定義了一維整型數(shù)組a[N],接著運(yùn)用for循環(huán)互換數(shù)組a中前后對(duì)稱元素的值,使得a中的每個(gè)元素值按原有位置的逆序排列,然后依次輸出a中每個(gè)元素值。該程序運(yùn)營結(jié)果為:198247615201283程序9:#include<iostream.h>voidinput0;voidoutput();intsumSquare(intb[],intn);constintnn=5;〃定義文獻(xiàn)域常量nninta[nn];〃定義全局域數(shù)組a[nn]voidmain()(,input();。output();。cout?sumSquare(a,nn)?endl;〃使用數(shù)組a和常量nn作為實(shí)參voidinput()>cout<〈”為數(shù)組a輸入"VVnn<<”個(gè)整數(shù):*?end1;。for(inti=0;i<nn;i++)cin?a[i];//i是本函數(shù)的局部變量)voidoutput()(cout?"輸出數(shù)組a中的"V<nnV<"個(gè)元素值:〃<<end1;for(inti=0;i<nn;i++)cout<<a[i]<<*';//i是本函數(shù)的局部變最。cout?end1;}intsumSquare(intb[],intn)〃b將指向相應(yīng)的實(shí)參數(shù)組a,//形參指針b和形參n是本函數(shù)中的局部變量(//求數(shù)組a中n個(gè)元素之和的平方。ints=0,i;//s和i是本函數(shù)的局部變量。for(i=0;i<n;i++)s+=b[i];rcturns*s;)該程序包含一個(gè)主函數(shù)和三個(gè)一般函數(shù),主函數(shù)依次調(diào)用這三個(gè)函數(shù)。Input函數(shù)從鍵盤上向數(shù)組a[nn]輸入數(shù)據(jù),output函數(shù)依次輸出數(shù)組a[nn]中每個(gè)元素的值,sumSquarc函數(shù)求出數(shù)組b中n個(gè)元素值之和的平方。由于調(diào)用sumSquare函數(shù)是把實(shí)參數(shù)組a和常量nn分別傳送給形參數(shù)組b和形參變量n,所以在函數(shù)體中對(duì)數(shù)組b[n]的操作事實(shí)上是對(duì)實(shí)參數(shù)組a[nn]的操作。在本程序中,nn為文獻(xiàn)域常量,a[nn]為全局域數(shù)組,所以,它們可以使用在該程序中的任何地方,即在任何地方都是可見的。假定程序運(yùn)營時(shí)從鍵盤上輸入的5個(gè)整數(shù)為:1,2,3,4,5,則得到的運(yùn)營結(jié)果為:為數(shù)組a輸入5個(gè)整數(shù):12345輸出數(shù)組a中的5個(gè)元素值:12345225程序10:#inc1udc<iostrcam.h>intx=l0;voidmain(){inty=20;cout<<〃x,y=*<<x?,,1<<y<<end1;(。intx=30;…y=y+x;cout<<,zx,y=*?x<<*,><<y<<end1;}cout?"x,y=//?x?,/?y?end1;)在函數(shù)體外定義的x為全局變量,在主函數(shù)體中定義的y為作用于整個(gè)函數(shù)體的局部變量,在主函數(shù)體中的一條復(fù)合語句中又定義了一個(gè)變量x,它的作用域只局限于該復(fù)合語句內(nèi),離開了該復(fù)合語句它就不存在了。在C++中,當(dāng)一個(gè)作用域包含另一個(gè)作用域時(shí),則在里層作用域內(nèi)可以定義與外層作用域同名的對(duì)象,此時(shí)在外層定義的同名對(duì)象,在內(nèi)層將被重:新定義的同名對(duì)象屏蔽掉,使之變?yōu)椴豢梢?。如在此程序主函?shù)體中的一條復(fù)合語句內(nèi),由于重新定義了變量X,所以全局變量X在此復(fù)合語句內(nèi)暫時(shí)被屏蔽掉,當(dāng)離開這條復(fù)合語句后,全局變量X為有效。此程序運(yùn)營結(jié)果如下:x,y=10,20x,y=30,50x,y=10,50提醒:若要在函數(shù)體內(nèi)訪問與局部變量同名的全局域或文獻(xiàn)域變量,則只要在該變量名前加上作用域區(qū)分符(::)即可。如::x使用在上述主函數(shù)中定義有x的復(fù)合語句內(nèi)時(shí),則就表達(dá)全局變最x,若不加作用域區(qū)分符則表達(dá)在當(dāng)前作用域內(nèi)定義的變量x。程序11:ttinclude<iostrcam.h>intxklO(intm,intn)//求出m和n的最大公約數(shù)(intr=m%n:while(r!=0){。m=n;。n=r;r=m%n;0)。returnn;}voidmain()intm,n;。do{cout<<end1;。cout<<〃輸入兩個(gè)整數(shù)求其最大公約數(shù)(若任一數(shù)<=0則結(jié)束):“;cin>>m>>n:°if(m<=0||n<=0)break;〃輸入的任一數(shù)小于等于0則結(jié)束循環(huán)?。coutXVm<V"和VnV〈”的最大公約數(shù)為:"V<xklO(m,n)〈<endl;。}while(1);)在這個(gè)程序中,主函數(shù)和xklO函數(shù)中都定義有m和n這兩個(gè)整數(shù)變量,并且主函數(shù)調(diào)用xklO是通過值傳送進(jìn)行的,所以主函數(shù)中的m和n與xk10函數(shù)中的m和分別占用各自的存儲(chǔ)空間,分別具有各自的作用域,一個(gè)函數(shù)中的m和n值的變化與另一個(gè)函數(shù)中的m和n無關(guān)。假定需要依次求出(75,15),(36,90),(74,25),(350,48)等四組整數(shù)的最大公約數(shù),則程序運(yùn)營結(jié)果如下:輸入兩個(gè)整數(shù)求其最大公約數(shù)(若任一數(shù)70則結(jié)束):751575和15的最大公約數(shù)為:15輸入兩個(gè)整數(shù)求其最大公約數(shù)(若任?數(shù)<=0則結(jié)束):369036和90的最大公約數(shù)為:18輸入兩個(gè)整數(shù)求其最大公約數(shù)(若任一數(shù)<=0則結(jié)束):742574和25的最大公約數(shù)為:1輸入兩個(gè)整數(shù)求其最大公約數(shù)(若任一數(shù)<=0則結(jié)束):35048350和48的最大公約數(shù)為:2輸入兩個(gè)整數(shù)求其最大公約數(shù)(若任一數(shù)<=0則結(jié)束):00程序12:#inc1ude<iostream.h>voidxk11(int&x,inty);voidmainO(aintx=12,y=25;。xk11(x,y);cout<<*main1:x,y="<<x?**<<y?endl;。xk11(y,x);,cout?"inain2:x,y=/z?x<<*J?y<<end1;。xk11(x,x+y):,coutin3:x,y=,,<<x?,'<<y<<end1;)voidxk11(int&x,inty)(ox=x+2;y=x+y;。cout<<"xkll:x,y=*<<x<<,1<<y<<endl:)在xkll函數(shù)中,說明x為引用參數(shù),y為非引用參數(shù),在主函數(shù)中也定義X和y變量,每次運(yùn)用不同的實(shí)參調(diào)用xkll函數(shù),并通過輸出語句顯示出x和y的值,讀者可以借此分析不同的參數(shù)傳遞方式對(duì)不同作用域內(nèi)變量的影響作用。該程序運(yùn)營結(jié)果為:xkll:x,y=1439mainl:x,y=l425xkll:x,y=2741main2:x,y=1427xkll:x,y=1657main3:x,y=1627程序13:#include<iostream.h>voidxk12();voidmain()(for(inti=0;i<5;i++)xk12();)voidxkl2()(inta=0;〃a若不被初始化,則初值是未知的a++;staticintb=0;//b若不被初始化,也將被自動(dòng)賦初值0b++;cout?"a="?a<</,,b=z,<<b<<endl;}在該程序的xkl2函數(shù)中定義有局部變量a和靜態(tài)局部變量b,主函數(shù)5次調(diào)用這個(gè)函數(shù),每次調(diào)用都將為a分派存儲(chǔ)空間并被初始化為0,但只有第一次調(diào)用才使為b分派存儲(chǔ)空間并初始化為0,其余4次調(diào)用都不會(huì)再建立b并初始化,將始終訪問第一次建立的b,也就是說,靜態(tài)局部變量同全局變量和文獻(xiàn)域變量同樣,一經(jīng)建立和初始化后將在整個(gè)程序運(yùn)營過程中始終存在,只有當(dāng)程序運(yùn)營結(jié)束時(shí)系統(tǒng)才收回分派給它的存儲(chǔ)空間。該程序的運(yùn)營結(jié)果為:a=l,b=la=l,b=2a=l,b=3寸10可以被省略。在第七條函數(shù)定義中,函數(shù)名為f7,無函數(shù)類型,參數(shù)表中包含三個(gè)參數(shù),一個(gè)為二維單精度型數(shù)組c,第二個(gè)為整型變量m,第三個(gè)為單精度引用變量max。注意:當(dāng)定義一個(gè)二維數(shù)組參數(shù)時(shí),第二維的尺寸必須給出,并且必須是一個(gè)常量表達(dá)式,第一維尺寸可給出也可不給出,其作用相同。在第八條函數(shù)定義中,函數(shù)名為f8,返【可類型為bo。1,即邏輯類型,該函數(shù)帶有兩個(gè)參數(shù),一個(gè)為形參bt,它為ElemType的指針引用類型,另一個(gè)為形參item,它是ElemType的引用類型,其中ElemType為一種用戶定義的類型或是通過typedef語句定義的一個(gè)類型的別名。(三)有關(guān)函數(shù)定義的幾點(diǎn)說明.函數(shù)原型語句在一個(gè)函數(shù)定義中,函數(shù)體之前的所有部分稱為函數(shù)頭,它給出了該函數(shù)的返回類型、每個(gè)參數(shù)的順序和類型等函數(shù)原型信息,所以當(dāng)沒有專門給出函數(shù)原型說明語句時(shí),系統(tǒng)就從函數(shù)頭中獲取函數(shù)原型信息。一個(gè)函數(shù)必須先定義或聲明而后才干被調(diào)用,否則編譯程序無法判斷該調(diào)用的對(duì)的性。?個(gè)函數(shù)的聲明是通過使用?條函數(shù)原型語句實(shí)現(xiàn)的,當(dāng)然使用多條相同的原型語句聲明同一個(gè)函數(shù)雖然多余但也是允許的,編譯時(shí)不會(huì)出現(xiàn)錯(cuò)誤。在?個(gè)完整的程序中,函數(shù)的定義和函數(shù)的調(diào)用可以在同一個(gè)程序文獻(xiàn)中,也可以處在不同的程序文獻(xiàn)中,但必須保證函數(shù)原型語句與函數(shù)調(diào)用表達(dá)式出現(xiàn)在同一個(gè)文獻(xiàn)中,并且函數(shù)原型語句出現(xiàn)在前,函數(shù)的調(diào)用出現(xiàn)在后。通常把一個(gè)程序中用戶定義的所有函數(shù)的原型語句組織在一起,構(gòu)成一個(gè)頭文獻(xiàn),讓該程序中所含的每個(gè)程序文獻(xiàn)的開始(即所有函數(shù)定義之前)包含這個(gè)頭文獻(xiàn)(通過#inelude命令實(shí)現(xiàn)),這樣不管每個(gè)函數(shù)的定義在哪里出現(xiàn),都可以保證函數(shù)先聲明后使用(即調(diào)用)這一原則的實(shí)現(xiàn)。?個(gè)函數(shù)的原型語句就是其函數(shù)頭的?個(gè)拷貝,當(dāng)然要在最后加上語句接上結(jié)束符分號(hào)。函數(shù)原型語句與函數(shù)頭也有細(xì)微的差別,在函數(shù)原型語句中,其參數(shù)表中的每個(gè)參數(shù)允許a=l,b=4a=1,b=5總之,對(duì)于全局變量、文獻(xiàn)域變量、加入static保存字定義的局部變量、運(yùn)用new運(yùn)算符動(dòng)態(tài)分派的對(duì)象,它們的生存期(即所占用存儲(chǔ)空間的連續(xù)時(shí)間)從定義點(diǎn)開始直到整個(gè)程序執(zhí)行結(jié)束;對(duì)于在任何函數(shù)體中定義的局部變量和值參(即非引用參數(shù)),它們的生存期從定義點(diǎn)開始到所在的復(fù)合語句塊結(jié)束。四、遞歸函數(shù)在C++語言程序中,主函數(shù)可以調(diào)用其他任何函數(shù),任一函數(shù)又可以調(diào)用除主函數(shù)之外的任何函數(shù)。特別地,一個(gè)函數(shù)還可以直接或間接地調(diào)用它自己,這種情況稱為直接或間接遞歸調(diào)用。直接遞歸是指在一個(gè)函數(shù)體中使用調(diào)用本函數(shù)的函數(shù)調(diào)用表達(dá)式,間接遞歸是指在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù),而在另一個(gè)函數(shù)中又反過來調(diào)用這個(gè)函數(shù)。這里只簡要討論一下直接遞歸調(diào)用的情況。若一個(gè)問題的求解可以化為較小問題的求解,而較小問題的求解又可化為更小問題的求解,依次類推,這種有規(guī)律地將原問題逐漸化小的過程,并且求解小問題的方法與求解大問題的方法相同,則稱為遞歸求解過程。由于在遞歸過程中,求解的問題越化越小,最后必然可.以得到一個(gè)最小問題的解,它不需要再向下遞歸求解,得到了這個(gè)最小問題的解后,再逐層向上返回,依次得到較大問題的解,最終必將得到原有問題的解。例1:運(yùn)用遞歸方法求解一維數(shù)組a[n]中n個(gè)元素之和。分析?:把求解數(shù)組a中n個(gè)元素之和看作為求解數(shù)組a中n—1個(gè)元素之和,把這個(gè)和與元素a[n-1]相加就得到了原問題的解,再把求解數(shù)組a中n-1個(gè)元素之和看作為求解數(shù)組a中n-2個(gè)元素之和,把這個(gè)和與元素a[n—2]相加就得到了上一層問題的解,依次類型,直到求解數(shù)組a中1個(gè)元素之和時(shí)可直接得到a[0],從此接上逐層向下遞歸的過程,接著逐層向上返回,第一次返回可由一個(gè)元素之和得到兩個(gè)元素之和,第二次返回再由二個(gè)元素之和得到三個(gè)元素之和,依次類推,直到第n-1次返回后根據(jù)返回值(即數(shù)組a中前n-1個(gè)元素之和)加上元素的值再返【可就結(jié)束了整個(gè)遞歸求解過程。采用遞歸方法編寫的計(jì)算函數(shù)稱為遞歸函數(shù)。假定a[n]數(shù)組的元素類型為int,則求解數(shù)組a中n個(gè)元素之和的遞歸函數(shù)為:intfun1(inta[],intn){if(n<0){?cerr?"參數(shù)n值非法!endl;exit(1);}。if(n==l)returna[0];§elsereturna[n-l]+funl(a,n-1);}在這個(gè)函數(shù)中,funl(a,n-1)為一個(gè)函數(shù)遞歸調(diào)用表達(dá)式,進(jìn)行遞歸調(diào)用和普通調(diào)用(即非遞歸調(diào)用)同樣,也通過參數(shù)傳遞、函數(shù)體執(zhí)行和結(jié)束返回這三個(gè)環(huán)節(jié)。在這個(gè)函數(shù)中,共需要進(jìn)行n-1次遞歸調(diào)用,每次都要把實(shí)參a的值賦給本次遞歸調(diào)用為形參a分派的存儲(chǔ)空間中,把實(shí)參n-1的值賦給本次遞歸調(diào)用為形參n分派的存儲(chǔ)空間中,接著執(zhí)行函數(shù)體,若當(dāng)前n的值等于1,則結(jié)束本次的遞歸調(diào)用,直接返回a[0]的值,并使程序執(zhí)行返回到進(jìn)行本次遞歸調(diào)用的return語句中,接著計(jì)算出a[nT]與返回值之和,然后又向上層的調(diào)用返回,依次類推;若當(dāng)前n的值大于1,則執(zhí)行else后面的return語句,接著再向下進(jìn)行遞歸調(diào)用。下面是計(jì)算一維數(shù)組b[n]中n個(gè)元素之和的完整程序。#include<iostream.h>#include<stdlib.h>intfun1(inta[],intn);voidmain()intb[8]={5,16,7,9,20,13,18,6);3ints=funl(b,8);ocout?s?endl;)intfun1(inta[],intn)(if(n<0){ocerrV<"參數(shù)n值非法!"VVendl;oexit(l);}§if(n==l)returna[0];oelsereturna[n-l]+fun1(a,n-1):)主函數(shù)中運(yùn)用fun1(b,8)調(diào)用遞歸函數(shù)fun1稱為第0次遞歸調(diào)用,進(jìn)行本次調(diào)用時(shí)把數(shù)組b的首地址傳送給數(shù)組參數(shù)(又稱指針參數(shù))a,把常量8傳送給形參n,以便計(jì)算出數(shù)組b中前8個(gè)元素之和。當(dāng)函數(shù)funl被主函數(shù)調(diào)用的過程中,n的值將在各層遞歸調(diào)用時(shí)從8依次變化到1,if后面的return語句只在最后一次遞歸調(diào)用時(shí)被執(zhí)行并返回a[0]的值,其余每次遞歸調(diào)用都執(zhí)行eIse后面的return語句,依次返回前2個(gè)、3個(gè)8個(gè)元素的值。該函數(shù)的運(yùn)營結(jié)果,即s的值為94。例2.運(yùn)用遞歸方法求解n階乘(n!)的值。分析:設(shè)用函數(shù)f(n)表達(dá)n!,由數(shù)學(xué)知識(shí)可知,n階乘的遞歸定義為:它等于n乘以n-1的階乘,當(dāng)n等于0或1時(shí),函數(shù)值為1,用數(shù)學(xué)公式表達(dá)為:"1(n==0或1)Yf(n)='n*f(n-1)(n>l)在這里n等于0或1是遞歸終止的條件,得到的函數(shù)值為1,當(dāng)n大于1時(shí)需要向下遞歸先求出f(n-l)的值后,再乘以n才可以得到f(n)的值。計(jì)算f(n)的遞歸函數(shù)為:intf(intn)if(n==0||n==l)return1;3elsereturnn*f(n-1);)假定用f(5)去調(diào)用f(n)函數(shù),該函數(shù)返回5*f(4)的值,因返回表達(dá)式中包具有函數(shù)f(4)表達(dá)式,所以接著進(jìn)行遞歸調(diào)用,返回4*f(3)的值,依次類推,當(dāng)最后進(jìn)行「(1)遞歸調(diào)用,返回函數(shù)值1后,結(jié)束本次遞歸調(diào)用,返回到調(diào)用函數(shù)f(1)的位置,從而計(jì)算出2*f(l)的值2,即2*f(l)=2*l=2,作為調(diào)用函數(shù)f(2)的返回值,返回到3*f⑵表達(dá)式中,計(jì)算出值6作為f(3)函數(shù)的返回值,接著返回到4*f(3)表達(dá)式中,計(jì)算出值24作為f(4)函數(shù)的返回值,再接著返回到5火f(4)表達(dá)式中,計(jì)算出f(5)的返回值120,從而結(jié)束整個(gè)調(diào)用過程,返回到調(diào)用函數(shù)f(5)的位置繼續(xù)向下執(zhí)行。上述調(diào)用和返回過程可形象地用圖6—1表達(dá)。24f⑷式I八X-~[1~/I/\,、TOC\o"1-5"\h\z1~~^3*f(2)2I八IV[圖6—1運(yùn)用f(5)調(diào)用f(n)遞歸函數(shù)的執(zhí)行流程運(yùn)用上述計(jì)算n階乘的函數(shù),可以編寫出一個(gè)完整程序計(jì)算出組合數(shù)CJ,其中m和k均為正整數(shù),并且m2k。由數(shù)學(xué)知識(shí)可知,組合數(shù)CJ的含義是從m個(gè)互不相同的元素中每次取出k個(gè)不同元素所有不同取法的種數(shù)。C/也可寫成C(m,k),C/的計(jì)算公式為:不二加下面給出此題的完整程序,其中m和k的值由鍵盤輸入。#inc1ude<iostream.h>intf(intn);voidmain()(intm,k;cout式”求從m個(gè)互不相同的元素中每次取出k個(gè)元素的組合數(shù).“〈〈edl;。do{3coutV〈”輸入m和k的值:";cin>>m>>k;if(m>0&&k>0&&m>=k)break;。elsecout<V〃輸入數(shù)據(jù)不對(duì)的,重輸!“<<endl;}while(1);cout<<,,c("V<m<<','<<k<<〃)=";cout<<f1oat(f(m))/(f(k)*f(m-k))?endl;)intf(intn)(if(n==0||n==l)return1;eIscrcturnn*f(n—1);)假定規(guī)定出C(10,3)的值,則程序運(yùn)營結(jié)果如下:求從m個(gè)互不相同的元素中每次取出k個(gè)元素的組合數(shù).輸入m和k的值:103c(10,3)=120對(duì)于象上述那樣的遞歸函數(shù)都可以很方便地改寫為非遞歸函數(shù),求n階乘的非遞歸函數(shù)如下:intf(intn){ints=l;。for(inti=l;i<=n;i++)s*=i;rcturns;)求數(shù)組a[n]中n個(gè)元素之和的非遞歸函數(shù)為:intfun1(inta[],intn)(oif(n<0){ocerr<<"參數(shù)n值非法!"<<endl;◎exit(1);}ints=0;。for(inti=0:i<n;i++)s+=a[i];returns;}遞歸求解是一種非常重要的求解問題的方法,在計(jì)算機(jī)領(lǐng)域有著廣泛的用途。當(dāng)然為了說明問題,上面列舉的只是最簡樸的例子,它們還不如非遞歸函數(shù)來得簡樸和易讀。五、函數(shù)重載C++程序中的每個(gè)函數(shù)都是并列定義的,不允許在一個(gè)函數(shù)中定義另一個(gè)函數(shù),即只允許函數(shù)嵌套調(diào)用,不允許嵌套定義。每個(gè)函數(shù)的函數(shù)名都是全局量,按理說不應(yīng)當(dāng)重名,若重名就是反復(fù)定義錯(cuò)誤。但有一種情況例外,即當(dāng)且僅當(dāng)兩個(gè)函數(shù)的參數(shù)表不同時(shí),允許這兩個(gè)函數(shù)重名(即具有相同的名字),進(jìn)行函數(shù)調(diào)用時(shí),系統(tǒng)會(huì)根據(jù)函數(shù)名和參數(shù)表唯一擬定調(diào)用哪一個(gè)函數(shù)。當(dāng)兩個(gè)參數(shù)表中的任一個(gè)參數(shù)的類型相應(yīng)不同,或者兩參數(shù)表中的參數(shù)個(gè)數(shù)不同(帶有缺省值的參數(shù)不算在內(nèi)),則認(rèn)為這兩個(gè)參數(shù)表不同。這種具有相同函數(shù)名但具有不同參數(shù)表的函數(shù)稱為重載函數(shù),允許使用相同函數(shù)名定義多個(gè)函數(shù)的情況稱為函數(shù)重載。如:(1)voidf1(intx,charh,floatd=1){...}charfl(){...}〃與(1)參數(shù)個(gè)數(shù)不同voidfl(intx){...}〃與⑴參數(shù)個(gè)數(shù)不同voidf1(charch){...}〃與(1)參數(shù)類型和個(gè)數(shù)均不同voidfl(charch,intx)(〃與(1)參數(shù)類型不同voidf1(inta,charb,doublec){...)//與(1)參數(shù)類型不同intfl(inta,intb){...}//與(1)參數(shù)類型不同)doub1e*f1(doub1ea[],intn){...}〃與(1)參數(shù)類型不同voidfl(inta,charb){...}(10)voidfl(inta,charb,floatc){...)intf1(intx,chary){...}在這些函數(shù)中,前八個(gè)函數(shù)為重載函數(shù),由于它們的函數(shù)名相同,并且要么它們的參數(shù)個(gè)數(shù)不同,要么它們相應(yīng)參數(shù)的類型不同,要么這兩者均不同;第九個(gè)函數(shù)不是第一個(gè)函數(shù)的重載函數(shù),由于相應(yīng)的參數(shù)類型和個(gè)數(shù)均相同(不考慮帶有缺省值的參數(shù)),當(dāng)在函數(shù)調(diào)用表達(dá)式中省略最后一個(gè)實(shí)參時(shí),系統(tǒng)就無法唯一擬定調(diào)用哪一個(gè)函數(shù);第10個(gè)函數(shù)也不是第一個(gè)函數(shù)的重載函數(shù),由于相應(yīng)的參數(shù)類型和個(gè)數(shù)均相同,當(dāng)在函數(shù)調(diào)用表達(dá)式中不省略最后一個(gè)實(shí)參時(shí),系統(tǒng)也無法唯一擬定調(diào)用哪一個(gè)函數(shù);第11個(gè)函數(shù)也不是第一個(gè)函數(shù)的重載函數(shù),由于它只是返回類型不同,參數(shù)表中相應(yīng)的參數(shù)類型和個(gè)數(shù)均相同,返回類型不同不是判斷是否可以重載的條件。當(dāng)然參數(shù)名不同更不是判斷重栽的條件。下面程序就使用了兩個(gè)重載函數(shù),函數(shù)名為FindMax,一個(gè)函數(shù)的功能是求出一維整型數(shù)組a中n個(gè)元素的最大值,另一個(gè)函數(shù)的功能是求出二維字符數(shù)組a中保存的n個(gè)字符串的最大值,由于這兩個(gè)函數(shù)的功能相同,只是參數(shù)的類型和實(shí)現(xiàn)上有所不同,所以應(yīng)定義為重載函數(shù)。#include<iostream.h>#include<string.h>constintM=15;intFindMax(inta[],intn);char*FindMax(chara[][M],intn);voidmain()(inta[6]={45,28,59,43,72,36};3charb[6][M]={"qiushuhua","wangchunfong",Mningchen",。*zhaoyuanlin","gu1iang","shenyafen"};。intx=FindMax(a,6);ochar*cp=FindMax(b,6);。cout<<x<<*'<<cp<Vendl;)intFindMax(inta[],intn)(ntx=a[0];for(inti=l;i<n;i++)。if(a[i]>x)x=a[i];returnx;char*FindMax(chara[][M],intn)char*x=ci[O];for(inti=l;i<n;i++)。if(strcmp(a[i],x)>0)x=a[i];?returnx;}該程序的運(yùn)營結(jié)果為:72zhaoyuanlin六、函數(shù)模板對(duì)于普通函數(shù),所使用的每個(gè)對(duì)象的類型都是擬定的,如:intmax(intx,inty)(return(x>y?x:y);}該函數(shù)中每個(gè)參數(shù)的類型和函數(shù)返回類型均為整型。該函數(shù)的功能是返回兩個(gè)整型參數(shù)x和y中的最大值。若規(guī)定兩個(gè)雙精度數(shù)中的最大值則需要定義出如下函數(shù):doublemax(doublex,doub1ey)(。return(x>y?x:y);)它是上述函數(shù)的一個(gè)重載,當(dāng)函數(shù)調(diào)用表達(dá)式中的兩個(gè)參數(shù)均為ini型時(shí)則自動(dòng)調(diào)用第一個(gè)重載函數(shù),當(dāng)這兩個(gè)參數(shù)均為double型時(shí)則自動(dòng)調(diào)用第二個(gè)重載函數(shù)。若可以把功能相同只是類型不同的多個(gè)重載函數(shù)用一個(gè)函數(shù)來描述,將會(huì)給程序設(shè)計(jì)帶來極大的方面。在C++中可以通過定義函數(shù)模板來實(shí)現(xiàn)。每個(gè)函數(shù)模板中可以定義一個(gè)或若干個(gè)類型參數(shù),每個(gè)類型參數(shù)代表一種數(shù)據(jù)類型,該數(shù)據(jù)類型由進(jìn)行函數(shù)調(diào)用時(shí)決定,函數(shù)模板中可以運(yùn)用這些類型參數(shù)定義函數(shù)返回類型,參數(shù)類型和函數(shù)體中的變顯類型。函數(shù)模板的定義格式為:template<〈類型參數(shù)表>>〈返回類型〉〈函數(shù)名)(V函數(shù)形參表,){...)<類型參數(shù)表》中包含一個(gè)或多個(gè)用逗號(hào)分開的類型參數(shù)項(xiàng),每一項(xiàng)由保存字class開始,后根一個(gè)用戶命名的標(biāo)記符,此標(biāo)記符為類型參數(shù),表達(dá)一種數(shù)據(jù)類型,它可以同一般數(shù)據(jù)類型同樣使用在函數(shù)中的任何地方。〈函數(shù)形參表>必須至少給出一個(gè)參數(shù)說明,并且在〈類型參數(shù)表》中給出的每個(gè)類型參數(shù)都必須在〈函數(shù)形參表》中得到使用,即作為形參的類型使用。下面給出一些函數(shù)模板定義的例子。格式舉例1:template<classT>Tmax(Tx,Ty)(return(x>y?x:y);}此函數(shù)模板定義了T為?種類型參數(shù),用T作為函數(shù)的返回類型以及x和y參數(shù)的類型。該函數(shù)模板的功能是返回類型為T的x和y中的最大值。模板中T的具體類型由調(diào)用它的函數(shù)表達(dá)式?jīng)Q定。格式舉例2:template<classA,classB>voidff(Aa,Bb){ocout<<a?>J<<b<<endl;ocout<<sizeof(a)<<z>?sizeof(b)<<endl;)此函數(shù)模板定義了A和B兩個(gè)類型參數(shù),用A作為形參a的類型,用B作為形參b的類型。該函數(shù)模板的功能是顯示出a和b的值及相應(yīng)的類型長度。同樣,A和B的具體類型只保存參數(shù)類型,而省略參數(shù)名,并且若使用參數(shù)名也允許與函數(shù)頭中相應(yīng)的參數(shù)名不同。.常量形參在定義一個(gè)函數(shù)時(shí),若只允許函數(shù)體訪問一個(gè)形參的值,不允許修改它的值,則應(yīng)把該形參說明為常量,這只要在形參說明的前面加上const保存字進(jìn)行修飾即可。如:voidf9(constint&x,constchar&y);voidf10(constchar*p,charkey);在函數(shù)f9的函數(shù)體中只允許使用x和y的值,不允許修改它們的值。在函數(shù)f10的函數(shù)體中只允許使用p所指向的字符對(duì)象或字符數(shù)組對(duì)象的值,不允許修改它們的值,但在函數(shù)體中既允許使用也允許修改形參key的值。3.缺省參數(shù)在一個(gè)函數(shù)定義中,可根據(jù)需要對(duì)參數(shù)表末尾的一個(gè)或連續(xù)若干個(gè)參數(shù)給出缺省值,當(dāng)調(diào)用這個(gè)函數(shù)時(shí),若實(shí)參表中沒有給出相應(yīng)的實(shí)參,則形參將采用這個(gè)缺省值。如:voidfl1(intx,inty=0){...}intfl2(inta[],charop,intk=10){...}函數(shù)f】l的定義帶有兩個(gè)參數(shù),分別為整型變量x和y,并且y帶有缺省值(),若調(diào)用該函數(shù)的表達(dá)式為fl1(a,b),將把a(bǔ)的值賦給x,把b的值賦給y,接著執(zhí)行函數(shù)體:若調(diào)用該函數(shù)的表達(dá)式為fl1(a+b),則也是對(duì)的的調(diào)用格式,它將把a(bǔ)+b的值賦給x,因y沒有相應(yīng)的實(shí)參,將采用缺省值0,參數(shù)傳送后接著執(zhí)行函數(shù)體。函數(shù)f12的定義帶有三個(gè)參數(shù),其中后兩個(gè)帶有缺省值,所以調(diào)用它的函數(shù)格式有三種,一種只帶一個(gè)實(shí)參,用于向形參a傳送數(shù)據(jù),后兩個(gè)形參采用缺省值,第二種帶有兩個(gè)實(shí)參,用于分別向形參a和op傳送數(shù)據(jù),第三個(gè)形參采用缺省值,第三種帶有三個(gè)實(shí)參,分別用于傳送給三個(gè)形參。若一個(gè)函數(shù)帶有專門的函數(shù)原型語句,則形參的缺省值只能在該函數(shù)原型語句中給出,不允許在函數(shù)頭中給出。如對(duì)于上述的「11和fl2函數(shù),其相應(yīng)的函數(shù)原型語句分別為:voidfll(intx,inty=0);intf12(inta口,charop=>,intk=10);由調(diào)用它的函數(shù)表達(dá)式?jīng)Q定。格式舉例3:template<c1assType>voidinverse(Typea[],intn)(Typex;inti;for(i=0;i<n/2;i++){…x=a[i];。a[i]=a[n-i-1];a[n—i—1]=x;)}該函數(shù)模板定義了Type為一種類型參數(shù),用該類型定義形參數(shù)組a和函數(shù)體中的變量xo該模板的功能是使數(shù)組a中的n個(gè)元素的值按逆序排列。函數(shù)模板的原型語句也是由它的函數(shù)頭后加分號(hào)所組成。如上述三個(gè)函數(shù)模板的原型語句分別如下:template<c1assT>Tmax(Tx,Ty);template<classA,classB>voidff(Aa,Bb);temp1ate<classType>voidinverse(Typea[],intn);調(diào)用函數(shù)模板的表達(dá)式同調(diào)用一般函數(shù)的表達(dá)式的格式相同,由函數(shù)名和實(shí)參表所組成,如可以使用max(a,b)調(diào)用函數(shù)模板max,當(dāng)a和b均為int型時(shí),則自動(dòng)為類型參數(shù)T賦予int類型,當(dāng)a和b均為double型時(shí),則自動(dòng)為類型參數(shù)T賦予double類型??傊瘮?shù)模板中的每個(gè)類型參數(shù)將在調(diào)用時(shí)賦予具有該類型的形參所相應(yīng)的實(shí)參的類型。當(dāng)運(yùn)用一個(gè)函數(shù)調(diào)用表達(dá)式調(diào)用一個(gè)函數(shù)模板時(shí),系統(tǒng)一方面擬定類型參數(shù)所相應(yīng)的具體類型,并按該類型生成一個(gè)具體函數(shù),然后再調(diào)用這個(gè)具有擬定類型的具體函數(shù)。由函數(shù)模板在調(diào)用時(shí)生成的具體函數(shù),稱為模板函數(shù),它是函數(shù)模板的?個(gè)實(shí)例。如運(yùn)用max(a,b)調(diào)用函數(shù)模板max時(shí),假定a和b均為int型實(shí)參,則由系統(tǒng)自動(dòng)生成的模板函數(shù)為:intmax(intx,inty)。return(x>y?x:y);)若運(yùn)用inverseCb,10)調(diào)用相應(yīng)的函數(shù)模板,并假定實(shí)參數(shù)組b中的元素類型為doub1e,則由系統(tǒng)自動(dòng)生成的模板函數(shù)為:voidinverse(doublea口,intn)(doub1cx;inti;for(i=0;i<n/2;i++){。x=a[i];a[i]=a[n-i-1];,a[n-i-1]=x;}}在一個(gè)程序中,當(dāng)進(jìn)行函數(shù)調(diào)用時(shí)若存在相應(yīng)的一般函數(shù)(即非模板函數(shù)),則將優(yōu)先調(diào)用這個(gè)?般函數(shù),只有當(dāng)不存在相應(yīng)的?般函數(shù)時(shí),才會(huì)由相應(yīng)的函數(shù)模板生成模板函數(shù),然后調(diào)用之。如假定在一個(gè)程序中既存在max函數(shù)模板的定義,又存在如下的一個(gè)重載函數(shù)的定義:char*max(char*x,char*y){return(strcmp(x,y)>0)?x:y;)當(dāng)使用max(a,b)進(jìn)行函數(shù)調(diào)用時(shí),并假定a和b均為char*類型,則系統(tǒng)將優(yōu)先調(diào)用非模板的max函數(shù),而不會(huì)去調(diào)用由max函數(shù)模板生成的、類型為char*的模板函數(shù)。若沒有專門給出類型為字符指針的max函數(shù),將調(diào)用由函數(shù)模板生成的函數(shù),此時(shí)比較的只是兩個(gè)指針的值,而達(dá)不到比較兩個(gè)指針?biāo)缸址腍的,這種調(diào)用將是不對(duì)的的。因此,對(duì)于函數(shù)模板中特殊類型的解決,必須再給出相應(yīng)的一般函數(shù)的定義,該函數(shù)是帶有具體類型的函數(shù)模板的一個(gè)重載函數(shù)。在調(diào)用函數(shù)模板時(shí),類型參數(shù)是根據(jù)該類型的形參所相應(yīng)的實(shí)參的類型自動(dòng)擬定的,但也可以由用戶在函數(shù)調(diào)用表達(dá)式中顯式給出。即在函數(shù)名和實(shí)參表之間用一對(duì)尖括號(hào)把一種或若干個(gè)用逗號(hào)分開的實(shí)際類型括起來。如函數(shù)調(diào)用max<int>(a,b)將使max函數(shù)模板生成一個(gè)類型參數(shù)T為int的模板函數(shù),不管a和b的類型如何,都將會(huì)把它們的值轉(zhuǎn)換為整數(shù)后再傳送給相應(yīng)的整型參數(shù)x和y。下面給出一個(gè)使用函數(shù)模板的程序的例子,供讀者分析。#inc1ude<iomanip.h>#inc1ude<string.h>template<c1assTT>voidswop(TT&x,TT&y);voidswop(char*x,char*y);voidmain()(,inta1=20,a2=35;odoublebl=3.25,b2=-4.86;charcl=,a',c2='b';chardl[10]=Mabcdef”,d2[10]="ghijk";cout.setf(ios::left);〃使輸出的數(shù)據(jù)在顯示區(qū)域內(nèi)靠左顯示cout〈V”數(shù)據(jù)互換前:endl;couta1="VVsetw(10)?a1<<^a2="<<setw(10)?a2<<endl;cout?"bl="?setw(l0)?bl?"b2="<<setw(10)?b2?end1;cout?,,c1="<<setw(10)<<cl<<,zc2="<<set\v(10)<<c2<<endl;coutV<"d1=*<<setw(10)<<dlV<"d2="<<setw(10)<<d2<<endl;endl;endl;endl;endl;endl;endl;<endl;swop(a1,a2);swop(b1,b2);endl;<endl;swop(a1,a2);swop(b1,b2);swop(c1,c2);swop(d1,d2);cout?end1<<”數(shù)據(jù)互換后:*?endl;couta1="<Vsetw(10)<<al<<"a2=°<<setw(10)<<a2<<cout<</zbl=/,?sctw(10)?b1<<,,b2=,/?setw(10)<<b2?end1;cout?*c1=*?setw(l0)?c1?"c2=,,?setw(10)?c2式endl;cout<<"dl="<<setw(10)?dl<<"d2=*?setw(10)<<d2<template<classTT>voidswop(TT&x,TT&y)(TTw=x;x=y;y=\v;)voidswop(char*x,char*y)(intn=strlen(x);char*w=newchartn+1];strcpy(w,x);strcpy(x,y);strcpy(y,w);數(shù)據(jù)互換前:數(shù)據(jù)互換前:a1=20b1=3.25cl=ad1=abcdef數(shù)據(jù)互換后:a1=35bl=-4.86c1=bdl=ghijk該程序的運(yùn)營結(jié)果為:a2=35b2=-4.86c2=bd2=ghijka2=20b2=3.25c2=ad2=abcdef注:具體內(nèi)容請(qǐng)參考由清華大學(xué)出版社出版的、徐孝凱主編的《C++語言基礎(chǔ)教程》一書。函數(shù)定義應(yīng)分別改寫為:voidf11(intx,inty){...)intf12(inta[],charop,intk){...}.數(shù)組參數(shù)在函數(shù)定義中的每個(gè)數(shù)組參數(shù)事實(shí)上是指向元素類型的指針參數(shù)。對(duì)于一維數(shù)組參數(shù)說明:V數(shù)據(jù)類型》V數(shù)組名,口它與下面的指針參數(shù)說明完全等價(jià):〈數(shù)據(jù)類型〉水指針變量名)其中〈指針變顯名>就是數(shù)組參數(shù)說明中的〈數(shù)組名>。如對(duì)于f12函數(shù)定義中的數(shù)組參數(shù)說明inta口,等價(jià)于指針參數(shù)說明int*a。也就是說,數(shù)組參數(shù)說明中的數(shù)組名a是一個(gè)類型為int*的形參。注意:在變量定義語句中定義的數(shù)組,其數(shù)組名代表的是一個(gè)數(shù)組,它的值是指向第一個(gè)元素的指針常量,這與數(shù)組形參的含義有區(qū)別。對(duì)于二維數(shù)組參數(shù)說明:<數(shù)據(jù)類型><參數(shù)名>口卜第二維尺寸>]它與下面的指針參數(shù)說明完全等價(jià):〈數(shù)據(jù)類型〉(*<參數(shù)名>)[<第二維尺寸》]如對(duì)于f7函數(shù)定義中的二維數(shù)組參數(shù)說明f1oat等價(jià)于指針參數(shù)說明float(*c)[N]o.函數(shù)類型當(dāng)調(diào)用一個(gè)函數(shù)時(shí)就執(zhí)行一遍循環(huán)體,對(duì)于類型為非void的函數(shù),函數(shù)體中至少必須帶有一條return語句,并且每條return語句必須帶有一個(gè)表達(dá)式,當(dāng)執(zhí)行到任一條return語句時(shí),將計(jì)算出它的表達(dá)式的值,結(jié)束整個(gè)函數(shù)的調(diào)用過程,把這個(gè)值作為所求的函數(shù)值帶回到調(diào)用位置,參與相應(yīng)的運(yùn)算;對(duì)于類型為void的函數(shù),它不需要返回任何函數(shù)值,所以在函數(shù)體中既可以使用return語句,也可以不使用,對(duì)于使用的每條return語句不允許也不需要帶有表達(dá)式,當(dāng)執(zhí)行到任一條return語句時(shí),或執(zhí)行到函數(shù)體最后結(jié)束
位置時(shí),將結(jié)束函數(shù)的調(diào)用過程,返回到調(diào)用位置向下繼續(xù)執(zhí)行。.內(nèi)聯(lián)函數(shù)當(dāng)在一個(gè)函數(shù)的定義或聲明前加上關(guān)鍵字inline則就把該函數(shù)聲明為內(nèi)聯(lián)函數(shù)。計(jì)算機(jī)在執(zhí)行一般函數(shù)的調(diào)用時(shí),無論該函數(shù)多么簡樸或復(fù)雜,都要通過參數(shù)傳遞、執(zhí)行函數(shù)體和返回等操作。若把一個(gè)函數(shù)聲明為內(nèi)聯(lián)函數(shù)后,在程序編譯階段系統(tǒng)就有也許把所有調(diào)用該函數(shù)的地方都直接替換為該函數(shù)的執(zhí)行代碼,由此省去函數(shù)調(diào)用時(shí)的參數(shù)傳遞和返I可操作,從而加快整個(gè)程序的執(zhí)行速度。通??砂岩恍┫鄬?duì)簡樸的函數(shù)聲明為內(nèi)聯(lián)函數(shù),對(duì)于較復(fù)雜的函數(shù)則不應(yīng)聲明為內(nèi)聯(lián)函數(shù)。從用戶的角度看,調(diào)用內(nèi)聯(lián)函數(shù)和一般函數(shù)沒有任何區(qū)別。下面就是一個(gè)內(nèi)聯(lián)函數(shù)定義的例子,它返回形參值的立方。inlineintcube(intn)(returnn*n*n;}二、函數(shù)的調(diào)用(一)調(diào)用格式調(diào)用一個(gè)已定義或聲明的函數(shù)需要給出相應(yīng)的函數(shù)調(diào)用表達(dá)式,其格式為:<函數(shù)名)(口實(shí)參表〉])若調(diào)用的是一個(gè)無參函數(shù),或所有形
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 餐飲租賃合同范本
- 能源站施工協(xié)議
- 高層建筑自來水安裝合同
- 幼兒園專車定時(shí)接送合同
- 行紀(jì)合同范本指南制作教程
- 商標(biāo)糾紛保證金協(xié)議書
- 生態(tài)園化糞池施工合同
- 保險(xiǎn)服務(wù)辦公室租賃合同模板
- xx區(qū)分布式光伏項(xiàng)目可行性研究報(bào)告
- 辦公用品庫房管理招聘合同
- 力的合成與分解 說課課件-2024-2025學(xué)年高一上學(xué)期物理人教版(2019)必修第一冊(cè)
- 《風(fēng)車》第1課時(shí)(教案)蘇科版勞動(dòng)一年級(jí)上冊(cè)1
- 油浸式電力變壓器(電抗器)現(xiàn)場低頻加熱試驗(yàn)導(dǎo)則
- DL-T820.2-2019管道焊接接頭超聲波檢測(cè)技術(shù)規(guī)程第2部分:A型脈沖反射法
- 橋式、門式起重機(jī)安裝竣工試驗(yàn)報(bào)告書
- 勞務(wù)派遣突發(fā)事件應(yīng)急預(yù)案
- 大學(xué)生助農(nóng)直播創(chuàng)業(yè)計(jì)劃書
- GB/T 43912-2024鑄造機(jī)械再制造通用技術(shù)規(guī)范
- 2024政府采購評(píng)審專家考試題庫附含答案
- 《法理學(xué)》(第三版教材)形成性考核作業(yè)1234答案
- 某廠1000MW發(fā)電機(jī)測(cè)絕緣
評(píng)論
0/150
提交評(píng)論