第7章_指針C++_第1頁
第7章_指針C++_第2頁
第7章_指針C++_第3頁
第7章_指針C++_第4頁
第7章_指針C++_第5頁
已閱讀5頁,還剩113頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、1第7章 指針與引用第7章 指 針2第7章 指針與引用思考: A、B、C三人欲借用旅館的房間。A先到達(dá)旅館,在服務(wù)臺登記了房間,房號是5818。然后A電話通知了B,但沒有通知C。 B和C該怎樣找到A呢?方法:B可以直接到5818找到A。 C可以到旅館的服務(wù)臺查詢到A的房間號是 5818,再找到A。3第7章 指針與引用7.1 指針與指針變量7.2 指針的使用及運(yùn)算7.3 指針與數(shù)組7.4 指針與字符串7.5 指針與函數(shù)7.6 動態(tài)內(nèi)存7.7 帶參數(shù)的main函數(shù)*7.8 引用類型47.1 指針與指針變量可以按變量名稱直接訪問內(nèi)存單元,也可以通過指針間接訪問內(nèi)存單元。當(dāng)兩個(gè)函數(shù)相互之間要訪問數(shù)據(jù)時(shí)

2、,由于函數(shù)內(nèi)部數(shù)據(jù)互不可視,只能通過指針間接訪問(直接訪問做不到了)本章的指針有許多讓初學(xué)者頭疼的復(fù)雜形式和復(fù)雜概念,請牢記:之所以有如此多的復(fù)雜形式,是因?yàn)楹瘮?shù)參數(shù)傳遞具有如此多的復(fù)雜形式57.1.1 地址和指針的概念程序中的數(shù)據(jù)對象總是存放在內(nèi)存中,在生命期內(nèi)這些對象占據(jù)一定的存儲空間,有確定的存儲位置。實(shí)際上,每個(gè)內(nèi)存單元都有一個(gè)地址,即以字節(jié)為單位連續(xù)編碼。編譯器將程序中的對象名轉(zhuǎn)換成機(jī)器指令能識別的地址,通過地址來存取對象值。67.1.1 地址和指針的概念圖7.1 變量的內(nèi)存形式int int i i; ; /定義整型變量定義整型變量double double f f; ; /定義雙

3、精度浮點(diǎn)型變量定義雙精度浮點(diǎn)型變量按對象名稱存取對象的方式稱為對象直接訪問。一個(gè)對象的地址稱為該對象的指針。通過對象地址存取對象的方式稱為指針間接訪問。1005.04000if40004500P77.1.2 指針變量C+將專門用來存放對象地址的變量稱為指針變量,定義形式如下:例如:指針類型指針類型 * *指針變量名指針變量名,.,.int int * *p1p1, , * *p2p2; ; /定義定義p1p1和和p2p2為指針變量為指針變量int int * *p p, , k k; ; /定義定義p p為指針變量,為指針變量,k k為整型變量為整型變量通過指針變量,可以間接訪問(或間接存?。?/p>

4、對象。87.1.2 指針變量圖7.2 通過指針變量間接訪問97.1.2 指針變量圖7.3 指向類型的含義假定指針變量p的值是4000,下面三種寫法char char * *p p; ;int int * *p p; ;double double * *p p; ;107.2 指針的使用及運(yùn)算獲取變量的地址可以通過取地址運(yùn)算(&)獲取對象的地址。117.2.1 獲取對象的地址表7-1 取地址運(yùn)算符int int a a= =2020, , * *p p; ; /定義指針變量定義指針變量p p = &= &a a ; ; /指針變量指針變量p p指向指向a a圖7.4 &運(yùn)算的含義127.2.1

5、獲取對象的地址例7.1 1 # #include include 2 using namespace using namespace stdstd; ; 3 int int main()main() 4 5 int int i i= =400400; ; 6 couti=i,&i=&i couti=i,&i=&iendlendl; ; 7 return return 0 0; ; 8 137.2.1 獲取對象的地址例7.1 1 #include #include 2 using namespace std;using namespace std; 3 int main()int main()

6、4 5 int i=400; int i=400; 6 couti=i,&i=&iendl; couti=i,&i=&iendl; 7 return 0; return 0; 8 i=400,&i=0012FF7C程序運(yùn)行屏幕147.2.2 指針的間接訪問表7-2 間接引用運(yùn)算符指針的間接訪問通過間接引用運(yùn)算(*)可以訪問指針?biāo)赶虻膶ο蠡騼?nèi)存單元157.2.2 指針的間接訪問圖7.5 *運(yùn)算的含義int int a a, , * *p=&ap=&a; ;a a= =100100; ; /直接訪問直接訪問a a(對象直接訪問)(對象直接訪問)* *p p= =100100; ; /* *p p

7、就是就是a a,間接訪問,間接訪問a a(指針間接訪問)(指針間接訪問)* *p=p=* *p p+ +1 1; ; /等價(jià)于等價(jià)于a=a+1a=a+1167.2.2 指針的間接訪問【例7.2】 已知:則&*p1的含義是什么?*&a的含義是什么?int int a a, , b b, , * *p1=&ap1=&a, , * *p2p2; ;&*p1 p1 &a*&a a *p177.2.2 指針的間接訪問例7.3 1 int int main()main() 2 3 int int i i= =100100, , j j= =200200; ; 4 int int * *p1p1, , *

8、*p2p2; ; 5 p1=&i p1=&i, , p2=&jp2=&j; ; /p1/p1指向指向i i,p2p2指向指向j j 6 * *p1 p1 = = * *p1 p1 + + 1 1; ; /等價(jià)于等價(jià)于i=i+1i=i+1 7 p1 p1= =p2p2; ; /將將p2p2的值賦值給的值賦值給p1p1,則,則p1p1指向指向j j 8 * *p1 p1 = = * *p1 p1 + + 1 1; ; /等價(jià)于等價(jià)于j=j+1j=j+1 9 return return 0 0; ; 10 187.2.2 指針的間接訪問例7.4 1 # #include include 2 usin

9、g namespace using namespace stdstd; ; 3 int int main()main() 4 5 int int a a, ,b,b,* *p,p,* *p1,p1,* *p2p2; ; 6 p1=&a p1=&a, , p2=&bp2=&b; ; /p1/p1指向指向a a,p2p2指向指向b b 7 cin cin* *p1p1* *p2p2; ; 8 ifif( (* *p1p1* *p2) pp2) p= =p1p1, , p1p1= =p2p2, , p2p2= =p p; ; 9 couta=a,b=b couta=a,b=bendlendl; ;

10、10 coutmin= coutmin=* *p1,max=p1,max=* *p2p2endlendl; ; 11 return return 0 0; ; 12 197.2.2 指針的間接訪問圖7.7 指針交換示意207.2.3 指針變量的初始化與賦值可以在定義指針變量時(shí)對其初始化,一般形式為:指針類型指針類型 * *指針變量名指針變量名= =地址初值地址初值,.,.int int a a; ;int int * *p=&ap=&a; ; /p/p的初值為變量的初值為變量a a的地址的地址int int b b, , * *p1=&bp1=&b; ; /正確,正確,p1p1初始化時(shí)變量初始

11、化時(shí)變量b b已有地址值已有地址值復(fù)習(xí):指針的定義:專門用來存放地址的變量指針的類型:int *p; double *q; char *t;間接引用:int a, *p=&a; *p=100; 21227.2.3 指針變量的初始化與賦值由于指針數(shù)據(jù)的特殊性,其初始化和賦值運(yùn)算是有約束條件的,只能使用以下四種值:(1)0值常量表達(dá)式,例如:int int a a, , z z= =0 0; ;int int * *p1p1= =a a; ; /錯誤錯誤,地址初值不能是變量,地址初值不能是變量p1p1= =z z; ;/錯誤錯誤,整型變量不能作為指針,即使值為,整型變量不能作為指針,即使值為0 0

12、p1p1= =40004000; ; /錯誤錯誤,整型數(shù)據(jù)不能作為指針,整型數(shù)據(jù)不能作為指針p1p1= =nullnull; ; /正確,指針允許正確,指針允許0 0值常量表達(dá)式值常量表達(dá)式p1p1= =0 0; ; /正確,指針允許正確,指針允許0 0值常量表達(dá)式值常量表達(dá)式237.2.3 指針變量的初始化與賦值(2)相同指向類型的對象的地址。例如:int int a a, , * *p1p1; ;double double f f, , * *p3p3; ;p1=&ap1=&a; ; /正確正確p3=&fp3=&f; ; /正確正確p1=&fp1=&f; ; /錯誤錯誤,p1p1和和&f&

13、f指向類型不相同指向類型不相同247.2.3 指針變量的初始化與賦值(3)相同指向類型的另一個(gè)有效指針。例如:(4)對象存儲空間后面下一個(gè)有效地址,如數(shù)組下一個(gè)元素的地址。int int x x, , * *px=&xpx=&x; ; /正確正確int int * *pypy= =pxpx; ; /正確,相同指向類型的另一個(gè)指針正確,相同指向類型的另一個(gè)指針double double * *pzpz; ;pypy= =pxpx; ; /正確,相同指向類型的另一個(gè)指針正確,相同指向類型的另一個(gè)指針pzpz= =pxpx; ; /錯誤錯誤,pzpz和和pxpx指向類型不相同指向類型不相同257.2

14、.4 指針的有效性指針指向一個(gè)有確定存儲空間的對象(稱為已知對象),則該指針是有效的;即如果對該指針使用間接引用運(yùn)算,總能夠得到這個(gè)已知對象。指針理論上可以為任意的地址值,若一個(gè)指針不指向程序中任何已知對象,稱其指向未知對象。未知對象的指針是無效的,無效的指針使用間接引用運(yùn)算幾乎總會導(dǎo)致崩潰性的異常錯誤。267.2.4 指針的有效性(1)如果指針的值為0,稱為0值指針,又稱空指針(null pointer),空指針是無效的。(2)如果指針未經(jīng)初始化,或者沒有賦值,稱為野指針,那么該指針是無效的。int int * *p p= =0 0; ;* *p p= =2 2; ; /空指針間接引用將導(dǎo)致

15、程序產(chǎn)生嚴(yán)重的異常錯誤空指針間接引用將導(dǎo)致程序產(chǎn)生嚴(yán)重的異常錯誤int int * *p p; ;* *p p= =100100; ; / /錯誤錯誤,p p為無效指針,不能間接引用為無效指針,不能間接引用277.2.4 指針的有效性一個(gè)指針還沒有初始化,稱為“野指針”(wild pointer),大多數(shù)的編譯器都對此產(chǎn)生警告。例如:一個(gè)指針曾經(jīng)指向一個(gè)已知對象,在對象的內(nèi)存空間釋放后,雖然該指針仍是原來的內(nèi)存地址,但指針?biāo)敢咽俏粗獙ο?,稱為“迷途指針”(dangling pointer)。例如:int int * *p p; ; /p/p是野指針是野指針* *p p= =2 2; ; /幾

16、乎總會導(dǎo)致程序產(chǎn)生嚴(yán)重的異常錯誤幾乎總會導(dǎo)致程序產(chǎn)生嚴(yán)重的異常錯誤287.2.4 指針的有效性char char * *p p= =NULLNULL; ; /p/p是空指針,全局變量是空指針,全局變量void void fun()fun() char char c c; ; /局部變量局部變量 p p = &= &c c; ; /指向局部變量指向局部變量c c,函數(shù)調(diào)用結(jié)束后,函數(shù)調(diào)用結(jié)束后,c c的空間釋放,的空間釋放,p p就成了迷途指針就成了迷途指針 void void caller()caller() fun(); fun(); * *p p= =2 2; ; /p p現(xiàn)在是迷途指針現(xiàn)

17、在是迷途指針 297.2.5 指針運(yùn)算(1)指針加減整數(shù)運(yùn)算設(shè)p是一個(gè)指針,n是一個(gè)整型量,則p+n的結(jié)果是一個(gè)指針,指向p所指向?qū)ο蟮暮竺娴牡趎個(gè)對象;而p-n的結(jié)果是一個(gè)指針,指向p所指向?qū)ο蟮那懊娴牡趎個(gè)對象。int int x x, , n n= =3 3 , , * *p=&xp=&x; ;p p+ +1 1 /指向存儲空間中變量指向存儲空間中變量x x后面的第后面的第1 1個(gè)個(gè)intint型存儲單元型存儲單元p p+ +n n /指向存儲空間中變量指向存儲空間中變量x x后面的第后面的第n(3)n(3)個(gè)個(gè)intint型存儲單元型存儲單元p p- -1 1 /指向存儲空間中變量指向

18、存儲空間中變量x x前面的第前面的第1 1個(gè)個(gè)intint型存儲單元型存儲單元p p- -n n /指向存儲空間中變量指向存儲空間中變量x x前面的第前面的第n(3)n(3)個(gè)個(gè)intint型存儲單元型存儲單元307.2.5 指針運(yùn)算例7.5 1 # #include include 2 using namespace using namespace stdstd; ; 3 int int main()main() 4 5 int int x x, , n n= =3 3, , * *p=&xp=&x; ; 6 coutp=hex coutp=hexp,pp,p+ +1=p1=p+ +1, ;

19、 1, ; /地址輸出用十六進(jìn)制形式地址輸出用十六進(jìn)制形式 7 cout“p cout“p+ +n=”hexn=”hexp p+ +n“,pn“,p- -n=”pn=”p- -n nendlendl; ; /地址輸出用十六進(jìn)制形式地址輸出用十六進(jìn)制形式 8 return return 0 0; ; 9 317.2.5 指針運(yùn)算(2)指針變量自增自減運(yùn)算設(shè)p是一個(gè)指針變量,其自增自減運(yùn)算包括p+、+p、p-、-p形式。327.2.5 指針運(yùn)算int int x x, , * *p=&xp=&x; ;p p+ + /運(yùn)算后表達(dá)式的值指向變量運(yùn)算后表達(dá)式的值指向變量x x,p p指向變量指向變量x

20、x后面的第后面的第1 1個(gè)個(gè)intint型內(nèi)存單元型內(nèi)存單元+p p /運(yùn)算后表達(dá)式的值和運(yùn)算后表達(dá)式的值和p p均指向變量均指向變量x x后面的第后面的第1 1個(gè)個(gè)intint型內(nèi)存型內(nèi)存單元單元p p- - /運(yùn)算后表達(dá)式的值指向變量運(yùn)算后表達(dá)式的值指向變量x x,p p指向變量指向變量x x前面的第前面的第1 1個(gè)個(gè)intint型內(nèi)存單元型內(nèi)存單元-p p /運(yùn)算后表達(dá)式的值和運(yùn)算后表達(dá)式的值和p p均指向存儲空間中變量均指向存儲空間中變量x x前面的第前面的第1 1個(gè)個(gè)intint型內(nèi)存單元型內(nèi)存單元337.2.5 指針運(yùn)算例7.6 1 # #include include 2 usi

21、ng namespace using namespace stdstd; ; 3 int int main()main() 4 5 int int x x, , * *p1p1, , * *p p; ; 6 p=&x p=&x , , p1p1= =p+;p+; 7 coutp+: coutp+: & &x=hex&x, p=p, x=hex&x, p=p, p1=p1p1=p1endlendl; ; 8 p=&x p=&x , , p1=+pp1=+p; ; 9 cout“+p cout“+p: &: &x=”hex&x“, p=”p“, x=”hex&x“, p=”p“, 平平p1=p1p

22、1=p1 b b /正確,表示兩個(gè)地址的比較,而非兩個(gè)數(shù)組內(nèi)容的比較正確,表示兩個(gè)地址的比較,而非兩個(gè)數(shù)組內(nèi)容的比較487.3.1 指向一維數(shù)組元素的指針2指向一維數(shù)組元素的指針變量定義指向一維數(shù)組元素的指針變量時(shí),指向類型應(yīng)該與數(shù)組元素類型一致,例如:int int a10, a10, * *p1p1; ;double double f10, f10, * *p2p2; ;p1p1= =a a; ; /正確正確p2p2= =f f; ; /正確正確p1p1= =f f; ; /錯誤錯誤,指向類型不同不能賦值,指向類型不同不能賦值497.3.1 指向一維數(shù)組元素的指針3通過指針訪問一維數(shù)組元素

23、由于數(shù)組元素的地址是規(guī)律性增加的,根據(jù)指針?biāo)阈g(shù)運(yùn)算規(guī)則,可以利用指針及其運(yùn)算來訪問數(shù)組元素。設(shè)有如下定義:int int * *p p, , a10=1a10=1, ,2 2, ,3 3, ,4 4, ,5 5, ,6 6, ,7 7, ,8 8, ,9 9, ,10;10;p p= =a a; ; /p/p指向數(shù)組指向數(shù)組a ap+p+; ;507.3.1 指向一維數(shù)組元素的指針圖7.11 指向一維數(shù)組的指針設(shè):a是一維數(shù)組名,p是指針變量且p=a。根據(jù)以上敘述,訪問一個(gè)數(shù)組元素ai,可以用:數(shù)組下標(biāo)法:ai;指針下標(biāo)法:pi;地址引用法:*(a+i);指針引用法:*(p+i)。517.3.

24、1 指向一維數(shù)組元素的指針例7.8 用多種方法遍歷一維數(shù)組元素 1 # #include include 2 using namespace using namespace stdstd; ; 3 int int main()main() 4 5 int int a10, ia10, i; ; 6 for for (i(i= =0 0; ;i i a a i;i; 7 for for (i(i= =0 0; ;i i 1010; ;i+) couti+) couta a i ;i ; 8 return return 0 0; ; 9 下標(biāo)法。527.3.1 指向一維數(shù)組元素的指針 1 # #i

25、nclude include 2 using namespace using namespace stdstd; ; 3 int int main()main() 4 5 int int a10, ia10, i; ; 6 for for (i(i= =0 0; ;i i i+) cin* *(a(a+ +i);i); 7 for for (i(i= =0 0; ;i i 1010; ;i+) couti+) cout* *(a(a+ +i) ;i) ; 8 return return 0 0; ; 9 通過地址間接訪問數(shù)組元素。537.3.1 指向一維數(shù)組元素的指針 1 # #include

26、 include 2 using namespace using namespace stdstd; ; 3 int int main()main() 4 5 int int a10, a10, * *p p; ; 6 for for (p(p= =a a; ;p p p+) cin* *p p; ; 7 for for (p(p= =a a; ;p p a a+ +1010; ;p+) coutp+) cout* *p ;p ; 8 return return 0 0; ; 9 通過指向數(shù)組的指針變量間接訪問元素。547.3.1 指向一維數(shù)組元素的指針4數(shù)組元素訪問方法的比較(1)使用下標(biāo)法

27、訪問數(shù)組元素,程序?qū)懛ū容^直觀,能直接知道訪問的是第幾個(gè)元素。(2)下標(biāo)法與地址引用法運(yùn)行效率相同。而使用指針引用法,指針變量直接指向元素,不必每次都重新計(jì)算地址,能提高運(yùn)行效率。557.3.1 指向一維數(shù)組元素的指針(3)ai和pi的運(yùn)行效率相同,但兩者還是有本質(zhì)的區(qū)別。數(shù)組名a是數(shù)組元素首地址,它是一個(gè)常量,其值在程序運(yùn)行期間是固定不變的。(4)將自增和自減運(yùn)算用于指針變量十分有效,可以使指針變量自動向前或向后指向數(shù)組的下一個(gè)或前一個(gè)元素。567.3.1 指向一維數(shù)組元素的指針(5)需要注意指針變量各種運(yùn)算形式的含義。*p+。*(p+)和*(+p)不同。(*p)+表示p所指向的元素加1。a

28、*(p+)等價(jià)于ai+;b*(+p)等價(jià)于a+i;c*(p-)等價(jià)于ai-;d*(-p)等價(jià)于a-i。577.4 指針與字符串可以利用一個(gè)字符型的指針處理字符數(shù)組和字符串,其過程與通過指針訪問數(shù)組元素相同。使用指針可以簡化字符串的處理,是程序員處理字符串常用的編程方法。587.4.1 指向字符串的指針可以定義一個(gè)字符數(shù)組,用字符串常量初始化它,例如:系統(tǒng)會在內(nèi)存中創(chuàng)建一個(gè)字符數(shù)組str,且將字符串常量的內(nèi)容復(fù)制到數(shù)組中,并在字符串末尾自動增加一個(gè)結(jié)束符0。char char str=C Language;str=C Language;597.4.1 指向字符串的指針C+允許定義一個(gè)字符指針,初

29、始化時(shí)指向一個(gè)字符串常量,一般形式為:charchar * *字符字符指針變量指針變量= =字符串常量字符串常量,.,.char char * *p=C Language;p=C Language;char char * *p p; ;p=C Language; p=C Language; 初始化時(shí),p存儲了這個(gè)字符串首字符地址4000,而不是字符串常量本身,稱p指向字符串。607.4.1 指向字符串的指針圖7.19 指向字符串的指針617.4.1 指向字符串的指針通過字符指針可以訪問字符串。例如:char char str=C Language, str=C Language, * *p p

30、= =strstr; ; /p/p指向字符串的指針指向字符串的指針coutcoutp pendlendl; ; /輸出:輸出:C LanguageC Languagecoutcoutp p+ +2 2endlendl; ; /輸出:輸出:LanguageLanguagecout&str7endlcout&str7endl; ; /輸出:輸出:ageage627.4.1 指向字符串的指針通過字符指針遍歷字符串。char char str=C Language, str=C Language, * *p p= =strstr; ; /p/p指向字符串的指針指向字符串的指針while while (

31、 (* *p p!=!=0) cout0) cout* *p+;p+;637.4.1 指向字符串的指針例7.15 1 # #include include 2 using namespace using namespace stdstd; ; 3 int int main()main() 4 5 char char str100,str100,* *p p= =strstr; ; 6 cin cinstrstr; ; /輸入字符串輸入字符串 7 while while ( (* *p) p+; p) p+; /指針指針p p指向到字符串結(jié)束符指向到字符串結(jié)束符 8 coutstrlen=p c

32、outstrlen=p- -strstrendlendl; ; 9 return return 0 0; ; 10 647.4.1 指向字符串的指針例7.15 1 #include #include 2 using namespace std;using namespace std; 3 int main()int main() 4 5 char str100, char str100,* *p=str;p=str; 6 cinstr; / cinstr; /輸入字符串輸入字符串 7 while ( while (* *p) p+; /p) p+; /指針指針p p指向到字符串結(jié)束符指向到字符

33、串結(jié)束符 8 coutstrlen=p-strendl; coutstrlen=p-strendl; 9 return 0; return 0; 10 strlen=10程序運(yùn)行屏幕JavaScript657.4.1 指向字符串的指針圖7.20 指針相減的含義667.4.2 指針與字符數(shù)組的比較1存儲內(nèi)容不同2運(yùn)算方式不同3賦值操作不同char char s100=Computer;s100=Computer;char char * *p=Computer;p=Computer;s=C+; s=C+; /錯誤錯誤s+; s+; /錯誤錯誤s0=Cs0=C; ; /正確正確p=C+; p=C+;

34、 /正確正確* *p p= =CC; ; /正確正確p+; p+; /正確正確677.4.2 指針與字符數(shù)組的比較例7.16 1 # #include include 2 using namespace using namespace stdstd; ; 3 int int main()main() 4 5 char char * *p=VisualBasic;p=VisualBasic; 6 int int i i= =0 0; ; 7 while while (pi) cout(pi) coutp p i+i+ ; ; 8 return return 0 0; ; 9 687.4.3 指向

35、字符串?dāng)?shù)組的指針字符串?dāng)?shù)組是一個(gè)二維字符數(shù)組,例如:char char sa67=C+,Java,C,PHP,sa67=C+,Java,C,PHP, CSharp,Basic; CSharp,Basic;697.4.3 指向字符串?dāng)?shù)組的指針圖7.21 字符串?dāng)?shù)組的內(nèi)存形式C+程序員更偏愛使用指針來訪問數(shù)組元素,這樣做的好處是運(yùn)行效率高、寫法簡潔。復(fù)習(xí):設(shè):a是一維數(shù)組名,p是指針變量且p=a。數(shù)組元素ai 可以表示為:pi、*(a+i)、*(p+i)。ai的地址可以表示為:&ai、a+i、p+i 71 1 # #include include 2 using namespace using n

36、amespace stdstd; ; 3 int int main()main() 4 5 int int a10, ia10, i; ; 6 for for (i(i= =0 0; ;i i ai;ai; 7 for for (i(i= =0 0; ;i i 1010; ;i+) couti+) coutai ;aicin* *(a(a+ +i);i);coutcout* *(a(a+ +i) “;i) “;72 1 # #include include 2 using namespace using namespace stdstd; ; 3 int int main()main() 4

37、5 int int a10, a10, * *p p; ; 6 for for (p(p= =a a; ;p p p+) cin* *p p; ; 7 for for (p(p= =a a; ;p p a a+ +1010; ;p+) coutp+) cout* *p ;p ; 8 return return 0 0; ; 9 復(fù)習(xí):73使用字符指針處理字符串可以簡化字符串的處理,是程序員處理字符串常用的編程方法。 1 # #include include 2 using namespace using namespace stdstd; ; 3 int int main()main() 4

38、5 char char * *p=VisualBasic;p=VisualBasic; 6 int int i i= =0 0; ; 7 while while (pi) cout(pi) coutp p i+i+ ; ; 8 return return 0 0; ; 9 復(fù)習(xí):747.5 指針與函數(shù)指針最重要的應(yīng)用是作為函數(shù)參數(shù),它使得被調(diào)函數(shù)除了返回值之外,能夠?qū)⒏嗟倪\(yùn)算結(jié)果返回到主調(diào)函數(shù)中指針是函數(shù)參數(shù)傳遞的重要工具。757.5.1 指針作為函數(shù)參數(shù)1指針變量作為函數(shù)形參函數(shù)形參可以是指針類型,一般形式為:返回類型 函數(shù)名(指向類型 *指針變量名,.)函數(shù)體 767.5.1 指針作為函

39、數(shù)參數(shù)例7.18 1 # #include include 2 using namespace using namespace stdstd; ; 3 void void swap(swap(int int * *p1p1, , int int * *p2)p2) 4 5 int int t t; ; 6 t= t=* *p1 p1 , , * *p1=p1=* *p2p2, , * *p2p2= =t t; ; 7 8 int int main()main() 9 10 int int a a, , b b; ; 11 cin cina ab b; ; 12 swap(&a swap(&a,

40、 , &b);&b); 13 coutmin=a,max=b coutmin=a,max=a ab b; ; 12 swap(&a swap(&a, , &b);&b); 13 return 0; return 0; 14 int int * *t;t;t=p1 , p1=p2, p2=t;t=p1 , p1=p2, p2=t;797.5.1 指針作為函數(shù)參數(shù)通過將指針作為函數(shù)參數(shù)的方法,既可以返回多個(gè)運(yùn)算結(jié)果,又避免了使用全局變量。807.5.1 指針作為函數(shù)參數(shù)例7.19 計(jì)算a和b的平方和、自然對數(shù)和、幾何平均數(shù)、和的平方根 1 # #include include 2 # #inclu

41、de include 3 using namespace using namespace stdstd; ; 4 double double fun(fun(double double a a, ,double double b b, ,double double * *sqabsqab, , double double * *lnablnab, , double double * *avg)avg) 5 6 * *sqabsqab= =a a* *a a+ +b b* *b b; ; * *lnablnab= =log(a)+log(b);log(a)+log(b); 8 * *avg=(a

42、avg=(a+ +b)/2b)/2; ; 9 return return (sqrt(a(sqrt(a+ +b);b);/函數(shù)返回和的平方根函數(shù)返回和的平方根 10 11 int int main()main() 12 13 double double x x= =1010, ,y y= =1212, ,fsqfsq, ,flnfln, ,favgfavg, ,fsqrfsqr; ; 14 fsqr fsqr= =fun(xfun(x, , y y, &, &fsqfsq, &, &flnfln, &, &favg);favg); 15 cout coutx,y,fsq,flnx,y,fsq,

43、fln ,favg,fsqr ,favg,fsqrendlendl; ; 16 return return 0 0; ; 17 817.5.1 指針作為函數(shù)參數(shù)2數(shù)組作為函數(shù)形參(一維或多維)數(shù)組作為函數(shù)的形參,例如:函數(shù)調(diào)用形式如下:double double average(average(double double * *a, a, int int n)n) /函數(shù)體函數(shù)體 double double X100, fX100, f; ;f f = = average(Xaverage(X, , 100);100);827.5.1 指針作為函數(shù)參數(shù)例7.20 編寫函數(shù)average,返回?cái)?shù)

44、組n個(gè)元素的平均值。 1 # #include include 2 using namespace using namespace stdstd; ; 3 double double average(average(double double * *a a, , int int n)n) 4 5 double double avgavg= =0 0. .0 0, , * *p p= =a a; ; 6 int int i i; ; 7 for for (i(i= =1 1; ;i i=n n; ;i+,p+) avgi+,p+) avg= =avg avg + + * *p p; ; 8 re

45、turn return n n=0 0 ? ? 0 0 : : avgavg/ /n n ; ; 9 837.5.1 指針作為函數(shù)參數(shù)例7.20 10 int int main()main() 11 12 double double x10=66x10=66, ,7676. .5 5, ,8989, ,100100, ,7171. .5 5, , 8686, ,9292, ,9090. .5 5, ,7878, ,88;88; 13 coutaverage=average(x coutaverage=average(x, ,10)endl10)endl; ; 14 return return

46、0 0; ; 15 847.5.1 指針作為函數(shù)參數(shù)要想在子函數(shù)中改變主調(diào)函數(shù)中的數(shù)組元素,實(shí)參與形參的對應(yīng)關(guān)系有如下4種,這4種情況作用相同。(1)形參和實(shí)參都用數(shù)組名,例如:(2)形參用指針變量,實(shí)參用數(shù)組名,例如:void void fun(fun(int int x100, x100, int int n); n); /函數(shù)原型函數(shù)原型int int a100;a100;fun(afun(a, , 100); 100); /函數(shù)調(diào)用函數(shù)調(diào)用void void fun(fun(int int * *x x, , int int n); n); /函數(shù)原型函數(shù)原型int int a100;

47、a100;fun(afun(a, , 100); 100); /函數(shù)調(diào)用函數(shù)調(diào)用857.5.1 指針作為函數(shù)參數(shù)(3)形參與實(shí)參都用指針變量,例如:(4)形參用數(shù)組,實(shí)參用指針變量,例如:void void fun(fun(int int * *x x, , int int n); n); /函數(shù)原型函數(shù)原型int int a100, pa100, p= =a a; ;fun(pfun(p, , 100); 100); /函數(shù)調(diào)用函數(shù)調(diào)用void void fun(fun(int int x100, x100, int int n); n); /函數(shù)原型函數(shù)原型int int a100, pa

48、100, p= =a a; ;fun(pfun(p, , 100); 100); /函數(shù)調(diào)用函數(shù)調(diào)用867.5.1 指針作為函數(shù)參數(shù)4字符指針變量作為函數(shù)形參將一個(gè)字符串傳遞到函數(shù)中,傳遞的是地址,則函數(shù)形參既可以用字符數(shù)組,又可以用指針變量,兩種形式完全等價(jià)。在子函數(shù)中可以修改字符串的內(nèi)容,主調(diào)函數(shù)得到的是變化后的字符串。877.5.1 指針作為函數(shù)參數(shù)例7.21 自定義函數(shù)實(shí)現(xiàn)strcpy函數(shù)的字符串復(fù)制功能 1 # #include include 2 using namespace using namespace stdstd; ; 3 char char * *stringcpy(s

49、tringcpy(char char * *strDeststrDest, , const char const char * *strSrc)strSrc) 4 5 char char * *p1p1= =strDeststrDest; ; 6 const char const char * *p2p2= =strSrcstrSrc; ; 7 while while ( (* *p2p2!=!=0 0 ) ) 8 * *p1=p1=* *p2p2, , p1p1+ , + , p2p2+; ; 9 * *p1p1=00; ; 10 return return strDeststrDest;

50、; /返回實(shí)參指針返回實(shí)參指針 11 887.5.1 指針作為函數(shù)參數(shù)例7.21 11 int int main()main() 12 13 char char s180,s280,s380=string=;s180,s280,s380=string=; 14 cin cins1s1; ; /輸入字符串輸入字符串 15 stringcpy(s2 stringcpy(s2, ,s1); s1); /復(fù)制復(fù)制s1s1到到s2s2 16 couts2:s2 couts2:s2endlendl; ; 17 stringcpy(&s37,s1); stringcpy(&s37,s1);/復(fù)制復(fù)制s1s1

51、到到s3s3的后面的后面 18 couts3:s3 couts3:s3endlendl; ; 19 return return 0 0; ; 20 7.5.3 函數(shù)指針C+允許定義指向函數(shù)的指針變量,定義形式為:它可以指向形如返回類型 (*函數(shù)指針變量名)(形式參數(shù)列表),.;返回類型 函數(shù)名(形式參數(shù)列表)函數(shù)體 int int ( (* *p)(p)(int int a a, , int int b); b); /定義函數(shù)指針變量定義函數(shù)指針變量7.5.3 函數(shù)指針1指向函數(shù)可以將函數(shù)的地址賦值給函數(shù)指針變量,形式為它要求函數(shù)指針變量與指向函數(shù)必須有相同的返回類型、參數(shù)個(gè)數(shù)、參數(shù)類型。函數(shù)

52、指針變量函數(shù)指針變量= =函數(shù)名函數(shù)名; ;7.5.3 函數(shù)指針例如假設(shè):則稱p指向函數(shù)max。它也可以指向函數(shù)min,即可以指向所有與它有相同的返回類型、參數(shù)個(gè)數(shù)、參數(shù)類型的函數(shù)。int int max(max(int int a a, , int int b); b); /max/max函數(shù)原型函數(shù)原型int int min(min(int int a a, , int int b); b); /min/min函數(shù)原型函數(shù)原型int int ( (* *p)(p)(int int a a, , int int b); b); /定義函數(shù)指針變量定義函數(shù)指針變量p p= =maxmax; ;

53、7.5.3 函數(shù)指針2通過函數(shù)指針調(diào)用函數(shù)對函數(shù)指針間接引用即是通過函數(shù)指針調(diào)用函數(shù),一般形式為:兩種形式是完全相同的。通常,程序員偏愛用第種形式。通過函數(shù)指針調(diào)用函數(shù),在實(shí)參、參數(shù)傳遞、返回值等方面與函數(shù)名調(diào)用相同。例如:(*函數(shù)指針)(實(shí)參列表)函數(shù)指針(實(shí)參列表)c c= =p(ap(a, ,b); b); /等價(jià)于等價(jià)于c=max(a,b);c=max(a,b);7.5.3 函數(shù)指針例7.23 1 # #include include 2 using namespace using namespace stdstd; ; 3 int int max(max(int int a a, ,

54、 int int b) b) /求最大值求最大值 4 5 return return a a b b ? ? a a: :b b ; ; 6 7 int int min(min(int int a a, , int int b) b) /求最小值求最小值 8 9 return return a a b b ? ? a a: :b b ; ; 10 7.5.3 函數(shù)指針例7.23 11 int int main()main() 12 13 int int ( (* *p)(p)(int int a a, ,int int b);b);/定義函數(shù)指針變量定義函數(shù)指針變量 14 p p= =maxm

55、ax; ; /p/p指向指向maxmax函數(shù)函數(shù) 15 cout coutp(3p(3, ,4) ; 4) ; /通過通過p p調(diào)用函數(shù)調(diào)用函數(shù) 16 p p= =minmin; ; /p/p指向指向minmin函數(shù)函數(shù) 17 cout coutp(3p(3, ,4) ; 4) ; /通過通過p p調(diào)用函數(shù)調(diào)用函數(shù) 18 return return 0 0; ; 19 從中看出,函數(shù)調(diào)用p(3,4)究竟調(diào)用max或者min,取決于調(diào)用前p指向哪個(gè)函數(shù)。7.5.3 函數(shù)指針3函數(shù)指針的用途指向函數(shù)的指針多用于指向不同的函數(shù),從而可以利用指針變量調(diào)用不同函數(shù),相當(dāng)于將函數(shù)調(diào)用由靜態(tài)方式(固定地調(diào)用

56、指定函數(shù))變?yōu)閯討B(tài)方式(調(diào)用哪個(gè)函數(shù)是由指針值來確定)。熟練掌握函數(shù)指針的應(yīng)用,有利于程序的模塊化設(shè)計(jì),提高程序的可擴(kuò)展性。7.5.3 函數(shù)指針函數(shù)指針變量可以作為函數(shù)形參,此時(shí)實(shí)參要求是函數(shù)名(即函數(shù)地址),或者是函數(shù)指針,而形參和實(shí)參有相同的返回類型、參數(shù)個(gè)數(shù)、參數(shù)類型。7.5.3 函數(shù)指針232(1)xbbbaaax dxedxx dx【例7.24】 編寫程序計(jì)算如下公式。說明:這里用梯形法求定積分 的近似值。如圖所示,求 f(x)的定積分就是求f(x)曲線與x軸包圍圖形的面積,梯形法是把所要求的面積垂直分成n個(gè)小梯形,然后面積求和。( )baf x dx7.5.3 函數(shù)指針圖7.24

57、梯形法求定積分示意7.5.3 函數(shù)指針根據(jù)上述思想編寫函數(shù)integral,由于需要計(jì)算多個(gè)不同f(x)的值,因此向integral傳遞f(x)的函數(shù)指針,由integral回調(diào)具體的f(x)求值,其函數(shù)原型為:在integral中通過函數(shù)指針f調(diào)用傳進(jìn)去的具體函數(shù),即稱為回調(diào)。double double integral(integral(double double a a, ,double double b b, , double double ( (* *f)(f)(double double x) x) /求定積分求定積分7.5.3 函數(shù)指針例7.24 1 # #include inc

58、lude 2 # #include include 3 using namespace using namespace stdstd; ; 4 double double integral(integral(double double a a, ,double double b b, , double double ( (* *f)(f)(double double x) x) /求定積分求定積分 5 6 int int n n= =10001000, , i i; ; 7 double double h h, , x x, , s s= =0 0. .0 0; ; 8 h=(b h=(b-

59、-a)/na)/n; ; 9 forfor(i(i= =1 1; ;i i=a ab b; ; 28 cout(integral(a cout(integral(a, ,b b, ,f1)+f1)+ integral(a integral(a, ,b b, ,f2)+integral(af2)+integral(a, ,b b, ,f3)f3) endl endl; ; 29 return return 0 0; ; 30 103*7.8 引用類型通過對象名稱直接訪問對象,優(yōu)點(diǎn)是直觀,操作哪個(gè)對象一目了然,缺點(diǎn)是由于對象名存在作用域的限制,某些情況下是不能按名稱訪問對象的,例如一個(gè)函數(shù)內(nèi)部不能

60、使用另一個(gè)函數(shù)的局部變量;通過指針(或地址)間接訪問對象,優(yōu)點(diǎn)是無所不能,缺點(diǎn)是程序中大量出現(xiàn)的間接訪問,實(shí)在分不清具體是哪個(gè)對象,需要通過上下文去分析。C+擴(kuò)充了C語言對象訪問方式,提供了引用訪問。通過引用訪問對象,結(jié)合了按名訪問和按地址訪問各自的優(yōu)點(diǎn),非常適合作為函數(shù)參數(shù)。1047.8.1 引用的概念與定義簡單地說,引用(reference)就是一個(gè)對象的別名(alias name),其聲明形式為:在C+中,引用全部是const類型,聲明之后不可更改(即不能再是別的對象的引用)。引用類型引用類型 & &引用名稱引用名稱= =對象名稱對象名稱 , .;, .;int int x x; ; /

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論