2014-03-30 31 views
0

我有一個簡單的問題,並希望通過引用傳遞背後的基礎邏輯。通過引用傳遞的不一致性 - 通過引用傳遞的這個簡單示例如何工作?

這裏有一個代碼(姑且稱之爲代碼1):

void fn(int& a) 
{ 
    a = 6; 
} 

int main() 
{ 
    int b = 5; 
    fn(b); 
    cout << b; 
} 

這裏的另一個代碼(代碼2):

void fn(int* ptr) 
{ 
    *ptr = 6; 
} 

int main() 
{ 
    int b = 5; 
    fn(&b); 
    cout << b; 
} 

,按價值計算碼通(代碼3):

void fn(int a) 
{ 
    a = 6; 
} 

int main() 
{ 
    int b = 5; 
    fn(b); 
    cout << b; 
} 

這裏是我的問題。直觀上,我發現在傳遞值(Code3)的同時,這些值被複制,即只需要將自己的值複製到b。因此,作爲一般規則,我發現傳遞的值總是被複制到被調用的函數(這裏是fn)。即使使用指針代碼(即Code2)Code 2的第一行確保int *ptr = &a;

我不明白這將如何在Code1中工作。說&a = b是沒有意義的。這是一個例外,還是這符合與上述段落中討論的情況一致的規則?

謝謝!

回答

2

在這個函數:

void fn(int &a) { 
a=6; 
} 

術語 「&一個」 並不意味着 「變量a的地址」。它的意思是「一個名爲a的參考文獻」。代碼1和代碼2實際上是相同的(但是請注意,代碼2中的功能可以傳遞一個無效的指針,這對於代碼1來說(幾乎)是不可能的)。

+0

「,這對代碼1來說(幾乎)是不可能的」這基本上是一種語義上的區別。所有的編譯器都在下面實現引用作爲指針,如果你有像'void fn2(int * a){fn(* a); }',它會編譯這個函數,只是簡單地傳遞地址,而不是「解除引用」。所以*有效*你可以像傳遞一個無效指針那樣容易地傳遞一個無效的引用。一個語言純粹主義者會說無效指針的解引用表達是未定義的行爲,所以之後的任何東西都是沒有意義的。但這只是一個學術技術性問題,對程序員來說是不可見的。 – newacct

2

對於大多數意圖和目的,引用只是一個僞裝的指針。不同的語法,相同的效果(大部分)。

+0

你想要引用的唯一原因是a)指針通常太過泛泛和強大,b)我們喜歡語法糖。讓編譯器消除理解指針的沉重負擔。 – Deduplicator

+0

@Deduplicator我從來沒有買過參數a。它使得指針看起來像是黑暗的魔法,並且阻止瞭解它們。 –

+0

如果您實際上不需要對指針本身執行算術運算,則會消除一個間接概念級別。在大約4-5星的時候,你應該爲此感謝......否則,它肯定只有糖。 – Deduplicator

0

從概念上講,在你的第一種情況下,會發生什麼是同一個變量有兩個標籤:b,在main()範圍內可見;和a,在fn的範圍內可見。

您不必擔心編譯器在「幕後」執行此概念的功能。

如果您從心理上推動編譯器的「幕後」操作,以真正成爲C++的想象原則, 「引用是僞裝的指針」,那麼它會讓你對實際上是一個非常簡單的概念感到困惑:給變量賦予多個名字的能力。

作爲函數參數沒什麼特別的;例如你可以在main()寫:

int a; 
int &c = a; 

這是完全等同於:

int c; 
int &a = c; 

在這兩種情況下,有一個int變量有兩個標籤,ac