指標指向一塊記憶體,
它的內容是所指記憶體的位址;而引用則是某塊記憶體的別名,
引用初始化後不能改變指向。
使用時,
引用更加安全,
指針更加靈活。
在任何情況下都不能使用指向空值的引用。 一個引用必須總是指向某些物件。 因此如果你使用一個變數並讓它指向一個物件, 但是該變數在某些時候也可能不指向任何物件, 這時你應該把變數聲明為指標, 因為這樣你可以賦空值給該變數。 相反, 如果變數肯定指向一個物件, 例如你的設計不允許變數為空, 這時你就可以把變數聲明為引用。
指標可以被重新賦值以指向另一個不同的物件。
但是引用則總是指向在初始化時被指定的物件,
以後不能改變,
但是指定的物件其內容可以改變。
在使用引用之前不需要測試它的合法性。 相反, 指標則應該總是被測試, 防止其為空。 引用必須初始化, 指標可以不必初始化。
4 引用、指針與const。存在常量指標和常量引用指標, 表示指向的物件是常量, 不能通過指標或者常量修改常量;存在指標常量,
總的來說, 在以下情況下應該使用指標:一是考慮到存在不指向任何物件的可能(在這種情況下, 能夠設置指標為空), 二是需要能夠在不同的時刻指向不同的物件(在這種情況下, 你能改變指標的指向)。 如果總是指向一個物件並且一旦指向一個物件後就不會改變指向, 那麼應該使用引用。
6 其它區別函數參數傳遞時使用指標或者引用的效果是相同的, 都是簡潔操作主調函數中的相關變數, 當時引用會更加的安全, 因為指標一些修改指向, 將不能影響主調函數中的相關變數。
sizeof引用的時候是物件的大小, sizeof指標是指標本身的大小;
指標和引用的自增(++)運算意義不一樣;
引用使用時無需解引用(*), 指標需要解引用;
在重載操作符並為防止不必要的語義誤解時, 通常使用引用;
7 代碼說明int a,b,*p,&r=a; //正確
r=3; //正確:等價於a=3
int &rr; //出錯:引用必須初始化
p=&a; //正確:p中存儲a的位址, 即p指向a
*p=4; //正確:p中存的是a的位址, 對a所對應的存儲空間存入值4
p=&b; //正確:p可以多次賦值, p存儲b的位址
通俗化說明在C和C++中, 指標一般指的是某塊記憶體的位址, 通過這個位址, 我們可以定址到這塊記憶體;而引用是一個變數的別名,
對於指標來說, 它是一個位址, 這個位址是一個數值, 那麼就意味這個數值可以為0(空指標), 也可以為其他, 即指標可以不指向任何東西。
而對於引用來說, 他是一個外號, 外號一定是“某個存在物體”的外號, 所以引用不能為空, 即不能存在空引用。
根據以上可知指標和引用的一個重要不同:指標可以為空, 引用不能為空。 這就意味著我們拿到一個引用的時候, 是不需要判斷引用是否為空的, 而拿到一個指標的時候, 我們則需要判斷它是否為空。 這點經常在判斷函數參數是否有效的時候使用。
我們根據前面的描述,
int a = 0;
int b = 1;
int *point = NULL;
point = &a; // 在某個時刻, 指標可以指向a
point = &b; // 換個時刻, 指標可以指向b
而引用則不同, 引用只能在初始化的時候就賦好值, 之後就不能改變了, 用外號的例子來說就是"明明"這個外號在出現的時候就是代指小明, 之後“明明”這個外號就綁在小明身上了, 它不能過段時間換成小暗的外號。 代碼如下:
int xiaoming = 1;
int &refence_mingming = xiaoming;
int xiaoan = 2;
refence_mingming = xiaoan; // error,引用不能換了
由以上可以, 當我們需要某個是否指向為空的時候, 我們就需要使用指標了, 還有指向的物件需要變化的時候, 我們也需要使用指標。 其他地方一般推薦引用。
共同點都是位址的概念, 指標與引用都是讓你間接引用其他物件;
指標指向一塊記憶體, 它的內容是所指記憶體的位址;而引用則是某塊記憶體的別名。
從物件的角度理解指標C++primer中對 物件的定義:物件是指一塊能存儲資料並具有某種類型的記憶體空間
一個物件a,它有值和位址&a,運行程式時,電腦會為該物件分配存儲空間,來存儲該物件的值,我們通過該物件的位址,來訪問存儲空間中的值
指標p也是物件,它同樣有位址&p和存儲的值p,只不過,p存儲的資料類型是資料的位址。如果我們要以p中存儲的資料為位址,來訪問物件的值,則要在p前加解引用操作符"*",即*p。
物件有常量(const)和變數之分,既然指標本身是物件,那麼指標所存儲的位址也有常量和變數之分,常量指標是指,指標這個物件所存儲的位址是不可以改變的,而指向常量的指標的意思是,不能通過該指標來改變這個指標所指向的物件。
我們可以把引用理解成變數的別名。定義一個引用的時候,程式把該引用和它的初始值綁定在一起,而不是拷貝它。電腦必須在聲明r的同時就要對它初始化,並且,r一經聲明,就不可以再和其它物件綁定在一起了。
實際上,你也可以把引用看做是通過一個常量指標來實現的,它只能綁定到初始化它的物件上。
也可以理解引用是操作受限了的指標(僅容許取內容操作)。
引用的主要功能是傳遞函數的參數和返回值。C++語言中,函數的參數和返回值的傳遞方式有三種:值傳遞、 指針傳遞和引用傳遞。
以下是“值傳遞”的示例程式:
void Func1(int x) {
x = x + 10;
}
int n = 0;
Func1(n);
cout << “n = ” << n << endl; // n = 0
由於Func1 函數體內的x 是外部變數n 的一份拷貝, 改變x 的值不會影響n, 所以n 的值仍然是0。
以下是“指標傳遞”的示例程式:
void Func2(int *x) {
(* x) = (* x) + 10;
}
int n = 0;
Func2(&n);
cout << “n = ” << n << endl; // n = 10
由於Func2 函數體內的x 是指向外部變數n 的指標,改變該指標的內容將導致n 的值改變,所以n 的值成為10。
以下是“引用傳遞”的示例程式:
void Func3(int &x) {
x = x + 10;
}
int n = 0;
Func3(n);
cout << “n = ” << n << endl; // n = 10
由於Func3 函數體內的x 是外部變數n 的引用,x 和n 是同一個東西,改變x 等於改變n,所以n 的值成為10。
所以,如果要修改當前被傳遞的參數的話,要麼加一級指針,要麼用引用。
對比上述三個示例程式,會發現“引用傳遞”的性質象“指標傳遞”,而書寫方式象 “值傳遞”。實際上“引用”可以做的任何事情“指標”也都能夠做,為什麼還要“引用” 這東西?
指標能夠毫無約束地操作記憶體中的如何東西,儘管指標功能強大,但是非常危險。
如果的確只需要借用一下某個物件的“別名”,那麼就用“引用”,而不要用“指針”。
無論你傳值還是傳指標,函數都會生成一個臨時變數,但傳引用時,不會生成臨時變數,當你傳值時,只可以引用值而不可以改變值,但傳值引用時,可以改變值,當你傳指標時,只可以改變指標所指的內容,不可以改變指標本身,但傳指標引用時,既可以改變指標所指的內容,又可以改變指標本身,但傳引用主要是它不生成臨時變數,不進行返回值copy等,速度快。
-End-
它的內容是所指記憶體的位址;而引用則是某塊記憶體的別名。從物件的角度理解指標C++primer中對 物件的定義:物件是指一塊能存儲資料並具有某種類型的記憶體空間
一個物件a,它有值和位址&a,運行程式時,電腦會為該物件分配存儲空間,來存儲該物件的值,我們通過該物件的位址,來訪問存儲空間中的值
指標p也是物件,它同樣有位址&p和存儲的值p,只不過,p存儲的資料類型是資料的位址。如果我們要以p中存儲的資料為位址,來訪問物件的值,則要在p前加解引用操作符"*",即*p。
物件有常量(const)和變數之分,既然指標本身是物件,那麼指標所存儲的位址也有常量和變數之分,常量指標是指,指標這個物件所存儲的位址是不可以改變的,而指向常量的指標的意思是,不能通過該指標來改變這個指標所指向的物件。
我們可以把引用理解成變數的別名。定義一個引用的時候,程式把該引用和它的初始值綁定在一起,而不是拷貝它。電腦必須在聲明r的同時就要對它初始化,並且,r一經聲明,就不可以再和其它物件綁定在一起了。
實際上,你也可以把引用看做是通過一個常量指標來實現的,它只能綁定到初始化它的物件上。
也可以理解引用是操作受限了的指標(僅容許取內容操作)。
引用的主要功能是傳遞函數的參數和返回值。C++語言中,函數的參數和返回值的傳遞方式有三種:值傳遞、 指針傳遞和引用傳遞。
以下是“值傳遞”的示例程式:
void Func1(int x) {
x = x + 10;
}
int n = 0;
Func1(n);
cout << “n = ” << n << endl; // n = 0
由於Func1 函數體內的x 是外部變數n 的一份拷貝, 改變x 的值不會影響n, 所以n 的值仍然是0。
以下是“指標傳遞”的示例程式:
void Func2(int *x) {
(* x) = (* x) + 10;
}
int n = 0;
Func2(&n);
cout << “n = ” << n << endl; // n = 10
由於Func2 函數體內的x 是指向外部變數n 的指標,改變該指標的內容將導致n 的值改變,所以n 的值成為10。
以下是“引用傳遞”的示例程式:
void Func3(int &x) {
x = x + 10;
}
int n = 0;
Func3(n);
cout << “n = ” << n << endl; // n = 10
由於Func3 函數體內的x 是外部變數n 的引用,x 和n 是同一個東西,改變x 等於改變n,所以n 的值成為10。
所以,如果要修改當前被傳遞的參數的話,要麼加一級指針,要麼用引用。
對比上述三個示例程式,會發現“引用傳遞”的性質象“指標傳遞”,而書寫方式象 “值傳遞”。實際上“引用”可以做的任何事情“指標”也都能夠做,為什麼還要“引用” 這東西?
指標能夠毫無約束地操作記憶體中的如何東西,儘管指標功能強大,但是非常危險。
如果的確只需要借用一下某個物件的“別名”,那麼就用“引用”,而不要用“指針”。
無論你傳值還是傳指標,函數都會生成一個臨時變數,但傳引用時,不會生成臨時變數,當你傳值時,只可以引用值而不可以改變值,但傳值引用時,可以改變值,當你傳指標時,只可以改變指標所指的內容,不可以改變指標本身,但傳指標引用時,既可以改變指標所指的內容,又可以改變指標本身,但傳引用主要是它不生成臨時變數,不進行返回值copy等,速度快。
-End-