詳解C++ 參數(shù)的三種傳遞方式和應(yīng)用場景
值傳遞
值傳遞的實(shí)質(zhì)
- 將實(shí)參的值(a、b)復(fù)制到形參(m、n)相應(yīng)的存儲單元中,即形參和實(shí)參分別占用不同的存儲單元。
值傳遞的特點(diǎn)
- 值傳遞的特點(diǎn)是單向傳遞,即主調(diào)函數(shù)被調(diào)用時(shí)給形參分配存儲單元,把實(shí)參的值傳遞給形參,在調(diào)用結(jié)束后,形參的存儲單元被釋放,而形參值的任何變化都不會影響到實(shí)參的值,實(shí)參的存儲單元仍保留并維持?jǐn)?shù)值不變。
值傳遞的應(yīng)用場景
- 適用于傳遞簡單的數(shù)據(jù)類型,如int、float、double等。傳值是將參數(shù)的值傳遞給函數(shù),函數(shù)內(nèi)部會創(chuàng)建一個(gè)新的變量來存儲該值,對該變量的修改不會影響原變量的值。
例子1:我們首先講值傳遞,并且把它的特性列出來。下面我們先看代碼:
void test(int a) {
a += 3;
cout << “a的值:” << a << “\n”
<< “a的地址:” << &a << “\n”;
}
void main()
{
int b = 10;
test(b);
cout << “b的值:” << b << “\n”
<< “b的地址:” << &b << “\n”;
}這是一個(gè)簡單的值傳遞,而地址就是內(nèi)存位置,學(xué)過C++的人都清楚,下面是運(yùn)行的結(jié)果

根據(jù)代碼和結(jié)果我們可以知道的是值傳傳遞的參數(shù)是有自己的內(nèi)存的,并且當(dāng)b把自己的值傳遞進(jìn)去之后,對b是沒有影響的,那么值傳遞則是等于把b的值賦給了a等于進(jìn)行了一個(gè)賦值操作這就是值傳遞。
指針傳遞
指針傳遞的實(shí)質(zhì)
- 所謂的地址傳遞,指的就是函數(shù)的參數(shù)是數(shù)組名或者指針。傳遞的是數(shù)組的首地址或指針的值,而形參接收到的是實(shí)參的地址,即指向?qū)崊⒌拇鎯卧?,形參和?shí)參占用相同的存儲單元,所以形參和實(shí)參是相同的。
特點(diǎn)
- 形參并不存在存儲空間,編譯系統(tǒng)不為形參數(shù)組分配內(nèi)存。因此在數(shù)組名或指針作函數(shù)參數(shù)時(shí)所進(jìn)行的傳送只是地址傳送,形參在取得該地址之后,與實(shí)參共同擁有一段內(nèi)存空間,形參的變化也就是實(shí)參的變化。
運(yùn)用場景
- 適用于傳遞數(shù)組、結(jié)構(gòu)體等復(fù)雜的數(shù)據(jù)類型。指針傳遞是將參數(shù)的地址傳遞給函數(shù),函數(shù)內(nèi)部通過指針來訪問該變量,對該變量的修改會影響原變量的值。
例子2:接下下來我講指針傳遞,下面是指針傳遞的代碼:
void test(int *a) {
*a += 3;
cout << “a所指向地址:” << a << “\n”
<< “a的地址:” << &a << “\n”
<< “a所指向地址的值:” << *a << “\n”;
}
void main()
{
int b = 10;
test(&b);
cout << “b的值:” << b << “\n”
<< “b的地址:” << &b << “\n”;
}這是一個(gè)指針傳遞,可以明顯的發(fā)現(xiàn)和值傳遞的差別,指針是存儲地址的,當(dāng)我們想要把b的值傳進(jìn)test()函數(shù)時(shí),我們傳的是b的地址,然后通過b的地址,來獲得b的值,下面是結(jié)果

我們輸出的跟值傳遞不同的是什么呢,很明顯的是這次輸出的地址比值傳遞多一個(gè)地址,那這個(gè)多的地址和b的地址一模一樣,可以說明的是指針傳遞的是地址,然后還有不同的是b的值也被改變了,這就指針傳遞和值傳遞的不同。
引用傳遞
引用傳遞的實(shí)質(zhì)
- 形參相當(dāng)于是實(shí)參的“別名”,對形參的操作其實(shí)就是對實(shí)參的操作,在引用傳遞過程中,被調(diào)函數(shù)的形式參數(shù)雖然也作為局部變量在棧中開辟了內(nèi)存空間,但是這時(shí)存放的是由主調(diào)函數(shù)放進(jìn)來的實(shí)參變量的地址。
- 形參的地址是實(shí)參地址的映射,即擁有不同的儲存空間但是里面存放的地址相同。
特點(diǎn)
- 被調(diào)函數(shù)對形參的任何操作都被處理成間接尋址,即通過棧中存放的地址訪問主調(diào)函數(shù)中的實(shí)參變量。正因?yàn)槿绱耍徽{(diào)函數(shù)對形參做的任何操作都影響了主調(diào)函數(shù)中的實(shí)參變量。
運(yùn)用場景
- 適用于傳遞對象、類等復(fù)雜的數(shù)據(jù)類型。引用傳遞是將參數(shù)的引用傳遞給函數(shù),函數(shù)內(nèi)部通過引用來訪問該變量,對該變量的修改也會影響原變量的值。引用傳遞與指針傳遞相似,但使用起來更加簡潔明了。
例子3:最后一個(gè)是引用傳遞,引用傳遞,傳遞的是什么呢?它和值傳遞、指針傳遞不同的地方是什么呢,下面是代碼:
void test(int &a) {
a += 3;
cout << “a的值:” << a << “\n”
<< “a的地址:” << &a << “\n”;
}
void main()
{
int b = 10;
test(b);
cout << “b的值:” << b << “\n”
<< “b的地址:” << &b << “\n”;
}在代碼上是不是發(fā)現(xiàn)和值傳遞差不多,只是參數(shù)聲明哪里比值傳遞的多了一個(gè)&符號其他的和值傳遞一樣,但是就是在參數(shù)聲明哪里多一個(gè)&符號,它就不是值傳遞,它的傳遞方式和值傳遞的是完全不一樣的,所以在寫參數(shù)聲明時(shí),要注意不要在你需要的引用傳遞時(shí)漏了一個(gè)&符號,它們的不同之處在哪里呢,我們看輸出結(jié)果就知道了,下面是結(jié)果:

可以發(fā)現(xiàn)的是a的值和b的值是一樣的,上面我們說指針傳遞時(shí),是輸出了一個(gè)a所指向地址的值,它的值和b的值是一樣,那么引用是不是和指針一樣傳的地址呢,其實(shí)不是的因?yàn)橐脗鬟f其實(shí)是等于把b作為test()函數(shù)的全局變量,為什么這樣說呢,是因?yàn)閍的地址和b相同,然后a所做的所有操作都等于b做的,這a像是b的什么呢,這是名字不同,其他一樣,a其實(shí)就是b的一個(gè)別名,所以test()函數(shù)對a的所有操作,都等于對b進(jìn)行,而a只是b的另外一個(gè)標(biāo)識。
那么有人對引用傳遞還有疑惑對吧,&在參數(shù)處是引用在所有非參數(shù)聲明處都是獲取某個(gè)變量的地址。還有就是引用可不可以解地址對吧,其實(shí)是不可以的,我們可以看一下它如果對引用解地址的話會報(bào)什么錯(cuò)誤。下面錯(cuò)誤提示

它提示的*(解址符)的操作數(shù)必須是指針,意思只能對指針進(jìn)行解址,對其他的類型是不能解址的。
總結(jié):
然后我們總結(jié)一下值傳遞、指針傳遞和引用傳遞不同的地方,首先它們都是可以把值傳遞給函數(shù)的只不過是傳遞的方式不同,有一點(diǎn)是可以很明顯的,指針傳遞和引用傳遞都會改變b的值,值傳遞不會,這就是值傳遞和另外的區(qū)別,而指針傳遞和引用傳遞的不同的地方則是指針傳遞的是b的地址,而引用傳遞則等于給b起了一個(gè)別名,然后通過別名來操作b的值,和它所在的內(nèi)存地址。
總而言之
值傳遞:形參開辟內(nèi)存空間,與形參不同的地址,不能改變值。(變量名的訪問)
地址傳遞:形參不開辟內(nèi)存空間,與形參相同的地址,能改變值。(地址的訪問)
引用傳遞:形參開辟內(nèi)存空間,與形參相同的地址,能改變值。
到此這篇關(guān)于詳解C++ 參數(shù)的三種傳遞方式和應(yīng)用場景的文章就介紹到這了,更多相關(guān)C++ 參數(shù)傳遞方式和應(yīng)用場景內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)鼠標(biāo)控制的黑框象棋
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)鼠標(biāo)控制的黑框象棋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
c語言實(shí)現(xiàn)把文件中數(shù)據(jù)讀取并存到數(shù)組中
下面小編就為大家?guī)硪黄猚語言實(shí)現(xiàn)把文件中數(shù)據(jù)讀取并存到數(shù)組中。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12
利用Matlab實(shí)現(xiàn)迭代適應(yīng)點(diǎn)算法
道格拉斯-普克算法(Douglas–Peucker?algorithm,亦稱為拉默-道格拉斯-普克算法、迭代適應(yīng)點(diǎn)算法、分裂與合并算法)是將曲線近似表示為一系列點(diǎn),并減少點(diǎn)的數(shù)量的一種算法。本文將利用Matlab實(shí)現(xiàn)這一算法,需要的可以參考一下2022-04-04
基于C語言實(shí)現(xiàn)個(gè)人通訊錄管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了基于C語言實(shí)現(xiàn)個(gè)人通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06
詳解QTreeWidget隱藏節(jié)點(diǎn)的兩種方式
本文主要介紹了QTreeWidget隱藏節(jié)點(diǎn)的兩種方式,一種是直接隱藏,一種是間接隱藏,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C++編譯器無法捕捉到的8種錯(cuò)誤實(shí)例分析
這篇文章主要介紹了C++編譯器無法捕捉到的8種錯(cuò)誤,是深入學(xué)習(xí)C++所必須加以掌握的排錯(cuò)技能,需要的朋友可以參考下2014-09-09

