指針和引用教學(xué)課件_第1頁
指針和引用教學(xué)課件_第2頁
指針和引用教學(xué)課件_第3頁
指針和引用教學(xué)課件_第4頁
指針和引用教學(xué)課件_第5頁
已閱讀5頁,還剩81頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、2020/10/4,1,C+高級(jí)語言程序設(shè)計(jì),第6章 指針和引用 北京郵電大學(xué) 信息與通信工程學(xué)院,北京郵電大學(xué)信息與通信工程學(xué)院,指針(Pointer)是C+和C的一種數(shù)據(jù)類型。很多其他高級(jí)語言也有類似的數(shù)據(jù)類型。引用(Reference)則是C+所特有的一種數(shù)據(jù)類型。指針和引用在概念上和使用上都有相似之處,但是也有重要的差別。,2020/10/4,-2-,北京郵電大學(xué)信息與通信工程學(xué)院,第六章 指針和引用,6.1 指針的概念 6.2 指針的運(yùn)算 6.3 指針訪問動(dòng)態(tài)內(nèi)存 6.4 指向結(jié)構(gòu)體的指針 6.5 引用概念 6.6 指針和引用作為函數(shù)的參數(shù) 6.7 指針和引用作為函數(shù)的返回值 6.8

2、 指針和字符串 6.9 通過指針訪問數(shù)組,2020/10/4,-3-,北京郵電大學(xué)信息與通信工程學(xué)院,6.1 指針的概念,2020/10/4,4,北京郵電大學(xué)信息與通信工程學(xué)院,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-5-,6.1.1 指針和指針變量,指針是變量的地址。或者說是在內(nèi)存中,存放某種類型變量的地址。 例如,定義了整型變量a,a的地址就是一個(gè)指針。 也可以不定義任何變量,只是指定內(nèi)存某個(gè)地址開始(如0 x00430100)的4個(gè)字節(jié)存放整型變量,這樣的地址也是指針。 存放指針的變量就是指針變量。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-6-,6.1.1 指

3、針和指針變量,當(dāng)聲明了一個(gè)指針變量后,確定如下事實(shí): 變量本身在內(nèi)存中所分配的地址和字節(jié)數(shù),指針變量總是占有4個(gè)字節(jié); 指針?biāo)赶虻膬?nèi)存單元內(nèi)可以存放的數(shù)據(jù)類型。 訪問指針變量時(shí),只能看到地址。只有通過這個(gè)地址,才能訪問地址單元中的內(nèi)容。這樣的訪問稱為對(duì)于內(nèi)存單元的間接訪問。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院24-26,-7-,6.1.2 指針變量的聲明和初始化,指針變量聲明的格式是: *變量名1, *變量名2; 例如: int *va1, *va2; char *ch1, *ch2; 指針變量在聲明后,變量的值(地址)是隨機(jī)的。這樣的指針變量是不能安全的使用的。因?yàn)槠渲械碾S

4、機(jī)地址完全可能不是有效的數(shù)據(jù)地址。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-8-,6.1.2 指針變量的聲明和初始化,在聲明指針變量時(shí)的“*”,有兩個(gè)含義: 聲明變量va1、va2、ch1、ch2都是指針變量; 說明變量va1和va2的類型是(int *)型,即指向整型變量的指針。va1和va2所指定的地址單元中,只能存放整型數(shù)據(jù)。類似地,ch1和ch2的類型是(char *)型,它們所指定的地址單元中,只能存放字符。 指針變量都是有類型的.指針變量的類型就是它所指定的地址單元中存放的數(shù)據(jù)的類型。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-9-,6.1.2 指針變量的

5、聲明和初始化,聲明指針變量時(shí)進(jìn)行初始化,其格式是: *指針變量名=,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-10-,6.1.2 指針變量的聲明和初始化,也可以在聲明指針變量后,對(duì)它進(jìn)行賦值。 例如: int i1=Y, i2=A; int *pi1, *pi2; pi1= 沒有初始化或賦值的指針變量是不可以使用的。編譯時(shí)會(huì)給出警告,而運(yùn)行時(shí)會(huì)出現(xiàn)錯(cuò)誤。,6.2 指針的運(yùn)算,2020/10/4,-11-,北京郵電大學(xué)信息與通信工程學(xué)院,6.2 指針的運(yùn)算,表6.1 指針的運(yùn)算,2020/10/4,-12-,北京郵電大學(xué)信息與通信工程學(xué)院,2020/10/4,北京郵電大學(xué)信息與通信工

6、程學(xué)院,-13-,6.2.1 指針的賦值運(yùn)算,指針的賦值運(yùn)算一定是地址的賦值,可以是: 同類型變量的地址賦值; 同類型的已經(jīng)初始化的指針變量賦值。 此外,也可以用0或者NULL對(duì)指針變量賦值。使得變量包含的是“空指針”,即不指向任何的內(nèi)存物理地址。 必須注意:不同類型的指針是不可以互相賦值的。在指針賦值時(shí),不存在類型自動(dòng)轉(zhuǎn)換的機(jī)制。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-14-,例6.1 觀察以下指針賦值運(yùn)算的結(jié)果。如果將注釋去掉,結(jié)果將如何? #include using namespace std; void main() int va1=100,*pva1; float

7、vf1=A,*pvf1,*pvf2; int *pva2=NULL; coutvalue of pva1 is pva2endl; pva1= ,value of pva1 is 0 x00000000 0 x0012FF7C 0 x0012FF7C 0 x0012FF74 0 x0012FF74 注釋去掉會(huì)出現(xiàn)編譯錯(cuò)誤,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-15-,6.2.2 間接引用運(yùn)算,間接引用運(yùn)算符“*”是一種一元算符,它和指針變量連用,對(duì)指針?biāo)赶虻膬?nèi)存地址單元進(jìn)行間接訪問。使用的格式是: *指針變量 如果指針變量iptr指向整型變量va,*iptr就是變量va的內(nèi)容

8、,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-16-,例6.2 對(duì)變量的直接訪問和間接訪問:寫出以下程序運(yùn)行結(jié)果。 #include using namespace std; void main() char ch1=a,*ch; int k1=100; ch= /間接訪問 ,運(yùn)行結(jié)果: *ch=a ch1=B *ch=d,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-17-,例6.3 定義指向指針的指針變量。觀察對(duì)這種指針變量間接訪問的結(jié)果。 #include using namespace std; void main() int va=100,*pva,*ppva; /

9、ppva是指向指針的指針 int k1=100; pva= /就是指針pva的內(nèi)容 ,運(yùn)行結(jié)果: *pva=100 *ppva=0 x0012FF7C pva=0 x0012FF7C,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-18-,6.2.2 間接引用運(yùn)算,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-19-,6.2.3 指針的算術(shù)運(yùn)算,指針可以進(jìn)行的算術(shù)運(yùn)算只有加法和減法。 指針可以和一個(gè)整數(shù)n做加法或者減法運(yùn)算。,指針p和整數(shù)n相加(相減)的含義是指向當(dāng)前指向位置p的前方或后方第n個(gè)數(shù)據(jù)的地址。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-20-,例6.3

10、通過指針的間接訪問,輸出下標(biāo)為偶數(shù)的數(shù)組元素的值。 #include using namespace std; void main() int k110=11,24,37,44,58,66,79,86,93,108,*k; k= ,運(yùn)行結(jié)果: K10=11 k12=37.,數(shù)組第一個(gè)元素(下標(biāo)為0)的地址賦值給指針k,每次循環(huán),指針加2,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-21-,6.2.3 指針的算術(shù)運(yùn)算,指針和指針的直接加法是沒有意義的,也是不允許的。 指針和指針的減法是可以進(jìn)行的,其意義是求出兩個(gè)指針之間可以存放幾個(gè)指定類型的數(shù)據(jù)。 不允許用一個(gè)整數(shù)減一個(gè)指針。,202

11、0/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-22-,6.2.4指針的關(guān)系運(yùn)算和邏輯運(yùn)算,相同類型的指針可以進(jìn)行各種關(guān)系運(yùn)算。比較兩個(gè)指針相等還是不相等。 還可以進(jìn)行指針“大于”、“小于”的比較,判定指針在內(nèi)存中的相對(duì)位置。 指針和一般的整數(shù)比較是沒有意義的,也是不允許的。惟一可以和指針比較的整數(shù)是0。通過指針和0的比較來判定指針本身是不是空指針。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-23-,6.2.5 void類型指針,void類型的指針就是“無類型”指針。聲明的方式如下: void *; void類型的指針變量中存放的也是內(nèi)存地址,但是不指定這個(gè)地址單元內(nèi)的數(shù)據(jù)類型。,

12、2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-24-,6.2.5 void類型指針,void類型的指針的使用: 任何其他類型的指針都可以賦值給void指針。必須注意,這樣賦值后的void指針的類型仍然是void。 void類型指針不可以直接賦值給任何其他類型的指針。 無論何時(shí),void指針都不可以通過間接引用來訪問內(nèi)存中的數(shù)據(jù)。 要通過void類型指針訪問內(nèi)存的數(shù)據(jù),必須進(jìn)行指針類型的強(qiáng)制轉(zhuǎn)換,才可以通過指針間接引用訪問內(nèi)存數(shù)據(jù)。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-25-,void類型指針,void類型指針還有一個(gè)具體的應(yīng)用:顯示字符指針的內(nèi)容。除了字符指針外,其他

13、指針都可以直接用cout語句來輸出地址值。但是,用cout輸出字符指針時(shí),則是輸出它所指向的字符串。可以將字符指針強(qiáng)制轉(zhuǎn)換為void指針,再用cout語句輸出,就可以看到地址值。如: char *pch=Hello C+; coutpchendl; cout(void*)pchendl;,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-26-,例6.4 使用memcpy通用復(fù)制函數(shù)復(fù)制數(shù)組。 #include using namespace std; #include void main() char dest10,src10=012345678“; char* pc=(char*)me

14、mcpy(dest,src,10); cout pc endl; int s13=1,2,3,d13; int *pi=(int*)memcpy(d1,s1,12); cout*pi *(pi+1) *(pi+2)endl; / void *memcpy(void *dest, const void *src, size_t n);,運(yùn)行結(jié)果: 012345678 1 2 3,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-27-,6.2.6 指針類型轉(zhuǎn)換,實(shí)際應(yīng)用的指針變量都是有類型的,指針類型就是指針?biāo)傅牡刂房臻g所存放的數(shù)據(jù)的類型。 除了void指針,不同類型的指針是不可以相互賦值

15、的。在例6-1中的語句pvf1=pva1(整型指針賦值給float指針)就是有語法錯(cuò)誤的語句。 一般地,指針也不能進(jìn)行強(qiáng)制類型轉(zhuǎn)換。(?),2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-28-,指針類型轉(zhuǎn)換,若pch是字符指針,p是double類型指針,以下的語句: pch=static_cast(p); 在編譯時(shí)有語法錯(cuò)誤:“不能將double*轉(zhuǎn)換為char*”,也就是說指針的強(qiáng)制類型轉(zhuǎn)換也是不允許的。 如果使用C風(fēng)格的類型轉(zhuǎn)換:pch=(char*)p;在編譯時(shí)沒有語法錯(cuò)誤,僅在執(zhí)行時(shí)有問題。 要使用static_cast來進(jìn)行強(qiáng)制類型轉(zhuǎn)換。 void指針和其它類型指針之間可以相

16、互轉(zhuǎn)換。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-29-,/例6-5利用格式控制符hex可以顯示整數(shù)的機(jī)器數(shù)的程序,void main() float f=1.0; float* fPtr= ,6.3 指針訪問動(dòng)態(tài)內(nèi)存,2020/10/4,-30-,北京郵電大學(xué)信息與通信工程學(xué)院,指針訪問動(dòng)態(tài)內(nèi)存,動(dòng)態(tài)內(nèi)存是在程序執(zhí)行時(shí)才可以申請(qǐng)、使用和釋放的內(nèi)存。也就是存放動(dòng)態(tài)數(shù)據(jù)的內(nèi)存區(qū)域。存放動(dòng)態(tài)數(shù)據(jù)的區(qū)域稱為“堆”,動(dòng)態(tài)內(nèi)存也稱為堆內(nèi)存。 動(dòng)態(tài)內(nèi)存不能通過變量名來使用,而只能通過指針來使用。,2020/10/4,-31-,北京郵電大學(xué)信息與通信工程學(xué)院,2020/10/4,北京郵電大學(xué)信

17、息與通信工程學(xué)院,-32-,6.3.1 動(dòng)態(tài)內(nèi)存的申請(qǐng)和釋放,C+中通過運(yùn)算符new申請(qǐng)動(dòng)態(tài)內(nèi)存,運(yùn)算符delete釋放動(dòng)態(tài)內(nèi)存。 動(dòng)態(tài)內(nèi)存申請(qǐng)運(yùn)算符new的使用格式: new (初值) 運(yùn)算的結(jié)果:如果申請(qǐng)成功,返回指定類型內(nèi)存的地址;如果申請(qǐng)失敗,返回NULL指針。 動(dòng)態(tài)內(nèi)存使用完畢后,要用delete運(yùn)算來釋放。delete運(yùn)算符使用格式: delete ;,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-33-,6.3.2 動(dòng)態(tài)數(shù)組空間的申請(qǐng)和釋放,對(duì)于數(shù)組情況,需要在new表達(dá)式中加上申請(qǐng)數(shù)組的大?。?new 常量表達(dá)式 ; 注意:在動(dòng)態(tài)申請(qǐng)數(shù)組空間時(shí),不可以對(duì)數(shù)組進(jìn)行初始化。

18、 也可以申請(qǐng)二維數(shù)組的空間: int (*pi_marray)4; pi_marray = new int34; 釋放動(dòng)態(tài)數(shù)組空間都用相同的表達(dá)式: delete ;,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-34-,6.3.3 內(nèi)存泄漏和指針懸掛,內(nèi)存泄漏是指動(dòng)態(tài)申請(qǐng)的內(nèi)存空間,沒有正常釋放,但是也不能繼續(xù)使用的情況。如: char *ch1; ch1 = new char(A); char *ch2 = new char; ch1=ch2; 原來為ch1所申請(qǐng)的存放字符A的空間不能被釋放, 產(chǎn)生了內(nèi)存泄漏。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-35-,6.3.

19、3 內(nèi)存泄漏和指針懸掛,讓指針指向一個(gè)已經(jīng)釋放的空間,即所謂的指針懸掛(Dangling)。如: char *ch1, *ch2; ch1 = new char; ch2 = ch1; *ch2 = B; delete ch1; 指針ch2指向了一個(gè)已經(jīng)釋放的地址空間,產(chǎn)生指針懸 掛。若要用delete ch2;語句來釋放ch2所指向的空間, 會(huì)出現(xiàn)運(yùn)行錯(cuò)誤。,6.4 指向結(jié)構(gòu)體的指針,2020/10/4,-36-,北京郵電大學(xué)信息與通信工程學(xué)院,指向結(jié)構(gòu)體的指針,定義變量時(shí),可以定義指向int型的指針變量,也可以定義指向結(jié)構(gòu)體類型的指針變量。 聲明了指向結(jié)構(gòu)體的指針后,可以對(duì)指針初始化:其一

20、是用已經(jīng)定義的變量地址來初始化,其二是用new申請(qǐng)一個(gè)地址來對(duì)指針初始化。,2020/10/4,-37-,北京郵電大學(xué)信息與通信工程學(xué)院,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-38-,舉例: (1) struct student /聲明新的數(shù)據(jù)類型 long num;/學(xué)號(hào) char name20; /姓名 float score;/成績 ; student stu=20041118,Li Li,18; /定義結(jié)構(gòu)變量并初始化 student * ps= /定義結(jié)構(gòu)體指針始化,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-39-,用結(jié)構(gòu)指針訪問結(jié)構(gòu)成員時(shí),用箭頭操作符代

21、替原來的點(diǎn)操作符對(duì)結(jié)構(gòu)體成員進(jìn)行操作。比如,把學(xué)生的成績輸出顯示: coutscore; 其中,ps-score等價(jià)于(*ps).score。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-40-,解:員工信息包括姓名、工作證號(hào)、薪水,可定義為結(jié) 構(gòu)體類型。 #include #include using namespace std; struct Employee char name20; unsigned long id; float salary; ;,例6-6 顯示員工信息,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-41-,void main() Employee

22、pr1, *prPtr; prPtr= 程序運(yùn)行結(jié)果: zhang san 98001 3350,6.5 引用概念,2020/10/4,-42-,北京郵電大學(xué)信息與通信工程學(xué)院,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-43-,引用概念,引用(Reference)是C+中新引入的概念,也是C語言中不存在的數(shù)據(jù)類型。 引用是變量或者其他編程實(shí)體(如對(duì)象)的別名。如圖6.4(a)所示,變量A在內(nèi)存中有自己的地址,而A的引用B實(shí)際上就是變量A,只是A的另外一個(gè)名字。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-44-,6.5.1 引用的聲明,引用是通過運(yùn)算符 必須注意:引用必須

23、在聲明的時(shí)候就完成初始化,不可以先聲明引用,然后再用另一個(gè)語句對(duì)它賦值。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-45-,引用有以下的特點(diǎn): 引用不能獨(dú)立存在,它只是其他變量的別名; 引用必須在聲明的同時(shí)就初始化; 引用一旦定義,引用關(guān)系就不可以更改,即B若是A的引用,就不可能是其他變量的引用; 引用的類型就是相關(guān)變量的類型,引用的使用和變量的使用相同。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-46-,例6-7 使用引用 void main() int intA=10; int ,6.5.2 引用的使用,運(yùn)行結(jié)果: refA=10 intA=5 intA的地址0 x

24、0012FF7C refA的地址0 x0012FF7C,6.6指針和引用作為函數(shù)的參數(shù),2020/10/4,-47-,北京郵電大學(xué)信息與通信工程學(xué)院,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-48-,指針和函數(shù),在程序設(shè)計(jì)中,指針有很多應(yīng)用。其中之一就是用指針作為函數(shù)的參數(shù)。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-49-,6.6.1 指針作為函數(shù)的參數(shù),用指針作為函數(shù)參數(shù),必須滿足以下條件: 函數(shù)的形式參數(shù)是指針變量; 函數(shù)的實(shí)參數(shù)是內(nèi)存的地址,具體來說可以是數(shù)組名、變量的地址、地址常量; 形參指針類型和實(shí)參地址類型必須相同。,2020/10/4,北京郵電大學(xué)信息與

25、通信工程學(xué)院,-50-,6.6.1 指針作為函數(shù)的參數(shù),滿足以上條件后,這樣的函數(shù)調(diào)用有以下特點(diǎn): 實(shí)參傳遞給形參的是內(nèi)存的地址,所以形參指針指向?qū)崊⒆兞浚?形參指針通過間接引用,直接訪問實(shí)參變量,包括改變實(shí)參變量的值; 函數(shù)調(diào)用后,可以保留對(duì)實(shí)參變量的操作結(jié)果,如果有多個(gè)實(shí)參,就可以有多個(gè)實(shí)參變量在函數(shù)調(diào)用中得到修改。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-51-,例6.8 數(shù)據(jù)交換 void Swap(int *a, int *b); void main() int x(5), y(10); cout“x=x y=yendl; Swap( ,運(yùn)行結(jié)果: x=5 y=10 x

26、=10 y=5,變量的地址作為實(shí)參數(shù),指針變量作為形式參數(shù),2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-52-,6.6.1 指針作為函數(shù)的參數(shù),程序中用變量x和y的地址作實(shí)參,傳遞給指針 a和b,如圖6.1(a)。通過間接引用*a和*b進(jìn)行交 換,實(shí)際上就是x和y進(jìn)行交換,如圖6.1(b)。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-53-,6.6.2 引用作為函數(shù)參數(shù),引用使用最多的場(chǎng)合是作為函數(shù)的形參。 引用作為函數(shù)的形參具有以下的特點(diǎn): 實(shí)參是相同類型的變量; 參數(shù)傳遞屬于地址傳遞; 在函數(shù)中并不產(chǎn)生實(shí)參的副本,形參引用和實(shí)參變量實(shí)際上是同一個(gè)實(shí)體; 函數(shù)對(duì)引用的操

27、作,也是對(duì)實(shí)參變量的操作,函數(shù)調(diào)用可以改變實(shí)參的值。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-54-,例6.9 引用作為形參,通過函數(shù)調(diào)用,交換兩個(gè)實(shí)參的值。 void swap_1(int ,調(diào)用前:a= 12345 b=54321 調(diào)用后:a= 54321 b=12345,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-55-,6.6.2 引用作為函數(shù)參數(shù),引用作為形參需要注意: 如果實(shí)參要保護(hù),可使用“常引用”作為形式參數(shù); 引用作形參和變量作形參雖有區(qū)別,但要注意以下用法。 例:swap(int a, int b); swap(int 雖然兩個(gè)函數(shù)的原型不同,但在以

28、下情況會(huì)出現(xiàn)“二義性”錯(cuò)誤。 swap(x, y); / x,y是int變量,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-56-,6.6.3 常指針和常引用,常指針是指向常量的指針(Pointer to Constant data),它規(guī)定指針?biāo)赶虻膬?nèi)容不可以通過指針的間接引用(間接訪問)來改變。 常指針說明的格式是: const *; 例如: const int *ptint; 指針ptint的類型是(const int *),也就是指向一個(gè) 恒定的整型數(shù)。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-57-,例6.10 使用常指針 #include using nam

29、espace std; void main() int ia=10, ib=20; const int *ptint; ptint= /語句錯(cuò)誤 ,運(yùn)行結(jié)果: 10 120,常指針聲明,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-58-,6.6.4 指針的指針作為函數(shù)的參數(shù),如果一定要改變實(shí)參指針的值,可以用 指針變量的地址作實(shí)參,形式參數(shù)就應(yīng)該 是指針的指針。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-59-,例6.12 指針變量指向數(shù)組。 void Move(int *a); void main() int x5=10,20,30,40,50, *px=x; cout

30、調(diào)用前的*px=*pxendl; Move(px); cout調(diào)用后的px; if(px=x)cout沒有變化,*px還是*pxendl; else cout也向前移動(dòng),*px變?yōu)?pxendl; void Move(int *a) a=a+1; cout函數(shù)中完成了指針移動(dòng):*a=*aendl; ,運(yùn)行結(jié)果: 調(diào)用前的*px=10 函數(shù)中完成了指針移動(dòng):*a=20 調(diào)用后的px沒有變化*px還是10,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-60-,例6.13:修改上例,使得實(shí)參指針返回后,指向新地址。 void Move(int *a); void main() int x5=

31、10,20,30,40,50, *px=x; cout*px=*pxendl; Move( ,運(yùn)行結(jié)果: *px=10 *a=20 px向前移動(dòng),*px變?yōu)?0,指針的地址作為實(shí)參數(shù),指針的指針作為形式參數(shù),6.7指針和引用作為函數(shù)的返回值,2020/10/4,-61-,北京郵電大學(xué)信息與通信工程學(xué)院?,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-62-,6.7.1 指針函數(shù),如果一個(gè)函數(shù)的返回值是指針,則這樣的函數(shù)稱為指針函數(shù)。如: int *func01(int k); 函數(shù)func01返回一個(gè)指向整型數(shù)據(jù)的指針。 返回指針,實(shí)際就是返回一個(gè)內(nèi)存的地址。 要注意:不能返回函數(shù)中局

32、部變量的地址。這樣的地址處于內(nèi)存的堆棧區(qū),是所有函數(shù)公用的區(qū)域。其中的數(shù)據(jù)是不穩(wěn)定的,可能因?yàn)槠渌瘮?shù)的執(zhí)行而發(fā)生改變。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-63-,例6-15 一個(gè)指針函數(shù)完成一個(gè)數(shù)組的倒序。源數(shù)組由函數(shù)參數(shù)傳遞,倒序后的數(shù)組地址由指針函數(shù)返回。 #include using namespace std; int * reverse(int const * list, const int size)/指針函數(shù) int result6;/函數(shù)中定義的局部數(shù)組 for (int i = 0, j = size - 1; i size; i+, j-) resul

33、tj = listi; return result;/返回局部數(shù)組的地址 ,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-64-,void printArray(int const *list, const int size) for (int i = 0; i size; i+) cout listi ; void main() int list = 1, 2, 3, 4, 5, 6; int *pList = reverse(list, 6); /獲得倒序后數(shù)組的地址 printArray(pList, 6);/顯示倒序后的數(shù)組 程序運(yùn)行結(jié)果: -858993460 -858993

34、460 -858993460 -858993460 -858993460 5 結(jié)果完全不對(duì)。原因就在于指針函數(shù)返回的是函數(shù)局部數(shù)組的地址。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-65-,例6-16 對(duì)例6-15的修改。只要修改指針函數(shù)reverse??梢栽诤瘮?shù)這申請(qǐng)一個(gè)動(dòng)態(tài)數(shù)組的地址,最后返回這個(gè)地址就可以。注意不要忘了用delete來釋放這個(gè)地址。 #include using namespace std; int * reverse(int const * list, const int size)/指針函數(shù) int *result = new intsize; /函數(shù)中定

35、義的動(dòng)態(tài)數(shù)組 for (int i = 0, j = size - 1; i size; i+, j-) resultj = listi; return result; /返回動(dòng)態(tài)數(shù)組的地址 ,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-66-,void printArray(int const *list, const int size) for (int i = 0; i size; i+) cout listi ; void main() int list = 1, 2, 3, 4, 5, 6; int *pList = reverse(list, 6);/獲得倒序后數(shù)組的地址

36、 printArray(pList, 6);/顯示倒序后的數(shù)組 delete pList; 程序運(yùn)行結(jié)果: 6 5 4 3 2 1,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-67-,6.7.2 用引用作為函數(shù)的返回值,返回引用有以下需要注意的地方: 返回引用需要在函數(shù)的返回值類型中加以說明,形式為: 返回引用實(shí)際是返回地址。在使用上,或者直接使用這個(gè)地址;或者使用這個(gè)地址單元的數(shù)據(jù)。 返回的引用可以作為左值繼續(xù)操作,而返回的變量值是不可以繼續(xù)運(yùn)算的。這是返回引用和返回變量值在使用上的主要區(qū)別。,2020/10/4,/例6-17 引用作為函數(shù)的返回值 #include #includ

37、e using namespace std; struct person char name15; int contribution; double bonus; ;/定義結(jié)構(gòu)體 person p1=Li Li,500,0,p2=Zhao Zhao,600,0;/兩名職工是全局變量 person ,2020/10/4,例6.17引用作為函數(shù)返回值。 void main() compare().bonus=1000; /返回值作為左值直接操作 coutsetw(10) p1.contribution p1.bonusendl; coutsetw(10) p2.cont

38、ribution p2.bonusendl; 程序運(yùn)行結(jié)果: Li Li 500 0 Zhao Zhao 600 1000,6.8 指針和字符串,2020/10/4,-70-,北京郵電大學(xué)信息與通信工程學(xué)院,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-71-,6.8.1 字符串處理的兩種方式,C+字符串常量是用雙引號(hào)括起的字符序列,并以字符0作為結(jié)束標(biāo)志。如 This is a string。 字符串常量存放在內(nèi)存的某個(gè)區(qū)域,有自己固定的首地址。 如果將字符串常量的首地址看成是指針,這種指針既是常指針,也是指針常量。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-72-,6.

39、8.1 字符串處理的兩種方式,C+處理字符串有兩種方式:數(shù)組方式和指針方式。 數(shù)組方式是將字符串存入字符數(shù)組后,再進(jìn)行處理。一般可以在聲明數(shù)組的時(shí)候用字符串來初始化: char string_array=Whats a nice day!; 指針方式是用字符串常量來初始化一個(gè)字符指針: char *string_pt=Whats a nice day!;,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-73-,6.8.1 字符串處理的兩種方式,常量不能放在等式左邊,運(yùn)行時(shí)會(huì)出錯(cuò),2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-74-,6.8.2 字符串操作函數(shù),調(diào)用這些函數(shù)時(shí),原則

40、上可以使用字符數(shù)組名、已經(jīng)初始化的字符指針作為實(shí)參數(shù)。字符串常量還可以作為源字符串的實(shí)參數(shù)。 目的串必須是可寫的。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-75-,例6.18 strcpy和strncpy的比較。 #include #include using namespace std; void main() int n; char *array1 = Happy Birthday to You; char array3 15 ; char array2 25 ; strcpy( array2, array1 ); cout The string in array1 is:

41、array1 nThe string in array2 is: array2 n; /*strcpy(array3,array1); coutarray3endl; */ n=sizeof(array3); strncpy( array3, array1, n-1 ); / 復(fù)制array1的n-1個(gè)字符到array3 array3 14 = 0; / 添加0 到array3 cout The string in array3 is: array3 endl; ,不包括提示的運(yùn)行結(jié)果 Happy Birthday to You Happy Birthday to You Happy Birt

42、hday,復(fù)制array1到array2,沒有問題,復(fù)制array1到array3,空間不夠,有運(yùn)行錯(cuò)誤,按實(shí)際數(shù)組大小,復(fù)制array1到array3,沒有問題,6.9 通過指針訪問數(shù)組,2020/10/4,-76-,北京郵電大學(xué)信息與通信工程學(xué)院,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-77-,通過指針訪問數(shù)組,指針和數(shù)組有天然的聯(lián)系。因?yàn)閿?shù)組名本身就是地址,也就是某種類型的指針。將指針和數(shù)組名聯(lián)系起來,訪問數(shù)組就多了一種方法。 雖然一維數(shù)組名和二維數(shù)組名都是地址,都可以看作是某種指針,但是指針的類型是不同的。因此,通過指針訪問一維數(shù)組和二維數(shù)組的方法是不同的。,2020/1

43、0/4,北京郵電大學(xué)信息與通信工程學(xué)院,-78-,6.9.1 通過指針訪問一維數(shù)組,要通過指針訪問一維數(shù)組,必須首先聲明一個(gè)和數(shù)組類型相同的指針,并且用數(shù)組名來對(duì)指針初始化,如: int A10, *pa=A; 然后,就可以用多種方式訪問數(shù)組元素: 數(shù)組名和下標(biāo),如A0、A4; 指針和下標(biāo),如pa0、pa4; 指針加偏移量的間接引用,如*(pa+4); 數(shù)組名加偏移量的間接引用,如*(A+4); 指針自加后的間接引用,如*pa+。,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-79-,例6.19 求數(shù)組內(nèi)所存放的字符串的長度。 #include using namespace std;

44、 void main() char ChArray=This is a string.,*ptch; int i,j,k,offset1,offset2; ptch=ChArray;/指針初始化 for(i=0;ChArrayi!=0;i+); coutThe length of the string is:iendl; for(j=0;ptchj!=0;j+); coutThe length of the string is:jendl; for(offset1=0;*(ChArray+offset1)!=0;offset1+); coutThe length of the string i

45、s:offset1endl; for(offset2=0;*(ptch+offset2)!=0;offset2+); coutThe length of the string is:offset2endl; for(k=0;*ptch+!=0;k+); coutThe length of the string is:kendl; ,運(yùn)行結(jié)果 都相同,方式1:數(shù)組名和下標(biāo),方式2:指針和下標(biāo),方式3: 數(shù)組名加偏移量的間接引用,方式4:指針加偏移量的間接引用,方式5:指針自加的間接引用,2020/10/4,北京郵電大學(xué)信息與通信工程學(xué)院,-80-,例6.20 求整型數(shù)組的平均值,顯示數(shù)組元素和平均值。 #include using namespace std; void main() int intArray10=8,11,23,34,45,56,6

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論