??博主CSDN主頁:杭電碼農(nóng)-NEO??
?
?專欄分類:C++初階之路?
?
??代碼倉庫:NEO的學習日記??
?
??關(guān)注我??帶你學習排序知識
? ????
1. 前言
寫C語言代碼的時候
特別是在寫數(shù)據(jù)結(jié)構(gòu)時:
經(jīng)常忘記傳函數(shù)的參數(shù)
或者當前不需要什么參數(shù)
C++增加了缺省參數(shù)來解決這個問題
而為了解決相似功能的函數(shù)的函數(shù)名問題
C++增加了函數(shù)重載來解決這個問題
本篇文章將簡單介紹缺省參數(shù)
并著重講解函數(shù)重載的底層原理!
2. 缺省參數(shù)
缺省參數(shù)是聲明或定義函數(shù)時
為函數(shù)的參數(shù)指定一個缺省值
在調(diào)用該函數(shù)時,若沒有指定實參
則采用該形參的缺省值
否則使用指定的實參
缺省參數(shù)分類:
- 全缺省
- 半缺省
2.1 全缺省
類似于這樣的代碼:
void Func(int a = 10, int b = 20, int c = 30)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
全缺省指的是函數(shù)的所有參數(shù)都給缺省值
有四種調(diào)用此函數(shù)的方式:
- 什么都不傳:
Func();
此時系統(tǒng)默認a,b,c的值分別為10 - 20 - 30
- 只傳一個參數(shù):
Func(15);
此時,a的值為15
而系統(tǒng)默認b,c的值為:20-30
- 傳兩個參數(shù):
Func(15,25);
此時a,b的值為:15 - 25
系統(tǒng)默認c的值為30
- 三個參數(shù)都傳:
Func(15,25,35);
此時a,b,c的值為:15-25-35
注意:傳參不能寫成這種形式:
Func(,25,);
Func(,,35);
Func(,25,35);
Func(15,,35);
2.2 半缺省
半缺省類似于這種形式:
void Func(int a, int b = 10, int c = 20)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
只要有參數(shù)沒有給缺省值
那么它就是半缺省的
注意:
- 半缺省參數(shù)必須
從右往左
依次來給出,不能間隔著給 - 缺省參數(shù)不能在函數(shù)聲明和定義中同時出現(xiàn)
- 缺省值必須是
常量
或者全局變量
比如下面這樣定義半缺省是不行的:
void Func1(int a=10,int b,int c);
void Func2(int a,int b=20,int c);
//有缺省值的前提是它的右邊的參數(shù)都有缺省值
3. 函數(shù)重載概念
以前有一個笑話:國有兩個體育項目大家根本不用看,也不用擔心。一個是乒乓球,一個
是男足。前者是“誰也贏不了!”,后者是“誰也贏不了
這里使用了一語雙關(guān).
而函數(shù)重載的概念和它類似:
函數(shù)重載是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個功能類似的同名函數(shù),這些同名函數(shù)的形參列表(參數(shù)個數(shù) 或 類型 或 類型順序)不同,常用來處理實現(xiàn)功能類似數(shù)據(jù)類型不同的問題。
舉個例子:
void func(int i,char ch) //函數(shù)1
{
//...
}
void func(char ch,int i) //函數(shù)2
{
//...
}
函數(shù)1和2可以同時存在
并且它們不是同一個函數(shù)
4. 幾種不同類型的函數(shù)重載
總結(jié)三種支持函數(shù)重載的情況:
參數(shù)類型不同
int Add(int left, int right)
{
return left + right;
}
double Add(double left, double right)
{
return left + right;
}
參數(shù)個數(shù)不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
參數(shù)類型順序不同
void f(int a, char b)
{
cout << "杭州電子科技大學" << endl;
}
void f(char b, int a)
{
cout << "圣光機聯(lián)合學院" << endl;
}
(注意:下面這種不屬于函數(shù)重載):
short Add(short x,short y)
{
return x+y;
}
int Add(short x,short y)
{
return x+y;
}
因為它們參數(shù)類型,數(shù)量,順序都一樣
只是返回值不同,不構(gòu)成函數(shù)重載!
5. C++如何支持函數(shù)重載?
在C/C++中,一個程序要運行起來
需要經(jīng)歷以下幾個階段:
- 預處理
- 編譯
- 匯編
- 鏈接
因為c++區(qū)別于c在這幾個過程中
的差別,所以使C++能夠支持函數(shù)重載
5.1 C程序為什么不支持函數(shù)重載?
定義兩個源文件和一個頭文件來解釋:
- func.h
- func.c
- main.c
在.h文件聲明兩個函數(shù)
int func(int x,int y);
int func(int x,double y);
這三個文件會經(jīng)歷以下過程:
- 預處理階段
主要內(nèi)容:頭文件展開,宏替換
條件編譯,去掉注釋
這個過程結(jié)束后,func.h被展開了
main.c和func.c源文件變成了:func.i和main.i文件
- 編譯階段
主要內(nèi)容:語法檢查和生成匯編代碼
這個過程結(jié)束后,func.i和main.i
文件變成了func.s和main.s文件
(此文件中為匯編代碼)
- 匯編階段
主要內(nèi)容:將匯編代碼轉(zhuǎn)換成二進制碼
以便機器能夠讀懂
這個過程結(jié)束后,func.s和main.s
文件變成了func.o和main.o文件
注:前面的過程只用了解,真正的主角在下面!
-
鏈接過程
func.o和main.o文件
以及鏈接過程是這部分的重中之重
5.2 C程序的鏈接過程
func.c到func.o和main.c到main.o
都是單線程的
鏈接過程:
.o的目標文件會合并到一起
其次還需找一些只給了聲明的函數(shù)
的函數(shù)地址
而每一個.o文件都有一個符號表
符號表中存放函數(shù)的地址
當main文件要調(diào)用這個函數(shù)時
會去符號表中找函數(shù)的地址
而符號表中兩個func函數(shù)的地址
編譯器不知道應該調(diào)用哪個
所以c程序不支持函數(shù)重載!
5.3 C++函數(shù)名修飾規(guī)則
相比起C程序而言,C++新增了一個
函數(shù)名修飾規(guī)則來支持函數(shù)重載
這個規(guī)則就是將函數(shù)的參數(shù)帶入符號表
所以參數(shù)的類型,數(shù)量,順序不同
代表的是不同的函數(shù),找地址時就不會出錯!
我們在C++的匯編代碼中找到了
這兩個函數(shù)對應的部分:
綜上所述:
函數(shù)參數(shù)的類型,數(shù)量,順序不同
那么對應在符號表中的名字就不一樣
main文件再去找函數(shù)地址時就不會沖突
對比c程序:
c程序符號表中只有一個函數(shù)名
函數(shù)參數(shù)沒有參與進來
所以C程序不支持相同函數(shù)名的函數(shù)
6. 總結(jié)以及拓展
前面很多過程只是為了
后面的鏈接.o文件打基礎
所以前面的聽不懂也沒關(guān)系
只需要知道C++有函數(shù)名修飾規(guī)則
c++的.o文件的符號表的函數(shù)名
和函數(shù)參數(shù)相關(guān)
而c程序的符號表和參數(shù)無關(guān)!
文章來源:http://www.zghlxwxcb.cn/news/detail-523803.html
拓展:
C/C++函數(shù)調(diào)用約定和名字修飾規(guī)則
有興趣好奇的同學可以看看里面
有對vs下函數(shù)名修飾規(guī)則講解
C/C++約定文章來源地址http://www.zghlxwxcb.cn/news/detail-523803.html
到了這里,關(guān)于【C++初階(二)】缺省參數(shù)以及函數(shù)重載的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!