C++掃盲篇之指針詳解_第1頁(yè)
C++掃盲篇之指針詳解_第2頁(yè)
C++掃盲篇之指針詳解_第3頁(yè)
C++掃盲篇之指針詳解_第4頁(yè)
C++掃盲篇之指針詳解_第5頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第C++掃盲篇之指針詳解目錄前言指針為什么要有類型指針和數(shù)組二級(jí)指針指針與多態(tài)綁定函數(shù)指針類成員指針補(bǔ)充:用指針的指針指向指針數(shù)組總結(jié)

前言

指針對(duì)于學(xué)習(xí)C/C++的人來(lái)說(shuō)是一道必須邁過(guò)去的坎,就像學(xué)習(xí)九陽(yáng)神功必須要打通任督二脈一樣的道理。雖然說(shuō)隨著智能指針的普及,很少需要程序員再手動(dòng)操作原始指針,但是如果你連原始指針的都沒(méi)學(xué)好,那你怎么可能用好智能指針呢?

無(wú)論是原始指針還是智能指針,要想用好它就一定要做到知其然,知其所以然。

因?yàn)楸疚拈喿x對(duì)象是有了一定指針基礎(chǔ)的童鞋,所以如果你對(duì)指針如果是處于一無(wú)所知的狀態(tài)的話,建議先去溫習(xí)下指針的基礎(chǔ)知識(shí),不然可能讀起來(lái)會(huì)打擊你求知的欲望。

指針為什么要有類型

是為了指針運(yùn)算和取值。

當(dāng)使用指針取值的時(shí)候需要知道怎么取值,比如按照多少個(gè)字節(jié)去取值,這是需要確定才能取到正確的值的,要知道用多少個(gè)字節(jié)去取就得知道指針的類型是什么。

我們知道指針的運(yùn)算增加或者減少1意味著需要偏移指針?biāo)硎镜念愋偷拇笮€(gè)字節(jié)數(shù),比如說(shuō)一個(gè)int字節(jié)的指針增加1,表示偏移4個(gè)字節(jié)(一般情況下int都是4個(gè)字節(jié)),所以這也是需要知道指針的類型。

指針和數(shù)組

本來(lái)從字面上來(lái)說(shuō)指針和數(shù)組是八竿子打不著的,它們理應(yīng)是井水不犯河水的,怎么就扯上了呢?我們經(jīng)常聽(tīng)說(shuō)數(shù)組指針、指針數(shù)組,這些都是什么意思呢?他們到底是指針還是數(shù)組呢?下面將一一為你解答。

指針數(shù)組,首先它是一個(gè)數(shù)組,數(shù)組里面的每個(gè)元素都是一個(gè)指針,例如比如int*p[4]就是一個(gè)指針數(shù)組,因?yàn)檫\(yùn)算符[]的優(yōu)先級(jí)運(yùn)算符*的優(yōu)先級(jí)高,所以p優(yōu)先和[]組成數(shù)組,然后*和類型int組合成數(shù)組元素的類型。例如以下程序就是一個(gè)指針數(shù)組的示例:

main.c

#includestdio.h

intmain(){

char*str[3]={

"我是數(shù)組1",

"我是數(shù)組2",

"我是數(shù)組3"

printf("%s\n%s\n%s\n",str[0],str[1],str[2]);

return0;

}

數(shù)組指針,首先它是一個(gè)指針,這個(gè)指針?biāo)赶虻膶?duì)象是數(shù)組,比如這個(gè)指針是p,那么通過(guò)解引用*p獲得內(nèi)容就是一個(gè)數(shù)組,例如int(*p)[4],主意帶上括號(hào),通常數(shù)組指針也作為一個(gè)二維數(shù)組來(lái)使用。

二級(jí)指針

所謂的二級(jí)指針其實(shí)就是一個(gè)指向指針的指針,例如int**p就是一個(gè)二級(jí)指針,它內(nèi)部存放的對(duì)象是一個(gè)指針,通過(guò)一次解引用獲得的是內(nèi)存存放的指針的地址,需要再次對(duì)這個(gè)內(nèi)部的指針進(jìn)行解引用才能獲取到這個(gè)真是內(nèi)容的值。

理解起來(lái)有點(diǎn)繞,那么這個(gè)拗口的二級(jí)指針有什么作用呢?二級(jí)指針在C++中可能用的不多,但是在C中是經(jīng)常使用的一把利器,它通常作為一個(gè)函數(shù)的參數(shù),起到在函數(shù)內(nèi)部對(duì)一個(gè)指針進(jìn)行初始化的作用,比如經(jīng)典的音視頻處理工具FFmpeg中就大量使用了二級(jí)指針。以下例子展示如何通過(guò)二級(jí)指針對(duì)指針形式賦值:

main.cpp

voidinitP(int**p){

*p=newint(10);

intmain(){

int*p=nullptr;//一個(gè)空的指針

initP(//通過(guò)二級(jí)指針初始化指針p

std::cout"*p的值:"*pendl;

deletep;

return0;

}

可能在這里就有人和當(dāng)初筆者剛接觸C語(yǔ)言一樣迷惑了,難道不能通過(guò)給函數(shù)傳遞一級(jí)指針給指針初始化嗎?這是不行的,這是因?yàn)橹祩鬟f的緣故,像深入探討的童鞋們可以寫(xiě)個(gè)例子打印下實(shí)參的具體地址對(duì)比下研究下其背后的原理。

指針與多態(tài)綁定

我們都知道C++是一門面向?qū)ο蟮脑O(shè)計(jì)語(yǔ)言,支持多態(tài)就是它的一個(gè)重要特性之一,在學(xué)習(xí)C++類的相關(guān)知識(shí)的時(shí)候老師就告訴我們:*在C++語(yǔ)言中,當(dāng)我們使用基類的引用(或指針)調(diào)用一個(gè)虛函數(shù)時(shí)將發(fā)生動(dòng)態(tài)綁定。*也就是說(shuō)使用通過(guò)父類的指針或引用就能按照實(shí)參的實(shí)際類型是父類還是子類調(diào)用不同的虛函數(shù)。

例如如以下代碼:

main.cpp

classBase{

public:

virtualvoidprint()const{

std::cout"baseprint"endl;

virtual~Base(){

classChild:publicBase{

public:

voidprint()constoverride{

std::cout"Childprint"endl;

voidtestPrint(constBasebase){

base.print();

intmain(){

Basea=Child();

testPrint(a);//打印Baseprint

Childb=Child();//注意,不能寫(xiě)成Baseb=Child(),否則打印的是Base的print

testPrint(b);//打印Childprint

Base*c=newChild();//指針,動(dòng)態(tài)類型與靜態(tài)類型不一致

testPrint(*c);//打印Childprint

Baser=Child();//表達(dá)式是右值引用,動(dòng)態(tài)類型與靜態(tài)類型不一致

testPrint(r);//打印Childprint

return0;

}

為什么在上面的程序中變量a的實(shí)際類型是Child,但是函數(shù)testPrint內(nèi)部調(diào)用的卻是父類的打印方法呢?不是說(shuō)引用會(huì)觸發(fā)多態(tài)嗎?函數(shù)testPrint也是通過(guò)引用傳遞的呀,真是百思不得其jie呀。

要解開(kāi)這個(gè)疑惑就得了解下靜態(tài)類型和動(dòng)態(tài)類型的知識(shí)了。靜態(tài)類型在編譯時(shí)總是已知的,首先靜態(tài)類型是變量聲明時(shí)的類型或表達(dá)式生成的類型;動(dòng)態(tài)類型則是變量或表達(dá)式表示的內(nèi)存中的對(duì)象的類型,動(dòng)態(tài)類型直到運(yùn)行時(shí)才可知。如果變量在定義時(shí)表達(dá)式既不是引用也不是指針,則它的動(dòng)態(tài)類型永遠(yuǎn)與靜態(tài)類型一致的,也就是聲明時(shí)所指的類型,否則的話靜態(tài)類型可能與動(dòng)態(tài)類型不一致。

那么有了靜態(tài)類型與動(dòng)態(tài)類型的概念之后再結(jié)合注釋看上面的示例代碼是不是就有一種撥開(kāi)云霧見(jiàn)青天的感覺(jué)了呢?

函數(shù)指針

函數(shù)指針顧名思義就是指向函數(shù)的指針,它的定義:函數(shù)指針是指向函數(shù)的指針變量。因此函數(shù)指針本身首先應(yīng)是指針變量,只不過(guò)該指針變量指向函數(shù)。

其聲明方式是:

返回值類型(*函數(shù)名)(參數(shù))

函數(shù)指針的一個(gè)重要用途就是作為函數(shù)的參數(shù),用于在函數(shù)內(nèi)部進(jìn)行指針函數(shù)的調(diào)用,一般用作回調(diào)函數(shù),比如在創(chuàng)建一個(gè)POSIX線程的就需要傳遞一個(gè)函數(shù)指針用于指明該線程做點(diǎn)什么事情。

以下代碼展示了一個(gè)簡(jiǎn)單的函數(shù)指針的使用方法:

voidtestFunc(inta,intb,void(*func)(intc,intd)){

//dosomething

func(a,b);

voidcallback(inta,intb){

intmain(){

testFunc(1,2,callback);

return0;

}

類成員指針

這里類成員指針表示的是指向類的某個(gè)對(duì)象的非靜態(tài)成員的指針,而不是表示類成員變量的指針,首先需要區(qū)分好這是兩個(gè)不同的概念,如果不能好好區(qū)分這兩個(gè)概念的童鞋,需要再好好思考一下。

成員指針的類型囊括了類的類型以及成員的類型。當(dāng)初始化一個(gè)這樣的指針時(shí),我們令其指向類的某個(gè)成員,但是不指定該成員所屬的對(duì)象;直到使用成員指針時(shí),才提供成員所屬的對(duì)象。

和其他指針一樣,在聲明成員指針時(shí)我們也使用*來(lái)表示當(dāng)前聲明的名字是一個(gè)指針。與普通指針不同的是,成員指針還必須包含成員所屬的類。下面是一個(gè)使用的示例:

classPerson{

public:

virtualvoidprint()const{

std::cout"baseprint"endl;

virtual~Person(){

public:

stringlastName;

stringfirstName;

intmain(){

stringPerson::*p;//聲明了一個(gè)類成員指針

p=Person::firstName;//成員變量的指針指向了Peron的name

Personperson;

person.*p="hello";//使用成員指針

p=Person::lastName;//成員變量的指針指向了Peron的lastName

person.*p="world";//使用成員指針

std::coutperson.firstName""person.lastNamestd::endl;

return0;

}

至于這個(gè)成員指針有什么用處,給筆者的感覺(jué)就是重新命了一個(gè)別名的感覺(jué),甚至有點(diǎn)脫褲子放屁?但是存在即合理,不是沒(méi)有用處,只是筆者見(jiàn)過(guò)那種場(chǎng)景而已吧。。。

除了有指向類成員變量的指針外還有指向類成員函數(shù)的指針,這里就不多展開(kāi)探討了!??!

補(bǔ)充:用指針的指針指向指針數(shù)組

#includestdio.h

intchange(char**p)

inti,j;

for(i=0;ii++)

for(j=0;*(*(p+i)+j)!='\0';j++)//利用指針的指針取二維數(shù)組的元素

*(*(p+i)+j)='c';

printf("%c",*(*(p+i)+j));

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論