国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
c++中引用與指針的區(qū)別

最近一個(gè)禮拜,都在進(jìn)行SDL的研究,感覺這個(gè)東西還不錯(cuò)。

 

我入門的課程就是Uvi Studio寫的一本入門書, 還寫的不錯(cuò)。不過可惜的是他里面的技術(shù)采用的是C++語言。

 

對我這個(gè)外行來說就有點(diǎn)困難了, 整整花了一個(gè)禮拜才把上面的技術(shù)點(diǎn)都看完了。

 

不過也只是表面的理解, C++的確是一門博大的技術(shù)。

 

這里我對引用與指針區(qū)別就很是不明白了。

 

首先, 我從匯編的層次來分析。

對于匯編, 函數(shù)的調(diào)用只是很簡單的call, ret兩個(gè)指令。而對它來說, 它需要做的事情就是

1,保存現(xiàn)場, 就是保存主調(diào)函數(shù)的寄存器等的信息。

2,將傳遞的參數(shù)值壓入到線程棧中,然后在調(diào)用call指令, 轉(zhuǎn)移到被調(diào)函數(shù)中。

3,在完成調(diào)用后清除堆棧, 最后調(diào)用ret指令。

 

其次對于C來說:

 它是對匯編的一個(gè)封裝。這里我就不去討論函數(shù)的調(diào)用約定(相關(guān)資料可以google查看__stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall)。C一般我們都是使用_stdcall或者_(dá)cdecl。

在C中,我們知道函數(shù)的形參有兩種模式進(jìn)行傳遞。

1,值傳遞。

2,指針傳遞。

 

這個(gè)是譚老和我們說的。但是從內(nèi)存模型的角度分析, 其實(shí)只有一種模式。

就是值傳遞, 實(shí)參與形參的結(jié)合的過程如下:

1,編譯器將你的形參在編譯的階段全部轉(zhuǎn)換成相對符號(hào)引用。

2,調(diào)用一個(gè)函數(shù)。需要做的事情。

將傳入?yún)?shù)(實(shí)參)的值壓入的棧中,無論你是int, float原生的類型,還是指針類型。

3,執(zhí)行調(diào)用函數(shù)的指令,如果用到了形參的地方,通過形參在棧中的基地址+偏移量,找到相應(yīng)形參的值。

進(jìn)行使用。

 

所以在我的眼里, 沒有值傳遞與指針傳遞之分, 都是值傳遞。指針傳遞也是值傳遞, 區(qū)別只是后者傳遞的是指針類型。

 

 

OK! 分析到這里, 問題來了。

那么在C++中, 引用調(diào)用與值傳遞有什么區(qū)別呢?

 

下面是我從http://blog.csdn.net/dujiangyan101/archive/2008/08/28/2844138.aspx摘抄的:

(1)引用總是指向一個(gè)對象,沒有所謂的 null reference .所有當(dāng)有可能指向一個(gè)對象也由可能不指向?qū)ο髣t必須使用 指針.

由于C++ 要求 reference 總是指向一個(gè)對象所以 reference要求有初值.

String & rs = string1;

由于沒有所謂的 null reference 所以所以在使用前不需要進(jìn)行測試其是否有值.,而使用指針則需要測試其的有效性.

(2)指針可以被重新賦值而reference則總是指向最初或地的對象.

(3)必須使用reference的場合. Operator[] 操作符 由于該操作符很特別地必須返回 [能夠被當(dāng)做assignment賦值對象] 的東西,所以需要給他返回一個(gè) reference.

(4)其實(shí)引用在函數(shù)的參數(shù)中使用很經(jīng)常.

void Get***(const int& a) //這樣使用了引用有可以保證不修改被引用的值

{

}

引用和指針

★ 相同點(diǎn):
1. 都是地址的概念;
指針指向一塊內(nèi)存,它的內(nèi)容是所指內(nèi)存的地址;引用是某塊內(nèi)存的別名。

★ 區(qū)別:
1. 指針是一個(gè)實(shí)體,而引用僅是個(gè)別名;
2. 引用使用時(shí)無需解引用(*),指針需要解引用;
3.引用只能在定義時(shí)被初始化一次,之后不可變;指針可變;
引用“從一而終” ^_^
4. 引用沒有 const,指針有const,const 的指針不可變;
5. 引用不能為空,指針可以為空;
6. “sizeof引用”得到的是所指向的變量(對象)的大小,而“sizeof 指針”得到的是指針本身(所指向的變量或?qū)ο蟮牡刂?的大小;
typeid(T)== typeid(T&) 恒為真,sizeof(T) == sizeof(T&) 恒為真,
但是當(dāng)引用作為成員時(shí),其占用空間與指針相同(沒找到標(biāo)準(zhǔn)的規(guī)定)。
7. 指針和引用的自增(++)運(yùn)算意義不一樣;

★ 聯(lián)系
1. 引用在語言內(nèi)部用指針實(shí)現(xiàn)(如何實(shí)現(xiàn)?)。
2.對一般應(yīng)用而言,把引用理解為指針,不會(huì)犯嚴(yán)重語義錯(cuò)誤。引用是操作受限了的指針(僅容許取內(nèi)容操作)。
引用是C++中的概念,初學(xué)者容易把引用和指針混淆一起。一下程序中,n 是m 的一
個(gè)引用(reference),m 是被引用物(referent)。
int m;
int&n = m;
n 相當(dāng)于m 的別名(綽號(hào)),對n 的任何操作就是對m 的操作。例如有人名叫王小毛,
他的綽號(hào)是“三毛”。說“三毛”怎么怎么的,其實(shí)就是對王小毛說三道四。所以n 既不
是m 的拷貝,也不是指向m 的指針,其實(shí)n 就是m 它自己。
引用的一些規(guī)則如下:
(1)引用被創(chuàng)建的同時(shí)必須被初始化(指針則可以在任何時(shí)候被初始化)。
(2)不能有NULL引用,引用必須與合法的存儲(chǔ)單元關(guān)聯(lián)(指針則可以是NULL)。
(3)一旦引用被初始化,就不能改變引用的關(guān)系(指針則可以隨時(shí)改變所指的對象)。
以下示例程序中,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;
上面的程序看起來象在玩文字游戲,沒有體現(xiàn)出引用的價(jià)值。引用的主要功能是傳
遞函數(shù)的參數(shù)和返回值。C++語言中,函數(shù)的參數(shù)和返回值的傳遞方式有三種:值傳遞、
指針傳遞和引用傳遞。
以下是“值傳遞”的示例程序。由于Func1 函數(shù)體內(nèi)的x 是外部變量n 的一份拷貝,
改變x 的值不會(huì)影響n, 所以n 的值仍然是0。
voidFunc1(int x)
{
x = x + 10;
}
int n = 0;
Func1(n);
cout<< “n = ” << n << endl;// n = 0
以下是“指針傳遞”的示例程序。由于Func2 函數(shù)體內(nèi)的x 是指向外部變量n 的指
針,改變該指針的內(nèi)容將導(dǎo)致n 的值改變,所以n 的值成為10。
voidFunc2(int *x)
{
(* x) = (* x) + 10;
}

intn = 0;
Func2(&n);
cout << “n = ” << n <<endl; // n = 10
以下是“引用傳遞”的示例程序。由于Func3 函數(shù)體內(nèi)的x 是外部變量n 的引用,x
和n是同一個(gè)東西,改變x 等于改變n,所以n 的值成為10。
void Func3(int &x)
{
x = x +10;
}

int n = 0;
Func3(n);
cout<< “n = ” << n << endl; // n = 10
對比上述三個(gè)示例程序,會(huì)發(fā)現(xiàn)“引用傳遞”的性質(zhì)象“指針傳遞”,而書寫方式象
“值傳遞”。實(shí)際上“引用”可以做的任何事情“指針”也都能夠做,為什么還要“引用”
這東西?
答案是“用適當(dāng)?shù)墓ぞ咦銮∪缙浞值墓ぷ?#8221;。
指針能夠毫無約束地操作內(nèi)存中的如何東西,盡管指針功能強(qiáng)大,但是非常危險(xiǎn)。
就象一把刀,它可以用來砍樹、裁紙、修指甲、理發(fā)等等,誰敢這樣用?
如果的確只需要借用一下某個(gè)對象的“別名”,那么就用“引用”,而不要用“指針”,
以免發(fā)生意外。比如說,某人需要一份證明,本來在文件上蓋上公章的印子就行了,如
果把取公章的鑰匙交給他,那么他就獲得了不該有的權(quán)利。
----------
摘自『高質(zhì)量c++編程』
指針與引用,在More Effective C++的條款一有詳細(xì)講述,我給你轉(zhuǎn)過來
條款一:指針與引用的區(qū)別
指針與引用看上去完全不同(指針用操作符’*’和’->’,引用使用操作符’.’),但是它們似乎有相同的功能。指針與引用都是讓你間接引用其他對象。你如何決定在什么時(shí)候使用指針,在什么時(shí)候使用引用呢?
首先,要認(rèn)識(shí)到在任何情況下都不能用指向空值的引用。一個(gè)引用必須總是指向某些對象。因此如果你使用一個(gè)變量并讓它指向一個(gè)對象,但是該變量在某些時(shí)候也可能不指向任何對象,這時(shí)你應(yīng)該把變量聲明為指針,因?yàn)檫@樣你可以賦空值給該變量。相反,如果變量肯定指向一個(gè)對象,例如你的設(shè)計(jì)不允許變量為空,這時(shí)你就可以把變量聲明為引用。
“但是,請等一下”,你懷疑地問,“這樣的代碼會(huì)產(chǎn)生什么樣的后果?”
char *pc = 0; //設(shè)置指針為空值
char& rc = *pc; // 讓引用指向空值
這是非常有害的,毫無疑問。結(jié)果將是不確定的(編譯器能產(chǎn)生一些輸出,導(dǎo)致任何事情都有可能發(fā)生),應(yīng)該躲開寫出這樣代碼的人除非他們同意改正錯(cuò)誤。如果你擔(dān)心這樣的代碼會(huì)出現(xiàn)在你的軟件里,那么你最好完全避免使用引用,要不然就去讓更優(yōu)秀的程序員去做。我們以后將忽略一個(gè)引用指向空值的可能性。
因?yàn)橐每隙〞?huì)指向一個(gè)對象,在C里,引用應(yīng)被初始化。
string& rs; // 錯(cuò)誤,引用必須被初始化
string s("xyzzy");
string&rs = s; // 正確,rs指向s
指針沒有這樣的限制。
string *ps; // 未初始化的指針
//合法但危險(xiǎn)
不存在指向空值的引用這個(gè)事實(shí)意味著使用引用的代碼效率比使用指針的要高。因?yàn)樵谑褂靡弥安恍枰獪y試它的合法性。
voidprintDouble(const double& rd)
{
cout << rd; //不需要測試rd,它
} // 肯定指向一個(gè)double值
相反,指針則應(yīng)該總是被測試,防止其為空:
voidprintDouble(const double *pd)
{
if (pd) { // 檢查是否為NULL
cout<< *pd;
}
}
指針與引用的另一個(gè)重要的不同是指針可以被重新賦值以指向另一個(gè)不同的對象。但是引用則總是指向在初始化時(shí)被指定的對象,以后不能改變。
string s1("Nancy");
string s2("Clancy");
string&rs = s1; // rs 引用 s1
string *ps = &s1; // ps 指向 s1
rs = s2;// rs 仍舊引用s1,
// 但是 s1的值現(xiàn)在是
// "Clancy"
ps = &s2; // ps現(xiàn)在指向 s2;
// s1 沒有改變
總的來說,在以下情況下你應(yīng)該使用指針,一是你考慮到存在不指向任何對象的可能(在這種情況下,你能夠設(shè)置指針為空),二是你需要能夠在不同的時(shí)刻指向不同的對象(在這種情況下,你能改變指針的指向)。如果總是指向一個(gè)對象并且一旦指向一個(gè)對象后就不會(huì)改變指向,那么你應(yīng)該使用引用。
還有一種情況,就是當(dāng)你重載某個(gè)操作符時(shí),你應(yīng)該使用引用。最普通的例子是操作符[]。這個(gè)操作符典型的用法是返回一個(gè)目標(biāo)對象,其能被賦值。
vector<int> v(10); //建立整形向量(vector),大小為10;
// 向量是一個(gè)在標(biāo)準(zhǔn)C庫中的一個(gè)模板(見條款35)
v[5] = 10; //這個(gè)被賦值的目標(biāo)對象就是操作符[]返回的值
如果操作符[]返回一個(gè)指針,那么后一個(gè)語句就得這樣寫:
*v[5] = 10;
但是這樣會(huì)使得v看上去象是一個(gè)向量指針。因此你會(huì)選擇讓操作符返回一個(gè)引用。(這有一個(gè)有趣的例外,參見條款30)
當(dāng)你知道你必須指向一個(gè)對象并且不想改變其指向時(shí),或者在重載操作符并為防止不必要的語義誤解時(shí),你不應(yīng)該使用指針。而在除此之外的其他情況下,則應(yīng)使用指針
假設(shè)你有
voidfunc(int* p, int&r);
int a = 1;
int b = 1;
func(&a,b);
指針本身的值(地址值)是以pass by value進(jìn)行的,你能改變地址值,但這并不會(huì)改變指針?biāo)赶虻淖兞康闹担?
p =someotherpointer; //a is still 1
但能用指針來改變指針?biāo)赶虻淖兞康闹担?
*p =123131; // a now is 123131
但引用本身是以pass byreference進(jìn)行的,改變其值即改變引用所對應(yīng)的變量的值
r = 1231; // b now is 1231

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C++中引用與指針的區(qū)別
3、C++中函數(shù)返回引用
C++_指針懸掛和賦值操作符的重載
C筆記
動(dòng)態(tài)內(nèi)存
C++深淺拷貝淺析
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服