C++基礎(chǔ)7:指針和引用

一.指針

** 1.指針概念**:指針就是用來保存內(nèi)存地址的變量。

2.聲明指針的方式int *p棒动;與運(yùn)算符*結(jié)合婚脱,p就表示一個指針

為什么使用指針(指針的三大作用):由于指針可以通過內(nèi)存地址直接訪問數(shù)據(jù)雹仿,可避免在程序中復(fù)制大量的代碼,因此指針的效率最高玄组,其三大作用如下

2.1 處理堆中存放的大型數(shù)據(jù)
2.2 快速訪問類的成員數(shù)據(jù)和函數(shù)
2.3 以別名的方式向函數(shù)傳遞參數(shù)

3.運(yùn)算符和&滔驾,以及運(yùn)算符->*

&是取地址運(yùn)算符(后面再講引用的時候這個就變成引用運(yùn)算符了)。 如

int a=5;  
cout<<&a<<endl;//使用&獲取變量a的內(nèi)存地址

*是指針運(yùn)算符或間接引用運(yùn)算符(注意:如果*用于聲明指針巧勤,那么它就是指針說明符嵌灰,如下)

int a=1;  
int *p=&a;//這里的*表明是指針說明符  
cout<<*p<<endl;//這里的*表示指針運(yùn)算符,使用*獲取指針變量p中保存的地址處的值颅悉,也就是1  

->是成員指針運(yùn)算符或指向成員運(yùn)算符

4.復(fù)雜變量的解釋(要判斷是一個變量的類型就看與他最先結(jié)合的運(yùn)算符是什么)沽瞭,舉例如下:
int p 變量p是一個普通的整形變量

int *p 由于變量p先與運(yùn)算符*結(jié)合,所以p本質(zhì)是一個指針剩瓶,再與int結(jié)合驹溃,所以p就是一個指向整形數(shù)據(jù)的指針

int p[3] 由于變量p只與運(yùn)算符[]結(jié)合城丧,所以p本質(zhì)是一個數(shù)組,再與int結(jié)合豌鹤,所以p就是一個由整形數(shù)據(jù)組成的數(shù)組

int *p[3] 變量p先與[]結(jié)合亡哄,因?yàn)閇]的優(yōu)先級高于,所以p本質(zhì)上是一個數(shù)組布疙,剩下的就是要知道p是一個什么數(shù)組蚊惯,然后p再與結(jié)合,說明是p是一個指針數(shù)組灵临,然后再與int結(jié)合截型,說明p是一個指向整形數(shù)據(jù)的指針?biāo)M成的數(shù)組

int (*p)[3] 由于()改變了優(yōu)先級,所以變量p先與*結(jié)合儒溉,所以p本質(zhì)上是一個指針宦焦,那它是什么類型的指針呢,然后p再與[]結(jié)合顿涣,說明p是一個指向數(shù)組的指針波闹,然后再與int結(jié)合,說明p是一個指向整形數(shù)據(jù)組成的數(shù)組的指針

int **p 變量p先與結(jié)合涛碑,說明p本質(zhì)是一個指針精堕,那它是什么指針呢,然后再與結(jié)合锌唾,說明p是一個指向指針的指針锄码,然后再與int結(jié)合,說明p是一個指向整形數(shù)據(jù)的指針的指針

int p(int a)p首先與()結(jié)合晌涕,說明p是一個函數(shù),然后進(jìn)入()分析痛悯,發(fā)現(xiàn)函數(shù)有一個int型的參數(shù)a余黎,然后再與int結(jié)合,說明p是具有整型參數(shù)且返回類型為整型的函數(shù)载萌。

int (*p)(int a) 由于(p)改變了優(yōu)先級惧财,所以p先與結(jié)合,說明p本質(zhì)是一個指針扭仁,然后再與(int a)結(jié)合垮衷,說明p是一個函數(shù)指針,然后再看(int a)發(fā)現(xiàn)函數(shù)具有一個int型的參數(shù)a乖坠,然后再與int結(jié)合搀突,說明p是一個指向具有整型參數(shù)且返回類型為整型的函數(shù)的指針

5.指針的四方面重要內(nèi)容

指針的類型,指針?biāo)赶虻念愋托鼙茫羔樀闹担ㄖ羔標(biāo)赶虻膬?nèi)存區(qū))仰迁,指針本身所占據(jù)的內(nèi)存區(qū)

5.1 判斷這四個方面的規(guī)則

指針的類型:把指針聲明語句的指針名字去掉甸昏,剩下的部分就是指針的類型

指針?biāo)赶虻念愋?/code>:把指針聲明語句里的指針名字和名字左邊的指針聲明符*去掉,就是指針?biāo)赶虻念愋?/p>

指針的值:在32位程序里徐许,所有類型的指針的值都是一個32位整數(shù)施蜜,指針的值是指向的內(nèi)存區(qū)域的首地址

指針本身所占據(jù)的內(nèi)存區(qū):指針本身占據(jù)的內(nèi)存長度可以使用sizeof(指針的類型)測一下就知道,在32位平臺里雌隅,指針本身占據(jù)了4個字節(jié)的長度

舉例說明指針的類型和指針?biāo)赶虻念愋?/strong>:

舉例 指針(ptr)(本身)的類型 指針?biāo)赶虻念愋?/th>
int *ptr int * int
char *ptr char * char
int **ptr int ** int *
int (*ptr)[3] int (*)[3] int ()[3]
int (ptr)[4] int ()[4] int *()[4]

6.指針與常量

聲明定義式 注釋
常量指針 int *const p; 指針本身不可改變翻默,指向的變量可變
指向常量的指針 const int *p; 指針本身可變,其指向的變量不可變
指向常量的常指針 const int *const p; 指針本身不可變恰起,其指向的變量也不可變

** 7.指針的注意事項(xiàng):迷途指針**

定義一個指針之后冰蘑,如果沒有給他賦初值,那么該指針就是一個迷途指針村缸,它可以指向任何地址祠肥,并且如果對該指針進(jìn)行操作就會對位置區(qū)域的數(shù)據(jù)進(jìn)行修改或刪除,照成意想不到的后果梯皿,所以解決辦法是將定義的指針進(jìn)行初始化仇箱,如下

[cpp] 
int *p=0;

這樣东羹,這個指針就稱為空指針剂桥。

不僅在初始化的時候,還有一種情況迷途指針也會造成危害属提,就是刪除指針delete p权逗;之后,雖然指向的內(nèi)存空間釋放了冤议,但是指針本身還存在斟薇,如果再次使用該指針也會造成很嚴(yán)重的后果,所以再刪除一個指針之后恕酸,將該指針賦值為空堪滨。雖然空指針是非法的,容易是程序奔潰蕊温,但是我們寧愿程序崩潰袱箱,也不愿意調(diào)試起來很困難。如下:

int *p=new int;  
delete p;  
p=0;  
[cpp] view plain copy print?
*p=23;  

刪除指針p后义矛,賦值為0发笔,然后在使用該空指針,程序運(yùn)行的時候凉翻,運(yùn)行到*p=23就會報(bào)錯了讨,這樣我們就知道我們使用了一個迷途指針,從而及時修改程序。要是我們將p=0這句話去掉量蕊,那么程序就不會報(bào)錯铺罢,但是何時崩潰就不知道了,這樣加重了我們查問題的難度残炮。

二.引用

1.引用的概念:引用就是別名韭赘,如

[cpp]
int &rnum=num;//這里的&是引用運(yùn)算符 

rnum是整形變量num的別名势就,這樣泉瞻,對rnum的操作實(shí)際就是對num的操作

這里要注意苞冯,別名rnum前面的符號&不是取地址運(yùn)算符袖牙,而是引用運(yùn)算符。

2.引用的作用(為什么要用“引用”)

其實(shí)引用只是為變量另外起了一個名字舅锄,就像#define num rnum==(int &runm=num)鞭达,將num定義成rnum,兩者在內(nèi)存中是同一個空間皇忿。引用它不像int rnum=num畴蹭;rnum其實(shí)是在內(nèi)存中新分配了一個空間,所以rnum和num占據(jù)的是兩個不同的內(nèi)存空間鳍烁。那么引用在程序中到底有什么用呢叨襟?

我們知道我們在傳函數(shù)的參數(shù)的時候,分兩種:按值傳遞按地址傳遞幔荒。

按值傳遞
void swap(int a糊闽,int b)

按值傳遞,編譯器會自動在棧中創(chuàng)建a和b的副本爹梁,如果形參不是int類型右犹,而是類類型,那么副本就會很大卫键,效率很低傀履,這時候就要考慮按地址傳遞

按地址傳遞

[cpp] 
void swap(int *a,int *b)  
{  
   int c;  
    c=*a;  
    *a=*b;  
    *b=c;  
}  

上面的功能是達(dá)到了莉炉,把指針作為函數(shù)的接受參數(shù)雖然能正常使用,但是它卻不易閱讀碴犬,而且很難使用絮宁。這時候引用作為形參就派上用場了:

如果引用作為參數(shù),在函數(shù)內(nèi)部可以修改a的值和b的值服协,這樣破壞了按值傳遞的保護(hù)機(jī)制绍昂,不過我們可以使用const來聲明一個不可修改值的引用,假設(shè)我們不想在函數(shù)內(nèi)修改a的值,那么上面的代碼修改如下:

[cpp] 
<span style="font-size:14px;">void swap(const int &a窘游,int &b)  
{  
   int c;  
    c=a;  
    a=b;//編譯報(bào)錯:不能給常量a賦值  
    b=c;  
}

通過上面的代碼唠椭,a就不能被賦值了,這樣a就被稱為常引用
總結(jié):引用在使用中單純的給某個變量取個別名是沒有意義的忍饰,引用的主要目的是可以作為按地址的參數(shù)傳遞還可以作為函數(shù)的返回值(注意:局部變量是不能返回引用的贪嫂,因?yàn)榫植孔兞吭诤瘮?shù)返回后會被銷毀)

3.引用的兩個特點(diǎn):

第一:定義引用的同時要對該引用進(jìn)行初始化,否則編譯不能通過艾蓝。如下

[cpp] 
//正確的定義引用  
int a=0;  
int &ra=a;  
//錯誤的定義引用ra力崇,必須進(jìn)行初始化  
int a=0;  
int &ra;  
ra=a;  

第二:引用可以改變其指向地址的數(shù)據(jù),但是不能改變其自身的地址(也就是說別名的地址是不會被改變的赢织,但是別名的值會變)亮靴,如

[cpp] 
int a;  
int &ra=a;  
a=999;  
cout<<"a="<<a<<"  "<<"&a="<<&a<<endl;//a=999 &a=0012ff60  
cout<<"ra="<<ra<<"  " <<"&ra="<<&ra<<endl;//ra=999 &ra=0012ff60  
  
int b=1000;  
ra=b;  
cout<<"a="<<a <<"  "<<"&a="<<&a<<endl;//a=1000 &a=0012ff60  
cout<<"ra="<<ra<<"  " <<"&ra="<<&ra<<endl;//ra=1000 &ra=0012ff60  
cout<<"b="<<b <<"  "<<"&b="<<&b<<endl;//b=1000 &b=0012ff48  
  
ra=1;  
cout<<"a="<<a <<"  "<<"&a="<<&a<<endl;//a=1 &a=0012ff60  
cout<<"ra="<<ra<<"  " <<"&ra="<<&ra<<endl;//ra=1 &ra=0012ff60  
cout<<"b="<<b<<"  " <<"&b="<<&b<<endl;//b=1000 &b=0012ff48  

上面的例子中ra=b之后,查看ra的地址可以看出來于置,ra的地址并沒有變化茧吊,也就是說ra是a的別名,那么就不可能變成其他變量(b)的別名八毯,對ra的操作還是在操作a搓侄,而不是b,所以最后在ra=1之后改變的還是a的值宪彩。

4.引用的注意事項(xiàng)

4.1 引用聲明的時候必須進(jìn)行初始化 int num=5休讳;int &rnum=num;

4.2 不能建立數(shù)組的引用(int &a[5])尿孔,不能建立引用的引用(int &&a)蔬螟,不能建立引用的指針(int &*a)菜皂,

4.3 可以建立指針的引用:

[cpp] 
int *p;  
int *&q=p;

上面的q與它最先結(jié)合的運(yùn)算符是&椰弊,所以他的本質(zhì)是一個引用,然后再與*結(jié)合戏仓,所以q是一個指針的引用印蔗,也就是指針p的別名。

4.4 引用在作為函數(shù)的返回值的時候告嘲,千萬注意错维,局部變量是不能作為返回值的,因?yàn)榫植孔兞吭诤瘮?shù)返回的時候已經(jīng)被釋放了橄唬,如下:

[cpp]
class A  
{  
  
}  
  
A &func()  
{  
     A a;  
     return a;  
}  

上面的func函數(shù)返回的是局部變量類A的對象a赋焕,如果外部使用了它會報(bào)錯,因?yàn)榫植孔兞縜在函數(shù)返回的時候已經(jīng)被釋放了仰楚。

三.指針和引用

1.首先對指針和引用的運(yùn)算符&和*進(jìn)行說明:

運(yùn)算符&*在聲明定義的時候(包括形參的聲明)稱為引用運(yùn)算符(聲明變量是引用)和指針說明符(聲明變量是指針)隆判;它們在使用的時候稱為取地址運(yùn)算符(獲取變量的內(nèi)存地址)和指針運(yùn)算符(獲取指針指向的地址里的內(nèi)存數(shù)據(jù))犬庇,例如:

運(yùn)算符&

[cpp] 
int a=5;  
int &a1=a;//引用運(yùn)算符  
cout<<&a1<<endl;//取地址運(yùn)算符  
int func(int &a,int &b);//引用運(yùn)算符  

運(yùn)算符*

[cpp] 
int b=6;  
int *b1=&b;//指針說明符;取地址運(yùn)算符  
cout<<*b1<<endl;//指針運(yùn)算符  
int func(int *a,int *b);//指針說明符  

2.常指針和常引用

它們的聲明方式相同侨嘀,都是使用const來定義臭挽,但是由于引用本身是不可更改的,所以不用這樣聲明:int const &a;

3.指針和引用的區(qū)別

指針可以為空咬腕,引用不可以欢峰。

指針可以被賦值,引用只能被初始化郎汪,不能被賦值赤赊。

在堆中創(chuàng)建一塊內(nèi)存區(qū)域,必須使用指針來指向它煞赢,不能使用引用來指向它抛计,如int &r=new int;這句話是錯誤的照筑。這時候你可以這樣int *&r=new int吹截;r表示一個指針的引用,也就是指向new int所在的堆區(qū)的指針的別名凝危。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末波俄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蛾默,更是在濱河造成了極大的恐慌懦铺,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件支鸡,死亡現(xiàn)場離奇詭異冬念,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)牧挣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門急前,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瀑构,你說我怎么就攤上這事裆针。” “怎么了寺晌?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵世吨,是天一觀的道長。 經(jīng)常有香客問我呻征,道長另假,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任怕犁,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奏甫。我一直安慰自己戈轿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布阵子。 她就那樣靜靜地躺著思杯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挠进。 梳的紋絲不亂的頭發(fā)上色乾,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音领突,去河邊找鬼暖璧。 笑死,一個胖子當(dāng)著我的面吹牛君旦,可吹牛的內(nèi)容都是我干的澎办。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼金砍,長吁一口氣:“原來是場噩夢啊……” “哼局蚀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起恕稠,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤琅绅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鹅巍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體千扶,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年昆著,在試婚紗的時候發(fā)現(xiàn)自己被綠了县貌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡凑懂,死狀恐怖煤痕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情接谨,我是刑警寧澤摆碉,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站脓豪,受9級特大地震影響巷帝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扫夜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一楞泼、第九天 我趴在偏房一處隱蔽的房頂上張望驰徊。 院中可真熱鬧,春花似錦堕阔、人聲如沸棍厂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牺弹。三九已至,卻和暖如春时呀,著一層夾襖步出監(jiān)牢的瞬間张漂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工谨娜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留航攒,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓瞧预,卻偏偏與公主長得像屎债,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子垢油,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型盆驹。 運(yùn)用指針編程是C語言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu)滩愁; ...
    朱森閱讀 3,443評論 3 44
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,516評論 1 51
  • 重新系統(tǒng)學(xué)習(xí)下C++躯喇;但是還是少了好多知識點(diǎn);socket硝枉;unix廉丽;stl;boost等妻味; C++ 教程 | 菜...
    kakukeme閱讀 19,878評論 0 50
  • --help會在終端列出所有可用的命令,可以使用任何命令的-h或-help選項(xiàng)來查看該命令的具體用法 mac或li...
    吧啦啦小湯圓閱讀 345評論 0 0
  • 春節(jié)聚在一起责球,七大姑八大姨們除了聊孩子還是聊孩子。于是雏逾,話題繞來繞去總是走不出這個彎: “你怎么還沒個對象嘉裤?!” ...
    小瑜姑娘閱讀 382評論 1 3