從概念上講。指標從本質上講就是存放變數位址的乙個變數,在邏輯上是獨立的,它可以被改變,包括其所指向的位址的改變和其指向的位址中所存放的資料的改變。
而引用是乙個別名,它在邏輯上不是獨立的,它的存在具有依附性,所以引用必須在一開始就被初始化,而且其引用的物件在其整個生命週期中是不能被改變的(自始至終只能依附於同乙個變數)。
在c++中,指標和引用經常用於函式的引數傳遞,然而,指標傳遞引數和引用傳遞引數是有本質上的不同的:
指標傳遞引數本質上是值傳遞的方式,它所傳遞的是乙個位址值。值傳遞過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在棧中開闢了記憶體空間以存放由主調函式放進來的實參的值,從而成為了實參的乙個副本。值傳遞的特點是被調函式對形式引數的任何操作都是作為區域性變數進行,不會影響主調函式的實參變數的值。
而在引用傳遞過程中,被調函式的形式引數雖然也作為區域性變數在棧中開闢了記憶體空間,但是這時存放的是由主調函式放進來的實參變數的位址。被調函式對形參的任何操作都被處理成間接定址,即通過棧中存放的位址訪問主調函式中的實參變數。正因為如此,被調函式對形參做的任何操作都影響了主調函式中的實參變數。
引用傳遞和指標傳遞是不同的,雖然它們都是在被調函式棧空間上的乙個區域性變數,但是任何對於引用引數的處理都會通過乙個間接定址的方式操作到主調函式中的相關變數。而對於指標傳遞的引數,如果改變被調函式中的指標位址,它將影響不到主調函式的相關變數。如果想通過指標引數傳遞來改變主調函式中的相關變數,那就得使用指向指標的指標,或者指標引用。
為了進一步加深大家對指標和引用的區別,下面我從編譯的角度來闡述它們之間的區別:
程式在編譯時分別將指標和引用新增到符號表上,符號表上記錄的是變數名及變數所對應位址。指標變數在符號表上對應的位址值為指標變數的位址值,而引用在符號表上對應的位址值為引用物件的位址值。符號表生成後就不會再改,因此指標可以改變其指向的物件(指標變數中的值可以改),而引用物件則不能修改。
最後,總結一下指標和引用的相同點和不同點:
★相同點:
●都是位址的概念;
指標指向一塊記憶體,它的內容是所指記憶體的位址;而引用則是某塊記憶體的別名。
★不同點:
●指標是乙個實體,而引用僅是個別名;
●引用只能在定義時被初始化一次,之後不可變;指標可變;引用「從一而終」,指標可以「見異思遷」;
●引用沒有const,指標有const,const的指標不可變;
●引用不能為空,指標可以為空;
●「sizeof 引用」得到的是所指向的變數(物件)的大小,而「sizeof 指標」得到的是指標本身的大小;
●指標和引用的自增(++)運算意義不一樣;
●引用是型別安全的,而指標不是 (引用比指標多了型別檢查
c++引用與指標的比較
引用是c++中的概念,初學者容易把引用和指標混淆一起。
一下程式中,n是m的乙個引用(reference),m是被引用物(referent)。
int m;
int &n = m;
n相當於m的別名(綽號),對n的任何操作就是對m的操作。
所以n既不是m的拷貝,也不是指向m的指標,其實n就是m它自己。
引用的規則:
(1)引用被建立的同時必須被初始化(指標則可以在任何時候被初始化)。
(2)不能有null引用,引用必須與合法的儲存單元關聯(指標則可以是null)。
(3)一旦引用被初始化,就不能改變引用的關係(指標則可以隨時改變所指的物件)。
以下示例程式中,k被初始化為i的引用。
語句k = j並不能將k修改成為j的引用,只是把k的值改變成為6。
由於k是i的引用,所以i的值也變成了6。
int i = 5;
int j = 6;
int &k = i;
k = j; // k和i的值都變成了6;
引用的主要功能是傳遞函式的引數和返回值。
c++語言中,函式的引數和返回值的傳遞方式有三種:值傳遞、指標傳遞和引用傳遞。
以下是"值傳遞"的示例程式。
由於func1函式體內的x是外部變數n的乙份拷貝,改變x的值不會影響n, 所以n的值仍然是0。
void func1(int x)
...
int n = 0;
func1(n);
cout << "n = " << n << endl; // n = 0
以下是"指標傳遞"的示例程式。
由於func2函式體內的x是指向外部變數n的指標,改變該指標的內容將導致n的值改變,所以n的值成為10。
void func2(int *x)
...
int n = 0;
func2(&n);
cout << "n = " << n << endl; // n = 10
以下是"引用傳遞"的示例程式。
由於func3函式體內的x是外部變數n的引用,x和n是同乙個東西,改變x等於改變n,所以n的值成為10。
void func3(int &x)
...
int n = 0;
func3(n);
cout << "n = " << n << endl; // n = 10
對比上述三個示例程式,會發現"引用傳遞"的性質象"指標傳遞",而書寫方式象"值傳遞"。
實際上"引用"可以做的任何事情"指標"也都能夠做,為什麼還要"引用"這東西?
答案是"用適當的工具做恰如其分的工作"。
指標能夠毫無約束地操作記憶體中的任何東西,儘管指標功能強大,但是非常危險。
如果的確只需要借用一下某個物件的"別名",那麼就用"引用",而不要用"指標",以免發生意外。
C 引用和指標區別
一 引用簡介 引用就是某一變數 目標 的乙個別名,對引用的操作與對變數直接操作完全一樣。引用的宣告方法 型別識別符號 引用名 目標變數名 例1 int a int ra a 定義引用ra,它是變數a的引用,即別名 說明 1 在此不是求位址運算,而是起標識作用。2 型別識別符號是指目標變數的型別。3 ...
C 引用和指標的區別
很久沒寫過這類文章了,本來是想做下筆記,既然要做筆記,不如寫下部落格,就動起手來。文采不怎麼樣,還忘大家見諒 c 引用變數是c 中新增的一種復合型別,也就是說標準c語言中沒有引用變數。所謂引用,實際上就是乙個已定義變數的別名,別名我想大家小時候都有,應該可以理解,別名表示的是同乙個人,這裡引用變數和...
C 引用和指標的區別
c 引用和指標在間接使用其他物件的各種操作功能上面類似,但是兩者的不同之處也很明顯 1.指標本身佔據記憶體空間,但是引用只是乙個物件的別名,本身不分配記憶體空間 2.指標定義時可以不初始化,但是定義乙個引用必須進行初始化,並且初始化時只能是乙個物件 比如 int b 3.14 這樣是錯的,要明白 引...