在c語言中是沒有函數默認值的概念,可以利用宏來模擬參數默認值;在c++中可以爲參數指定默認值;所謂函數默認值就是當調用點沒有相對應的形參時,就自動使用默認參數,編譯器會自動把默認值傳遞給調用語句中;設置函數默認值需要注意有以下幾點
1.函數默認值一般寫在聲明中
2.函數的默認值必須設置爲自右向左依次賦值
3.默認值只能賦一次
4.函數的默認值不能設置爲局部變量
第一點:
先寫一段簡單的代碼:
#include <iostream>
using namespace std;
int Func(int a,int b,int c = 30);//函數聲明
int main()
{
Func(10,20);//函數調用點
}
int Func(int a,int b,int c)//函數定義
{
return a+b+c;
}
代碼在函數聲明中設置了默認值,其特點是函數定義在函數調用點之後,代碼的調試結果是沒有問題的;所有的默認值都是在編譯階段進行的,並且編譯階段是自頂向下編譯的,當編譯到第6行時,就已經從編譯過的第2行中知道了Func函數是有默認的;所以調試是沒有任何問題的。現在把代碼改一下:
#include <iostream>
using namespace std;
int Func(int a,int b,int c);//函數聲明
int main()
{
Func(10,20);//函數調用點
}
int Func(int a,int b,int c = 30)//函數定義
{
return a+b+c;
}
注意一下,這時函數的默認被設置在了函數定義裏;調試一下,會出現這樣的錯誤:
1>c:\users\dell\desktop\源.cpp(7): error C2660: “Func”: 函數不接受 2 個參數
同樣的道理,編譯是自頂向下的,在編譯到第6行時,這個時候只能知道函數聲明(定義點在調用點的下面,無法知道函數定義中的默認值),而函數聲明中並沒有設置默認值。所以總結出函數默認值的第一條,函數默認值一般寫在聲明中,聲明一般在調用的前面
第二點:
#include <iostream>
using namespace std;
int Func(int a =10,int b,int c = 30);//函數聲明
int Func(int a,int b,int c)//函數定義
{
return a+b+c;
}
int main()
{
Func(20);//函數調用點
}
調試這段代碼會出現以下的錯誤:
1>c:\users\dell\desktop\源.cpp(3): error C2548: “Func”: 缺少參數 2 的默認參數
1>c:\users\dell\desktop\源.cpp(10): error C2660: “Func”: 函數不接受 1 個參數
在聲明中只對第一個和第三個數字進行的默認值的設置,而在函數的調用點只有一個參數,參數的傳遞是自左向右一一對應的,實參會覆蓋聲明中對a默認值的設置,c使用默認值,而b接受不到值的傳遞;所以函數的默認值必須設置爲自右向左依次賦值,以防參數的遺漏
第三點:
#include <iostream>
using namespace std;
int Func(int a,int b,int c = 30);//函數聲明
int Func(int a,int b,int c = 15)//函數定義
{
return a+b+c;
}
int main()
{
Func(10,20);//函數調用點
}
對函數聲明和定義中對同一個變量設置默認值;調試代碼會出現以下的錯誤
1>c:\users\dell\desktop\源.cpp(5): error C2572: “Func”: 重定義默認參數 : 參數 3
這是因爲重定義變量c,使編譯器產生二義性,編譯器不知道使用30還是15,編譯器只能報錯;所以默認值只能賦一次
第四點:
默認值的限制:函數的默認值不能設置爲局部變量,可以是全局變量,和函數的返回值(前提是函數在設有默認值的聲明之前)
四點已經總結完了,那麼下面的代碼是否正確呢
#include <iostream>
using namespace std;
int Func(int a,int b,int c = 30);//函數聲明
int Func(int a,int b = 15,int c)//函數定義
{
return a+b+c;
}
int main()
{
Func(10,20);//函數調用點
}
結果是正確的,編譯自上向下,雖然默認值分別設置在了函數聲明和函數定義中,仍然滿足自右向左賦值,也沒有度統一變量重複設置默認值,綜上,結果是沒有任何問題滴!