詳解C++ 參數(shù)的三種傳遞方式和應(yīng)用場(chǎng)景
值傳遞
值傳遞的實(shí)質(zhì)
- 將實(shí)參的值(a、b)復(fù)制到形參(m、n)相應(yīng)的存儲(chǔ)單元中,即形參和實(shí)參分別占用不同的存儲(chǔ)單元。
值傳遞的特點(diǎn)
- 值傳遞的特點(diǎn)是單向傳遞,即主調(diào)函數(shù)被調(diào)用時(shí)給形參分配存儲(chǔ)單元,把實(shí)參的值傳遞給形參,在調(diào)用結(jié)束后,形參的存儲(chǔ)單元被釋放,而形參值的任何變化都不會(huì)影響到實(shí)參的值,實(shí)參的存儲(chǔ)單元仍保留并維持?jǐn)?shù)值不變。
值傳遞的應(yīng)用場(chǎng)景
- 適用于傳遞簡(jiǎn)單的數(shù)據(jù)類型,如int、float、double等。傳值是將參數(shù)的值傳遞給函數(shù),函數(shù)內(nèi)部會(huì)創(chuàng)建一個(gè)新的變量來存儲(chǔ)該值,對(duì)該變量的修改不會(huì)影響原變量的值。
例子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è)簡(jiǎn)單的值傳遞,而地址就是內(nèi)存位置,學(xué)過C++的人都清楚,下面是運(yùn)行的結(jié)果
根據(jù)代碼和結(jié)果我們可以知道的是值傳傳遞的參數(shù)是有自己的內(nèi)存的,并且當(dāng)b把自己的值傳遞進(jìn)去之后,對(duì)b是沒有影響的,那么值傳遞則是等于把b的值賦給了a等于進(jìn)行了一個(gè)賦值操作這就是值傳遞。
指針傳遞
指針傳遞的實(shí)質(zhì)
- 所謂的地址傳遞,指的就是函數(shù)的參數(shù)是數(shù)組名或者指針。傳遞的是數(shù)組的首地址或指針的值,而形參接收到的是實(shí)參的地址,即指向?qū)崊⒌拇鎯?chǔ)單元,形參和實(shí)參占用相同的存儲(chǔ)單元,所以形參和實(shí)參是相同的。
特點(diǎn)
- 形參并不存在存儲(chǔ)空間,編譯系統(tǒng)不為形參數(shù)組分配內(nèi)存。因此在數(shù)組名或指針作函數(shù)參數(shù)時(shí)所進(jìn)行的傳送只是地址傳送,形參在取得該地址之后,與實(shí)參共同擁有一段內(nèi)存空間,形參的變化也就是實(shí)參的變化。
運(yùn)用場(chǎng)景
- 適用于傳遞數(shù)組、結(jié)構(gòu)體等復(fù)雜的數(shù)據(jù)類型。指針傳遞是將參數(shù)的地址傳遞給函數(shù),函數(shù)內(nèi)部通過指針來訪問該變量,對(duì)該變量的修改會(huì)影響原變量的值。
例子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)和值傳遞的差別,指針是存儲(chǔ)地址的,當(dāng)我們想要把b的值傳進(jìn)test()函數(shù)時(shí),我們傳的是b的地址,然后通過b的地址,來獲得b的值,下面是結(jié)果
我們輸出的跟值傳遞不同的是什么呢,很明顯的是這次輸出的地址比值傳遞多一個(gè)地址,那這個(gè)多的地址和b的地址一模一樣,可以說明的是指針傳遞的是地址,然后還有不同的是b的值也被改變了,這就指針傳遞和值傳遞的不同。
引用傳遞
引用傳遞的實(shí)質(zhì)
- 形參相當(dāng)于是實(shí)參的“別名”,對(duì)形參的操作其實(shí)就是對(duì)實(shí)參的操作,在引用傳遞過程中,被調(diào)函數(shù)的形式參數(shù)雖然也作為局部變量在棧中開辟了內(nèi)存空間,但是這時(shí)存放的是由主調(diào)函數(shù)放進(jìn)來的實(shí)參變量的地址。
- 形參的地址是實(shí)參地址的映射,即擁有不同的儲(chǔ)存空間但是里面存放的地址相同。
特點(diǎn)
- 被調(diào)函數(shù)對(duì)形參的任何操作都被處理成間接尋址,即通過棧中存放的地址訪問主調(diào)函數(shù)中的實(shí)參變量。正因?yàn)槿绱?,被調(diào)函數(shù)對(duì)形參做的任何操作都影響了主調(diào)函數(shù)中的實(shí)參變量。
運(yùn)用場(chǎng)景
- 適用于傳遞對(duì)象、類等復(fù)雜的數(shù)據(jù)類型。引用傳遞是將參數(shù)的引用傳遞給函數(shù),函數(shù)內(nèi)部通過引用來訪問該變量,對(duì)該變量的修改也會(huì)影響原變量的值。引用傳遞與指針傳遞相似,但使用起來更加簡(jiǎn)潔明了。
例子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è)&符號(hào)其他的和值傳遞一樣,但是就是在參數(shù)聲明哪里多一個(gè)&符號(hào),它就不是值傳遞,它的傳遞方式和值傳遞的是完全不一樣的,所以在寫參數(shù)聲明時(shí),要注意不要在你需要的引用傳遞時(shí)漏了一個(gè)&符號(hào),它們的不同之處在哪里呢,我們看輸出結(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ù)對(duì)a的所有操作,都等于對(duì)b進(jìn)行,而a只是b的另外一個(gè)標(biāo)識(shí)。
那么有人對(duì)引用傳遞還有疑惑對(duì)吧,&在參數(shù)處是引用在所有非參數(shù)聲明處都是獲取某個(gè)變量的地址。還有就是引用可不可以解地址對(duì)吧,其實(shí)是不可以的,我們可以看一下它如果對(duì)引用解地址的話會(huì)報(bào)什么錯(cuò)誤。下面錯(cuò)誤提示
它提示的*(解址符)的操作數(shù)必須是指針,意思只能對(duì)指針進(jìn)行解址,對(duì)其他的類型是不能解址的。
總結(jié):
然后我們總結(jié)一下值傳遞、指針傳遞和引用傳遞不同的地方,首先它們都是可以把值傳遞給函數(shù)的只不過是傳遞的方式不同,有一點(diǎn)是可以很明顯的,指針傳遞和引用傳遞都會(huì)改變b的值,值傳遞不會(huì),這就是值傳遞和另外的區(qū)別,而指針傳遞和引用傳遞的不同的地方則是指針傳遞的是b的地址,而引用傳遞則等于給b起了一個(gè)別名,然后通過別名來操作b的值,和它所在的內(nèi)存地址。
總而言之
值傳遞:形參開辟內(nèi)存空間,與形參不同的地址,不能改變值。(變量名的訪問)
地址傳遞:形參不開辟內(nèi)存空間,與形參相同的地址,能改變值。(地址的訪問)
引用傳遞:形參開辟內(nèi)存空間,與形參相同的地址,能改變值。
到此這篇關(guān)于詳解C++ 參數(shù)的三種傳遞方式和應(yīng)用場(chǎng)景的文章就介紹到這了,更多相關(guān)C++ 參數(shù)傳遞方式和應(yīng)用場(chǎng)景內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言小項(xiàng)目實(shí)戰(zhàn)之通訊錄功能
這篇文章主要介紹了如何設(shè)計(jì)和實(shí)現(xiàn)一個(gè)簡(jiǎn)單的通訊錄管理系統(tǒng),包括聯(lián)系人信息的存儲(chǔ)、增加、刪除、查找、修改和排序等功能,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01C++用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列(面試官的小結(jié))
這篇文章主要給大家介紹了關(guān)于C++用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列的相關(guān)資料,這是來自一名面試官的小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05C語(yǔ)言循環(huán)結(jié)構(gòu)深入刨析
C語(yǔ)言條件控制語(yǔ)句選擇結(jié)構(gòu),是屬于計(jì)算機(jī)的語(yǔ)言編輯,有在C語(yǔ)言條件控制中的語(yǔ)句選擇結(jié)構(gòu)的存在,即是C語(yǔ)言條件控制語(yǔ)句選擇結(jié)構(gòu),循環(huán)控制語(yǔ)句是一個(gè)基于C語(yǔ)言的編程語(yǔ)句,該語(yǔ)句主要有while循環(huán)語(yǔ)句、do-while循環(huán)語(yǔ)句和for循環(huán)語(yǔ)句來實(shí)現(xiàn)循環(huán)結(jié)構(gòu)2022-08-08STL區(qū)間成員函數(shù)及區(qū)間算法總結(jié)
這篇文章主要匯總介紹了STL區(qū)間成員函數(shù)及區(qū)間算法,有需要的小伙伴可以參考下。2015-07-07C語(yǔ)言對(duì)于volatile與gcc優(yōu)化的探究
這篇文章主要介紹了C語(yǔ)言對(duì)于volatile與gcc優(yōu)化的探究,volatile是一個(gè)特征修飾符(type specifier) volatile的作用是作為指令關(guān)鍵字,確保本條指令不會(huì)因編譯器的優(yōu)化而省略,且要求每次直接讀值。這是百度百科的介紹,那編譯器是具體是怎么優(yōu)化的呢2023-02-02FFRPC應(yīng)用 Client/Server使用及原理解析
這篇文章主要介紹了FFRPC應(yīng)用 Client/Server使用及原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08