C語(yǔ)言開發(fā)基礎(chǔ)教程第6章-指針-教學(xué)PPT_課件_第1頁(yè)
C語(yǔ)言開發(fā)基礎(chǔ)教程第6章-指針-教學(xué)PPT_課件_第2頁(yè)
C語(yǔ)言開發(fā)基礎(chǔ)教程第6章-指針-教學(xué)PPT_課件_第3頁(yè)
C語(yǔ)言開發(fā)基礎(chǔ)教程第6章-指針-教學(xué)PPT_課件_第4頁(yè)
C語(yǔ)言開發(fā)基礎(chǔ)教程第6章-指針-教學(xué)PPT_課件_第5頁(yè)
已閱讀5頁(yè),還剩98頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第6章 指針指針與函數(shù) 指針數(shù)組 二級(jí)指針 指針概念 指針運(yùn)算 指針與數(shù)組6.1 指針的概念程序運(yùn)行過程中產(chǎn)生的數(shù)據(jù)都保存在內(nèi)存中,內(nèi)存是以字節(jié)為單位的連續(xù)存儲(chǔ)空間,每個(gè)字節(jié)都有一個(gè)編號(hào),這個(gè)編號(hào)稱為內(nèi)存地址。程序中的變量在生存期內(nèi)都占據(jù)一定字節(jié)的內(nèi)存,這些字節(jié)在內(nèi)存中是連續(xù)的,第一個(gè)字節(jié)的地址就稱為該變量的地址。6.1 指針的概念1、指針的概念定義一個(gè)int類型變量a:int a=10;a在內(nèi)存中的存儲(chǔ)如右圖。6.1 指針的概念1、指針的概念編譯器會(huì)根據(jù)變量a的類型int,為其分配4個(gè)字節(jié)地址連續(xù)的存儲(chǔ)空間。假如這塊連續(xù)空間的首地址為0 x0037FBCC,那么這個(gè)變量占據(jù)0 x0037FB

2、CC0 x0037FBCF這四個(gè)字節(jié)的空間,0 x0037FBCC就是變量a的地址。6.1 指針的概念1、指針的概念因?yàn)橥ㄟ^變量的地址可以找到變量所在的存儲(chǔ)空間,所以說變量的地址指向變量所在的存儲(chǔ)空間,地址是指向該變量的指針。6.1 指針的概念1、指針的概念存儲(chǔ)變量a的內(nèi)存地址為0 x0037FBCC,如果用一個(gè)變量保存該地址,如變量p,那么p就稱為指向變量a的指針。6.1 指針的概念2、指針變量的定義定義指針變量的語(yǔ)法如下:變量類型 *變量名;變量類型指定定義的指針指向的數(shù)據(jù)的類型,變量名前的符號(hào)“*”表示該變量是一個(gè)指針類型的變量。int *p; /定義一個(gè)int類型的指針變量多學(xué)一招:內(nèi)

3、存四區(qū)1、棧區(qū)棧區(qū)是一塊連續(xù)的內(nèi)存區(qū)域,該區(qū)域由編譯器自動(dòng)分配和釋放,一般用來存放局部變量。棧區(qū)空間小,特點(diǎn)是先進(jìn)后出。2、堆區(qū)堆區(qū)是不連續(xù)的內(nèi)存區(qū)域,各塊區(qū)域由鏈表將它們串聯(lián)起來。該區(qū)域一般由程序員分配或釋放,若程序員不釋放,程序結(jié)束時(shí)可能由操作系統(tǒng)回收(程序不正常結(jié)束則回收不了)。堆區(qū)空間大,多學(xué)一招:內(nèi)存四區(qū)3、數(shù)據(jù)區(qū)數(shù)據(jù)區(qū)根據(jù)功能又可以分為靜態(tài)全局區(qū)和常量區(qū)兩個(gè)域。全局區(qū)(靜態(tài)區(qū))(static):用于存儲(chǔ)全局變量和靜態(tài)變量的區(qū)域,初始化的全局變量和靜態(tài)變量在一塊區(qū)域,未初始化的全局變量在靜態(tài)變量的相鄰區(qū)域。全局區(qū)在程序結(jié)束后由操作系統(tǒng)釋放。常量區(qū):用于存儲(chǔ)字符串常量和其他常量的區(qū)域,

4、該區(qū)域在程序結(jié)束后由操作系統(tǒng)釋放。多學(xué)一招:內(nèi)存四區(qū)4、代碼區(qū)代碼區(qū)用于存放函數(shù)體的二進(jìn)制代碼。程序中每定義一個(gè)函數(shù),代碼區(qū)都會(huì)添加該函數(shù)的二進(jìn)制代碼,用于描述如何運(yùn)行函數(shù)。當(dāng)程序調(diào)用函數(shù)時(shí),就會(huì)在代碼區(qū)尋找該函數(shù)的二進(jìn)制代碼并運(yùn)行。6.2 指針運(yùn)算指針的運(yùn)算都是針對(duì)內(nèi)存中的地址來實(shí)現(xiàn)的,主要包括取址運(yùn)算、取值運(yùn)算、加減運(yùn)算、自增自減運(yùn)算、同類指針相減運(yùn)算。指針運(yùn)算6.2.1 取址運(yùn)算符在程序中定義變量時(shí)系統(tǒng)會(huì)為變量在內(nèi)存中開辟一段空間,用于存儲(chǔ)該變量的值,每個(gè)變量的存儲(chǔ)空間都有唯一的編號(hào),這個(gè)編號(hào)就是變量的內(nèi)存地址。C語(yǔ)言支持以取址運(yùn)算符“&”獲得變量的地址。6.2.1 取址運(yùn)算符&符號(hào)的使

5、用方法:&變量; int a = 10; /定義變量a int *p = &a; /定義int類型的指針p,并取變量a的地址賦值給p6.2.1 取址運(yùn)算符 小提示:指針變量的賦值在為指針變量賦值時(shí),變量數(shù)據(jù)類型與指針的基類型最好相同,例如,將int型變量的地址賦值給int*型指針。如果將int型變量的地址賦值給float*型指針,程序雖然不會(huì)報(bào)錯(cuò),但由于不同類型指針對(duì)應(yīng)的內(nèi)存單元數(shù)量不同,在解讀指針指向的變量時(shí)會(huì)產(chǎn)生錯(cuò)誤。6.2.2 取值運(yùn)算符指針變量存儲(chǔ)的數(shù)值是一個(gè)地址,直接對(duì)地址操作容易出錯(cuò),針對(duì)指針變量的取值并非取出它所存儲(chǔ)的地址,而是間接取得該地址中存儲(chǔ)的值。C語(yǔ)言支持以取值運(yùn)算符“*

6、”取得指針變量所指內(nèi)存中存儲(chǔ)的值。6.2.2 取值運(yùn)算符*符號(hào)使用方法:*指針表達(dá)式int a = 10; /定義變量a int *p = &a; /定義int類型的指針p,并取變量a的地址賦值給p int b = *p; /定義int型變量b,并取指針變量p中存儲(chǔ)的變量值賦給b6.2.3 常用指針運(yùn)算1、指針變量與整數(shù)相加減指針變量可以與整數(shù)進(jìn)行相加或相減操作:p+n, p-np是一個(gè)指針變量,p+1表示將指針向后移動(dòng)1個(gè)數(shù)據(jù)長(zhǎng)度。數(shù)據(jù)長(zhǎng)度是指針對(duì)應(yīng)的基類型所占的字節(jié)數(shù),也稱為步長(zhǎng),若指針是int*類型的指針,則p的步長(zhǎng)為4字節(jié),執(zhí)行p+1,則p的值加上4個(gè)字節(jié),即p向后移動(dòng)4個(gè)字節(jié)。6.2

7、.3 常用指針運(yùn)算1、指針變量與整數(shù)相加減如果p為int*類型的指針變量,則p與p+1的位置如下圖。p步長(zhǎng)為4字節(jié)6.2.3 常用指針運(yùn)算指針變量的加減運(yùn)算實(shí)質(zhì)上是指針在內(nèi)存中的移動(dòng)。6.2.3 常用指針運(yùn)算對(duì)于單獨(dú)零散的變量,指針的加減運(yùn)算并無(wú)意義,只有指向連續(xù)的同類型數(shù)據(jù)區(qū)域,指針加、減整數(shù)才有實(shí)際意義,因此指針的加減運(yùn)算通常出現(xiàn)在數(shù)組操作中。注 意6.2.3 常用指針運(yùn)算2、指針表達(dá)式的自增自減運(yùn)算指針類型變量也可以進(jìn)行自增或自減運(yùn)算:p+ , p- , +p, -p指針的自增自減運(yùn)算與指針的加減運(yùn)算含意是相同的,每自增(減)一次都是向后(前)移動(dòng)一個(gè)步長(zhǎng),即p+、+p最終的結(jié)果與p+1

8、是相同的。6.2.3 常用指針運(yùn)算3、同類指針相減運(yùn)算同類指針類型可以進(jìn)行相減操作。pm-pnpm和pn是兩個(gè)指向同一類型的指針變量。同類指針進(jìn)行相減運(yùn)算其結(jié)果為兩個(gè)指針之間數(shù)據(jù)元素的個(gè)數(shù),即指針的步長(zhǎng)個(gè)數(shù)。6.2.3 常用指針運(yùn)算同類指針之間只有相減運(yùn)算,沒有相加運(yùn)算,兩個(gè)地址相加是沒有意義的,此外,不同類型指針之間不能進(jìn)行相減運(yùn)算。注 意多學(xué)一招:空指針、無(wú)類型指針、野指針空指針:沒有指向任一存儲(chǔ)單元的指針。有時(shí)可能需要用到指針,但是不確定指針在何時(shí)何處使用,因此先使定義好的指針指向空。int *p1=0; /0是唯一不必轉(zhuǎn)換就可以賦值給指針的數(shù)據(jù)int *p2=NULL;/NULL是一個(gè)

9、宏定義,其作用與0相同 /在ASCII碼中,編號(hào)為0的字符就是空多學(xué)一招:空指針、無(wú)類型指針、野指針無(wú)類型指針:使用void*修飾的指針。無(wú)類型指針指向一塊內(nèi)存,但其類型不定,程序無(wú)法根據(jù)這種定義確定為該指針指向的變量分配多少存儲(chǔ)空間,所以若要使用該指針為其他基類指針賦值,必須先轉(zhuǎn)換成其他類型的指針。void *p=NULL,*q;/定義一個(gè)無(wú)類型的指針變量int *m=(int*)p; /將無(wú)類型的指針變量p強(qiáng)制轉(zhuǎn)換為int*型再賦值多學(xué)一招:空指針、無(wú)類型指針、野指針野指針:指向不可用區(qū)域的指針。野指針的形成主要有以下兩種原因:(1)指針變量沒有被初始化。(2)若兩個(gè)指針指向同一塊存儲(chǔ)空間

10、,指針與內(nèi)存使用完畢之后,調(diào)用相應(yīng)函數(shù)釋放了一個(gè)指針與其指向的內(nèi)存,卻未改變另一個(gè)指針的指向,將其置空。6.3.1 指針與一維數(shù)組1、定義一維數(shù)組指針數(shù)組在內(nèi)存中占據(jù)一段連續(xù)的空間,對(duì)于一維數(shù)組來說,數(shù)組名默認(rèn)保存了數(shù)組在內(nèi)存中的地址,而一維數(shù)組的第1個(gè)元素與數(shù)組的地址是重合的,因此在定義指向數(shù)組的指針時(shí)可以直接將數(shù)組名賦值給指針變量,也可以取第1個(gè)元素的地址賦值給指針變量,另外,指向數(shù)組的指針變量的基類型與數(shù)組元素的類型是相同的。6.3.1 指針與一維數(shù)組1、定義一維數(shù)組指針有一個(gè)int類型的數(shù)組:int a5=1,2,3,4,5;定義指向該數(shù)組的指針:int *p1 = a; /將數(shù)組名a

11、賦值給指針變量p1int *p2 = &a0; /取第1個(gè)元素的地址賦值給指針變量p26.3.1 指針與一維數(shù)組小提示:數(shù)組名保存了數(shù)組的地址,其功能與指針相同,對(duì)數(shù)組名取值可以得到數(shù)組第1個(gè)元素。但數(shù)組名與指針又有不同,數(shù)組名是一個(gè)常量,不可以再對(duì)其進(jìn)行賦值,另外,對(duì)數(shù)組名取地址得到的還是數(shù)組的地址6.3.1 指針與一維數(shù)組2、使用指針訪問一維數(shù)組元素定義了指向數(shù)組的指針,則指針可以像使用數(shù)組名一樣,使用下標(biāo)取值法對(duì)數(shù)組中的元素進(jìn)行訪問。p下標(biāo) /下標(biāo)取值法6.3.1 指針與一維數(shù)組2、使用指針訪問一維數(shù)組元素除了下標(biāo)法,指針還可以通過“*”符號(hào)訪問數(shù)組元素。6.3.1 指針與一維數(shù)組以訪問

12、數(shù)組int a5=1,2,3,4,5;為例(1)移動(dòng)指針,使指針指向a2,獲取指針指向元素的值。p = p+2; /將指針加2,使指針指向a2*p; /通過*運(yùn)算符獲取到a2元素指針p從數(shù)組首地址后移動(dòng)了2個(gè)步長(zhǎng),指向了數(shù)組第3個(gè)元素。6.3.1 指針與一維數(shù)組數(shù)組是一段連續(xù)的內(nèi)存空間,因此可以使指針在這段內(nèi)存空間上進(jìn)行加減運(yùn)算,其內(nèi)存圖解如下圖。6.3.1 指針與一維數(shù)組(2)不移動(dòng)指針,通過數(shù)組元素指針間的關(guān)系運(yùn)算指針并取值。*(p+2) /獲取元素a2指針p還是指向數(shù)組首地址,以指針為依據(jù),取后面兩個(gè)步長(zhǎng)處的元素,即a2。6.3.1 指針與一維數(shù)組當(dāng)指針指向數(shù)組時(shí),指針與整數(shù)加減表示指針

13、向后或向前移動(dòng)整數(shù)個(gè)元素,同樣指針每自增自減一次,表示向后或向前移動(dòng)一個(gè)元素。當(dāng)有兩個(gè)指針分別指向數(shù)組不同元素時(shí),則兩個(gè)指針還可以進(jìn)行相減運(yùn)算,結(jié)果為兩個(gè)指針之間的數(shù)組元素個(gè)數(shù)。6.3.1 指針與一維數(shù)組指針p1指向數(shù)組首元素,指針p2指向數(shù)組第4個(gè)元素,則執(zhí)行p2-p1,結(jié)果為3,表示兩個(gè)指針之間相差3個(gè)元素。這是因?yàn)橹羔樦g的運(yùn)算單位是步長(zhǎng),其實(shí)p1與p2之間的相差12個(gè)字節(jié),即相差3個(gè)sizeof(int)。6.3.2 指針與二維數(shù)組二維數(shù)組與一維數(shù)組一樣,可以使用指針指向二維數(shù)組,通過指針訪問二維數(shù)組的元素。6.3.2 指針與二維數(shù)組假設(shè)定義一個(gè)二行三列的二維數(shù)組:int a23=1,

14、2,3,4,5,6;則數(shù)組a的邏輯結(jié)構(gòu)與內(nèi)存圖解如右圖。6.3.2 指針與二維數(shù)組1、定義二維數(shù)組指針與一維數(shù)組一樣,二維數(shù)組的首地址與數(shù)組第1個(gè)元素是的地址是重合的,因此在定義指向二維數(shù)組的指針時(shí),可以將二維數(shù)組的數(shù)組名賦值給指針,也可以取二維數(shù)組的第1個(gè)元素的地址賦值給指針。6.3.2 指針與二維數(shù)組1、定義二維數(shù)組指針二維數(shù)組指針的定義要比一維數(shù)組復(fù)雜一些,定義二維數(shù)組指針時(shí)需指定列的個(gè)數(shù),其格式如下:數(shù)組元素類型 (* 數(shù)組指針變量名)列數(shù);例如,定義指向二維數(shù)組a的指針:int (*p1)3 = a; /二維數(shù)組名賦值給指針p1 int (*p2)3 = &a00; /取第一個(gè)元素的

15、地址賦值給p26.3.2 指針與二維數(shù)組1、定義二維數(shù)組指針二維數(shù)組又可以看作每一行存儲(chǔ)的元素為一維數(shù)組,在數(shù)組a中,a0是個(gè)一維數(shù)組,表示二維數(shù)組的第1行,它保存的也是一個(gè)地址,這個(gè)地址就是二維數(shù)組的首地址,因此在定義二維數(shù)組指針時(shí),也可以將二維數(shù)組的第1行地址賦值給指針。int (*p3)3 = a0; /取第一行地址賦值給 p36.3.2 指針與二維數(shù)組2、使用指針訪問二維數(shù)組元素使用二維數(shù)組指針訪問數(shù)組元素可以通過下標(biāo)的方式:p00; /訪問第1個(gè)元素6.3.2 指針與二維數(shù)組2、使用指針訪問二維數(shù)組元素除了下標(biāo)法,還可以通過移動(dòng)指針來訪問二維數(shù)組的元素,在二維數(shù)組中,指針每加1,指針

16、將移動(dòng)一行,以數(shù)組a為例,若定義了指向數(shù)組的指針p,則p初始時(shí)指向數(shù)組首地址,即數(shù)組的第1行元素,若使p+1,則p將指向數(shù)組中的第二行元素。6.3.2 指針與二維數(shù)組2、使用指針訪問二維數(shù)組元素二維數(shù)組指針移動(dòng)的邏輯結(jié)構(gòu)與內(nèi)存圖解如右圖。6.3.2 指針與二維數(shù)組2、使用指針訪問二維數(shù)組元素在二維數(shù)組a中,指針加1,是從第1行移動(dòng)到了第2行,在內(nèi)存中,則是從第1個(gè)元素移動(dòng)到了第4個(gè)元素,即跳過了一行(3個(gè)元素)的距離。綜上,在二維數(shù)組中,指針每加1,就移動(dòng)1行,即移動(dòng)二維數(shù)組中列的個(gè)數(shù),如果每行有n個(gè)元素,則指針的移動(dòng)距離為n*步長(zhǎng)。6.3.2 指針與二維數(shù)組在二維數(shù)組a中,a0就表示第一行數(shù)

17、據(jù),a1表示第二行數(shù)據(jù)。a0、a1相當(dāng)于二維數(shù)組中一維數(shù)組的數(shù)組名,指向二維數(shù)組對(duì)應(yīng)行的第一個(gè)元素,a0=&a00,a1=&a10。6.3.2 指針與二維數(shù)組2、使用指針訪問二維數(shù)組元素在二維數(shù)組的每一行中,首地址為ai,此時(shí)的ai相當(dāng)于一維數(shù)組的數(shù)組名,類比一維數(shù)組中使用指針的基本原則,使ai+j,則可以得到第i行中第j個(gè)元素的地址,對(duì)其使用“*”操作符,則*(ai+j)表示二維數(shù)組中的元素aij。若類比取值原則對(duì)行地址ai進(jìn)行轉(zhuǎn)化,則ai可表示為a+i。6.3.2 指針與二維數(shù)組在二維數(shù)組中,a+i雖然指向的是該行元素的首地址,但它代表的是整行數(shù)據(jù)元素,只是一個(gè)地址,并不表示某一元素的值。

18、*(a+i)仍然表示一個(gè)地址,與ai等價(jià)。*(a+i)+j表示二維數(shù)組元素aij的地址,等價(jià)于&aij,也等價(jià)于ai+j。注 意6.3.2 指針與二維數(shù)組通過以上描述可知,使用指針訪問二維數(shù)組中的元素有多種表示方法,例如定義指向二維數(shù)組的指針p,通過p訪問二維數(shù)組a中的第2行第2列的元素:p11*(p1+1)*(*(p+1)+1)6.3.2 指針與二維數(shù)組二維數(shù)組中相關(guān)指針與數(shù)據(jù)的表示形式表示形式含義a二維數(shù)組名,指向一維數(shù)組a0,為0行元素首地址,也是a00的地址ai,*(a+i)一維數(shù)組名,表示二維數(shù)組第i行元素首地址,值為&ai0*(a+i)+j二維數(shù)組元素地址,二維數(shù)組中最小數(shù)據(jù)單元地

19、址,等價(jià)于&aij*(*(a+i)+j)二維數(shù)組元素,表示第i行第j列數(shù)據(jù)的值,等價(jià)于aij6.4 階段案例幻方一、案例描述將從1至n2的自然數(shù)排列成縱橫各有n個(gè)數(shù)的矩陣,使每行、每列、每條主對(duì)角線上的n個(gè)數(shù)之和都相等。這樣的矩陣就是魔方陣,也稱作幻方。本案例要求編寫程序,實(shí)現(xiàn)奇數(shù)階的幻方。6.4 階段案例幻方二、案例分析觀察3階幻方,其中的每一行之和、每一列之和、對(duì)角線之和都為15,其行、列、對(duì)角線之和全部相等。其和sum=n(n2+1)/2=3(32+1)/2=15。6.4 階段案例幻方二、案例分析幻方的構(gòu)造規(guī)則如下:假定陣列的行列下標(biāo)都從1開始,在第1行中間置1,對(duì)從2開始的其余數(shù)依次按

20、下列規(guī)則存放:(1)假設(shè)當(dāng)前數(shù)的下標(biāo)為(x,y),則下一個(gè)數(shù)的放置位置為當(dāng)前位置的右上方,即坐標(biāo)為(x-1,y+1)的位置;6.4 階段案例幻方二、案例分析(2)如果當(dāng)前數(shù)在第1行,則將下一個(gè)數(shù)放在最后一行的下一列上;(3)如果當(dāng)前數(shù)在最后一列上,則將下一個(gè)數(shù)放在上一行的第一列上;(4)如果下一個(gè)數(shù)的位置已經(jīng)被占用,則下一個(gè)數(shù)直接放在當(dāng)前位置的正下方,即放在下一行同一列上。6.4 階段案例幻方三、案例實(shí)現(xiàn)思路(1)矩陣的行數(shù)、列數(shù)、矩陣中元素的數(shù)量都由n確定,在程序中設(shè)置scanf()函數(shù),由用戶手動(dòng)控制幻方的規(guī)模。本案例針對(duì)奇數(shù)階的幻方,因此如果輸入的數(shù)據(jù)不是奇數(shù),則使用goto語(yǔ)句回到輸入

21、函數(shù)之前;(2)本案例中元素的數(shù)量不確定,因此使用malloc()函數(shù)動(dòng)態(tài)申請(qǐng)存儲(chǔ)空間;6.4 階段案例幻方三、案例實(shí)現(xiàn)思路(3)幻方中的數(shù)據(jù)按行序優(yōu)先存儲(chǔ)在malloc()函數(shù)開辟的空間中,在輸出時(shí),每輸出n個(gè)數(shù)據(jù),進(jìn)行一次換行;(4)將所有的操作封裝在一個(gè)函數(shù)中,在主函數(shù)中調(diào)用該函數(shù)。在函數(shù)結(jié)束之前,使用free()函數(shù)釋放函數(shù)中申請(qǐng)的堆空間。多學(xué)一招:內(nèi)存分配與回收1、malloc()函數(shù)malloc()函數(shù)用于申請(qǐng)指定大小的存儲(chǔ)空間,其函數(shù)原型如下:void* malloc(unsigned int size);參數(shù)size為申請(qǐng)的空間字節(jié)大小。多學(xué)一招:內(nèi)存分配與回收2、calloc

22、()函數(shù)calloc()函數(shù)原型如下:void* calloc(unsigned int count,unsigned int size);參數(shù)size為需要分配的字節(jié)大小,count為分配多少個(gè)size。calloc()函數(shù)分配的空間會(huì)被初始化為0。多學(xué)一招:內(nèi)存分配與回收3、relloc()函數(shù)relloc()函數(shù)原型如下:void* realloc(void* memory,unsigned int newSize);參數(shù)memory為指向堆空間的指針,newSize為新分配空間的大小。該函數(shù)是指為memory重新分配一塊newSize大小的空間。多學(xué)一招:內(nèi)存分配與回收4、free()

23、函數(shù)free()函數(shù)用于釋放在堆上申請(qǐng)的空間,其參數(shù)為指向堆空間的指針。int *p=(int*)malloc(sizeof(int)*n); /申請(qǐng)free(p); /釋放指針還經(jīng)常與函數(shù)結(jié)合使用,指針可以作為函數(shù)參數(shù)進(jìn)行傳遞,提高參數(shù)傳遞的效率,降低直接傳遞變量的開銷。除此之外,還可以定義指向函數(shù)的指針,此種指針稱為函數(shù)指針,函數(shù)指針在實(shí)際編程開發(fā)中也經(jīng)常使用。6.5 指針與函數(shù)用指針變量作為函數(shù)的形參,通過傳遞地址的方式,使形參和實(shí)參都指向主調(diào)函數(shù)中數(shù)據(jù)所在地址,從而使被調(diào)函數(shù)可以對(duì)主調(diào)函數(shù)中的數(shù)據(jù)進(jìn)行操作。需要注意的是指針交換包括兩個(gè)方面:指針指向交換,數(shù)據(jù)交換。6.5.1 指針變量作

24、為函數(shù)參數(shù)1、指針指向交換指針指向交換只是指針指向發(fā)生了改變,原來地址中的數(shù)據(jù)并沒有改變。6.5.1 指針變量作為函數(shù)參數(shù)1、指針指向交換指針指向交換只是指針指向發(fā)生了改變,原來地址中的數(shù)據(jù)并沒有改變。6.5.1 指針變量作為函數(shù)參數(shù)1、指針指向交換指針指向交換需要一個(gè)輔助指針實(shí)現(xiàn):int *tmp=NULL; /創(chuàng)建輔助變量指針tmp=p; /使用輔助指針記錄指針p的指向p=q; /使指針p記錄指針q的指向q=tmp; /使指針q指向p原來指向的地址6.5.1 指針變量作為函數(shù)參數(shù)2、數(shù)據(jù)交換數(shù)據(jù)交換是指針指向沒有改變,但指向的地址中的數(shù)據(jù)發(fā)生了改變。6.5.1 指針變量作為函數(shù)參數(shù)2、數(shù)據(jù)

25、交換數(shù)據(jù)交換也需要一個(gè)中間輔助變量實(shí)現(xiàn):int tmp=0;/創(chuàng)建輔助變量tmp=*p;/使用輔助變量記錄指針p指向地址中的數(shù)據(jù)*p=*q;/將q指向地址中的數(shù)據(jù)放到p所指地址中*q=tmp;/將p中原來的數(shù)據(jù)放到q所指地址中6.5.1 指針變量作為函數(shù)參數(shù)int a = 10;int b = 20;6.5.1 指針變量作為函數(shù)參數(shù)int func(int *p1, int *p2)/直接取變量a與b的地址傳遞給函數(shù)func(&a,&b); /定義指向變量的指針int *pa = &a, *pb = &b; func(pa,pb); /將指針作為函數(shù)進(jìn)行傳遞傳遞指針傳遞指針數(shù)組指針也可以作為函

26、數(shù)參數(shù)。數(shù)組指針作為函數(shù)參數(shù)進(jìn)行傳遞時(shí),是將數(shù)組的首地址傳遞給函數(shù),這樣在函數(shù)內(nèi)部可以通過地址訪問數(shù)組元素,對(duì)數(shù)組進(jìn)行操作。6.5.1 指針變量作為函數(shù)參數(shù)/一維數(shù)組指針作為函數(shù)參數(shù)int arr110;int *p1 =arr1;func1(p1);/二維數(shù)組指針作為函數(shù)參數(shù)int arr223;int (*p2)3 = arr2;func2(p2);若在程序中定義了一個(gè)函數(shù),在編譯時(shí),編譯器會(huì)為函數(shù)代碼分配一段存儲(chǔ)空間,這段空間的起始地址(又稱入口地址)稱為這個(gè)函數(shù)的指針。6.5.2 函數(shù)指針1、函數(shù)指針的定義與普通變量相同,同樣可以定義一個(gè)指針指向存放函數(shù)代碼的存儲(chǔ)空間的起始地址,這樣的

27、指針叫做函數(shù)指針。函數(shù)指針的定義格式如下:返回值類型 (*變量名)(參數(shù)列表)6.5.2 函數(shù)指針1、函數(shù)指針的定義“*”表示這是一個(gè)指針變量,參數(shù)列表表示該指針?biāo)负瘮?shù)的形參列表。需要注意的是,由于優(yōu)先級(jí)的關(guān)系,“*變量名”要用圓括號(hào)括起來。6.5.2 函數(shù)指針/聲明函數(shù)int func(int a,int b);/定義函數(shù)指針int (*p)(int,int);/將指針指向函數(shù)p=func;2、函數(shù)指針的應(yīng)用(1)調(diào)用函數(shù)。(2)將函數(shù)的地址作為函數(shù)參數(shù)傳入其他函數(shù)。6.5.2 函數(shù)指針6.5.2 函數(shù)指針函數(shù)指針不能進(jìn)行算術(shù)運(yùn)算,如p+n、p+、-p等等,這些運(yùn)算是無(wú)意義的。注 意多學(xué)一

28、招:右左法則首先從左側(cè)第1個(gè)未定義的標(biāo)識(shí)符看起,然后往右看,再往左看。每當(dāng)遇到圓括號(hào)時(shí),就應(yīng)該掉轉(zhuǎn)閱讀方向。一旦解析完圓括號(hào)里面所有的東西,就跳出圓括號(hào)。重復(fù)這個(gè)過程直到整個(gè)聲明解析完畢。在實(shí)際開發(fā)中,函數(shù)指針一個(gè)非常重要的應(yīng)用就是回調(diào)函數(shù),回調(diào)函數(shù)在大型的工程和一些系統(tǒng)框架中很常見,如在服務(wù)器領(lǐng)域使用的Reactor架構(gòu)、MFC編程中使用“句柄”等?;卣{(diào)函數(shù)存在的意義是在特定的條件發(fā)生時(shí),調(diào)用方對(duì)該條件下即時(shí)的響應(yīng)處理。6.5.3 回調(diào)函數(shù)void show(char *s,void (* ptr)() /回調(diào)函數(shù)(*ptr)(s); void print(char *p) printf(

29、%sn,p); int main()char str16=回調(diào)函數(shù);show(str,print);return 0; 6.5.3 回調(diào)函數(shù)6.5.3 回調(diào)函數(shù)以上代碼包含三個(gè)函數(shù):show()、print()和main()。show()接收一個(gè)字符指針s和一個(gè)函數(shù)指針ptr,并在函數(shù)中將字符指針s作為函數(shù)指針?biāo)负瘮?shù)的參數(shù),調(diào)用ptr函數(shù);print()接收一個(gè)字符指針,并打印該字符指針?biāo)傅淖址籱ain()函數(shù)是程序的入口。6.6 指針數(shù)組指針變量也是C語(yǔ)言中的一種變量,同樣的,指針變量也可以構(gòu)成數(shù)組。若一個(gè)數(shù)組中的所有元素都是指針類型,那么這個(gè)數(shù)組是指針數(shù)組,該數(shù)組中的每一個(gè)元素都存

30、放一個(gè)地址。6.6.1 定義指針數(shù)組定義一維指針數(shù)組的語(yǔ)法格式如下:類型名* 數(shù)組名數(shù)組長(zhǎng)度;例如,定義一個(gè)大小為5的int類型指針數(shù)組int *p5; /該數(shù)組中的每一個(gè)元素都指向一個(gè)int類型數(shù)據(jù)6.6.1 定義指針數(shù)組由于“”的優(yōu)先級(jí)比“*”高,在一維指針數(shù)組中,數(shù)組名先和“”結(jié)合,表示這是一個(gè)數(shù)組,之后數(shù)組名與“*”結(jié)合,表示該數(shù)組中元素的數(shù)據(jù)類型都是指針類型。注 意6.6.1 定義指針數(shù)組指針數(shù)組的數(shù)組名是一個(gè)地址,它指向該數(shù)組中的第一個(gè)元素,也就是該數(shù)組中存儲(chǔ)的第一個(gè)地址。指針數(shù)組的數(shù)組名的實(shí)質(zhì)就是一個(gè)指向數(shù)組的二級(jí)指針。一個(gè)單純的地址沒有意義,地址應(yīng)作為變量的地址存在,所以指針數(shù)

31、組中存儲(chǔ)的指針應(yīng)該指向?qū)嶋H的變量。6.6.1 定義指針數(shù)組定義一個(gè)字符型的指針數(shù)組a:char* a3= this is a string, hello world, I love China“;該數(shù)組的邏輯結(jié)構(gòu)如右圖。6.6.1 定義指針數(shù)組指針數(shù)組名a代表的指針指向指針數(shù)組中第一個(gè)元素a0所在的地址,a+1即為第二個(gè)元素a1所在的地址,以此類推,a+2為第三個(gè)元素a3所在地址。訪問數(shù)組中數(shù)據(jù):a0; /值為this is stringa1; /值為hello worlda3; /值為i love China6.6.2 指針數(shù)組的應(yīng)用有一個(gè)float類型的數(shù)組存儲(chǔ)了學(xué)生的成績(jī),其定義如下:f

32、loat arr10 = 88.5,90,76,89.5,94,98,65,77,99.5,68;、再定義一個(gè)指針數(shù)組str,將arr數(shù)組中的成績(jī)的地址賦值給數(shù)組str中的元素。6.6.2 指針數(shù)組的應(yīng)用6.6.2 指針數(shù)組的應(yīng)用使用冒泡排序?qū)@一組學(xué)生成績(jī)進(jìn)行排序,有兩種方法:操作指針數(shù)組str,操作數(shù)組arr。(1)操作指針數(shù)組str對(duì)學(xué)生成績(jī)進(jìn)行排序,只是使指針的指向發(fā)生了改變,而原數(shù)組arr并沒有改變。6.6.2 指針數(shù)組的應(yīng)用6.6.2 指針數(shù)組的應(yīng)用(2)操作數(shù)組arr排序時(shí),str數(shù)組中的指針指向并沒有改變,而數(shù)組arr中的數(shù)據(jù)位置發(fā)生了改變。多學(xué)一招:指針數(shù)組作為main()函

33、數(shù)的參數(shù)main()函數(shù)的完整定義方式如下所示:int main( int argc, char *argv );main()函數(shù)有兩個(gè)參數(shù),參數(shù)argc表示在命令行中輸入的參數(shù)個(gè)數(shù),參數(shù)argv是字符串指針數(shù)組,各元素值為命令行中各字符串的首地址。數(shù)組第1個(gè)元素指向當(dāng)前運(yùn)行程序文件名的字符串。指針數(shù)組的長(zhǎng)度即參數(shù)個(gè)數(shù),數(shù)組元素初值由系統(tǒng)自動(dòng)賦予。6.7 二級(jí)指針指針還可以指向一個(gè)指針,即指針中存儲(chǔ)的是指針的地址,這樣的指針稱為二級(jí)指針。根據(jù)二級(jí)指針中存放的數(shù)據(jù),二級(jí)指針可分為指向指針變量的指針,和指向指針數(shù)組的指針。6.7 二級(jí)指針1、指向指針變量的指針定義格式如下:變量類型 *變量名;int a=10; /整型變量int *p=&a; /一級(jí)指針p,指向整型變量aint *q=&p; /二級(jí)指針q,指向一級(jí)指針p6.7 二級(jí)指針2、指向指針數(shù)組的指針指向指針數(shù)組的指針也是二級(jí)指針。char *a3=0;char *p=a;以上語(yǔ)句中定義的p是指向指針數(shù)組的指針,當(dāng)把指針數(shù)組a的地址賦給指針p時(shí),p就指向指針數(shù)組a的首元素a0,a0為一個(gè)指針型的元素,指向一個(gè)char型數(shù)組的首元素,而指針p初始時(shí)的值為該元素的地址。6.8 階段案例天生棋局一

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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)論