C++缺省參數(shù)、函數(shù)重載與引用深入解析
前言
1. 缺省參數(shù)
1.1 缺省參數(shù)概念
缺省參數(shù)是聲明或定義函數(shù)時為函數(shù)的參數(shù)指定一個缺省值。在調(diào)用該函數(shù)時,如果沒有指定實參則采用該形參的缺省值,否則使用指定的實參。
#include<iostream> using namespace std;//使用using namespace 命名空間名稱引入C++標(biāo)準(zhǔn) void Func(int a = 0) { cout<<a<<endl; } int main() { Func(); // 沒有傳參時,使用參數(shù)的默認(rèn)值 Func(10); // 傳參時,使用指定的實參 return 0; }
結(jié)果如下:
可以看到在定義
void Func(int a = 0)
時給int a 參數(shù)賦值為0;
所以當(dāng)使用該函數(shù)時,如果不傳參數(shù):Func();
就默認(rèn)傳的參數(shù)為之前定義時賦值的0;
如果傳參數(shù):Func(10);
就正常傳參即可;
注意:
缺省參數(shù)不能在函數(shù)聲明和定義中同時出現(xiàn)(寫在聲明中):
- 缺省值必須是常量或者全局變量;
- C語言不支持(編譯器不支持)缺省參數(shù);
1.2 缺省參數(shù)分類
全缺省參數(shù)
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ù)時將所有的參數(shù)都賦值
半缺省參數(shù)
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ù)必須從右往左依次連續(xù)來給出,中間不能有間隔;
2.函數(shù)重載
2.1函數(shù)重載概念
- 函數(shù)重載:是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個功能類似的同名函數(shù),這些同名函數(shù)的形參列表(參數(shù)個數(shù)或類型或 類型順序)不同,常用來處理實現(xiàn)功能類似數(shù)據(jù)類型不同的問題。
- 函數(shù)重載的優(yōu)點是能夠提高代碼的可讀性和可維護(hù)性。通過使用同一個函數(shù)名來表示一組相關(guān)的操作,可以讓調(diào)用者更容易理解代碼的意圖,并且減少了代碼的重復(fù)性。
- 函數(shù)重載的條件是函數(shù)名相同,但是參數(shù)列表不同。參數(shù)列表可以包括參數(shù)的個數(shù)、類型、順序等方面的差異。在編譯器中,通過函數(shù)的參數(shù)列表來區(qū)分同名的函數(shù),并選擇合適的函數(shù)進(jìn)行調(diào)用。
例如:
#include<iostream> using namespace std; // 1、參數(shù)類型不同 int Add(int left, int right) { cout << "int Add(int left, int right)" << endl; return left + right; } double Add(double left, double right) { cout << "double Add(double left, double right)" << endl; return left + right; } // 2、參數(shù)個數(shù)不同 void f() { cout << "f()" << endl; } void f(int a) { cout << "f(int a)" << endl; } // 3、參數(shù)類型順序不同 void f(int a, char b) { cout << "f(int a,char b)" << endl; } void f(char b, int a) { cout << "f(char b, int a)" << endl; } int main() { Add(10, 20); Add(10.1, 20.2); f(); f(10); f(10, 'a'); f('a', 10); return 0; }
結(jié)果如下:
可以看到雖然函數(shù)名相同,但是對應(yīng)不同的參數(shù)會調(diào)用不同的函數(shù)
這里注意,相同類型的參數(shù)順序調(diào)換不構(gòu)成函數(shù)重載:
int Add(int left, int right) { cout << "int Add(int left, int right)" << endl; return left + right; } int Add(int right, int left) { cout << "int Add(int left, int right)" << endl; return left + right; }
結(jié)果如下:
當(dāng)然如果兩個函數(shù)函數(shù)名和參數(shù)是一樣的,返回值不同是不構(gòu)成重載的,因為調(diào)用時編譯器沒辦法區(qū)分。
2.2函數(shù)重載原因
C語言不支持函數(shù)重載的主要原因是它的編譯器在進(jìn)行函數(shù)調(diào)用時是根據(jù)函數(shù)名來確定具體調(diào)用的函數(shù)的,在編譯階段就已經(jīng)決定了函數(shù)的調(diào)用方式。而函數(shù)重載是指多個函數(shù)擁有相同的名稱但具有不同的參數(shù)列表,編譯器無法根據(jù)函數(shù)名來確定具體調(diào)用的函數(shù)。因此,C語言無法實現(xiàn)函數(shù)重載功能。
而C++是通過函數(shù)修飾規(guī)則來區(qū)分同名的函數(shù),只要參數(shù)不同,修飾出來的名字就不一樣,就支持了重載。
3.引用
3.1引用概念
- 引用不是新定義一個變量,而是給已存在變量取了一個別名,編譯器不會為引用變量開辟內(nèi)存空間,它和它引用的變量共用同一塊內(nèi)存空間
- 它允許我們使用一個變量名來引用另一個變量的值,而不是創(chuàng)建一個新的變量
- 引用通常用于傳遞函數(shù)的參數(shù)、返回函數(shù)值和簡化語法
在C++中,我們可以通過以下方式定義一個引用:
type &ref = variable;//類型& 引用變量名(對象名) = 被引用實體
例如:
void TestRef() { int a = 10; int& ra = a;//<====定義引用類型 printf("%p\n", &a); printf("%p\n", &ra); }
注意:引用類型必須和引用實體是同種類型的
再舉個例子:
可以看到它們都是同一個地址,指向同一個變量
#include <iostream> int main() { int num = 10; int &ref = num; // 引用num變量 std::cout << "num: " << num << std::endl; std::cout << "ref: " << ref << std::endl; num = 20; std::cout << "num: " << num << std::endl; std::cout << "ref: " << ref << std::endl; ref = 30; std::cout << "num: " << num << std::endl; std::cout << "ref: " << ref << std::endl; return 0; }
結(jié)果如下:
num: 10
ref: 10
num: 20
ref: 20
num: 30
ref: 30
可以看到,無論我們通過num還是ref來修改變量的值,都會影響到另一個變量的值,因為它們實際上是同一個變量的不同名稱。
3.2引用特性
- 引用在定義時必須初始化
- 一個變量可以有多個引用
- 引用一旦引用一個實體,再不能引用其他實體
void TestRef() { int a = 10; // int& ra; // 該條語句編譯時會出錯 int& ra = a; int& rra = a; printf("%p %p %p\n", &a, &ra, &rra); }
結(jié)果如下:
3.2常引用
C++中的常引用有兩種情況:
const引用:使用const關(guān)鍵字來修飾引用,表示引用的值不可修改。例如:
int x = 10; const int& ref = x;
在上面的例子中,ref是一個對x的常引用,意味著不能通過ref來修改x的值。
常對象的引用:當(dāng)引用一個常對象時,引用也必須是常引用。例如:
const int x = 10; const int& ref = x;
在上面的例子中,ref是對常對象x的常引用。
常引用的作用是為了在不修改值的情況下使用對象,同時可以避免不必要的復(fù)制。常引用經(jīng)常用于函數(shù)參數(shù)中,以便避免對實參進(jìn)行復(fù)制。
指針和引用進(jìn)行賦值和初始化時,權(quán)限可以縮小,但是不能放大
例如:
const int x = 10; int& ref = x;//這是錯誤的,它放大了權(quán)限
在上面的例子中,原本的x被const修飾不能被改變數(shù)據(jù),但是ref引用它時沒有用const修飾說明可以被改動,放大了權(quán)限是不被接受的;這和指針是類似的:
const int* p1 = NULL; int* p2 = p1;//這也是錯誤的
3.3使用場景
做參數(shù)
void Swap(int& left, int& right) { int temp = left; left = right; right = temp; }
結(jié)果如下:
可以看到我們沒有使用傳遞變量的指針給函數(shù)就改變了實參的數(shù)據(jù);
使用引用作為函數(shù)參數(shù)可以避免復(fù)制大量的數(shù)據(jù),提高函數(shù)的效率。同時,通過引用傳遞參數(shù)可以實現(xiàn)對原始數(shù)據(jù)的修改,而不需要借助指針來實現(xiàn)。
做返回值
引用作為函數(shù)的返回值前提是:返回的值在調(diào)用完函數(shù)后不會被釋放銷毀
例如:
int& Count() { static int n = 0; n++; return n; }
n用static修飾為靜態(tài)全局變量即使函數(shù)調(diào)用結(jié)束也不會被釋放,所以可以用引用作為函數(shù)的返回值,這樣就不需要再臨時拷貝一份,減少了空間的消耗;
那么作為函數(shù)的返回值有什么作用呢?
舉個例子:
#include<iostream> #include<assert.h> #define N 10 using namespace std; //順序表 typedef struct AY { int arr[N]; int size; }AY; int& PosAt(AY& ay, int x) { assert(x < N); return ay.arr[x]; } int main() { AY ay; for (int i = 0; i < N; i++) { PosAt(ay, i) = i;//利用引用返回修改對應(yīng)的值 } for (int i = 0; i < N; i++)//打印 { cout << PosAt(ay, i) << " "; } cout << endl; return 0; }
結(jié)果如下:
從上面的函數(shù)我們可以知道引用返回除了可以減少拷貝還可以修改返回的對象;
總結(jié):如果函數(shù)返回時,出了函數(shù)作用域,如果返回對象還在(還沒還給系統(tǒng)),則可以使用引用返回,如果已經(jīng)還給系統(tǒng)了,則必須使用傳值返回。
3.4引用和指針的區(qū)別
(1)在語法概念上引用就是一個別名,沒有獨立空間,和其引用實體共用同一塊空間;而指針是保存著變量的地址的,是有獨立的空間的;
例如:
int main() { int a = 10; int& ra = a; cout<<"&a = "<<&a<<endl; cout<<"&ra = "<<&ra<<endl; return 0; }
結(jié)果如下:
通過上述例子我們發(fā)現(xiàn)引用和原來的變量的地址是一樣的;
(2)在底層實現(xiàn)上實際是有空間的,因為引用是按照指針方式來實現(xiàn)的;
例如:
#include<iostream> using namespace std; int main() { int a = 10; int& ra = a; ra = 20; int* pa = &a; *pa = 20; return 0; }
結(jié)果如下:
通過上述例子,我們調(diào)試查看反匯編,發(fā)現(xiàn)引用和指針操作底層邏輯是一樣的;
(3)引用和指針的不同:
- 引用概念上定義一個變量的別名,指針存儲一個變量地址;
- 引用在定義時必須初始化,指針沒有要求;
- 引用在初始化時引用一個實體后,就不能再引用其他實體,而指針可以在任何時候指向任何一個同類型實體;
- 沒有NULL引用,但有NULL指針;
- 在sizeof中含義不同:引用結(jié)果為引用類型的大小,但指針始終是地址空間所占字節(jié)個數(shù)(32位平臺下占4個字節(jié));
- 引用自加即引用的實體增加1,指針自加即指針向后偏移一個類型的大?。?/li>
- 有多級指針,但是沒有多級引用;
- 訪問實體方式不同,指針需要顯式解引用,引用編譯器自己處理;
- 引用比指針使用起來相對更安全;
4.結(jié)語
以上就是C++中缺省參數(shù)、函數(shù)重載以及引用的所有內(nèi)容啦 ~,缺省參數(shù)函數(shù)重載以及引用的出現(xiàn)是為了補(bǔ)充C語言語法的不足以及對C語言設(shè)計不合理的地方進(jìn)行優(yōu)化,引用的出現(xiàn)大大降低了我們學(xué)習(xí)C語言時相對于指針的難度,也便于我們更好的理解和使用,完結(jié)撒花 ~??????????
到此這篇關(guān)于C++缺省參數(shù)、函數(shù)重載與引用的文章就介紹到這了,更多相關(guān)C++缺省參數(shù)、函數(shù)重載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
學(xué)好C++必須做到的50條 絕對經(jīng)典!
學(xué)好C++必須做到的50條,絕對經(jīng)典!想要學(xué)好C++的朋友一定要認(rèn)真閱讀本文,更要做到以下50條2016-09-09詳解C++設(shè)計模式編程中對狀態(tài)模式的運用
這篇文章主要介紹了C++設(shè)計模式編程中對狀態(tài)模式的運用,狀態(tài)模式允許一個對象在其內(nèi)部狀態(tài)改變時改變它的行為,對象看起來似乎修改了它的類,需要的朋友可以參考下2016-03-03C++超詳細(xì)講解函數(shù)參數(shù)的默認(rèn)值
在C++中,定義函數(shù)時可以給形參指定一個默認(rèn)的值,這樣調(diào)用函數(shù)時如果沒有給這個形參賦值(沒有對應(yīng)的實參),那么就使用這個默認(rèn)的值。也就是說,調(diào)用函數(shù)時可以省略有默認(rèn)值的參數(shù)2022-05-05C語言實現(xiàn)將字符串轉(zhuǎn)換成整數(shù)
這篇文章主要為大家詳細(xì)介紹了如何用C語言寫一個函數(shù),把字符串轉(zhuǎn)換成整數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04