C__帶默認值參數(shù)的函數(shù)說明 1.float area(float r=6.5); 指定r的默認值為6.5,如果在調用此函數(shù)時,確認r的值為6.5,則可以不必給出實參的值,如 area( ); //相當于area(6.5); 如果不想使形參取此默認值,則通過實參另行給出。如area(7.5); //形參得到的值為7.5,而不是6.5 這種方法比較靈活,可以簡化編程,提高運行效率。
2.如果有多個形參,可以使每個形參有一個默認值,也可以只對一部分形參指定默認值,另一部分形參不指定默認值。 如有一個求圓柱體體積的函數(shù),形參h代表圓柱體的高,r為圓柱體半徑。函數(shù)原型如下: float volume(float h,float r=12.5); //只對形參r指定默認值12.5 函數(shù)調用可以采用以下形式: volume(45.6); //相當于volume(45.6,12.5) volume(34.2,10.4) //h的值為34.2,r的值為10.4
3.實參與形參的結合是從左至右順序進行的。因此指定默認值的參數(shù)必須放在形參表列中的最右端,否則出錯。 例如: void f1(float a,int b=0,int c,char d=′a′); //不正確 void f2(float a,int c,int b=0, char d=′a′); //正確 如果調用上面的f2函數(shù),可以采取下面的形式: f2(3.5, 5, 3, ′x′) //形參的值全部從實參得到 f2(3.5, 5, 3) //最后一個形參的值取默認值′a′ f2(3.5, 5) //最后兩個形參的值取默認值,b=0,d=′a′ 可以看到,在調用有默認參數(shù)的函數(shù)時,實參的個數(shù)可以與形參的個數(shù)不同,實參未給定的,從形參的默認值得到值。利用這一特性,可以使函數(shù)的使用更加靈活。例如例4.7求2個數(shù)或3個數(shù)中的最大數(shù)。也可以不用重載函數(shù),而改用帶有默認參數(shù)的函數(shù)。 例4.8 求2個或3個正整數(shù)中的最大數(shù),用帶有默認參數(shù)的函數(shù)實現(xiàn)。 #include <iostream>
using namespace std; int max(int a, int b, int c=0);//函數(shù)聲明,形參c有默認值
int main( ) { int a,b,c; cin>>a>>b>>c; cout<<″max(a,b,c)=″<<max(a,b,c)<<endl; //輸出3個數(shù)中的最大者 cout<<″max(a,b)=″<<max(a,b)<<endl; //輸出2個數(shù)中的最大者 return 0; } int max(int a,int b,int c) //函數(shù)定義
{ if(b>a) a=b; if(c>a) a=c; return a; } 運行情況如下: 14 -56 135↙ max(a,b,c)=135 max(a,b)=14 在使用帶有默認參數(shù)的函數(shù)時有兩點要注意: (1) 如果函數(shù)的定義在函數(shù)調用之前,則應在函數(shù)定義中給出默認值。如果函數(shù)的定義在函數(shù)調用之后,則在函數(shù)調用之前需 要有函數(shù)聲明,此時必須在函數(shù)聲明中給出默認值,在函數(shù)定義時可以不給出默認值(如例4.8)。
(2) 一個函數(shù)不能既作為重載函數(shù),又作為有默認參數(shù)的函數(shù)。因為當調用函數(shù)時如果少寫一個參數(shù),系統(tǒng)無法判定是利用重載函數(shù) 還是利用默認參數(shù)的函數(shù),出現(xiàn)二義性,系統(tǒng)無法執(zhí)行。 (3) 在函數(shù)聲明和函數(shù)定義中,默認參數(shù)必須相同。這是錯的,因為定義時有實參,但是聲明的時候沒有實參的話那么定義的時候 的實參沒有用,等于沒有提供實參??!
C++__帶默認值參數(shù)的函數(shù)說明
我們可以賦予函數(shù)參數(shù)默認值。所謂默認值就是在調用時,可以不寫某些參數(shù)的值,編譯器會自動把默認值傳遞給調用語句中。默認值可以在聲明或定義中設置;也可在聲明或定義時都設置,都設置時要求默認值是相同的。 關于默認值要注意幾點: (1) .若在定義時而不是在聲明時置默認值,那么函數(shù)定義一定要在函數(shù)的調用之前。因為聲明時已經(jīng)給編譯器一個該函數(shù)的向導,所 以只在定義時設默認值時,編譯器只有檢查到定義時才知道函數(shù)使用了默認值。若先調用后定義,在調用時編譯器并不知道哪個 參數(shù)設了默認值。所以我們通常是將默認值的設置放在聲明中而不是定義中。 (2) .不能將實際值傳遞給引用類型的參數(shù)。可以將變量作引用類型參數(shù)的默認值,這時變量必須是已經(jīng)聲明且是全局變量。 聲明函數(shù)時,要將類或結構中定義 的靜態(tài)成員變量作為默認值,若該類或結構還未創(chuàng)建實例,那要在此靜態(tài)成員變量前加上作用 域操作符(::)。 若已聲明了類或結構的實例,則引用其成員變量作為函數(shù)參數(shù)的默認值,就要在變量前加上實例名和成員操作符(.)。 (3) .若給某一參數(shù)設置了默認值,那么在參數(shù)表中其后所有的參數(shù)都必須也設置默認值,否則,由于函數(shù)調用時可不列出已設置默認 值的參數(shù),編譯器無法判斷在調用時是否有參數(shù)遺漏。(實參和形參是從左向右結合的) (4) .在調用時,若給已經(jīng)設置默認值的參數(shù)傳遞實際值,既要取代默認值,則在參數(shù)表中被取代參數(shù)的左邊所定義的所有參數(shù),無論 是否有默認值,都必須傳遞實際參數(shù)。 這也是因為函數(shù)調用時可不列出已設置默認值的參數(shù)。假若被取代參數(shù)的左邊既有設置了默認值的參數(shù)也有未設置默認值的參 數(shù),若不對其左邊的所有參數(shù)傳遞實際參數(shù),編譯器也就無法分辨?zhèn)鬟f的這個取代值到底要傳遞給哪個參數(shù)。 例如有以下函數(shù)聲明: int FunctionOne(int x,int y=0,int z=0,int w=0); 我們要給z 傳遞整型值8,作如下調用: FunctionOne(8); 顯然,編譯器無法確定這個8 到底要傳遞給哪個參數(shù)。為了達到我們的目的,必須這樣調用: FunctionOne(0,0,8); 這是x 被傳遞了0,y 被傳遞了 0,z 被傳遞了8 ******************************************************************************************* 第九節(jié) 默認參數(shù)的函數(shù)
1.默認參數(shù)的目的 C++可以給函數(shù)定義默認參數(shù)值。通常,調用函數(shù)時,要為函數(shù)的每個參數(shù)給定對應的實參。例如: void delay(int loops); //函數(shù)聲明 void delay(int loops) //函數(shù)定義 { if(100ps==0) return; for(int i=0;i<loops,i++); } 無論何時調用delay()函數(shù),都必須給loops傳一個值以確定時間。但有時需要用相同的實參反復調用delay()函數(shù)。C++可以給參數(shù)定義默認值。如果將delay( )函數(shù)中的loops定義成默認值1000, 只需簡單地把函數(shù)聲明改為: void delay(int loops=1000); 這樣,無論何時調用delay()函數(shù),都不用給loops賦值,程序會自動將它當作值1000進行處理。例如,調用: delay(2500); //loops設置為2500 delay(); //ok:loops采用默認值1000 調用中,若不給出參數(shù),則按指定的默認值進行工作。 允許函數(shù)默認參數(shù)值,是為了讓編程簡單,讓編譯器做更多的檢查錯誤工作。
2.默認參數(shù)的聲明 默認參數(shù)在函數(shù)聲明中提供,當又有聲明又有定義時,定義中不允許默認參數(shù)。如果函數(shù)只有定義,則默認參數(shù)才可出現(xiàn)在函數(shù)定義中。例如: void point(int=3,int=4); //聲明中給出默認值 void point(intx,inty) //定義中不允許再給出默認值 { cout <<x<<endl; cout <<y<<endl; }
3.默認參數(shù)的順序規(guī)定
如果一個函數(shù)中有多個默認參數(shù),則形參分布中,默認參數(shù)應從右至左逐漸定義。當調用函數(shù)時,只能向左匹配參數(shù)。例如: void func(int a=1,int b,int c=3, int d=4); //error void func(int a, int b=2,int c=3,int d=4); //ok 對于第2個函數(shù)聲明,其調用的方法規(guī)定為: func(10,15,20,30); //ok:調用時給出所有實參 func(); //error:參數(shù)a沒有默認值 func(2,12); //ok:參數(shù)c和d默認 func(2,15,20); //error:只能從右到左順序匹配默認 (這好像有異議)
4.默認參數(shù)與函數(shù)重載
默認參數(shù)可將一系列簡單的重載函數(shù)合成為一個。例如, 下面3個重載函數(shù): void point(int,int){//...} void point(int a){return point(a,4);} void point(){return point(3,4);} 可以用下面的默認參數(shù)的函數(shù)來替代: void point(int=3,int=4); 當調用“point();”時,即調用“point(3,4);” 它是第3個聲明的重載函數(shù)。 當調用“point(6);”時,即調用“point(6,4);”,它是第2個聲明的重載函數(shù)。 當調用“point(7,8);”時,即調用第1個聲明的重載函數(shù) 如果一組重載函數(shù)(可能帶有默認參數(shù))都允許相同實參個數(shù)的調用,將會引起調用的二義性。例如: void func(int); //重載函數(shù)之一 void func(int,int=4); //重載函數(shù)之二,帶有默認參數(shù) void func(int=3,int=4); //重載函數(shù)之三,帶有默認參數(shù) func(7); //error: 到底調用3個重載函數(shù)中的哪個? func(20,30) //error:到底調用后面2個重載函數(shù)的哪個?
5.默認值的限定
默認值可以是全局變量、全局常量,甚至是一個函數(shù)。例如: int a=1; int fun(int); int g(int x;fun(a)); //ok:允許默認值為函數(shù) 默認值不可以是局部變量,因為默認參數(shù)的函數(shù)調用是在編譯時確定的,而局部變量的位置與值在編譯時均無法確定。例如: void fun() { int i; void g(int x=i); //error:處理g()函數(shù)聲明時,i不可見 } 本章小結
隨著程序量和程序復雜度的不斷增加,最好的辦法是把程序分成更小,更容易管理的模塊,這種模塊就是函數(shù)。 函數(shù)名最好能反映出所要完成的任務。 函數(shù)可以把數(shù)據(jù)返回給調用者,若函數(shù)要返回一個值,必須在函數(shù)名前規(guī)定返回值的類型,若函數(shù)沒有返回值,則類型為void。 程序通過參數(shù)把信息傳遞給函數(shù),若函數(shù)需要接受參數(shù),就必須給參數(shù)指定名稱及類型。 C++必須知道函數(shù)的返回類型以及接受的參數(shù)個數(shù)和類型, 如果函數(shù)的定義出現(xiàn)在函數(shù)調用之后,就必須在程序的開始部分用函數(shù)原型進行聲明。 局部變量是在函數(shù)內部定義的,只能被定義該變量的函數(shù)訪問。全局變量是指其作用域貫穿程序始終的變量。定義全局變量要在程序開始時進行,并且放在所有函數(shù)的外面。 靜態(tài)局部變量是在函數(shù)內部定義,但生命期卻隨函數(shù)的第一次被調用而產(chǎn)生, 隨程序的結束而結束, 靜態(tài)局部變量只能在定義該變量的函數(shù)中可見。 函數(shù)調用機制是由棧操作的過程實現(xiàn)的。函數(shù)可以遞歸調用。函數(shù)定義不能放在任何函數(shù)定義的里面。 內聯(lián)函數(shù)是為了提高編程效率而實現(xiàn)的, 它克服了用#define宏定義所帶來的弊病。 函數(shù)重載允許用同一個函數(shù)名定義多個函數(shù)。連接程序會根據(jù)傳遞給函數(shù)的參數(shù)數(shù)目、類型和順序調用相應的函數(shù)。函數(shù)重載使程序設計簡單化,程序員只要記住一個函數(shù)名,就可以完成一系列相關的任務。 在函數(shù)定義中通過賦值運算,即可指定默認參數(shù)值。一旦程序在調用函數(shù)時默認了參數(shù)值, 函數(shù)就使用默認參數(shù)值。 不允許在參數(shù)中間使用默認值。指定默認參數(shù)值可以使函數(shù)的使用更為簡單,同時也增強了函數(shù)的可重用性。
|