轉載來自:https://www.cnblogs.com/chenke1731/p/9651275.html
1、函數定義時指定默認參數
在C++中,定義函數時可以給形參指定一個默認的值,這樣調用函數時如果沒有給這個形參賦值(沒有對應的實參),那么就使用這個默認的值。也就是說,調用函數時可以省略有默認值的參數。如果用戶指定了參數的值,那么就使用用戶指定的值,否則使用參數的默認值。
所謂默認參數,指的是當函數調用中省略了實參時自動使用的一個值,這個值就是給形參指定的默認值。
下面是一個簡單的示例:
#include<iostream> using namespace std; //帶默認參數的函數 void func(int n, float b=1.2, char c='@'){ cout<<n<<", "<<b<<", "<<c<<endl; } int main(){ //為所有參數傳值 func(10, 3.5, '#'); //為n、b傳值,相當於調用func(20, 9.8, '@') func(20, 9.8); //只為n傳值,相當於調用func(30, 1.2, '@') func(30); return 0; }
運行結果:
10, 3.5, #
20, 9.8, @
30, 1.2, @
默認參數除了使用數值常量指定,也可以使用表達式指定,例如:
float d = 10.8; void func(int n, float b=d+2.9, char c='@') { cout<<n<<", "<<b<<", "<<c<<endl; }
C++規定,默認參數只能放在形參列表的最后,而且一旦為某個形參指定了默認值,那么它后面的所有形參都必須有默認值。實參和形參的傳值是從左到右依次匹配的,默認參數的連續性是保證正確傳參的前提。
下面的寫法是正確的:
void func(int a, int b=10, int c=20){ } void func(int a, int b, int c=20){ }
但這樣寫不可以:
void func(int a, int b=10, int c=20, int d){ } void func(int a, int b=10, int c, int d=20){ }
默認參數並非編程方面的重大突破,而只是提供了一種便捷的方式。在以后設計類時你將發現,通過使用默認參數,可以減少要定義的析構函數、方法以及方法重載的數量。
2、函數聲明時指定默認參數
除了函數定義,也可以在函數聲明處指定默認參數。不過當出現函數聲明時情況會變得稍微復雜,有時候可以在聲明處和定義處同時指定默認參數,有時候只能在聲明處指定:
#include <iostream> using namespace std; void func(int a, int b = 10, int c = 36); int main() { func(99); return 0; } void func(int a, int b = 10, int c = 36) { cout<<a<<", "<<b<<", "<<c<<endl; }
這段代碼在編譯時會報錯,錯誤信息表明不能在函數定義和函數聲明中同時指定默認參數。對代碼稍作修改,將 func() 函數的定義放到其他源文件中,如下所示(示例2)。
// main.cpp #include <iostream> using namespace std; void func(int a, int b = 10, int c = 36); int main() { func(99); return 0; } //module.cpp 代碼: #include <iostream> using namespace std; void func(int a, int b = 10, int c = 36) { cout<<a<<", "<<b<<", "<<c<<endl; }
運行結果:
99, 10, 36
修改后的代碼是可以編譯通過的,為什么將func()
的定義放到其他源文件中就不一樣了呢?
這是因為C++ 規定,在給定的作用域中只能指定一次默認參數。
對於示例1,func()
的定義和聲明位於同一個源文件,它們的作用域也都是整個源文件,這樣就導致在同一個文件作用域中指定了兩次默認參數,違反了 C++ 的規定。
對於示例2,func()
的聲明位於main.cpp
,作用域也是main.cpp
,而 func()
的定義位於module.cpp
,作用域也是module.cpp
,func()
的聲明和定義位於不同的作用域,相互之間不影響。
C/C++有四種作用域:
函數原型作用域
局部作用域(函數作用域)
塊作用域
文件作用域(全局作用域)
繼續對代碼進行修改,將 func() 定義處 b、c 的默認值分別設置為 5、57,而聲明處 b、c 的默認值不變,依然為 10、36。編譯並運行程序,發現輸出結果與上面一樣,這說明編譯器使用的是當前作用域中的默認參數。站在編譯器的角度看,它不管當前作用域中是函數聲明還是函數定義,只要有默認參數就可以使用。
3、多次聲明同一函數
在多文件編程時,我們通常的做法是將函數聲明放在頭文件中,並且一個函數只聲明一次,但是多次聲明同一函數也是合法的。
不過有一點需要注意,在給定的作用域中一個形參只能被賦予一次默認參數。換句話說,函數的后續聲明只能為之前那些沒有默認值的形參添加默認值,而且該形參右側的所有形參必須都有默認值。
#include <iostream> using namespace std; //多次聲明同一個函數 void func(int a, int b, int c = 36); void func(int a, int b = 5, int c); int main() { func(99); return 0; }
這種聲明方式是正確的。第一次聲明時為 c 指定了默認值,第二次聲明時為 b 指定了默認值;第二次聲明是添加默認參數。需要提醒的是,第二次聲明時不能再次給 c 指定默認參數,否則就是重復聲明同一個默認參數。