第7章 指針與引用_第1頁
第7章 指針與引用_第2頁
第7章 指針與引用_第3頁
第7章 指針與引用_第4頁
第7章 指針與引用_第5頁
已閱讀5頁,還剩72頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、-2-3-2000022002int a;-4-#include int main()short sVar = 5;long lVar = 65535;float fVar= 3.14f;std:coutShort:tsVartAdd:t&sVarn;std:coutLong:tlVartAddr:t&lVarn;std:coutFloat:tfVartAddr:t&fVarn“;return 0;p取變量地址運算符:取變量地址運算符:& &sVarsVar。ptt為轉(zhuǎn)義字符,輸出一個制表符。為轉(zhuǎn)義字符,輸出一個制表符。 用于輸出用于輸出 ,輸出雙引號,

2、輸出雙引號, 輸出輸出 單引號單引號p每個變量都有確定的地址每個變量都有確定的地址p編譯器確定應(yīng)分配內(nèi)存編譯器確定應(yīng)分配內(nèi)存 的數(shù)量,及對應(yīng)的地址的數(shù)量,及對應(yīng)的地址p程序員不用關(guān)心地址的細(xì)節(jié),程序員不用關(guān)心地址的細(xì)節(jié), 只需知道如何訪問變量即可只需知道如何訪問變量即可-5-p定義變量時,變量名定義變量時,變量名pAgepAge前面的前面的* *,表示,表示pAgepAge是一個變量,是一個變量, 用來存儲一個整型變量的地址,用來存儲一個整型變量的地址, 編譯器會為指針變量分配內(nèi)存單元。編譯器會為指針變量分配內(nèi)存單元。p指針變量的類型:可保存其地址的變量數(shù)據(jù)類型。指針變量的類型:可保存其地址的

3、變量數(shù)據(jù)類型。pNULLNULL為預(yù)定義常量,表示空指針,為預(yù)定義常量,表示空指針,NULLNULL通常等價于通常等價于0 0。p良好編程習(xí)慣:定義指針變量時應(yīng)對其執(zhí)行初始化,未初良好編程習(xí)慣:定義指針變量時應(yīng)對其執(zhí)行初始化,未初 始化的指針稱為野指針,非常危險。始化的指針稱為野指針,非常危險。-6-p指針變量中存儲的地址值實際上是一個整數(shù)值,但不能將指針變量中存儲的地址值實際上是一個整數(shù)值,但不能將 整數(shù)值直接賦值給指針變量。整數(shù)值直接賦值給指針變量。p賦值時,取地址的變量類型必須與指針變量類型一致。否賦值時,取地址的變量類型必須與指針變量類型一致。否 則編譯器報錯。則編譯器報錯。-7-8-

4、9-#include int main()int myAge;int *pAge=&myAge;myAge=5;std:coutMyAge:tmyAgen;std:cout*pAge:t*pAgen;*pAge=7;std:coutMyAge:tmyAgen;std:cout*pAge:t*pAgen;return 0;-10-11-12-void swap( int *x, int *y )int temp; temp = *x;*x = *y;*y = temp;std:cout *x , *y std:endl;#include void swap( int *a, int *b

5、 );int main()int a = 3, b = 2;swap(&a, &b);std:cout a , b std:endl;return 0;-13-p指針變量指針變量papa指向數(shù)組指向數(shù)組a ap傳遞數(shù)組的本質(zhì)上只是傳遞數(shù)組起始地址,在傳遞數(shù)組的本質(zhì)上只是傳遞數(shù)組起始地址,在averageaverage 函數(shù)中,通過指針變量間接訪問數(shù)組元素。函數(shù)中,通過指針變量間接訪問數(shù)組元素。p指針變量指針變量papa指向數(shù)組指向數(shù)組a+1a+1-14-#include double average( int array, int size);const int N = 10;

6、int main()int aN;int *p = a; /或者p = &a0;for(int k=0; kN; k+)* ( p + k ) = k;double ave ;ave = average(a, N);std:cout average= ave n;return 0;或者或者pk=k;或者或者( int *array, int size);或者(或者(int *, int );-15-int average( int array, int size)int sum=0;for(int i=0; isize; +i)sum+=arrayi;return sum/size;p

7、數(shù)組本身并不包含數(shù)據(jù)元素個數(shù)的信息,傳遞數(shù)組或指針數(shù)組本身并不包含數(shù)據(jù)元素個數(shù)的信息,傳遞數(shù)組或指針 時,往往傳遞輔助參數(shù)表示元素個數(shù)。時,往往傳遞輔助參數(shù)表示元素個數(shù)?;蛘呋蛘遱um += *(array + i);int *p ;for(p = array; p array + size ; p+)sum += *p;-16-17-18-p局部變量隨著函數(shù)的返回被丟棄,無法再訪問。局部變量隨著函數(shù)的返回被丟棄,無法再訪問。p全局變量存在于整個程序的運行期間,整個程序中都能全局變量存在于整個程序的運行期間,整個程序中都能 訪問,但全局變量容易出錯、難以理解與維護(hù),避免使用。訪問,但全局變量容

8、易出錯、難以理解與維護(hù),避免使用。-19-20-p從堆中分配可存儲從堆中分配可存儲1 1個個intint數(shù)據(jù)的空間。數(shù)據(jù)的空間。p堆中分配的內(nèi)存,沒有對應(yīng)的變量,只能通過指針間接訪問堆中分配的內(nèi)存,沒有對應(yīng)的變量,只能通過指針間接訪問p從堆中分配內(nèi)存可能會失敗,使用指針前一定要判斷是否從堆中分配內(nèi)存可能會失敗,使用指針前一定要判斷是否 分配成功。老式編譯器失敗后返回分配成功。老式編譯器失敗后返回NULLNULL指針,新的編譯器指針,新的編譯器 會拋出異常(后面討論)。會拋出異常(后面討論)。-21-p分配堆空間時,可以指定分配數(shù)據(jù)的數(shù)量,從而請求可保存分配堆空間時,可以指定分配數(shù)據(jù)的數(shù)量,從而

9、請求可保存 多個數(shù)據(jù)的存儲空間。多個數(shù)據(jù)的存儲空間。p* *pPointerpPointer訪問所指向的第一個數(shù)據(jù),訪問所指向的第一個數(shù)據(jù),* *(pPointer+n)(pPointer+n)訪問之訪問之 后的第后的第n n個數(shù)據(jù),注意不能超過所分配的內(nèi)存界限。個數(shù)據(jù),注意不能超過所分配的內(nèi)存界限。-22-p動態(tài)請求的多個數(shù)據(jù),如果只使用動態(tài)請求的多個數(shù)據(jù),如果只使用deletedelete釋放,將造成內(nèi)存釋放,將造成內(nèi)存 泄漏。泄漏。-23-#include int main()int *pHeap = new int;if(pHeap = NULL)std:coutError! No m

10、emory for pHeap!n;return 1;*pHeap = 7;std:cout*pHeap: *pHeapn;delete pHeap;return 0;-24-pdeletedelete指針后,該指針將成為懸擺指針(或野指針、迷失指針后,該指針將成為懸擺指針(或野指針、迷失 指針),解析或再次指針),解析或再次deletedelete該指針,會導(dǎo)致程序崩潰。該指針,會導(dǎo)致程序崩潰。p良好編程習(xí)慣:對指針執(zhí)行運算前,判斷該指針是否為良好編程習(xí)慣:對指針執(zhí)行運算前,判斷該指針是否為NULLNULL-25-void fun()int *pa = new int(5);*pa = 10

11、;delete pa;std:cout pa std:endl;2000pa52000pdeletedelete只是釋放只是釋放papa所指向的堆空間,對指針?biāo)赶虻亩芽臻g,對指針papa本身沒有任何本身沒有任何 影響。此時影響。此時papa仍然指向原先的內(nèi)存位置,變成了野指針。仍然指向原先的內(nèi)存位置,變成了野指針。ppapa是位于棧中的局部變量,是位于棧中的局部變量,funfun返回后返回后papa由系統(tǒng)自動銷毀。由系統(tǒng)自動銷毀。-26-ppNumberpNumber指向新分配的存儲空間后,原先分配的內(nèi)容為指向新分配的存儲空間后,原先分配的內(nèi)容為7575的的 內(nèi)存無法訪問,也無法再釋放!內(nèi)存

12、無法訪問,也無法再釋放!-27-&典型情況二:在函數(shù)內(nèi)分配的內(nèi)存空間,函數(shù)返回之前沒有釋放void fun()int *pa=new int;*pa = 5;int main()fun(); 2000 pa52000-28-29-p創(chuàng)建對象時會調(diào)用類的構(gòu)造函數(shù),此處調(diào)用缺省構(gòu)造函數(shù)創(chuàng)建對象時會調(diào)用類的構(gòu)造函數(shù),此處調(diào)用缺省構(gòu)造函數(shù)p每當(dāng)在棧中或堆中創(chuàng)建對象時,都將調(diào)用構(gòu)造函數(shù)。每當(dāng)在棧中或堆中創(chuàng)建對象時,都將調(diào)用構(gòu)造函數(shù)。p執(zhí)行執(zhí)行deletedelete操作后,將調(diào)用對象的析構(gòu)函數(shù),然后釋放堆操作后,將調(diào)用對象的析構(gòu)函數(shù),然后釋放堆 中的內(nèi)存(對象本身)。中的內(nèi)存(對象本身)。-30

13、-2000 myRectangleRectangle *my Rectangle = new Rectangle;. /使用使用my Rectangledelete myRectangle;300430002000 lengthwidth523000-31-32-#include class Apublic:A(int x=0) this-x = x;int getX() return x; void setX(int x) this-x = x; private:int x;int main() A *myA = new A;std:coutmy A is getX() setX(4);st

14、d:coutmyA is (*myA).getX() n;delete myA;return 0;-33-34-prSomeIntrSomeInt是一個是一個intint引用,被初始化指向引用,被初始化指向someIntsomeInt。p將來對將來對rSomeIntrSomeInt的操作都等價于對的操作都等價于對someIntsomeInt的操作。的操作。-35-#include int main()int intOne;int &rSomeRef = intOne;intOne=5;std:coutintOne: intOnen;std:coutrSomeRef: rSomeRefn

15、;rSomeRef=7;std:coutintOne: intOnen;std:coutrSomeRef: rSomeRefn;return 0;-36-37-prSomeIntrSomeInt仍然引用的是仍然引用的是someIntsomeInt,通過賦值運算符,只是,通過賦值運算符,只是 將將anotherIntanotherInt的值賦給的值賦給rSomeIntrSomeInt,也就是,也就是someIntsomeInt。-38-39-40-41-void swap( int &rx, int &ry )int temp;temp=rx;rx=ry;ry=temp;std:

16、cout rx “ , “ ry std:endl;prxrx和和ryry是是x x和和y y的引用,調(diào)用的引用,調(diào)用swapswap時沒有創(chuàng)建新的局部變時沒有創(chuàng)建新的局部變 量,對量,對rxrx和和ryry的操作就是對的操作就是對x x和和y y的操作。的操作。#include void swap( int &rx, int &ry );int main()int x=5, y=10;swap(x, y);std:cout x “ , y std:endl; return 0;-42-43-bool factor(int n, int &pSquared, int &

17、amp;pCubed)bool flag = false;pSquared= n * n;pCubed = n * n * n;if( pSquared 0 | n * pCubed 0 )flag = false;elseflag = true;return flag;p返回多個值(引用)返回多個值(引用)pflagflag記錄計算結(jié)果是否越界記錄計算結(jié)果是否越界 如返回如返回truetrue表示計算成功,表示計算成功, 返回返回falsefalse表示計算失敗。表示計算失敗。p通過傳入的引用將計算結(jié)果保存通過傳入的引用將計算結(jié)果保存 到引用的變量。到引用的變量。-44-#include b

18、ool factor(int n, int &pSquared, int &pCubed);int main() int number, squared, scubed;bool flag;std:coutnumber;flag = factor(number, squared,scubed);if( flag )std:cout number: “ number n squared: “ squared n scubed: “ scubed n;elsestd:coutError encountered!n;return 0;-45-46-47-class Rectangle

19、public:Rectangle();Rectangle();int getLength() return *itsLength; int getWidth() return *itsWidth; void setLength(int length ) *itsLength = length; void setWidth(int width) *itsWidth = width; void output();private:int *itsLength;int *itsWidth;p為含有指針成員的類編寫構(gòu)造與析構(gòu)函數(shù)。為含有指針成員的類編寫構(gòu)造與析構(gòu)函數(shù)。-48-Rectangle:Rect

20、angle()itsLength = new int(2);itsWidth = new int(5);Rectangle:Rectangle()delete itsLength;delete itsWidth;void Rectangle:output() std:cout getLength() , getWidth() length = length; void setWidth(int width) this-width = width; void output();private:int length;int width;-51-p三種形式的含義不同三種形式的含義不同p若若const

21、const位于位于* *號左側(cè),表示指向內(nèi)容為常量(內(nèi)容受保護(hù))號左側(cè),表示指向內(nèi)容為常量(內(nèi)容受保護(hù)) 若若constconst位于位于* *號右側(cè),表示指針本身為常量(指針受保護(hù))號右側(cè),表示指針本身為常量(指針受保護(hù))-52-ppOne:pOne:指向整型常量的指針,通過指向整型常量的指針,通過pOnepOne不能修改所指向變量不能修改所指向變量 的值;但可以指向別的整數(shù)。的值;但可以指向別的整數(shù)。-53-ppTwo:pTwo:指向整型的常量指針,指向整型的常量指針,pTwopTwo不能再指向其它變量,不能再指向其它變量, 但可以通過指針修改所指向變量的值。但可以通過指針修改所指向變量的

22、值。-54-ppThree:pThree:指向整型常量的常量指針,指向整型常量的常量指針,pThreepThree不能再指向其它不能再指向其它 變量,通過指針也不能修改所指向變量的值。變量,通過指針也不能修改所指向變量的值。-55-例例7-13完整源代碼完整源代碼-56-【例例7-14-1】對象的值作為函數(shù)的參數(shù)對象的值作為函數(shù)的參數(shù)【例例7-14-2】對象的指針作為函數(shù)的參數(shù)對象的指針作為函數(shù)的參數(shù)【例例7-14-3】對象的引用作為函數(shù)的參數(shù)對象的引用作為函數(shù)的參數(shù)-57-Rectangle FunctionOne(Rectangle r )return r;int main() Recta

23、ngle myRectangle;FunctionOne(myRectangle);return 0;p調(diào)用函數(shù)時創(chuàng)建調(diào)用函數(shù)時創(chuàng)建theCattheCat,調(diào)用復(fù)制構(gòu)造函數(shù)復(fù)制,調(diào)用復(fù)制構(gòu)造函數(shù)復(fù)制myCatmyCat 內(nèi)容;函數(shù)返回后調(diào)用析構(gòu)函數(shù),并銷毀內(nèi)容;函數(shù)返回后調(diào)用析構(gòu)函數(shù),并銷毀theCattheCat。p函數(shù)返回時創(chuàng)建臨時對象,調(diào)用復(fù)制構(gòu)造函數(shù)復(fù)制函數(shù)返回時創(chuàng)建臨時對象,調(diào)用復(fù)制構(gòu)造函數(shù)復(fù)制 theCat theCat的內(nèi)容;最后要析構(gòu)并銷毀臨時對象。的內(nèi)容;最后要析構(gòu)并銷毀臨時對象。-58-Rectangle* FunctionOne(Rectangle *r )return

24、 r;int main() Rectangle myRectangle;FunctionOne(&myRectangle);return 0;ptheCattheCat只是局部指針變量,接收只是局部指針變量,接收myCatmyCat的地址,不會的地址,不會 引起對象的復(fù)制構(gòu)造以及返回后的析構(gòu)函數(shù)調(diào)用。引起對象的復(fù)制構(gòu)造以及返回后的析構(gòu)函數(shù)調(diào)用。p函數(shù)返回臨時指針變量,保存的是函數(shù)返回臨時指針變量,保存的是theCattheCat存儲的地址存儲的地址 值,不會引起對象的復(fù)制構(gòu)造以及析構(gòu)。值,不會引起對象的復(fù)制構(gòu)造以及析構(gòu)。p指針變量占用的存儲空間較少,可以忽略。指針變量占用的存儲空間較少

25、,可以忽略。-59-Rectangle & FunctionOne(Rectangle &r )return r;int main() Rectangle myRectangle;FunctionOne(myRectangle);return 0;ptheCattheCat是是myCatmyCat的引用,不會引起構(gòu)造及析構(gòu)。的引用,不會引起構(gòu)造及析構(gòu)。p返回的臨時引用是返回的臨時引用是theCattheCat的引用,也就是對的引用,也就是對myCatmyCat的的 引用,不會引起構(gòu)造與析構(gòu)。引用,不會引起構(gòu)造與析構(gòu)。p傳遞引用不會創(chuàng)建新的對象,引用只是別名。傳遞引用不會創(chuàng)建新的

26、對象,引用只是別名。-60-61-62-63-p通過傳入的通過傳入的triketrike對象,創(chuàng)建和對象,創(chuàng)建和triketrike“相同相同”的新對象。的新對象。-64-65-66-class Tricyclepublic: Tricycle(); Tricycle(const Tricycle& rhs); Tricycle(); int getSpeed() const return *speed; void setSpeed(int newSpeed) *speed = newSpeed; void pedal(); void brake();private: int *spe

27、ed;-67-Tricycle:Tricycle() speed = new int; *speed = 5;Tricycle:Tricycle(const Tricycle& rhs) speed = new int; *speed = rhs.getSpeed(); /或:*speed = *rhs.speed;Tricycle:Tricycle() delete speed; speed = NULL;p構(gòu)造函數(shù)中分配內(nèi)存,析構(gòu)函數(shù)中釋構(gòu)造函數(shù)中分配內(nèi)存,析構(gòu)函數(shù)中釋 放內(nèi)存。放內(nèi)存。p默認(rèn)復(fù)制構(gòu)造函數(shù)中,不會分配內(nèi)存默認(rèn)復(fù)制構(gòu)造函數(shù)中,不會分配內(nèi)存 只是執(zhí)行只是執(zhí)行speed

28、= rhs.speedspeed = rhs.speed。-68-void Tricycle:pedal() setSpeed(getSpeed() + 1); /或(*speed) +; std:cout “ Pedaling getSpeed() “n;void Tricycle:brake() setSpeed(getSpeed() - 1); std:cout “ Pedaling getSpeed() “n;ppedalpedal中通過中通過setSpeedsetSpeed設(shè)置新速度,也可以直接修改數(shù)據(jù)設(shè)置新速度,也可以直接修改數(shù)據(jù) * *speed += 1speed += 1,但

29、通過調(diào)用,但通過調(diào)用setSpeedsetSpeed可以隱藏實現(xiàn)細(xì)節(jié)。可以隱藏實現(xiàn)細(xì)節(jié)。p更進(jìn)一步:更進(jìn)一步:setSpeed ( getSpeed()+1 ); setSpeed ( getSpeed()+1 ); 不用關(guān)心不用關(guān)心speedspeed 到底是如何存儲等實現(xiàn)細(xì)節(jié)。到底是如何存儲等實現(xiàn)細(xì)節(jié)。-69-#include int main() Tricycle wichita; Tricycle dallas(wichita); wichita.setSpeed(10); std:coutWichita; wichita.pedal(); std:coutDallas; dallas.pedal(); std:coutWichita; wichita.brake(); std:coutDallas; dallas.brake(); return 0;p復(fù)制構(gòu)造后,新創(chuàng)建的復(fù)制構(gòu)造后,新創(chuàng)建的dallasdallas 和和wichitawichita的狀態(tài)相同。的狀態(tài)相同。 * *speedspeed都是都是5 5

溫馨提示

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

評論

0/150

提交評論