




版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- Msoffice考試資源共享的試題及答案
- 作品鑒賞考試題及答案
- 幼師招聘論述試題及答案
- 2025設(shè)備保養(yǎng)協(xié)議合同范本
- 數(shù)據(jù)驅(qū)動(dòng)決策在2025年考試中的重要性分析試題及答案
- 社會(huì)工作者的科研能力與未來(lái)發(fā)展試題及答案
- 1到6單元試題及答案
- 和弦及轉(zhuǎn)位試題及答案
- 2025年護(hù)理三基知識(shí)復(fù)習(xí)測(cè)試卷附答案
- 道具社恐測(cè)試題及答案大全
- (一模)臨沂市2025屆高三高考第一次模擬考試歷史試卷(含標(biāo)準(zhǔn)答案)
- 2025年中國(guó)廣電山東網(wǎng)絡(luò)有限公司招聘筆試參考題庫(kù)含答案解析
- 《SVN版本控制培訓(xùn)》課件
- 考生所在單位考核意見(jiàn)填寫(xiě)模板
- 《三福百貨營(yíng)銷環(huán)境PEST、SWOT研究及其營(yíng)銷策略研究》11000字(論文)
- 鉆機(jī)安全操作規(guī)程(3篇)
- 2024年重慶市九龍坡區(qū)某中學(xué)小升初數(shù)學(xué)試卷(含答案)
- 【MOOC】運(yùn)動(dòng)損傷與急救-西安電子科技大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 2025年度應(yīng)急預(yù)案演練計(jì)劃
- 1、2024廣西專業(yè)技術(shù)人員繼續(xù)教育公需科目參考答案(98分)
- 【MOOC】結(jié)構(gòu)力學(xué)(一)-西南交通大學(xué) 中國(guó)大學(xué)慕課MOOC答案
評(píng)論
0/150
提交評(píng)論