CHAR10譚浩強(qiáng)C語(yǔ)言word版.DOC_第1頁(yè)
CHAR10譚浩強(qiáng)C語(yǔ)言word版.DOC_第2頁(yè)
CHAR10譚浩強(qiáng)C語(yǔ)言word版.DOC_第3頁(yè)
CHAR10譚浩強(qiáng)C語(yǔ)言word版.DOC_第4頁(yè)
CHAR10譚浩強(qiáng)C語(yǔ)言word版.DOC_第5頁(yè)
已閱讀5頁(yè),還剩33頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、10指針110.1地址指針的基本概念110.2變量的指針和指向變量的指針變量210.2.1定義一個(gè)指針變量310.2.2指針變量的引用310.2.3指針變量作為函數(shù)參數(shù)710.2.4指針變量幾個(gè)問(wèn)題的進(jìn)一步說(shuō)明1010.3數(shù)組指針和指向數(shù)組的指針變量1310.3.1指向數(shù)組元素的指針1310.3.2通過(guò)指針引用數(shù)組元素1410.3.3數(shù)組名作函數(shù)參數(shù)1610.3.4指向多維數(shù)組的指針和指針變量2210.4字符串的指針指向字符串的針指變量2510.4.1字符串的表示形式2510.4.2使用字符串指針變量與字符數(shù)組的區(qū)別2810.5函數(shù)指針變量2910.6指針型函數(shù)3010.7指針數(shù)組和指向指針的

2、指針3110.7.1指針數(shù)組的概念3110.7.2指向指針的指針3410.7.3main函數(shù)的參數(shù)3610.8有關(guān)指針的數(shù)據(jù)類(lèi)型和指針運(yùn)算的小結(jié)3710.8.1有關(guān)指針的數(shù)據(jù)類(lèi)型的小結(jié)3710.8.2指針運(yùn)算的小結(jié)3710.8.3void指針類(lèi)型3810 指針 指針是語(yǔ)言中廣泛使用的一種數(shù)據(jù)類(lèi)型。運(yùn)用指針編程是語(yǔ)言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu);能很方便地使用數(shù)組和字符串;并能象匯編語(yǔ)言一樣處理內(nèi)存地址,從而編出精練而高效的程序。指針極大地豐富了語(yǔ)言的功能。學(xué)習(xí)指針是學(xué)習(xí)語(yǔ)言中最重要的一環(huán),能否正確理解和使用指針是我們是否掌握語(yǔ)言的一個(gè)標(biāo)志。同時(shí),指針也是語(yǔ)言中最為困難的一

3、部分,在學(xué)習(xí)中除了要正確理解基本概念,還必須要多編程,上機(jī)調(diào)試。只要作到這些,指針也是不難掌握的。10.1 地址指針的基本概念在計(jì)算機(jī)中,所有的數(shù)據(jù)都是存放在存儲(chǔ)器中的。一般把存儲(chǔ)器中的一個(gè)字節(jié)稱(chēng)為一個(gè)內(nèi)存單元,不同的數(shù)據(jù)類(lèi)型所占用的內(nèi)存單元數(shù)不等,如整型量占2個(gè)單元,字符量占1個(gè)單元等,在前面已有詳細(xì)的介紹。為了正確地訪問(wèn)這些內(nèi)存單元,必須為每個(gè)內(nèi)存單元編上號(hào)。根據(jù)一個(gè)內(nèi)存單元的編號(hào)即可準(zhǔn)確地找到該內(nèi)存單元。內(nèi)存單元的編號(hào)也叫做地址。 既然根據(jù)內(nèi)存單元的編號(hào)或地址就可以找到所需的內(nèi)存單元,所以通常也把這個(gè)地址稱(chēng)為指針。 內(nèi)存單元的指針和內(nèi)存單元的內(nèi)容是兩個(gè)不同的概念。 可以用一個(gè)通俗的例子來(lái)

4、說(shuō)明它們之間的關(guān)系。我們到銀行去存取款時(shí), 銀行工作人員將根據(jù)我們的帳號(hào)去找我們的存款單, 找到之后在存單上寫(xiě)入存款、取款的金額。在這里,帳號(hào)就是存單的指針, 存款數(shù)是存單的內(nèi)容。對(duì)于一個(gè)內(nèi)存單元來(lái)說(shuō),單元的地址即為指針,其中存放的數(shù)據(jù)才是該單元的內(nèi)容。在語(yǔ)言中,允許用一個(gè)變量來(lái)存放指針,這種變量稱(chēng)為指針變量。因此,一個(gè)指針變量的值就是某個(gè)內(nèi)存單元的地址或稱(chēng)為某內(nèi)存單元的指針。圖中,設(shè)有字符變量c,其內(nèi)容為“k”(ascii碼為十進(jìn)制數(shù) 75),c占用了011a號(hào)單元(地址用十六進(jìn)數(shù)表示)。設(shè)有指針變量p,內(nèi)容為011a,這種情況我們稱(chēng)為p指向變量c,或說(shuō)p是指向變量c的指針。嚴(yán)格地說(shuō),一個(gè)指

5、針是一個(gè)地址,是一個(gè)常量。而一個(gè)指針變量卻可以被賦予不同的指針值,是變量。但常把指針變量簡(jiǎn)稱(chēng)為指針。為了避免混淆,我們中約定:“指針”是指地址,是常量,“指針變量”是指取值為地址的變量。定義指針的目的是為了通過(guò)指針去訪問(wèn)內(nèi)存單元。 既然指針變量的值是一個(gè)地址,那么這個(gè)地址不僅可以是變量的地址,也可以是其它數(shù)據(jù)結(jié)構(gòu)的地址。在一個(gè)指針變量中存放一個(gè)數(shù)組或一個(gè)函數(shù)的首地址有何意義呢? 因?yàn)閿?shù)組或函數(shù)都是連續(xù)存放的。通過(guò)訪問(wèn)指針變量取得了數(shù)組或函數(shù)的首地址,也就找到了該數(shù)組或函數(shù)。這樣一來(lái),凡是出現(xiàn)數(shù)組,函數(shù)的地方都可以用一個(gè)指針變量來(lái)表示,只要該指針變量中賦予數(shù)組或函數(shù)的首地址即可。這樣做,將會(huì)使程

6、序的概念十分清楚,程序本身也精練,高效。在語(yǔ)言中,一種數(shù)據(jù)類(lèi)型或數(shù)據(jù)結(jié)構(gòu)往往都占有一組連續(xù)的內(nèi)存單元。 用“地址”這個(gè)概念并不能很好地描述一種數(shù)據(jù)類(lèi)型或數(shù)據(jù)結(jié)構(gòu),而“指針”雖然實(shí)際上也是一個(gè)地址,但它卻是一個(gè)數(shù)據(jù)結(jié)構(gòu)的首地址,它是“指向”一個(gè)數(shù)據(jù)結(jié)構(gòu)的,因而概念更為清楚,表示更為明確。 這也是引入“指針”概念的一個(gè)重要原因。10.2 變量的指針和指向變量的指針變量變量的指針就是變量的地址。存放變量地址的變量是指針變量。即在語(yǔ)言中,允許用一個(gè)變量來(lái)存放指針,這種變量稱(chēng)為指針變量。因此,一個(gè)指針變量的值就是某個(gè)變量的地址或稱(chēng)為某變量的指針。為了表示指針變量和它所指向的變量之間的關(guān)系,在程序中用“*

7、”符號(hào)表示“指向”,例如,i_pointer代表指針變量,而*i_pointer是i_pointer所指向的變量。因此,下面兩個(gè)語(yǔ)句作用相同:i=3;*i_pointer=3;第二個(gè)語(yǔ)句的含義是將3賦給指針變量i_pointer所指向的變量。10.2.1 定義一個(gè)指針變量對(duì)指針變量的定義包括三個(gè)內(nèi)容:(1) 指針類(lèi)型說(shuō)明,即定義變量為一個(gè)指針變量;(2) 指針變量名;(3) 變量值(指針)所指向的變量的數(shù)據(jù)類(lèi)型。其一般形式為:類(lèi)型說(shuō)明符 *變量名;其中,*表示這是一個(gè)指針變量,變量名即為定義的指針變量名,類(lèi)型說(shuō)明符表示本指針變量所指向的變量的數(shù)據(jù)類(lèi)型。例如: int *p1;表示p1是一個(gè)指針

8、變量,它的值是某個(gè)整型變量的地址?;蛘哒f(shuō)p1指向一個(gè)整型變量。至于p1究竟指向哪一個(gè)整型變量,應(yīng)由向p1賦予的地址來(lái)決定。再如:int *p2; /*p2是指向整型變量的指針變量*/ float *p3; /*p3是指向浮點(diǎn)變量的指針變量*/char *p4; /*p4是指向字符變量的指針變量*/應(yīng)該注意的是,一個(gè)指針變量只能指向同類(lèi)型的變量,如p3 只能指向浮點(diǎn)變量,不能時(shí)而指向一個(gè)浮點(diǎn)變量,時(shí)而又指向一個(gè)字符變量。10.2.2 指針變量的引用指針變量同普通變量一樣,使用之前不僅要定義說(shuō)明,而且必須賦予具體的值。未經(jīng)賦值的指針變量不能使用,否則將造成系統(tǒng)混亂,甚至死機(jī)。指針變量的賦值只能賦予

9、地址, 決不能賦予任何其它數(shù)據(jù),否則將引起錯(cuò)誤。在語(yǔ)言中,變量的地址是由編譯系統(tǒng)分配的,對(duì)用戶(hù)完全透明,用戶(hù)不知道變量的具體地址。兩個(gè)有關(guān)的運(yùn)算符:1) &:取地址運(yùn)算符。2) *:指針運(yùn)算符(或稱(chēng)“間接訪問(wèn)” 運(yùn)算符)。語(yǔ)言中提供了地址運(yùn)算符&來(lái)表示變量的地址。其一般形式為: &變量名;如&a表示變量a的地址,&b表示變量b的地址。變量本身必須預(yù)先說(shuō)明。設(shè)有指向整型變量的指針變量p,如要把整型變量a 的地址賦予p可以有以下兩種方式:(1) 指針變量初始化的方法 int a; int *p=&a;(2) 賦值語(yǔ)句的方法 int a; int *p;p=&a;不允許把一個(gè)數(shù)賦予指針變量,故下面的

10、賦值是錯(cuò)誤的:int *p;p=1000;被賦值的指針變量前不能再加“*”說(shuō)明符,如寫(xiě)為*p=&a 也是錯(cuò)誤的。假設(shè):int i=200, x;int *ip;我們定義了兩個(gè)整型變量i,x,還定義了一個(gè)指向整型數(shù)的指針變量ip。i,x中可存放整數(shù),而ip中只能存放整型變量的地址。我們可以把i的地址賦給ip:ip=&i;此時(shí)指針變量ip指向整型變量i,假設(shè)變量i的地址為1800,這個(gè)賦值可形象理解為下圖所示的聯(lián)系。 以后我們便可以通過(guò)指針變量ip間接訪問(wèn)變量i,例如: x=*ip;運(yùn)算符*訪問(wèn)以ip為地址的存貯區(qū)域,而ip中存放的是變量i的地址,因此,*ip訪問(wèn)的是地址為1800的存貯區(qū)域(因?yàn)?/p>

11、是整數(shù),實(shí)際上是從1800開(kāi)始的兩個(gè)字節(jié)),它就是i所占用的存貯區(qū)域, 所以上面的賦值表達(dá)式等價(jià)于 x=i;另外,指針變量和一般變量一樣,存放在它們之中的值是可以改變的,也就是說(shuō)可以改變它們的指向,假設(shè)int i,j,*p1,*p2; i=a; j=b;p1=&i;p2=&j;則建立如下圖所示的聯(lián)系:這時(shí)賦值表達(dá)式:p2=p1就使p2與p1指向同一對(duì)象i,此時(shí)*p2就等價(jià)于i,而不是j,圖所示:如果執(zhí)行如下表達(dá)式: *p2=*p1;則表示把p1指向的內(nèi)容賦給p2所指的區(qū)域, 此時(shí)就變成圖所示通過(guò)指針訪問(wèn)它所指向的一個(gè)變量是以間接訪問(wèn)的形式進(jìn)行的,所以比直接訪問(wèn)一個(gè)變量要費(fèi)時(shí)間,而且不直觀,因?yàn)?/p>

12、通過(guò)指針要訪問(wèn)哪一個(gè)變量,取決于指針的值(即指向),例如*p2=*p1;實(shí)際上就是j=i;,前者不僅速度慢而且目的不明。但由于指針是變量,我們可以通過(guò)改變它們的指向,以間接訪問(wèn)不同的變量,這給程序員帶來(lái)靈活性,也使程序代碼編寫(xiě)得更為簡(jiǎn)潔和有效。指針變量可出現(xiàn)在表達(dá)式中, 設(shè)int x,y,*px=&x;指針變量px指向整數(shù)x,則*px可出現(xiàn)在x能出現(xiàn)的任何地方。例如:y=*px+5; /*表示把x的內(nèi)容加5并賦給y*/y=+*px; /*px的內(nèi)容加上1之后賦給y,+*px相當(dāng)于+(*px)*/y=*px+; /*相當(dāng)于y=*px; px+*/ 【例10.1】main() int a,b; i

13、nt *pointer_1, *pointer_2; a=100;b=10; pointer_1=&a;pointer_2=&b; printf(%d,%dn,a,b); printf(%d,%dn,*pointer_1, *pointer_2); 對(duì)程序的說(shuō)明:1) 在開(kāi)頭處雖然定義了兩個(gè)指針變量pointer_1和pointer_2,擔(dān)它們并未指向任何一個(gè)整型變量。只是提供兩個(gè)指針變量,規(guī)定它們可以指向整型變量。程序第5、6行的作用就是使pointer_1指向a,pointer_2指向b。2) 最后一行的*pointer_1和*pointer_2就是變量a和b。最后兩個(gè)printf函數(shù)作用

14、是相同的。3) 程序中有兩處出現(xiàn)*pointer_1和*pointer_2,請(qǐng)區(qū)分它們的不同含義。4) 程序第5、6行的“pointer_1=&a”和 “pointer_2=&b”不能寫(xiě)成“*pointer_1=&a”和 “*pointer_2=&b”。請(qǐng)對(duì)下面再的關(guān)于“&”和“*”的問(wèn)題進(jìn)行考慮:1) 如果已經(jīng)執(zhí)行了“pointer_1=&a;”語(yǔ)句,則&*pointer_1是什么含義?2) *&a含義是什么?3) (pointer_1)+和pointer_1+的區(qū)別?【例10.2】輸入a和b兩個(gè)整數(shù),按先大后小的順序輸出a和b。main() int *p1,*p2,*p,a,b; scan

15、f(%d,%d,&a,&b); p1=&a;p2=&b; if(ab) p=p1;p1=p2;p2=p; printf(na=%d,b=%dn,a,b); printf(max=%d,min=%dn,*p1, *p2); 10.2.3 指針變量作為函數(shù)參數(shù)函數(shù)的參數(shù)不僅可以是整型、實(shí)型、字符型等數(shù)據(jù),還可以是指針類(lèi)型。它的作用是將一個(gè)變量的地址傳送到另一個(gè)函數(shù)中?!纠?0.3】題目同例10.2,即輸入的兩個(gè)整數(shù)按大小順序輸出。今用函數(shù)處理,而且用指針類(lèi)型的數(shù)據(jù)作函數(shù)參數(shù)。swap(int *p1,int *p2)int temp; temp=*p1; *p1=*p2; *p2=temp;mai

16、n() int a,b;int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a;pointer_2=&b; if(ab) swap(pointer_1,pointer_2); printf(n%d,%dn,a,b); 對(duì)程序的說(shuō)明:swap是用戶(hù)定義的函數(shù),它的作用是交換兩個(gè)變量(a和b)的值。swap函數(shù)的形參p1、p2是指針變量。程序運(yùn)行時(shí),先執(zhí)行main函數(shù),輸入a和b的值。然后將a和b的地址分別賦給指針變量pointer_1和pointer_2,使pointer_1指向a,pointer_2指向b。接著執(zhí)行if語(yǔ)句,由于a

17、b,因此執(zhí)行swap函數(shù)。注意實(shí)參pointer_1和pointer_2是指針變量,在函數(shù)調(diào)用時(shí),將實(shí)參變量的值傳遞給形參變量。采取的依然是“值傳遞”方式。因此虛實(shí)結(jié)合后形參p1的值為&a,p2的值為&b。這時(shí)p1和pointer_1指向變量a,p2和pointer_2指向變量b。接著執(zhí)行執(zhí)行swap函數(shù)的函數(shù)體使*p1和*p2的值互換,也就是使a和b的值互換。函數(shù)調(diào)用結(jié)束后,p1和p2不復(fù)存在(已釋放)如圖。最后在main函數(shù)中輸出的a和b的值是已經(jīng)過(guò)交換的值。請(qǐng)注意交換*p1和*p2的值是如何實(shí)現(xiàn)的。請(qǐng)找出下列程序段的錯(cuò)誤:swap(int *p1,int *p2)int *temp; *

18、temp=*p1; /*此語(yǔ)句有問(wèn)題*/ *p1=*p2; *p2=temp;請(qǐng)考慮下面的函數(shù)能否實(shí)現(xiàn)實(shí)現(xiàn)a和b互換。swap(int x,int y)int temp; temp=x; x=y; y=temp;如果在main函數(shù)中用“swap(a,b);”調(diào)用swap函數(shù),會(huì)有什么結(jié)果呢?請(qǐng)看下圖所示?!纠?0.4】請(qǐng)注意,不能企圖通過(guò)改變指針形參的值而使指針實(shí)參的值改變。swap(int *p1,int *p2)int *p; p=p1; p1=p2; p2=p;main() int a,b;int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); po

19、inter_1=&a;pointer_2=&b; if(ab) swap(pointer_1,pointer_2); printf(n%d,%dn,*pointer_1,*pointer_2); 其中的問(wèn)題在于不能實(shí)現(xiàn)如圖所示的第四步(d)?!纠?0.5】輸入a、b、c3個(gè)整數(shù),按大小順序輸出。swap(int *pt1,int *pt2)int temp; temp=*pt1; *pt1=*pt2; *pt2=temp;exchange(int *q1,int *q2,int *q3) if(*q1*q2)swap(q1,q2);if(*q1*q3)swap(q1,q3);if(*q2pf2

20、表示pf1處于高地址位置;pf1b) /*如果第一個(gè)數(shù)字大于第二個(gè)數(shù)字*/ pmax=&a; /*指針變量賦值*/ pmin=&b; /*指針變量賦值*/ else pmax=&b; /*指針變量賦值*/ pmin=&a; /*指針變量賦值*/ if(c*pmax) pmax=&c; /*判斷并賦值*/ if(c*pmin) pmin=&c; /*判斷并賦值*/ printf(max=%dnmin=%dn,*pmax,*pmin); /*輸出結(jié)果*/10.3 數(shù)組指針和指向數(shù)組的指針變量一個(gè)變量有一個(gè)地址,一個(gè)數(shù)組包含若干元素,每個(gè)數(shù)組元素都在內(nèi)存中占用存儲(chǔ)單元,它們都有相應(yīng)的地址。所謂數(shù)組的

21、指針是指數(shù)組的起始地址,數(shù)組元素的指針是數(shù)組元素的地址。10.3.1 指向數(shù)組元素的指針一個(gè)數(shù)組是由連續(xù)的一塊內(nèi)存單元組成的。數(shù)組名就是這塊連續(xù)內(nèi)存單元的首地址。一個(gè)數(shù)組也是由各個(gè)數(shù)組元素(下標(biāo)變量)組成的。每個(gè)數(shù)組元素按其類(lèi)型不同占有幾個(gè)連續(xù)的內(nèi)存單元。一個(gè)數(shù)組元素的首地址也是指它所占有的幾個(gè)內(nèi)存單元的首地址。定義一個(gè)指向數(shù)組元素的指針變量的方法,與以前介紹的指針變量相同。例如: int a10; /*定義a為包含10個(gè)整型數(shù)據(jù)的數(shù)組*/int *p; /*定義p為指向整型變量的指針*/應(yīng)當(dāng)注意,因?yàn)閿?shù)組為int型,所以指針變量也應(yīng)為指向int型的指針變量。下面是對(duì)指針變量賦值:p=&a0;

22、把a(bǔ)0元素的地址賦給指針變量p。也就是說(shuō),p指向a數(shù)組的第0號(hào)元素。c語(yǔ)言規(guī)定,數(shù)組名代表數(shù)組的首地址,也就是第0號(hào)元素的地址。因此,下面兩個(gè)語(yǔ)句等價(jià):p=&a0;p=a;在定義指針變量時(shí)可以賦給初值:int *p=&a0;它等效于:int *p; p=&a0;當(dāng)然定義時(shí)也可以寫(xiě)成: int *p=a;從圖中我們可以看出有以下關(guān)系: p,a,&a0均指向同一單元,它們是數(shù)組a的首地址,也是0 號(hào)元素a0的首地址。應(yīng)該說(shuō)明的是p是變量,而a,&a0都是常量。在編程時(shí)應(yīng)予以注意。數(shù)組指針變量說(shuō)明的一般形式為:類(lèi)型說(shuō)明符 *指針變量名;其中類(lèi)型說(shuō)明符表示所指數(shù)組的類(lèi)型。從一般形式可以看出指向數(shù)組的指

23、針變量和指向普通變量的指針變量的說(shuō)明是相同的。10.3.2 通過(guò)指針引用數(shù)組元素c語(yǔ)言規(guī)定:如果指針變量p已指向數(shù)組中的一個(gè)元素,則p+1指向同一數(shù)組中的下一個(gè)元素。引入指針變量后,就可以用兩種方法來(lái)訪問(wèn)數(shù)組元素了。如果p的初值為&a0,則:1) p+i和a+i就是ai的地址,或者說(shuō)它們指向a數(shù)組的第i個(gè)元素。2) *(p+i)或*(a+i)就是p+i或a+i所指向的數(shù)組元素,即ai。例如,*(p+5)或*(a+5)就是a5。3) 指向數(shù)組的指針變量也可以帶下標(biāo),如pi與*(p+i)等價(jià)。根據(jù)以上敘述,引用一個(gè)數(shù)組元素可以用:1) 下標(biāo)法,即用ai形式訪問(wèn)數(shù)組元素。在前面介紹數(shù)組時(shí)都是采用這種

24、方法。2) 指針?lè)ǎ床捎?(a+i)或*(p+i)形式,用間接訪問(wèn)的方法來(lái)訪問(wèn)數(shù)組元素,其中a是數(shù)組名,p是指向數(shù)組的指針變量,其處值p=a?!纠?0.9】輸出數(shù)組中的全部元素。(下標(biāo)法)main() int a10,i; for(i=0;i10;i+) ai=i; for(i=0;i5;i+) printf(a%d=%dn,i,ai);【例10.10】輸出數(shù)組中的全部元素。(通過(guò)數(shù)組名計(jì)算元素的地址,找出元素的值)main() int a10,i; for(i=0;i10;i+) *(a+i)=i; for(i=0;i10;i+) printf(a%d=%dn,i,*(a+i);【例10.

25、11】輸出數(shù)組中的全部元素。(用指針變量指向元素)main() int a10,i,*p; p=a; for(i=0;i10;i+) *(p+i)=i; for(i=0;i10;i+) printf(a%d=%dn,i,*(p+i);【例10.12】main() int a10,i,*p=a; for(i=0;i10;) *p=i; printf(a%d=%dn,i+,*p+); 幾個(gè)注意的問(wèn)題:1) 指針變量可以實(shí)現(xiàn)本身的值的改變。如p+是合法的;而a+是錯(cuò)誤的。因?yàn)閍是數(shù)組名,它是數(shù)組的首地址,是常量。2) 要注意指針變量的當(dāng)前值。請(qǐng)看下面的程序。【例10.13】找出錯(cuò)誤。main() i

26、nt *p,i,a10; p=a;for(i=0;i10;i+) *p+=i; for(i=0;i10;i+) printf(a%d=%dn,i,*p+);【例10.14】改正。main() int *p,i,a10; p=a;for(i=0;i10;i+)*p+=i; p=a; for(i=0;i10;i+) printf(a%d=%dn,i,*p+);3) 從上例可以看出,雖然定義數(shù)組時(shí)指定它包含10個(gè)元素,但指針變量可以指到數(shù)組以后的內(nèi)存單元,系統(tǒng)并不認(rèn)為非法。4) *p+,由于+和*同優(yōu)先級(jí),結(jié)合方向自右而左,等價(jià)于*(p+)。5) *(p+)與*(+p)作用不同。若p的初值為a,則*

27、(p+)等價(jià)a0,*(+p)等價(jià)a1。6) (*p)+表示p所指向的元素值加1。7) 如果p當(dāng)前指向a數(shù)組中的第i個(gè)元素,則*(p-)相當(dāng)于ai-;*(+p)相當(dāng)于a+i;*(-p)相當(dāng)于a-i。10.3.3 數(shù)組名作函數(shù)參數(shù)數(shù)組名可以作函數(shù)的實(shí)參和形參。如:main()int array10; f(array,10); f(int arr,int n); array為實(shí)參數(shù)組名,arr為形參數(shù)組名。在學(xué)習(xí)指針變量之后就更容易理解這個(gè)問(wèn)題了。數(shù)組名就是數(shù)組的首地址,實(shí)參向形參傳送數(shù)組名實(shí)際上就是傳送數(shù)組的地址,形參得到該地址后也指向同一數(shù)組。這就好象同一件物品有兩個(gè)彼此不同的名稱(chēng)一樣。 同樣,

28、指針變量的值也是地址,數(shù)組指針變量的值即為數(shù)組的首地址,當(dāng)然也可作為函數(shù)的參數(shù)使用?!纠?0.15】float aver(float *pa);main() float sco5,av,*sp; int i; sp=sco; printf(ninput 5 scores:n); for(i=0;i5;i+) scanf(%f,&scoi); av=aver(sp); printf(average score is %5.2f,av);float aver(float *pa) int i; float av,s=0; for(i=0;i5;i+) s=s+*pa+; av=s/5; retur

29、n av;【例10.16】將數(shù)組a中的n個(gè)整數(shù)按相反順序存放。算法為:將a0與an-1對(duì)換,再a1與an-2 對(duì)換,直到將a(n-1/2)與an-int(n-1)/2)對(duì)換。今用循環(huán)處理此問(wèn)題,設(shè)兩個(gè)“位置指示變量”i和j,i的初值為0,j的初值為n-1。將ai與aj交換,然后使i的值加1,j的值減1,再將ai與aj交換,直到i=(n-1)/2為止,如圖所示。程序如下:void inv(int x,int n) /*形參x是數(shù)組名*/ int temp,i,j,m=(n-1)/2; for(i=0;i=m;i+)j=n-1-i; temp=xi;xi=xj;xj=temp; return;ma

30、in()int i,a10=3,7,9,11,0,6,7,5,4,2; printf(the original array:n); for(i=0;i10;i+) printf(%d,ai); printf(n); inv(a,10); printf(the array has benn inverted:n); for(i=0;i10;i+) printf(%d,ai); printf(n);對(duì)此程序可以作一些改動(dòng)。將函數(shù)inv中的形參x改成指針變量?!纠?0.17】對(duì)例10.16可以作一些改動(dòng)。將函數(shù)inv中的形參x改成指針變量。程序如下:void inv(int *x,int n) /*

31、形參x為指針變量*/ int *p,temp,*i,*j,m=(n-1)/2; i=x;j=x+n-1;p=x+m; for(;i=p;i+,j-)temp=*i;*i=*j;*j=temp; return;main()int i,a10=3,7,9,11,0,6,7,5,4,2; printf(the original array:n); for(i=0;i10;i+) printf(%d,ai); printf(n); inv(a,10); printf(the array has benn inverted:n); for(i=0;i10;i+) printf(%d,ai); print

32、f(n);運(yùn)行情況與前一程序相同?!纠?0.18】從0個(gè)數(shù)中找出其中最大值和最小值。調(diào)用一個(gè)函數(shù)只能得到一個(gè)返回值,今用全局變量在函數(shù)之間“傳遞”數(shù)據(jù)。程序如下:int max,min; /*全局變量*/void max_min_value(int array,int n)int *p,*array_end; array_end=array+n; max=min=*array; for(p=array+1;pmax)max=*p; else if (*pmin)min=*p; return;main()int i,number10; printf(enter 10 integer umbers

33、:n); for(i=0;i10;i+) scanf(%d,&numberi); max_min_value(number,10); printf(nmax=%d,min=%dn,max,min); 說(shuō)明:1) 在函數(shù)max_min_value中求出的最大值和最小值放在max和min中。由于它們是全局,因此在主函數(shù)中可以直接使用。2) 函數(shù)max_min_value中的語(yǔ)句:max=min=*array;array是數(shù)組名,它接收從實(shí)參傳來(lái)的數(shù)組numuber的首地址。*array相當(dāng)于*(&array0)。上述語(yǔ)句與 max=min=array0;等價(jià)。3) 在執(zhí)行for循環(huán)時(shí),p的初值為a

34、rray+1,也就是使p指向array1。以后每次執(zhí)行p+,使p指向下一個(gè)元素。每次將*p和max與min比較。將大者放入max,小者放min。4) 函數(shù)max_min_value的形參array可以改為指針變量類(lèi)型。實(shí)參也可以不用數(shù)組名,而用指針變量傳遞地址?!纠?0.19】程序可改為:int max,min; /*全局變量*/void max_min_value(int *array,int n)int *p,*array_end; array_end=array+n; max=min=*array; for(p=array+1;pmax)max=*p; else if (*pmin)mi

35、n=*p; return;main()int i,number10,*p; p=number; /*使p指向number數(shù)組*/ printf(enter 10 integer umbers:n); for(i=0;i10;i+,p+) scanf(%d,p); p=number; max_min_value(p,10); printf(nmax=%d,min=%dn,max,min); 歸納起來(lái),如果有一個(gè)實(shí)參數(shù)組,想在函數(shù)中改變此數(shù)組的元素的值,實(shí)參與形參的對(duì)應(yīng)關(guān)系有以下種:1) 形參和實(shí)參都是數(shù)組名。main()int a10; f(a,10) f(int x,int n) 和指的是同一

36、組數(shù)組。2) 實(shí)用數(shù)組,形參用指針變量。main()int a10; f(a,10) f(int *x,int n) 3) 實(shí)參、型參都用指針變量。4) 實(shí)參為指針變量,型參為數(shù)組名。【例10.20】用實(shí)參指針變量改寫(xiě)將n個(gè)整數(shù)按相反順序存放。void inv(int *x,int n)int *p,m,temp,*i,*j; m=(n-1)/2; i=x;j=x+n-1;p=x+m; for(;i=p;i+,j-) temp=*i;*i=*j;*j=temp; return;main()int i,arr10=3,7,9,11,0,6,7,5,4,2,*p; p=arr; printf(th

37、e original array:n); for(i=0;i10;i+,p+) printf(%d,*p); printf(n); p=arr; inv(p,10); printf(the array has benn inverted:n); for(p=arr;parr+10;p+) printf(%d,*p); printf(n);注意:main函數(shù)中的指針變量p是有確定值的。即如果用指針變作實(shí)參,必須現(xiàn)使指針變量有確定值,指向一個(gè)已定義的數(shù)組?!纠?0.21】用選擇法對(duì)10個(gè)整數(shù)排序。main()int *p,i,a10=3,7,9,11,0,6,7,5,4,2; printf(the

38、 original array:n); for(i=0;i10;i+) printf(%d,ai); printf(n); p=a; sort(p,10); for(p=a,i=0;i10;i+) printf(%d ,*p);p+; printf(n);sort(int x,int n)int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jxk)k=j; if(k!=i) t=xi;xi=xk;xk=t; 說(shuō)明:函數(shù)sort用數(shù)組名作為形參,也可改為用指針變量,這時(shí)函數(shù)的首部可以改為:sort(int *x,int n) 其他可一律不改。10.3.4 指

39、向多維數(shù)組的指針和指針變量本小節(jié)以二維數(shù)組為例介紹多維數(shù)組的指針變量。1. 多維數(shù)組的地址設(shè)有整型二維數(shù)組a34如下:0 1 2 3 4 5 6 78 9 10 11它的定義為:int a34=0,1,2,3,4,5,6,7,8,9,10,11設(shè)數(shù)組a的首地址為1000,各下標(biāo)變量的首地址及其值如圖所示。前面介紹過(guò),語(yǔ)言允許把一個(gè)二維數(shù)組分解為多個(gè)一維數(shù)組來(lái)處理。因此數(shù)組a可分解為三個(gè)一維數(shù)組,即a0,a1,a2。每一個(gè)一維數(shù)組又含有四個(gè)元素。例如a0數(shù)組,含有a00,a01,a02,a03四個(gè)元素。數(shù)組及數(shù)組元素的地址表示如下:從二維數(shù)組的角度來(lái)看,a是二維數(shù)組名,a代表整個(gè)二維數(shù)組的首地址

40、,也是二維數(shù)組0行的首地址,等于1000。a+1代表第一行的首地址,等于1008。如圖:a0是第一個(gè)一維數(shù)組的數(shù)組名和首地址,因此也為1000。*(a+0)或*a是與a0等效的, 它表示一維數(shù)組a00 號(hào)元素的首地址,也為1000。&a00是二維數(shù)組a的0行0列元素首地址,同樣是1000。因此,a,a0,*(a+0),*a,&a00是相等的。同理,a+1是二維數(shù)組1行的首地址,等于1008。a1是第二個(gè)一維數(shù)組的數(shù)組名和首地址,因此也為1008。&a10是二維數(shù)組a的1行0列元素地址,也是1008。因此a+1,a1,*(a+1),&a10是等同的。由此可得出:a+i,ai,*(a+i),&ai

41、0是等同的。此外,&ai和ai也是等同的。因?yàn)樵诙S數(shù)組中不能把&ai理解為元素ai的地址,不存在元素ai。語(yǔ)言規(guī)定,它是一種地址計(jì)算方法,表示數(shù)組a第i行首地址。由此,我們得出:ai,&ai,*(a+i)和a+i也都是等同的。另外,a0也可以看成是a0+0,是一維數(shù)組a0的0號(hào)元素的首地址,而a0+1則是a0的1號(hào)元素首地址,由此可得出ai+j則是一維數(shù)組ai的j號(hào)元素首地址,它等于&aij。由ai=*(a+i)得ai+j=*(a+i)+j。由于*(a+i)+j是二維數(shù)組a的i行j列元素的首地址,所以,該元素的值等于*(*(a+i)+j)?!纠?0.22】main() int a34=0,1

42、,2,3,4,5,6,7,8,9,10,11; printf(%d,a); printf(%d,*a); printf(%d,a0); printf(%d,&a0); printf(%dn,&a00); printf(%d,a+1); printf(%d,*(a+1); printf(%d,a1); printf(%d,&a1); printf(%dn,&a10); printf(%d,a+2); printf(%d,*(a+2); printf(%d,a2); printf(%d,&a2); printf(%dn,&a20); printf(%d,a1+1); printf(%dn,*(a+1)+1); printf(%d,%dn,*(a1+1),*(*(a+1)+1);2. 指向多維數(shù)組的指針變量把二維數(shù)組a分解為一維數(shù)組a0,a1,a2之后,設(shè)p為指向二維數(shù)組的指針變量??啥x為: int (*p)4它表示p是一個(gè)指針變量,它指向包含4個(gè)元素的一維數(shù)組。若指向第一個(gè)一維數(shù)組a0,其值等于a,a0,或&a00等。而p+i則指向一維數(shù)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論