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

下載本文檔

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

文檔簡介

1、10指針110.1地址指針的基本概念110.2變量的指針和指向變量的指針變量210.2.1定義一個指針變量310.2.2指針變量的引用310.2.3指針變量作為函數(shù)參數(shù)710.2.4指針變量幾個問題的進一步說明1010.3數(shù)組指針和指向數(shù)組的指針變量1310.3.1指向數(shù)組元素的指針1310.3.2通過指針引用數(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有關指針的數(shù)據(jù)類型和指針運算的小結(jié)3710.8.1有關指針的數(shù)據(jù)類型的小結(jié)3710.8.2指針運算的小結(jié)3710.8.3void指針類型3810 指針 指針是語言中廣泛使用的一種數(shù)據(jù)類型。運用指針編程是語言最主要的風格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu);能很方便地使用數(shù)組和字符串;并能象匯編語言一樣處理內(nèi)存地址,從而編出精練而高效的程序。指針極大地豐富了語言的功能。學習指針是學習語言中最重要的一環(huán),能否正確理解和使用指針是我們是否掌握語言的一個標志。同時,指針也是語言中最為困難的一

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

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

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

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

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

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

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

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

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

12、通過指針要訪問哪一個變量,取決于指針的值(即指向),例如*p2=*p1;實際上就是j=i;,前者不僅速度慢而且目的不明。但由于指針是變量,我們可以通過改變它們的指向,以間接訪問不同的變量,這給程序員帶來靈活性,也使程序代碼編寫得更為簡潔和有效。指針變量可出現(xiàn)在表達式中, 設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相當于+(*px)*/y=*px+; /*相當于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); 對程序的說明:1) 在開頭處雖然定義了兩個指針變量pointer_1和pointer_2,擔它們并未指向任何一個整型變量。只是提供兩個指針變量,規(guī)定它們可以指向整型變量。程序第5、6行的作用就是使pointer_1指向a,pointer_2指向b。2) 最后一行的*pointer_1和*pointer_2就是變量a和b。最后兩個printf函數(shù)作用

14、是相同的。3) 程序中有兩處出現(xiàn)*pointer_1和*pointer_2,請區(qū)分它們的不同含義。4) 程序第5、6行的“pointer_1=&a”和 “pointer_2=&b”不能寫成“*pointer_1=&a”和 “*pointer_2=&b”。請對下面再的關于“&”和“*”的問題進行考慮:1) 如果已經(jīng)執(zhí)行了“pointer_1=&a;”語句,則&*pointer_1是什么含義?2) *&a含義是什么?3) (pointer_1)+和pointer_1+的區(qū)別?【例10.2】輸入a和b兩個整數(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ù)據(jù),還可以是指針類型。它的作用是將一個變量的地址傳送到另一個函數(shù)中。【例10.3】題目同例10.2,即輸入的兩個整數(shù)按大小順序輸出。今用函數(shù)處理,而且用指針類型的數(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); 對程序的說明:swap是用戶定義的函數(shù),它的作用是交換兩個變量(a和b)的值。swap函數(shù)的形參p1、p2是指針變量。程序運行時,先執(zhí)行main函數(shù),輸入a和b的值。然后將a和b的地址分別賦給指針變量pointer_1和pointer_2,使pointer_1指向a,pointer_2指向b。接著執(zhí)行if語句,由于a

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

18、temp=*p1; /*此語句有問題*/ *p1=*p2; *p2=temp;請考慮下面的函數(shù)能否實現(xiàn)實現(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ù),會有什么結(jié)果呢?請看下圖所示?!纠?0.4】請注意,不能企圖通過改變指針形參的值而使指針實參的值改變。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); 其中的問題在于不能實現(xiàn)如圖所示的第四步(d)?!纠?0.5】輸入a、b、c3個整數(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) /*如果第一個數(shù)字大于第二個數(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ù)組的指針變量一個變量有一個地址,一個數(shù)組包含若干元素,每個數(shù)組元素都在內(nèi)存中占用存儲單元,它們都有相應的地址。所謂數(shù)組的

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

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

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

24、方法。2) 指針法,即采用*(a+i)或*(p+i)形式,用間接訪問的方法來訪問數(shù)組元素,其中a是數(shù)組名,p是指向數(shù)組的指針變量,其處值p=a?!纠?0.9】輸出數(shù)組中的全部元素。(下標法)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ù)組中的全部元素。(通過數(shù)組名計算元素的地址,找出元素的值)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+); 幾個注意的問題:1) 指針變量可以實現(xiàn)本身的值的改變。如p+是合法的;而a+是錯誤的。因為a是數(shù)組名,它是數(shù)組的首地址,是常量。2) 要注意指針變量的當前值。請看下面的程序?!纠?0.13】找出錯誤。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ù)組時指定它包含10個元素,但指針變量可以指到數(shù)組以后的內(nèi)存單元,系統(tǒng)并不認為非法。4) *p+,由于+和*同優(yōu)先級,結(jié)合方向自右而左,等價于*(p+)。5) *(p+)與*(+p)作用不同。若p的初值為a,則*

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

28、指針變量的值也是地址,數(shù)組指針變量的值即為數(shù)組的首地址,當然也可作為函數(shù)的參數(shù)使用。【例10.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個整數(shù)按相反順序存放。算法為:將a0與an-1對換,再a1與an-2 對換,直到將a(n-1/2)與an-int(n-1)/2)對換。今用循環(huán)處理此問題,設兩個“位置指示變量”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);對此程序可以作一些改動。將函數(shù)inv中的形參x改成指針變量?!纠?0.17】對例10.16可以作一些改動。將函數(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);運行情況與前一程序相同?!纠?0.18】從0個數(shù)中找出其中最大值和最小值。調(diào)用一個函數(shù)只能得到一個返回值,今用全局變量在函數(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); 說明:1) 在函數(shù)max_min_value中求出的最大值和最小值放在max和min中。由于它們是全局,因此在主函數(shù)中可以直接使用。2) 函數(shù)max_min_value中的語句:max=min=*array;array是數(shù)組名,它接收從實參傳來的數(shù)組numuber的首地址。*array相當于*(&array0)。上述語句與 max=min=array0;等價。3) 在執(zhí)行for循環(huán)時,p的初值為a

34、rray+1,也就是使p指向array1。以后每次執(zhí)行p+,使p指向下一個元素。每次將*p和max與min比較。將大者放入max,小者放min。4) 函數(shù)max_min_value的形參array可以改為指針變量類型。實參也可以不用數(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); 歸納起來,如果有一個實參數(shù)組,想在函數(shù)中改變此數(shù)組的元素的值,實參與形參的對應關系有以下種:1) 形參和實參都是數(shù)組名。main()int a10; f(a,10) f(int x,int n) 和指的是同一

36、組數(shù)組。2) 實用數(shù)組,形參用指針變量。main()int a10; f(a,10) f(int *x,int n) 3) 實參、型參都用指針變量。4) 實參為指針變量,型參為數(shù)組名。【例10.20】用實參指針變量改寫將n個整數(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是有確定值的。即如果用指針變作實參,必須現(xiàn)使指針變量有確定值,指向一個已定義的數(shù)組。【例10.21】用選擇法對10個整數(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; 說明:函數(shù)sort用數(shù)組名作為形參,也可改為用指針變量,這時函數(shù)的首部可以改為:sort(int *x,int n) 其他可一律不改。10.3.4 指

39、向多維數(shù)組的指針和指針變量本小節(jié)以二維數(shù)組為例介紹多維數(shù)組的指針變量。1. 多維數(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ù)組a的首地址為1000,各下標變量的首地址及其值如圖所示。前面介紹過,語言允許把一個二維數(shù)組分解為多個一維數(shù)組來處理。因此數(shù)組a可分解為三個一維數(shù)組,即a0,a1,a2。每一個一維數(shù)組又含有四個元素。例如a0數(shù)組,含有a00,a01,a02,a03四個元素。數(shù)組及數(shù)組元素的地址表示如下:從二維數(shù)組的角度來看,a是二維數(shù)組名,a代表整個二維數(shù)組的首地址

40、,也是二維數(shù)組0行的首地址,等于1000。a+1代表第一行的首地址,等于1008。如圖:a0是第一個一維數(shù)組的數(shù)組名和首地址,因此也為1000。*(a+0)或*a是與a0等效的, 它表示一維數(shù)組a00 號元素的首地址,也為1000。&a00是二維數(shù)組a的0行0列元素首地址,同樣是1000。因此,a,a0,*(a+0),*a,&a00是相等的。同理,a+1是二維數(shù)組1行的首地址,等于1008。a1是第二個一維數(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也是等同的。因為在二維數(shù)組中不能把&ai理解為元素ai的地址,不存在元素ai。語言規(guī)定,它是一種地址計算方法,表示數(shù)組a第i行首地址。由此,我們得出:ai,&ai,*(a+i)和a+i也都是等同的。另外,a0也可以看成是a0+0,是一維數(shù)組a0的0號元素的首地址,而a0+1則是a0的1號元素首地址,由此可得出ai+j則是一維數(shù)組ai的j號元素首地址,它等于&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之后,設p為指向二維數(shù)組的指針變量。可定義為: int (*p)4它表示p是一個指針變量,它指向包含4個元素的一維數(shù)組。若指向第一個一維數(shù)組a0,其值等于a,a0,或&a00等。而p+i則指向一維數(shù)

溫馨提示

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

最新文檔

評論

0/150

提交評論