C++默認參數與函數重載
一、默認參數
在C++中,可以爲參數指定默認值。在函數調用時沒有指定與形參相對應的實參時, 就自動使用默認參數。
默認參數的語法與使用:
(1)在函數聲明或定義時,直接對參數賦值。這就是默認參數;
(2)在函數調用時,省略部分或全部參數。這時可以用默認參數來代替。
注意:
(1)默認參數只可在函數聲明中設定一次。只有在無函數聲明時,纔可以在函數定義中設定。
(2)默認參數定義的順序爲自右到左。即如果一個參數設定了缺省值時,其右邊的參數都要有缺省值。
如:int mal(int a, int b=3, int c=6, int d=8) 正確,按從右到左順序設定默認值。
int mal(int a=6, int b=3, int c=5, int d) 錯誤,未按照從右到左設定默認值。c設定缺省值了,而其右邊的d沒有缺省值。
(3)默認參數調用時,則遵循參數調用順序,自左到右逐個調用。這一點要與第(2)分清楚,不要混淆。
如:void mal(int a, int b=3, int c=5); //默認參數
mal(3, 8, 9 ); //調用時有指定參數,則不使用默認參數
mal(3, 5); //調用時只指定兩個參數,按從左到右順序調用,相當於mal(3,5,5);
mal(3); //調用時只指定1個參數,按從左到右順序調用,相當於mal(5,3,5);
mal( ); //錯誤,因爲a沒有默認值
mal(3, , 9) //錯誤,應按從左到右順序逐個調用
再如: void mal(int a=8, int b=3, int c=5); //默認參數
mal( ); //正確,調用所有默認參數,相當於mal(8,3,5);
(4)默認值可以是全局變量、全局常量,甚至是一個函數。但不可以是局部變量。因爲默認參數的調用是在編譯時確定的,而局部變量位置與默認值在編譯時無法確定。
二、函數重載
在相同的聲明域中,函數名相同,而參數表不同。通過函數的參數表而唯一標識並且來區分函數的一種特殊的函數用法。
參數表的不同表現爲:
1、參數類型不同;
2、參數個數不同;
特別注意:返回類型不同不可以作爲函數重載的標識。
例:
usingnamespace std;
int test(int a,int b);
float test(float a,float b);
void main()
...{
cout << test(1,2) << endl << test(2.1f,3.14f) << endl;
cin.get();
}
int test(int a,int b)
...{
return a+b;
}
float test(float a,float b)
...{
return a+b;
}
在上面的程序中,用了兩個名爲test的函數來描述int類型和操作的和float類型和操作,方便對相同或者相似功能函數的管理!
那麼,計算機該如何來判斷同名稱函數呢?操作的時候會不會造成選擇錯誤呢?
回答是否定的,c++內部利用一種叫做名稱粉碎的機智來內部重命名同名函數,上面的例子在計算重命名後可能會是testii和testff ,他們是通過參數的類型或個數來內部重命名的。
1、參數類型不同的例子:
(1)
#include<iostream.h>
void Add(char x,char y)
{cout<<"字符串是:";
cout<<x<<y<<endl;
}
void Add(int x,int y)
{cout<<"兩數的和是: ";
cout<<x+y<<endl;
}
void main()
{
Add('O','k');
Add(65,100);
}
(2)重載函數abs(),求int、float和double類型數據的絕對值。
#include <iostream.h>
//求int型數據的絕對值
int abs(int x)
{
if (x<0) x=-x;
return x;
}
//求float型數據的絕對值
float abs(float x)
{
if (x<0) x=-x;
return x;
}
//求 double型數據的絕對值
//仿照上面的函數編寫
//主函數
void main()
{
int a=-357;
float b=63.85;
double c=-6974.26;
cout<<abs(a)<<'\t'<<abs(b)<<'\t'<<abs(c)<<endl;
2、參數個數不同的例子:求2~4個整數當中的最大值,根據參數個數的不同調用不同的max()函數
#include<iostream.h>
int max(int x,int y)
{
if(x>y) return x;
else return y;
}
int max(int x,int y,int z)
{
int a=max(x,y);
return max(a,z);
}
int max(int a,int b,int c,int d)
{
//自行編制這部分代碼
}
main()
{
cout<<max(1,2)<<endl;
cout<<max(1,2,3)<<endl;
cout<<max(1,2,3,4)<<endl;
}
函數重載的注意事項
1、函數的形參必須不同,或者個數不同,或者類型不同,不能夠只依靠函數的返回值類型不同或形參變量名不同來實現函數重載。
2、不要將不同功能的函數定義爲重載函數,以免出現對調用結果的誤解。如:
int add(int x,int y){return x+y;}
float add(float x,float y){return x-y;}
重載函數與默認參數重疊導致的二義性問題:
func(int); //重載函數1,只有1個參數,無默認參數
func(int, int =4); //重載函數2,有2個參數,有1個默認參數
func(int a=3, int b=4, int c=6); //重載函數3,有3個參數,有3個默認參數
fucn(float a=3.0, float b=4.0 float c=5.0); //重載函數4,有3個參數,有3個默認參數
fucn(float a=3.0, float b=4.0 float c=5.0 float d=7.9 ); //重載函數5,有4個參數,有4個默認參數
func(2); //可調用前3個函數,出現二義性
func(2.0); //可調用後2個函數,出現二義性
所以當重載函數與默認參數共同使用時,要注意出現二義性問題。