1. 程式人生 > >一、初級篇——指標(*)、取地址(&)、解引用(*)與引用(&)的區別

一、初級篇——指標(*)、取地址(&)、解引用(*)與引用(&)的區別

1. 初步瞭解——指標與取地址

先看程式:

#include<stdio.h>

int main(void)
{
	int num = 7;
	int *p = &num;//初始化指標,也可以寫作int* p = &num;
	printf("%d 的地址是 %p\n", num, p);
	return 0;
}
上面int *p定義了一個指向int型別指標p(我們使用*符號把p宣告為指標),並初始化p使其指向int型別的變數num,這裡&num中的&是取地址操作符,當&作用於一個物件上時,它返回了該物件的地址。

所以這裡指標p指向了num所對應的地址。(我測試時輸出了0028FF1C)

2. 如何使用指標?——解引用與指標賦值

讓我們繼續:

#include<stdio.h>

int main(void)
{
	int num = 7;
	int *p = &num;
	printf("數值%d所在的地址是 %p\n", num, p);
	printf("指標p所指向的地址為 %p , 該地址上所儲存的值為%d\n", p, *p);
	*p = 100;
	printf("指標p所指向的地址為 %p , 該地址上所儲存的值為%d\n", p, num);
	return 0;
}

注意這裡*操作符為解引用操作符,它返回指標p所指的物件(左值)。

我們可以對*p賦值(對左值賦值),從而改變p所指的地址上所儲存的值,從而改變此地址所儲存的變數num的值。(上面num的值變為100)

當然,我們也可以給指標p賦值,使其指向另外一個地址(這樣就改變了在解引用時獲取的左值):

#include<stdio.h>

int main(void)
{
	int num = 7, another = -5;
	int *p = &num;
	p = &another;
	printf("%d\n", *p);//此時p指向了another,所以輸出了another的值,即-5
	return 0;
}

3. 引用(引用概念在C++中才有,C中並沒有)

從某種意義上來說,引用完全有別於上面說介紹的內容:

#include<cstdio>

int main()
{
	int val = 7, val2 = 999;
	int &refval = val, &refval2 = val2; ///引用必須要初始化,使其繫結到一個變數上
	///修改引用的值將改變其所繫結的變數的值
	refval = -12;
	printf("%d %d\n", val, refval);//-12,refval的值和val一樣
	
	///將引用b賦值給引用a將改變引用a所繫結的變數的值,
	///引用一但初始化(繫結),將始終繫結到同一個特定物件上,無法繫結到另一個物件上
	refval = refval2;
	printf("%d %d\n", val, refval);//999
	return 0;
}

關鍵:作用在引用上的所有操作事實上都是作用在該引用所繫結的物件上。

可以用int *&refp = p;的方式將一個指標引用和一個指標繫結起來。

PS:如果還是不理解,可以把引用認為是一個物件的別名(外號、簡稱等等)。(類比#define ...,typedef ...)

答疑:使用引用有何優點?

在傳參的時候,使用指標傳參,編譯器需要給指標另行分配儲存單元,儲存一個該指標的副本,在函式中對這個副本進行操作;而使用引用傳參,編譯器就不需要分配儲存空間和儲存副本了,函式將直接對實參進行操作。所以使用引用使得程式的執行速度更快,執行效率更高。