




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第8章 指針引例:A、B、C、三人欲借用某旅館的房間。A先到達(dá)旅館,在服務(wù)臺登記了房間,房間號是5818。然后,A電話通知了B,但沒有通知C,B和C怎樣找到A呢?B可以直接到5818找到A(直接訪問)。C可以從旅館的服務(wù)臺查詢到A的房間號5818,再找到A。(間接訪問)8.1 指針和地址一、變量的地址計(jì)算機(jī)中,數(shù)據(jù)存儲在內(nèi)存中。內(nèi)存可劃分為若干存儲單元,每個(gè)單元可以存放8位二進(jìn)制數(shù),即一個(gè)字節(jié)。內(nèi)存單元采用線性地址編碼,每個(gè)單元具有唯一一個(gè)地址編碼。1、變量地址:系統(tǒng)為變量分配的內(nèi)存單元的地址。(一個(gè)無符號整型數(shù))int a;float b;a=3;b=5 3 53AB03AB82、變量的有關(guān)
2、概念存儲內(nèi)容:數(shù)據(jù)值空間大?。簲?shù)據(jù)類型空間位置:地址生存周期:存儲類別二、變量的訪問方式1、直接訪問2、間接訪問 3AB0 3AB8 3 5 3AB8如何定義P?如何獲得變量b的地址?如何通過P訪問b?abp8.2指針變量8.2.1指針變量的定義一、定義方法類型符 *指針變量名如:int *p1 ,*p2 ;char *ps; float *pf1,*pf2;指針變量的類型:所指向的內(nèi)存中存放的數(shù)據(jù)的類型。二、注意事項(xiàng)(1)必須先定義后使用;(2)指針變量名是p1,p2,而不是*p1,*p2;(3)一個(gè)指針變量只能指向同類型的變量;(4)定義指針變量時(shí),不僅要定義指針變量名,還必須指出指針變量
3、所指向的變量的類型.8.2.2指針變量的賦值指針變量的值為地址,是一個(gè)無符號整數(shù)。但不能直接將整型常量賦給指針變量。P1=12345u.(1)用變量的地址給指針變量賦值(求地址運(yùn)算符&)如:int a,b,*p;p=&a;注意:變量的類型必須與指針變量的相同。(2)用相同類型的指針變量賦值。如:int a;int *p1,*p2;p1=&a;p2=p1;注意:若不賦值,則指針變量的值是隨機(jī)的。(3)賦空值NULL如:P=NULL;或P=0;例8-1通過指針變量訪問整型變量.#include void main( ) int x; int *p1;x=8;p1=&x;printf(“%dn”,x
4、);printf(“%dn”,*p1);例8-2通過指針變量求兩個(gè)整數(shù)的和與積.#include void main( ) int i=100,b=200,s,t,*pi,*pb;pi=&i;pb=&b;s=*pi+*pb;t=*pi*pb;printf(“i=%dnb=%dni+b=%dni*b=%dn”,i,b,i+b,i*b);printf(“s=%dnt=%dn”,s,t);例8-3通過指針變量求三個(gè)整數(shù)中的最大數(shù)和最小數(shù).#include void main( ) int a,b,c,*pmax,*pmin;printf(input three numbers:n);scanf(%d
5、%d%d,&a,&b,&c);if(ab)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);8.2.3指針運(yùn)算符和指針表達(dá)式1、兩個(gè)相關(guān)的運(yùn)算符:*,&形式:&任意變量 /*取地址運(yùn)算符*/ *指針變量 /*指針運(yùn)算符*/含義:&a表示變量a所占據(jù)的內(nèi)存空間的首地址. *p表示指針變量p所指向的內(nèi)存中的數(shù)據(jù).應(yīng)用:通過指針變量訪問所指變量.將指針變量指向被訪問的變量.如:int a=5,*p,b;p=&a;訪問所指變量取內(nèi)容:
6、b=*p;printf(“%dn”,*p);存內(nèi)容:*p=100; 2、運(yùn)算規(guī)則 *,&:優(yōu)先級相同,且右結(jié)合 注意:與+,-,!等單目運(yùn)算符的優(yōu)先級相同,高于算術(shù)運(yùn)算符*,/,%。 如有:void main ( ) int a=2,*p=&a,*q=&a; printf(%d,%dn,*p+,*(q+); p=&a;q=&a; printf(%d,%dn,*p,(*q)+); printf(%d,%dn,*p,+*q); 結(jié)果是:2,2 2,2 4, 4 寫出下面表達(dá)式的結(jié)果,并找出具有等價(jià)關(guān)系的對子 int a=5,*p=&a; &*p *&a (*p)+ &a a *p+ *(p+) a
7、+思考:下列表達(dá)式是何含義?有什么要求?&*p,*&a8.2.4指針變量引用*指針變量例8-4 用指針變量進(jìn)行輸入和輸出.void main( ) float *pi,x;scanf(“%f”,&x);pi=&x;printf(“%f”,*pi);例8-5:#include void main()int a=5,b=3;int *p;p=&a; /*指針變量賦值*/b=*p+5;printf(%dn,b);*p=4;printf(%d,%dn,a,*p);結(jié)果:10 4,4注意:*p若出現(xiàn)在 “=“的右邊或其它表達(dá)式中,則為取內(nèi)容. *p若出現(xiàn)在 “=“的左邊則為存內(nèi)容&a&b95p2p1ba
8、&b&a95p2p1ba改為:c=a;a=b;b=c;&a&b59p2p1ba程序中改變的是指針變量的值,而變量本身沒變化;相當(dāng)只調(diào)整房間號,而未驚動客人例.8-6 輸入a和b兩個(gè)整數(shù),按先大后小的順序輸出#include void main()int *p1,*p2,*p,a,b;scanf(%d,%d,&a,&b);p1=&a;p2=&b;if (ab)p=p1,p1=p2,p2=p;printf(a=%d,b=%dn,a,b);printf(max=%d,min=%d,*p1,*p2);運(yùn)行結(jié)果:5,9a=5,b=9max=9,min=5例8-7讀程序#include void main
9、( )int a,b,c;int *pa,*pb,*pc;pa=&a;pb=&b;pc=&c;scanf(%d%d,pa,pb);printf(a=%d,b=%dn,*pa,*pb);c=a+b; printf(c=%dn,*pc);*pc=a+*pb; printf(c=%dn,c);c=*pa*pb; printf(c=%dn,c);c=+*pa+(*pb)+; printf(c=%dn,c);c=(*pa)+ +*pb; printf(c=%dn,c);printf(a=%d,b=%dn,a,b);結(jié)果:例:交換a,b兩個(gè)數(shù)#include void main( ) int a=5,b=
10、8; int t;printf(a=%db=%dn,a,b);t=a;a=b;b=t;printf(a=%d b=%dn,a,b);例:交換a,b兩個(gè)數(shù)#include void main( ) int a=5,b=8; int *pa=&a,*pb=&b; int t;printf(a=%d b=%dn,a,b);t=*pa;*pa=*pb;*pb=t;printf(a=%d b=%dn,a,b);8.2.5 指針變量作為函數(shù)參數(shù)主函數(shù)的實(shí)參與函數(shù)中的形參均為指針變量,互相傳遞的是指針變量,屬“單向地址值傳遞 ”.在被調(diào)函數(shù)中,如果改變的是變量,則影響主函數(shù) 若改變的是指針的指向,則不影響主
11、函數(shù)以前未用指針變量時(shí),函數(shù)調(diào)用時(shí),實(shí)參與形參相當(dāng)于不同房間住著相同的人,彼此互不影響,只從被調(diào)函數(shù)返回一個(gè)值return59959abcxy例如例如指針變量作函數(shù)參數(shù)時(shí),主函數(shù)可以從被調(diào)函數(shù)得到多個(gè)返回值,函數(shù)可以不要return()語句了。方法:1.在主函數(shù)中設(shè)n個(gè)變量, 用n個(gè)指針變量指向它們;2.然后將指針變量作為實(shí)參,將這n個(gè)變量的地址傳給被調(diào)函數(shù)的形參;3.通過形參指針變量,改變這n個(gè)變量的值;4.主函數(shù)中就可以使用這些改變了值的變量;例子8.3指針與數(shù)組8.3.1指向數(shù)組的指針1、數(shù)組是連續(xù)存放的若干元素的集合;2、數(shù)組名就是指向此數(shù)組第一個(gè)元素的指針(首地址);如:int a
12、=1,3,5,7;int *p;p=a;3、某個(gè)元素的地址:p=&a0用指針引用該元素:*p等價(jià)于ai4、數(shù)組元素的地址在內(nèi)部實(shí)現(xiàn)時(shí),統(tǒng)一按“基地址+位移”的方式處理。即a,a+1,a+i1357&a0pa0a1a2a3故表示數(shù)組元素的地址可以用:p+i,a+i表示數(shù)組元素的內(nèi)容可以用:ai、*(p+i)、*(a+i)注意:數(shù)組名a(數(shù)組的指針)與指向數(shù)組首地址的指針變量p不同,a不是變量。例8-10讀程序,寫出結(jié)果。 void main( )int i,a5;int *p;for(i=0;i5;i+)p=&ai;ai=i;printf(%3d,*p);printf(n);結(jié)果:0 1 2 3
13、 4 void main( )int i,a5;int *p=a;for(i=0;i5;i+,p+)*p=i;printf(%3d,*p);printf(n);結(jié)果:0 1 2 3 4 地址關(guān)系 內(nèi)容關(guān)系8.3.2 通過指針引用數(shù)組元素?cái)?shù)組指針、指針變量與數(shù)組元素之間的關(guān)系。設(shè)int a10,*p=a;則&a0a0a1a2a3*a*(a+1)*(a+2)*(a+3)*p*(p+1)*(p+2)*(p+3)&a1&a2&a3pp+1p+2p+3aa+1a+2a+3p0p1p2p3例8-11任意輸入10個(gè)數(shù),將這十個(gè)數(shù)按逆序輸出(1)用下標(biāo)法訪問數(shù)組#include void main()int
14、a10,i;for(i=0;i=0;i-)printf(%d ,ai);(2)用數(shù)組名訪問數(shù)組#include void main()int a10,i;for(i=0;i=0;i-)printf(%d ,*(a+i);(3)用指針變量指向數(shù)組元素方法一:#include void main()int a10,i,*p;for(i=0;i=0;i-)printf(%d ,*(p+i);方法二:#include void main()int a10,i,*p;p=a;for(i=0;i=a;p-)printf(%d ,*p);上述三種方法的比較: 例8-11中,和(3)中的“方法一”執(zhí)行效率是相
15、同的,編譯系統(tǒng)需要將ai轉(zhuǎn)換成*(a+i)處理的,即先計(jì)算地址再訪問數(shù)組元素。“方法二”執(zhí)行效率比其它方法快,因?yàn)樗幸?guī)律地改變地址值的方法(p-)能大大提高執(zhí)行效率。 要注意指針變量的當(dāng)前值。幾個(gè)要注意的問題: int a10=1,2,3,4,5,6,7,8,9,10, *p; for (p=a;a(p+10);a+) printf (%dn,*a); int a10=1,2,3,4,5,6,7,8,9,10, *p=a; for (;p(a+10);p+) printf (%dn,*p); 指針變量(p)值自身可以改變,但數(shù)組名(a)不能。p是一個(gè)指針變量,p+ +合法;而a是一個(gè)數(shù)組名,
16、是常量,a+ +不合法。要注意指針變量的當(dāng)前值;如void main() int *p,i,a10; p=a;for (i=0;i10;i+ +) scanf(“%d”,p+); for (i=0;i10;i+ +,p+) printf(“%d”,*p); 試分析此程序錯(cuò)在哪里?執(zhí)行完第一個(gè)循環(huán),p已指向數(shù)組的末尾了。如:有p=a;后a+1與p+1指向同一個(gè)地址;當(dāng)有p=b;后a+1與p+1指向不同地址。p=a;指針變量的運(yùn)算p=a p+ + ;p=p+1 或p+=1, p指向a1等效*(p+),取出p指向的元素的值,p指向下一元素例如*(+p), 先p指向下一元素取出p指向的元素的值,例如取
17、出p指向的元素的值,p指向的元素加1(*p)+ +*p+ + ;*(+p)如果p當(dāng)前指向a 數(shù)組的第i個(gè)元素。則:*(p-)相當(dāng)于 ai-*(+p) 相當(dāng)于 a+i*(-p) 相當(dāng)于 a-i想輸出a數(shù)組100個(gè)元素p=a;while(pa+100)printf(%d,*p+);p=a; while(pa+100) printf(%d,*p); p+;例8-12將數(shù)組a的數(shù)據(jù)復(fù)制到數(shù)組b中并輸出。(用三種方法實(shí)現(xiàn))#define M 7void main( )int i,aM=23,15,50,3,21,20,35;int bM; for(i=0;iM;i+) bi=ai;printf(“out
18、put these numbers:n”);for(i=0;iM;i+)printf(“%dn”,bi);printf(“n”,) 例8-12將數(shù)組a的數(shù)據(jù)復(fù)制到數(shù)組b中并輸出。#define M 7Void main( )int i,aM=23,15,50,3,21,20,35;int bM;int *p=a,*q=b; for(i=0;iM;i+) *q=*p;q+;p+;printf(“output these numbers:n”);for(i=0;iM;i+)printf(“%dn”,bi);Printf(“n”,) 例8-12將數(shù)組a的數(shù)據(jù)復(fù)制到數(shù)組b中并輸出。#define M
19、7void main( )int i,aM=23,15,50,3,21,20,35;int bM;int *p=a,*q=b; for(i=0;iM;i+) *q+=*p+;printf(“output these numbers:n”);for(i=0;iM;i+)printf(“%dn”,bi);printf(“n”,) printf(“%d”,*q+);8.3.3 數(shù)組名作為函數(shù)參數(shù)數(shù)組名作為函數(shù)參數(shù),實(shí)參和形參可歸納為以下四種情況實(shí)參和形參都用數(shù)組名int f(int x,int n) void main()int array10;f(array,10);實(shí)參用數(shù)組名,形參用指針變量i
20、nt f(int *x,int n) void main()int array10;f(array,10);實(shí)參用指針變量,形參用數(shù)組名int f(int x,int n) void main()int array10,*p=array;f(p,10);實(shí)參和形參都用指針變量int f(int *x,int n) void main()int array10,*p=array;f(p,10);說明:數(shù)組元素作函數(shù)參數(shù),與一般變量相同,是“單向值傳遞”數(shù)組名作函數(shù)參數(shù),是“單向地址傳遞”即實(shí)參數(shù)組與形參數(shù)組對應(yīng)內(nèi)存中同一個(gè)數(shù)組,調(diào)用時(shí)實(shí)參將數(shù)組首地址傳給形參。 數(shù)組名及指向數(shù)組的指針變量作函數(shù)參
21、數(shù),其作用是一樣的。數(shù)組名是可以即用的,而指針變量必須賦值后才能使用。實(shí)參與形參有4種對應(yīng)關(guān)系。例如例8-14用選擇法對10個(gè)整數(shù)按從大到小排序(用指針法)#include void sort(int *p,int n) int i, j, k, t; for(i=0;in-1;i+) k=i; for(j=i+1;j*(p+k) k=j; if(k!=i) t=*(p+i); *(p+i)=*(p+k); *(p+k)=t; void main()int *p, i, a10; p=a; for(i=0;i10;i+) scanf(%d,p+); p=a; sort(p,10); for(p
22、=a,i=0;i10;i+) printf(%5d,*p); p+; 【例8-15】將數(shù)組a中前n個(gè)元素按相反順序存放。 #include void inv(int *x,int n )int *i,*j,temp;for(i=x,j=x+n-1;ij;i+,j-)temp=*i;*i=*j;*j=temp;void main() int i,n,a10=2,4,6,8,10,12,14,16,18,20;int *p;printf(the original array:n);for(i=0;i10;i+)printf(%d,ai);printf(n);p=a; /*給實(shí)參指針變量p賦值*/p
23、rintf(input to n:n);scanf(%d,&n);inv(p,n); /*實(shí)參p為指針變量*/printf(the array after invented:n);for(p=a;pa+10;p+)printf(%d,*p);printf(n);8.3.4 指向多維數(shù)組的指針和指針變量1.多維數(shù)組的地址以二維數(shù)組為例,說明多維數(shù)組的地址: int s34=1,3,5,7,2,4,6,8,9,1,0,1;1 3 5 72 4 6 89 1 0 1s0s1s2s135724689101s0s1s2s此二維數(shù)組可以看作三個(gè)一維數(shù)組s為二維數(shù)組的首地址s0或*s為第一個(gè)一維數(shù)組的首地址
24、s00或*(*s+0)為第一個(gè)一維數(shù)組的第一個(gè)元素某行地址某元素地址某元素值s(二維數(shù)組名,數(shù)組首地址,0行首地址)s+0;s0;&s0(第0行首地址)&s00;s0+0;*(s+0)(第0行第0列)s00;*(s0+0);*(*(s+0)(第0行第0列元素值)s+1;s1;&s1(第1行首地址)&s10;s1+0;*(s+1)(第1行第0列)s10;*(s1+0);*(*(s+1)(第1行第0列元素值)s+2;s2;&s2(第2行首地址)&s20;s2+0;*(s+2)(第2行第0列)s20;*(s2+0);*(*(s+2)(第0行第0列元素值)s+i;si;&si(第2行首地址)&sij;
25、si+j;*(s+i)+j(第i行第j列)sij;*(si+j);*(*(s+i)(第0行第0列元素值)行轉(zhuǎn)列的概念表8-1 二維數(shù)組的指針表示形式表示形式含義地址s二維數(shù)組名,數(shù)組首地址,0行首地址2000s0,*(s+0),*s第0行第0列元素地址2000s+1,&s1第1行首地址2008s1,*(s+1)第1行第0列元素地址2008s1+2,*(s+1)+2,&s12第1行第2列元素地址2012*(s1+2),*(*(s+1)+2),s12第1行第2列元素的值數(shù)值5試分析下面程序,以加深對多維數(shù)組地址的理解。 #include #include void main()int s34= 0
26、,2,4,6,1,3,5,7,9,10,11,12;printf(%#x,%#xn,s,*s);printf(%#x,%#xn,s0,*(s+0);printf(%#x,%#xn,&s0,(s+0);printf(%#x,%#xn,s1,*(s+1);printf(%#x,%#xn,&s10,*(s+1)+0);printf(%#x,%#xn,s2,*(s+2);printf(%d,%dn,s10,*(*(s+1)+0);2. 指向多維數(shù)組的指針變量(1)指向數(shù)組元素的指針變量:例8-16#include void main() int a34=1,3,5,7,9,11,13,15,17,19
27、,21,23; int *p; for ( p=a0;pa0+12;p+) if(p-a0)%4=0) printf (n); printf(%4d, *p); 說明:若要輸出某個(gè)指定的數(shù)組元素,如a12,用指針如何實(shí)現(xiàn),則必須計(jì)算出該元素在數(shù)組中的相對位置。計(jì)算aij在數(shù)組中的相對位移量的公式為:i*m+j,如a12的相對位移量為:1*4+2=6,用指針則p+6即為a12的地址。(2)指向由m個(gè)數(shù)組成的一維數(shù)組的指針變量int a34; int (*p)4;p=a;1 3 5 72 4 6 89 1 0 1p+1pP為指針變量名例8-17 輸出二維數(shù)組任一行任一列元素的值#include v
28、oid main()int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4; int i,j;p=a; scanf (i=%d,j=%d,&i,&j); printf (a%d,%d=%dn,i,j,*(*(p+i)+j); 說明:p+2和*(p+2)具有相同的值, (p+2)+3 和*(p+2)+3的值就不同了。3.多維數(shù)組的指針作函數(shù)參數(shù) 例8-18有一個(gè)班,3個(gè)學(xué)生,各學(xué)4門課,計(jì)算總平均分?jǐn)?shù),及第n個(gè)學(xué)生的成績#include void main() void ave(float *p,int m);void search(float (*p
29、)4 ,int n);float score34=65,66,67,68,78,79,80,81,66,67,68,69;int n;ave(*score,12);printf(enter a number to n:n);scanf(%d,&n);search(score,n);void ave(float *p,int m) float *end=p+m;float aver=0;for(;pend;p+)aver=aver+*p;aver=aver/m;printf(Average=%6.2fn,aver);void search(float (*p)4 ,int o) int i; f
30、or(i=0;i4;i+) printf(%6.2f,*(*(p+o)+i);8.4指針與字符串1.字符數(shù)組將字符串的各字符(包括結(jié)尾標(biāo)志0)依次存放到字符數(shù)組中,利用下標(biāo)變量或數(shù)組名對數(shù)組進(jìn)行操作。【例8-19】 字符數(shù)組應(yīng)用#include void main()char str=I am a boy.;printf(%sn,str);運(yùn)行結(jié)果I am a boy.程序說明字符數(shù)組str長度為空,默認(rèn)的長度是字符串中字符個(gè)數(shù)外加結(jié)尾標(biāo)志,如上例str數(shù)組長度應(yīng)該為12。str是數(shù)組名,它表示字符數(shù)組首地址,str+3表示序號為3的元素的地址,它指向m。str 3,*(str+3)表示數(shù)組中
31、序號為 3的元素的值(m)。字符數(shù)組允許用%s格式進(jìn)行整體輸出。2.字符指針對字符串而言,也可以不定義字符數(shù)組,直接定義指向字符串的指針變量,利用該指針變量對字符串進(jìn)行操作?!纠?-20】字符指針應(yīng)用#include void main()char *str=I am a teacher.;printf(%sn,str);例8-21 輸入兩個(gè)字符串,比較是否相等,相等輸出YES,不等輸出NO.#include stdio.h#include string.hvoid main( )int t=0;char *s1,*s2;char str120,str220;s1=str1;s2=str2;g
32、ets(s1);gets(s2);while(*s1!=0&*s2!=0)if(*s1!=*s2) t=1;break;s1+;s2+;if(t=0) printf(YES);else printf(NO);(1) 用字符數(shù)組作函數(shù)參數(shù)。例8-23復(fù)制字符串#include stdio.hvoid copy_string(char from, char to) int i=0;while(fromi!=0) toi=fromi;i+;toi=0; void main()char a=I am a teacher.; char b=you are a student.; printf (stir
33、ng a=%snstring b =%sn,a,b); copy_string(a,b);printf (stirng a=%snstring b =%sn,a,b);8.4.2字符串指針作函數(shù)參數(shù)void main()char str1=I am a teacher.; char str2=you are a student.,*a=str1,*b=str2; printf (stirng a=%snstring b =%sn,a,b); copy_string(a,b); printf (stirng a=%snstring b =%sn,a,b);(2)形參用字符指針變量#include
34、 void copy_string(char *from, char *to) for (;*from !=0;from+,to+) *to=*from; *to=0;void main()char str1=I am a teacher.; char str2=you are a student.,*a=str1,*b=str2; printf (stirng a=%snstring b =%sn,a,b); copy_string(a,b); printf (stirng a=%snstring b =%sn,a,b);例8-22 寫一函數(shù)判斷一個(gè)字符串是否為回文。(順讀與逆讀相同)算法:
35、1、令q指向最后一個(gè)字符2、若*p=*q,則兩指針向里靠攏,直到p=q,則return 1,否則,return 0;int ishuiwen(char *p)int ishuiwen(char *p)char *q=p; char *q=p;while (*q!=0)q+; while (*q)q+; q-;q-;while(pq)while(pq)if(*p=*q)p+;q-;if(*p+!=*q-)else return 0;return 0;return 1; return 1;【例8-23】將輸入字符串中的大寫字母改成小寫字母,然后輸出字符串。 #include stdio.h#inc
36、lude string.hvoid inv(char *s)int i;for(i=0;i=A & *(s+i)=Z)*(s+i)+=32;void main()char str10,*string=str;gets(string);inv(string);puts(string);因?yàn)樽址且粋€(gè)整體,故只要指出字符串在內(nèi)存中的首地址,無論采用數(shù)組名或指針變量,均可以訪問字符串的全部成員,直到遇“0”為止。str1或*(str+1)均表示第1個(gè)字符數(shù)值型數(shù)組只能逐個(gè)元素引用,不能企圖用數(shù)組名來輸出全部元素。 字符串可以全部引用(用%s格式),也可以訪問每一個(gè)元素(用%c格式)。設(shè)一個(gè)指針變量
37、,通過改變它的值來指向不同的字符串。說明:8.4.3字符指針變量與字符數(shù)組的比較存儲的內(nèi)容不同:字符數(shù)組可以存字符串,存的是字符;字符指針變量存的是字符串在內(nèi)存的首地址。賦值方式不同字符數(shù)組只能對各個(gè)元素賦值;字符指針變量只賦值一次,賦的是地址。如:char a10,*p; p=“china”; a=“hello”當(dāng)沒有賦值時(shí): 字符數(shù)組名代表了一個(gè)確定的地址;字符指針變量中的地址是不確定的。如:char a10,*p; scanf(“%s”,a) scanf(“%s”,p)字符數(shù)組名不是變量,不能改變值; 字符指針變量可以改變值。如:a+; p+;可以象數(shù)組那樣用下標(biāo)形式引用指針變量所指字符
38、串的字符。如:char *p=“abcd”;putchar(p3);p2=x;用指針變量指向一個(gè)格式字符串;char *format;format=“a=%d,b=%fn”;printf(format,a,b);也可以用字符數(shù)組實(shí)現(xiàn)。如:char format=“a=%d,b=%fn”;printf(format,a,b);但不能:char format; format=“a=%d,b=%fn”; printf(format,a,b);8.5 指針和函數(shù)8.5.1 函數(shù)的指針一個(gè)函數(shù)在調(diào)用時(shí)被分配一個(gè)入口地址,即函數(shù)指針,可以定義一個(gè)指向函數(shù)的指針變量來指向它。一、定義指向函數(shù)的指針變量基類型
39、 (*指針變量名)(); 例如:int (*p)( )為一個(gè)指向函數(shù)的指針變量;二、將指針變量指向某函數(shù)指針變量名=函數(shù)名;三、利用指向函數(shù)的指針變量調(diào)用函數(shù)(*指針變量名)(實(shí)參表)例說明:(1)定義的形式:數(shù)據(jù)類型(*指針變量名)();(2) 函數(shù)的調(diào)用可以通過函數(shù)名調(diào)用,也可以通過函數(shù)指針調(diào)用。(3) (*p)()表示定義一個(gè)指向函數(shù)的指針變量,它并不固定指向哪一個(gè)函數(shù)的。(4) 給函數(shù)指針變量賦值時(shí),只需給出函數(shù)名而不必給出參數(shù)。p=max;(5) 用指針變量調(diào)用函數(shù)時(shí),只需將(*p)代替函數(shù)名。c=(*p)(a,b);(6) p+n, p+, p-無意義8.5.2 用指向函數(shù)的指針變
40、量作函數(shù)參數(shù)指向函數(shù)的指針是很有用的,理由有2:第一、我們不可能把函數(shù)本身當(dāng)成參數(shù)傳給另一個(gè)函數(shù),但可以把指針當(dāng)作參數(shù)。第二、我們不可能把函數(shù)本身存入數(shù)組或結(jié)構(gòu)體中,卻可以把函數(shù)指針存入數(shù)組或結(jié)構(gòu)體中。用函數(shù)指針可以設(shè)計(jì)所謂的派遣(dispatch)表,有一個(gè)index變量1,2.5,如index為1時(shí)執(zhí)行fn1,其余類推。要實(shí)現(xiàn)這一功能,通常要一大堆if或switch語句測試index的值。用指向函數(shù)的指針可使程序大為簡化。int (*fn0)(),(*fn1)(),(*fn2)(),(*fn3)(),(*fn4)(),(*fn5)(), static int (*disptach)()=
41、fn0,fn1,fn2,fn3,fn4,fn5 . (*disptachindex)();【例8.24】編制函數(shù)func,在調(diào)用它的時(shí)候,每次實(shí)現(xiàn)不同的功能。對于給定的兩個(gè)數(shù)a和b,第一次調(diào)用func時(shí)找到a和b中的大數(shù);第二次調(diào)用process時(shí)找到x和y中的小數(shù);第三次調(diào)用func時(shí)返回a和b的和。#include int max(int,int);int min(int,int);int add(int,int);void func(int a,int b,int (*fun)(int,int);void main() int x,y;printf(Enter two number to
42、 a and b:);scanf(%d,%d,&x,&y);printf(max=);func (x,y,max);printf(min=);func (x,y,min);printf(sum=);func (x,y,add);max(int a,int b) int c;c=(ab)?a:b;return(c);min(int a,int b) int z;z=(ab)?a:b;return(z);add(int a,int b) int c;c=a+b;return(c);/*函數(shù)定義,參數(shù)fun是指向函數(shù)的指針,該函數(shù)有兩個(gè)整型形式,函數(shù)類型是整型*/ void func(int a,i
43、nt b, int (*fun)(int,int) int result;result=(*fun)(a,b);printf(%dn,result);8.5.3返回指針值的函數(shù)類型名函數(shù)名(參數(shù)名)int *a(x,y); 表示一個(gè)返回指向整型變量的指針的函數(shù)【例8.25】以下函數(shù)把兩個(gè)整數(shù)形參中較大的那個(gè)數(shù)的地址作為函數(shù)值傳回。#include void main()int *maxc(int,int);/*函數(shù)說明*/ int *p,i,j; printf(Enter two number to i,j:); scanf(%d,%d,&i,&j); p=maxc(i,j);/*調(diào)用函數(shù)fu
44、n,返回最大數(shù)的地址賦值指針變量p*/ printf(max=%d,*p);int *maxc(int x,int y)/* 定義返回值為整型指針的函數(shù)maxc */int *z; if(xy) z=&x; else z=&y; return(z);8.6.1指向指針的指針指向指針的指針:一個(gè)變量中存放的是一個(gè)指針變量的地址。#include void main()int i=2;int *p1;p1=&i ; int *p2;p2=&p1;printf(%dn,i);printf(%#xn,p1);printf(%#xn,p2); printf(%dn,*p1);printf(%dn,*p2
45、);8.6 指向指針的指針8.6.2 指針數(shù)組類型名數(shù)組名數(shù)組長度一個(gè)數(shù)組,其元素均為指針類型數(shù)據(jù).例如: int * name4 ;試比較:int a4;它適合于用來指向若干個(gè)字符串,使字符串處理更方便;比用字符數(shù)組節(jié)省空間;指針數(shù)組的元素也可以指向整型或?qū)嵭蛿?shù)據(jù)例8.26 #include void main()int a5=1,3,5,7,9;int *num5=&a0,&a1,&a2,&a3,&a4;int *p,i;p=num; for(i=0;i5;i+) printf (%dt, *p); p+;Follow meBASICGreat WallFORTRANComputer de
46、signname0 name1 name2 name3 name41000p20002010201620272035printf(%#xt,name);printf(%#xt,*name);printf(%ct,*name); printf(%#xt,name2);printf(%st,name2);printf(%ct,*(name2+6);p=name+2;printf(%#xt,*p);printf(%st,*p);printf(%ct,*(*p+6);printf(n);指針的指針#include void main()char *name5,*p;char str520=Follow
47、 me,BASIC,Great Wall,FORTRAN,Computer design;int i;for(i=0;i5;i+)namei=stri;printf(%#xt,name);printf(%#xt,*name);printf(%ct,*name); printf(%#xt,name2);printf(%st,name2);printf(%ct,*(name2+6);p=name+2;printf(%#xt,*p);printf(%st,*p);printf(%ct,*(*p+6);printf(n);【例8.27】指針數(shù)組的應(yīng)用#include void main() char
48、*name=C Program,BASIC,Computer,English,Word;char *p;for(p=name;pname+4;p+)printf(%sn,*p);運(yùn)行結(jié)果:C Program BASICComputer EnglishWord例8.28 將若干字符串按字母(由小到大)順序輸出#include #include void main()void sort(char *name,int n); void print (char *name,int n);char *name=follow, basic, great wall, fortran, computer de
49、sign;int n=5;sort(name,n);print (name,n);void print (char *name,int n) int i; for(i=0;in;i+) printf(%sn,namei);void sort (char *name ,int n)char *temp;int i,j,k;for (i=0;in-1;i+) k=i; for(j=i+1; j0) k=j; if (k!=i) temp=namei;namei=namek;namek=temp; 8.6.3 指針數(shù)組作main函數(shù)的形參例如:main (int argc,char * argv)由
50、于main函數(shù)是由系統(tǒng)調(diào)用的,故形參值應(yīng)由系統(tǒng)提供,即實(shí)參是和命令一起給出的。命令名 參數(shù)1 參數(shù)2 參數(shù)3 .比如: file1 China Beijing Baoding argc: 命令行參數(shù)的個(gè)數(shù)(包括命令名),本例 argc 為 4argv:為指針數(shù)組,它指向命令行中的字符串B a o d i n g 0f i l e 1 0B e i j i n j 0C h i n a 0#include void main (int argc,char *argv)while (argc1)+argv; printf (%sn, *argv); -argc; File1 China Beiji
51、ng China Beijing 作業(yè):1、編一程序,首先將一個(gè)包含10個(gè)數(shù)的數(shù)組按照升序排列,然后將從一指定位置m開始的n個(gè)數(shù)按照逆置后重新排列,并將新生成的數(shù)組輸出。要求使用指針控制方法實(shí)現(xiàn)上述功能。2、選修某課程的學(xué)生有5人,學(xué)生的信息包括學(xué)號、姓名和成績,按成績高低對學(xué)生排序,輸出排序后的學(xué)生信息。從鍵盤輸入一學(xué)生姓名,查出其成績和成績等級。(用指向指針的指針處理學(xué)生的姓名、學(xué)號)第8章結(jié)束&a&a&b&b95bapoint2point1p2p1&a&a&b&b59bapoint2point1p2p1例. 8-8輸入兩個(gè)整數(shù)按大小順序輸出swap(int *p1,int *p2)int
52、 p ;p=*p1 ;*p1=*p2 ;*p2=p ;main()int a,b ;int *point1,*point2;scanf(“%d,%d”,&a,&b);point1=&a;point2=&b;if (ab) swap(point1,point2);printf(“n%d,%d”,a,b) ;swap(int *p1,int *p2)int *temp ;*temp=*p1 ;*p1=*p2 ;*p2=*temp ;swap(int x,int y) int temp ;temp=x ;x=y ;y=temp ;swap(a,b);結(jié)果:5,99,5此時(shí)temp無確定的指向 int
53、 *temp,x;temp=&x;6556&a&a&b&b95bapoint2point1p2p1&b&a&a&b95bapoint2point1p2p1不能企圖通過改變指針形參的值而使指針實(shí)參的值改變swap(int *p1,int *p2)int *p ;p=p1 ; p1=p2 ;p2=p ;main()int a,b ;int *point1,*point2;scanf(“%d,%d”,&a,&b);point1=&a;point2=&b;if (ab) swap(point1,point2);printf(“n%d,%d”,a,b) ;例8-13編寫一函數(shù)求一維數(shù)組的最大元素及下標(biāo)位
54、置(要求使用指針)已知:數(shù)組首地址p,元素個(gè)數(shù)n;結(jié)果:下標(biāo)k#include int max_array(int *p,int n)int k=0,max=*p,i;for(i=0;imax)max=*(p+i);k=i;return k;void main( )int a10=23,43,52,23,5,22,33,35,96,34;int i,*p=a,k;for(i=0;i10;i+)printf(%5d,*(p+i);k=max_array(a,10);printf(nmax=a%d=%dn,k,*(p+k); 一般函數(shù)調(diào)用方法#include void main() int max
55、(int *p);int i,m,a10;for(i=0;i10;i+)scanf(%d,&ai);m=max(a);printf(max=%d,m);max(int *p)int i,t=*p;for(i=1;it) t=*(p+i);return (t);定義指向函數(shù)的指針變量調(diào)用函數(shù)的方法void main()int max(int *p);int i,m,a10; int (*f)(int *p); for(i=0;i10;i+) scanf(%d,&ai); f=max; m=(*f)(a); printf(max=%d,m);int max(int *p)int i,t=*p; f
56、or(i=1;it) t=*(p+i);return (t);*p+ 的使用 #include void main() int a5=2,3,4,5,6; int *p=a,c; c=*p+; printf(%d,%dn,c, *p); 結(jié)果:3,3#include void main()int a5=2,3,4,5,6; int *p=a,c; c=*(+p); printf(%d,%dn,c, *p); 結(jié)果:2,3例8-9輸入a、b、c 3個(gè)整數(shù),按大小順序輸出swap(int *pt1,int *pt2) int temp; temp=*pt1;*pt1=*pt2;*pt2=temp;
57、exchange (int *q1,int *q2,int *q3)if (*q1*q2) swap(q1,q2);if (*q1*q3) swap(q1, q3);if (*q2*q3) swap(q2, q3);void main() int a,b,c,*p1,*p2,*p3;scanf(%d,%d,%d,&a,&b,&c);p1=&a,p2=&b;p3=&c;exchange(p1,p2,p3);printf (n%d,%d,%dn,a,b,c);運(yùn)行結(jié)果:9,0,1010,9,0例8.7 將數(shù)組a中n個(gè)整數(shù)按相反的順序存放void inv(int x , int n) int temp,
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 設(shè)備電流報(bào)警管理制度
- 設(shè)備計(jì)劃檢修管理制度
- 設(shè)計(jì)主管組員管理制度
- 設(shè)計(jì)投標(biāo)規(guī)章管理制度
- 設(shè)計(jì)項(xiàng)目制度管理制度
- 診所醫(yī)保財(cái)務(wù)管理制度
- 診所藥房安全管理制度
- 試驗(yàn)檢測安全管理制度
- 財(cái)務(wù)資金借支管理制度
- 財(cái)政完善權(quán)責(zé)管理制度
- 語文課堂精彩兩分鐘PPT課件
- 三生事業(yè)六大價(jià)值
- 鋯石基本特征及地質(zhì)應(yīng)用
- 絲網(wǎng)除沫器小計(jì)算
- 制缽機(jī)的設(shè)計(jì)(機(jī)械CAD圖紙)
- 學(xué)校財(cái)務(wù)管理制度
- 三年級下冊美術(shù)課件-第15課色彩拼貼畫|湘美版(共11張PPT)
- 水稻病蟲統(tǒng)防統(tǒng)治工作總結(jié)
- 水在不同溫度下的折射率、粘度和介電常數(shù)
- howdoyoucometoschoolPPT課件
- 四柱特高弟子班絕密資料——席學(xué)易
評論
0/150
提交評論