引用的理解
轉(zhuǎn)自:http://blog.csdn.net/wanwenweifly4/article/details/6739687
引用類(lèi)型到底是什么?它和指針有什么關(guān)系?它本身占用內(nèi)存空間嗎? 帶著這些疑問(wèn),我們來(lái)進(jìn)行分析。 先看代碼:
#include <stdio.h> #include <iostream>using namespace std;void main() {int x = 1;int &b = x;}通過(guò)匯編查看代碼如下:
9: int x = 1; 00401048 mov dword ptr [ebp-4],1 10: int &b = x; 0040104F lea eax,[ebp-4] 00401052 mov dword ptr [ebp-8],eax可以知道x的地址為ebp-4,b的地址為ebp-8,因?yàn)闂?nèi)的變量?jī)?nèi)存是從高往低進(jìn)行分配的。所以b的地址比x的低。
lea eax,[ebp-4] 這條語(yǔ)句將x的地址ebp-4放入eax寄存器
mov dword ptr [ebp-8],eax 這條語(yǔ)句將eax的值放入b的地址ebp-8中
上面兩條匯編的作用即:將x的地址存入變量b中,這不和將某個(gè)變量的地址存入指針變量是一樣的嗎?
所以從匯編層次來(lái)看,的確引用是通過(guò)指針來(lái)實(shí)現(xiàn)的。
下面我們通過(guò)程序來(lái)驗(yàn)證,我們知道,在程序一層我們只要直接涉及到引用變量的操作,我們操作的總是被引用變量,即編譯器幫我們做了些手腳,總是在引用前面加上*。所以我們要讀取真正的“引用變量的值”,必須采取一定的策略,好吧,我們就按照變量在棧中分布的特點(diǎn)來(lái)繞過(guò)編譯器的這個(gè)特點(diǎn)。
#include <stdio.h> #include <iostream>using namespace std;void main() {int x = 1;int y = 2;int &b = x;printf("&x=%x,&y=%x,&b=%x,b=%x\n",&x,&y,&y-1,*(&y-1));} 輸出結(jié)果為:&x=12ff7c,&y=12ff78,&b=12ff74,b=12ff7c
Press any key to continue void main() {int x = 1;int &b = x;printf("&x=%x,&b=%x\n",&x,&b);} 輸出結(jié)果為::&x=12ff7c,&b=12ff7c.
b的地址我們沒(méi)法通過(guò)&b獲得,因?yàn)榫幾g器會(huì)將&b解釋為:&(*b) =&x ,所以&b將得到&x。也驗(yàn)證了對(duì)所有的b的操作,和對(duì)x的操作等同。
但是我們可以間接通過(guò)&y-1來(lái)得到b的地址,從而得到b的值:*(&y-1) 從結(jié)果可以知道,b的值即x的地址,從而可以知道,從地層實(shí)現(xiàn)來(lái)看,引用變量的確存放的是被引用對(duì)象的地址,只不過(guò),對(duì)于高級(jí)程序員來(lái)說(shuō)是透明的,編譯器屏蔽了引用和指針的差別。
下面是程序的變量在內(nèi)存棧中的分布,引用變量一樣也占用內(nèi)存空間,而且應(yīng)該是4個(gè)字節(jié)的空間。
雖然從底層來(lái)說(shuō),引用的實(shí)質(zhì)是指針,但是從高層語(yǔ)言級(jí)別來(lái)看,我們不能說(shuō)引用就是指針,他們是兩個(gè)完全不同的概念。有人說(shuō)引用是受限的指針,這種說(shuō)法我不贊同,因?yàn)閺恼Z(yǔ)言級(jí)別上,指針和引用沒(méi)有關(guān)系,引用就是另一個(gè)變量的別名。對(duì)引用的任何操作等價(jià)于對(duì)被引用變量的操作。從語(yǔ)言級(jí)別上,我們就不要去考慮它的底層實(shí)現(xiàn)機(jī)制啦,因?yàn)檫@些對(duì)你是透明的。所以在面試的時(shí)候,如果面試的人問(wèn)到這個(gè)問(wèn)題,可以先從語(yǔ)言級(jí)別上談?wù)勔?#xff0c;深入的話就從底層的實(shí)現(xiàn)機(jī)制進(jìn)行分析。而不能什么條件沒(méi)有就說(shuō):引用就是指針,沒(méi)有差別,......之類(lèi)的回答
、
以下內(nèi)容摘自網(wǎng)上,覺(jué)得挺好的,借用過(guò)來(lái)
什么是引用?
對(duì)象的別名(另一個(gè)名稱(chēng))。
引用經(jīng)常用于“按引用傳遞(pass-by-reference)”: void swap(int& i, int& j){int tmp = i;i = j;j = tmp;}int main(){int x, y;// ...swap(x,y);}此處的 i 和 j 分別是main中的 x 和 y。換句話說(shuō),i 就是x —— 并非指向 x 的指針,也不是x 的拷貝,而是 x 本身。對(duì) i 的任何改變同樣會(huì)影響x,反之亦然。
OK,這就是作為一個(gè)程序員所認(rèn)知的引用。現(xiàn)在,給你一個(gè)不同的角度,這可能會(huì)讓你更糊涂,那就是引用是如何實(shí)現(xiàn)的。典型的情況下,對(duì)象 x 的引用i 是x 的機(jī)器地址。但是,當(dāng)程序員寫(xiě) i++ 時(shí),編譯器產(chǎn)生增加 x 的代碼。更詳細(xì)的來(lái)說(shuō),編譯器用來(lái)尋找x 的地址位并沒(méi)有被改變。C 程序員將此認(rèn)為好像是 C 風(fēng)格的按指針傳遞,只是句法不同 (1) 將 & 從調(diào)用者移到了被調(diào)用者處,(2)消除了*s。換句話說(shuō),C 程序員會(huì)將i 看作為宏(*p),而 p 就是指向 x 的指針(例如,編譯器自動(dòng)地將潛在的指針解除引用;i++被改變?yōu)?*p)++;i = 7 被自動(dòng)地轉(zhuǎn)變成*p = 7)。
很重要:請(qǐng)不要將引用看作為指向一個(gè)對(duì)象的奇異指針,即使引用經(jīng)常是用匯編語(yǔ)言下的地址來(lái)實(shí)現(xiàn)的。引用就是對(duì)象。不是指向?qū)ο蟮闹羔?#xff0c;也不是對(duì)象的拷貝,就是對(duì)象。
?
?以下內(nèi)容摘自網(wǎng)上,覺(jué)得挺好的,借用過(guò)來(lái)
總結(jié)
- 上一篇: 剑指offer 算法 (发散思维能力)
- 下一篇: 用位运算实现四则运算之加减乘除