1樓:
是這樣的
當你給函式形參傳值時,其實上可以理解為用實參初始化形參然後很多的初始化過程都是直接複製/呼叫複製建構函式,但是引用卻不是簡單的複製
其實上可以理解為
int a;//實參
int&b=a;//用實參初始化形參
簡直天經地義
2樓:573xmcgcg
使用指標或者引用作為形參是為了解決按值傳遞可能導致的問題。
所以這裡再次講一下使用指標,引用和值作為形參所導致的結果。
C++教科書都會用乙個交換兩個變數的值的函式來舉例:
void
swap
(inta,
intb
);//使用指標和引用的情況下形參型別分別為int*和int&
結果是怎麼樣的題主應該清楚:按值傳遞無法完成這一行為,而傳遞指標或者引用是可行的。
那麼原因是什麼?
在按值傳遞的情況下:
intx=4
,y=5
;swap(x
,y);main函式其它部分
void
swap
(inta,
intb
)第一步:編譯器會在記憶體開闢兩個能存放int型變數的區域(假設分別為0xAAAAAAAA和0xBBBBBBBB),用於儲存x和y的值。
第二步:swap函式接收x和y的值,編譯器會另外開闢兩個存放int型變數的區域(假設分別為0xCCCCCCCC和0xDDDDDDDD),將4和5分別賦給形參a和b。
第三步:swap函式完成交換,此時形參a=5, b=4,但是實參x和y的值並沒有發生變化。因為swap函式只交換了0xCCCCCCCC和0xDDDDDDDD兩塊區域儲存的值,並沒有影響到0xAAAAAAAA和0xBBBBBBBB。
所以x和y本身沒有受到swap函式的影響,交換失敗。
形參為指標的情況下:
intx=4
,y=5
;int*px
=&x,
*py=&
y;swap(px
,py);main函式其它部分
void
swap
(int*a
,int*b
)第一步:編譯器會在記憶體開闢兩個能存放int型變數的區域(假設分別為0xAAAAAAAA和0xBBBBBBBB),用於儲存x和y的值。
第二步:編譯器會在記憶體開闢兩個能存放int型指標的區域(假設分別為0xCCCCCCCC和0xDDDDDDDD),兩塊區域分別儲存x和y的位址(即0xAAAAAAAA和0xBBBBBBBB)
第三步:swap函式接收px和py的值,編譯器會另外開闢兩個存放int型指標的區域(假設分別為0xEEEEEEEE和0xFFFFFFFF),將0xAAAAAAAA和0xBBBBBBBB分別賦給形參a和b。
第四步:swap函式創造乙個int型變數temp,假設位址為0xGGGGGGGG。
第五步:
temp=*
a;*a的值就是x的值(即4),temp獲得4這個值。
第六步:*a=
*b;形參a的值是0xAAAAAAAA,所以這一句將0xAAAAAAAA這一塊記憶體所儲存的值由4修改為5,而0xAAAAAAAA正是x的位址。也就是說x本身的值被改成了5。
第七步:*b
=temp
;同理,形參b的值是0xBBBBBBBB,這一句將0xBBBBBBBB這一塊記憶體所儲存的值由5修改為4,而0xBBBBBBBB正是y的位址。也就是說y本身的值被改成了4。
swap函式執行完畢後x和y的值分別為5和4,交換成功。
在這種情況下,如果傳入兩個int型變數而不是int型指標,則編譯不會通過。因為int型變數並不是位址,在a為int型變數的情況下,*a並不是*符號的合法用途。
形參為引用的情況下:
intx=4
,y=5
;swap(x
,y);main函式其它部分
void
swap
(int&a
,int&b
)第一步:編譯器會在記憶體開闢兩個能存放int型變數的區域(假設分別為0xAAAAAAAA和0xBBBBBBBB),用於儲存x和y的值。
第二步:兩個int型引數傳入swap函式,函式將形參a和b分別宣告為x和y的引用。此時a的位址和x一樣是0xAAAAAAAA,b的位址和y一樣是0xBBBBBBBB。
第三步:此時swap函式交換a和b的值,由於a和b的位址分別與x和y的位址相同(即0xAAAAAAAA和0xBBBBBBBB),該函式完成了對x和y的值的交換。交換後0xAAAAAAAA儲存的值為5,0xBBBBBBBB儲存的值為4。
當形參型別為引用時,實參和形參共享乙個位址,對形參的修改也就是對實參的修改。
可以看到,使用指標和引用分別實現交換變數值的機制是不同的。儘管兩種方法都直接對x和y的位址儲存的值進行了修改,但是當形參是指標時,a和b的值並未發生變化(依然分別是x和y的位址);而當形參是引用時,a和b的值發生了變化。
最後回到問題本身:
為什麼形參是引用int &,既可以是int &又可以是int呢?舉個例子:
#include
using
namespace
std;
intmain
()在這個例子中,ra*rb的結果和a*b完全一致,儘管ra和rb是指向int型變數的引用,但是ra和rb在被宣告為引用以後也可以被當作int型變數進行處理。而pa和pb是指向int型變數的指標,它們儲存的是a和b的位址而不是a和b的值,所以對pa和pb進行int型變數的運算是非法的。
如果說形參是引用int &,傳int進去是為了繫結到實參上,那傳乙個已經繫結的int &進去是繫結什麼呢?
修改一下上面的例子:
#include
using
namespace
std;
intmain
()在這個例子中,rra為指向【指向int型變數的引用】的引用,國內的C++教科書在講到引用也會提一下指向引用的引用是合法的。在這種情況下,ra被引用是會被當作普通的int型變數處理。
當乙個int&引數傳入swap函式的時候,同樣地,該int&引數會被當作乙個int型變數,然後形參就是這個變數的引用。所以在這種情況下傳入int或int&的輸出都是一樣的。
c語言中,形參就是變數嗎?為什麼說函式的形參可以是指標型別?
C語言答疑課堂 別說形參了,實參也是變數,傳遞給函式的引數都是變數。指標也是一種變數,跟int變數,char變數一樣,都是變數。既然都是變數,函式大爺全然接受。 形參就是函式的引數 什麼是引數?比如你在dos下敲個命令dir如果目錄太多的話一螢幕顯示不完。那麼敲 dir p就可以分屏顯示,這個 p就...
C 1x模板如何確定確切形參型別的函式是否存在
土地測量員 class Person class Student public Person class Manager template T typename std add lvalue reference type declval l noexcept template Manager voi...
C語言 如何在函式體內,自動判斷傳入的陣列引數的長度。
飛著走的魚 裸陣列 內建 不可以判斷,陣列長度需要傳遞進去。這算是C語言本身的一種風格 要獲得可以判斷長度的陣列,需要自己設計陣列型別,用struct定義,並使用動態分配記憶體。 孔乙己 main函式的一般形式是 main int argc,char argv argc就是後邊那個argv陣列的個數...