中職C語(yǔ)言程序設(shè)計(jì)模塊八課件_第1頁(yè)
中職C語(yǔ)言程序設(shè)計(jì)模塊八課件_第2頁(yè)
中職C語(yǔ)言程序設(shè)計(jì)模塊八課件_第3頁(yè)
中職C語(yǔ)言程序設(shè)計(jì)模塊八課件_第4頁(yè)
中職C語(yǔ)言程序設(shè)計(jì)模塊八課件_第5頁(yè)
已閱讀5頁(yè),還剩49頁(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、(中職)C語(yǔ)言程序設(shè)計(jì)模塊八課件指針模塊88.1指針的基本概念在計(jì)算機(jī)中,所有數(shù)據(jù)都是存放在存儲(chǔ)器中的。各數(shù)據(jù)類(lèi)型占用不等的內(nèi)存單元,如int型占2 B、long型占4 B等。在16位環(huán)境中,規(guī)定指針占2 B的內(nèi)存單元,以此為基準(zhǔn),32位環(huán)境中為4 B,64位環(huán)境中為8 B。指針理解如圖8-1所示。圖8-1指針理解8.1指針的基本概念(1)內(nèi)存單元:一般把1個(gè)字節(jié)(1 B)作為一個(gè)內(nèi)存單元(8 bit)。數(shù)據(jù)以二進(jìn)制碼形式存儲(chǔ)于內(nèi)存單元中。(2)指針及指針值:給每個(gè)內(nèi)存單元編號(hào)(如1000),就可以快速準(zhǔn)確地找到該內(nèi)存單元。這個(gè)編號(hào)也稱(chēng)地址,這種地址就是指針。因此,指針值就是地址。(3)指針變

2、量:把指針保存于某個(gè)變量中,這個(gè)變量稱(chēng)為指針變量。上圖中,數(shù)組a有6個(gè)元素值,p為指針變量,保存有6個(gè)地址,這6個(gè)地址分別對(duì)應(yīng)6個(gè)元素值的內(nèi)存單元。通過(guò)這6個(gè)地址,就能快速地找到數(shù)組a的6個(gè)值。因而,p是指向數(shù)組a的指針。一個(gè)指針是一個(gè)地址,是常量;而一個(gè)指針變量卻可以被賦予不同的指針值,是變量。因此,嚴(yán)格地說(shuō),指針和指針變量并不是同一個(gè)概念。而在日常中,為了稱(chēng)呼方便,我們常把指針變量稱(chēng)為指針。讀者對(duì)此應(yīng)有清晰的認(rèn)識(shí)。8.2指針變量的定義和初始化一般指針變量值初始化為單變量地址:int *p,a;p=&a; /*定義一個(gè)整型指針p,該指針指向整型變量a的地址*/寫(xiě)為一行就是:int a,*p=

3、&a;指針變量值初始化為單變量地址時(shí),不要忘了“&”運(yùn)算符。再如:float m,*pf=&m;8.2.1一般指針變量的定義與初始化8.2指針變量的定義和初始化8.2.2一維數(shù)組指針變量的定義與初始化一維數(shù)組指針變量值初始化時(shí),只需指向數(shù)組名即可,因?yàn)閿?shù)組名即為該數(shù)組首元素首地址。int a10,*p;p=a; /*定義一個(gè)一維數(shù)組指針p,該指針指向一維數(shù)組a*/因?yàn)閿?shù)組名代表首元素首地址,因此p=a等價(jià)于p=&a0。寫(xiě)為一行就是:int a10,*p=a;再如:float b5,*pf=b;由此可見(jiàn):數(shù)組名、指針及第1個(gè)元素首地址均指向同一個(gè)內(nèi)存單元。8.2指針變量的定義和初始化8.2.3二

4、維數(shù)組指針變量的定義與初始化定義規(guī)則:類(lèi)型(*指針變量名)長(zhǎng)度長(zhǎng)度指的是二維數(shù)組的列數(shù)。int a23,(*p)3;p=a;/*定義二維數(shù)組指針p,該指針指向二維數(shù)組a*/寫(xiě)為一行就是:int a23,(*p)3=a;要特別注意的是:不能忘記(),否則就變成了指針數(shù)組(后述)。區(qū)分:int a23,*p3;/*這里p是指針數(shù)組名而不是數(shù)組指針*/8.2指針變量的定義和初始化8.2.4字符串指針變量的定義與初始化依上得知:字符串指針就是字符數(shù)組的首地址。char *p,c8;p=c;/*定義字符串指針p,該指針指向字符數(shù)組c的首地址*/寫(xiě)成一行就是:char c8,*p=c;在定義字符串指針變量

5、時(shí),可以給該指針變量初始化字符串,但要明白的是:該指針變量不是“存放”字符串,而是指向字符串的首地址。char *q,*p=How are you;q=Nice to meet you;這里定義了兩個(gè)字符串指針,p指向字符串How are you的首地址(元素H的地址),q指向字符串Nice to meet you的首地址(元素N的地址)。8.2指針變量的定義和初始化8.2.4字符串指針變量的定義與初始化最后需要指出的是:(1)指針變量在使用前必須初始化,否則會(huì)影響程序的運(yùn)行,甚至崩潰。(2)指針變量的初始化只有三種情況:賦地址。賦空值。例如,“int a,*p=NULL;”,賦空值表示不指向

6、任何內(nèi)存單元。賦0,如“int a,*p=0;”。(3)任何指針只能指向其同類(lèi),即指針變量的類(lèi)型必須和其指向的變量類(lèi)型一致。8.2指針變量的定義和初始化函數(shù)指針,顧名思義,就是指向函數(shù)的指針。1.函數(shù)指針的定義類(lèi)型 (*函數(shù)指針變量名)();注意兩個(gè)()都不能少。例如,“int (*p)();”定義一個(gè)函數(shù)指針p,該指針指向一個(gè)返回值為int型的函數(shù);“float (*p1)(float);”定義一個(gè)函數(shù)指針p1,該指針指向一個(gè)具有float形參,返回值為float型的函數(shù)。2.函數(shù)指針的初始化假設(shè)有float型函數(shù)fm()和fn()。函數(shù)名是函數(shù)的入口地址,同數(shù)組名一樣,是常量。函數(shù)指針的初

7、始化就是指向函數(shù)名。同樣,函數(shù)指針與其指向的函數(shù)必須是同一類(lèi)型的。例如:float (*p1)(float),(*p2)(float);p1=fm;p2=fn;寫(xiě)為一句就是:float (*p1)(float)=fm,(*p2)(float)=fn;8.2.5函數(shù)指針的定義與初始化8.3指針的運(yùn)算指針的運(yùn)算總體上表述為以下三個(gè)方面:(1)指針本身只有兩個(gè)運(yùn)算符。& 取地址取變量地址。* 取內(nèi)容取指針?biāo)赶蜃兞康膬?nèi)容。8.3指針的運(yùn)算(2)指針的數(shù)學(xué)運(yùn)算。指針的數(shù)學(xué)運(yùn)算指的是指針的加減運(yùn)算。必須理解以下幾點(diǎn):指針的加減運(yùn)算只針對(duì)數(shù)組而言,其他類(lèi)型指針的加減運(yùn)算無(wú)意義。舉例有“int a5=1,2

8、,3,4,5,*p=a;”。a.p+2的含義并不是0+2,而是指向a0后2個(gè)元素即a2的首地址,但指針位置沒(méi)有移動(dòng)。b.p+的含義是引用p的當(dāng)前值之后(先運(yùn)算)指針移向下一個(gè)元素(再自增),指針位置移動(dòng)到了a1。c.-p的含義是指針先移向上一個(gè)元素(先自減)。同一指針在數(shù)組內(nèi)的加減運(yùn)算同上。舉例有“int a5=1,2,3,4,5,*p=a,*p1=&a4;”。a.p1-p是成立的,結(jié)果為4,意為兩個(gè)指針之間的元素個(gè)數(shù)。b.p1+p是無(wú)意義的,即指向同一數(shù)組的兩個(gè)指針相加是沒(méi)有意義的。8.3指針的運(yùn)算(3)指針之間的關(guān)系運(yùn)算。p1=p2,指針p1,p2指向同一內(nèi)存單元(或元素地址)。p1p2,

9、指針p1處于高地址位置。p1p2,指針p1處于低地址位置。只有同類(lèi)型的指針才能進(jìn)行比較。8.3指針的運(yùn)算8.3.1指針內(nèi)存地址考查及指針類(lèi)型的轉(zhuǎn)換1.指針內(nèi)存地址考查(1)指針偏移量的計(jì)算。舉例有“int a20=1,2,3,4,5,*p=a;float b10,*p1=b;”。下面的四個(gè)例子舉的是單獨(dú)存在的情況:“p+;”:指針移動(dòng)到a1位置處,指向該元素首地址,偏移量為“1sizeof(int)=12=2”,即2個(gè)字節(jié)?!皃+3;”:指針指向a3元素首地址,偏移量有“3sizeof(int)=32=6”,即6個(gè)字節(jié);但指針p還停留在a0,指向a0首地址。“p1+2;”:指針指向b2元素首地

10、址,偏移量有“2sizeof(float)=24=8”,即8個(gè)字節(jié);但指針p還停留在b0,指向b0首地址?!皃1+;”:指針移動(dòng)到b1位置處,指向該元素首地址,偏移量為“1sizeof(float)=14=4”,即4個(gè)字節(jié)。8.3指針的運(yùn)算8.3.1指針內(nèi)存地址考查及指針類(lèi)型的轉(zhuǎn)換(2)內(nèi)存地址的運(yùn)算。以上面為例,若int型指針p地址為ffea,float型指針p1地址為ffec:同上面一致,下面的四個(gè)例子舉的是單獨(dú)存在的情況:p+:ffea+12=15 15 14 10+2=15 15 14 12=ffec。p+3:ffea+32=15 15 14 10+6=15 15 15 0=fff0(

11、十六進(jìn)制,逢16進(jìn)1,下同)。p1+2:ffec+24=15 15 14 12+8=15 15 15 4=fff4。p1+: ffec+14=15 15 14 12+4=15 15 15 0=fff0。在實(shí)際運(yùn)用中,要根據(jù)指針的實(shí)際情況來(lái)計(jì)算偏移量。例如,“int a20=1,2,3,4,5,*p=a;”,若指針p的地址為ffea,則p+;p+3;這時(shí)指針p的偏移量應(yīng)該是fff0。8.3指針的運(yùn)算8.3.1指針內(nèi)存地址考查及指針類(lèi)型的轉(zhuǎn)換2.指針類(lèi)型的強(qiáng)制轉(zhuǎn)換指針的轉(zhuǎn)換指的是指針類(lèi)型的強(qiáng)制轉(zhuǎn)換,如把字符串型指針p強(qiáng)制轉(zhuǎn)換為整型,即(int *)p。指針類(lèi)型被強(qiáng)制轉(zhuǎn)換以后要注意其位移長(zhǎng)度的變化。

12、注意:指針移動(dòng)的長(zhǎng)度是其數(shù)據(jù)類(lèi)型的長(zhǎng)度;16位環(huán)境下指針內(nèi)存長(zhǎng)度規(guī)定都是2個(gè)字節(jié),用sizeof()運(yùn)算符可以查看。因此,不要把二者混淆。#include int main()char *p=123456789;int *x;/*整型指針變量,2 B(字節(jié)),起始位0*/8.3指針的運(yùn)算8.3.1指針內(nèi)存地址考查及指針類(lèi)型的轉(zhuǎn)換char *m;/*字符型指針變量,1 B(字節(jié)),起始位0 */int *y;/*整型指針變量,2 B(字節(jié)),起始位0*/x=(int *)p; /*字符指針強(qiáng)制轉(zhuǎn)換為整型指針賦給x*/y=(int *)p; /*字符指針強(qiáng)制轉(zhuǎn)換為整型指針賦給y*/x+;/*整型指

13、針下移1次,2 B(字節(jié)),位置到3*/x+;/*再下移1次,2 B,位置到5*/x+;/*再下移1次,2 B,位置到7*/printf(%sn,x);/*輸出789*/printf(%sn,y);/*輸出123456789*/m=(char *)x;/*整型指針強(qiáng)制轉(zhuǎn)換為字符型指針賦給m*/m+;/*下移1位,到8*/printf(%s,m);/*輸出89*/8.3指針的運(yùn)算8.3.2一般指針變量的運(yùn)算示例1:#include int main()int a=5,*p,x;p=&a;/*取變量a的地址給指針p*/x=*p;/*對(duì)指針p取內(nèi)容,將結(jié)果賦給變量x*/printf(%d-%d,x,

14、*p);/*輸出5-5*/示例2:#include int main() int a=100,*p1,*p2,x;p1=&a;/*取變量a的地址給指針p1*/p2=p1;/*p1賦給p2,則p2也指向了變量a的地址*/x=*p2;/*對(duì)指針p2取內(nèi)容,取得100,賦給x*/a=20;printf(x=%dn,x); /*輸出x=100*/printf(x=%d,*p2); /*這里的*p2在a=20之后,輸出x=20*/8.3指針的運(yùn)算8.3.2一般指針變量的運(yùn)算示例3:#include int main()int a=10,b=20,s,t,*p1,*p2;p1=&a; p2=&b;s=*p

15、1+*p2;/*取內(nèi)容求和運(yùn)算,s得30*/t=*p1*p2;/*取內(nèi)容求積運(yùn)算,t得200*/printf(s=%d,t=%dn,s,t); /*輸出s=30,t=200*/由此可見(jiàn),如果有變量x及指向變量y的指針p:int x,y,*p;p=&y; “x=y;”則等價(jià)于 “x=*p;”?!皔+;”則等價(jià)于“(*p)+;”。“x=y+1;”則等價(jià)于“x=(*p)+1;”。8.3指針的運(yùn)算8.3.3指向一維數(shù)組的指針運(yùn)算示例1:#include int main() int a5=4,5,0,6,8,*p,*p1; p=a;printf(%dn,*p); /*依前所述,這里*p其實(shí)就是*(&a

16、0),即對(duì)首元素地址進(jìn)行取內(nèi)容運(yùn)算,輸出4*/p=p+1;/*p+1指的是指針向右移1位,到了地址&a1*/printf(%dn,*p); /*等同于 *(&a1),輸出5*/p1=p+;/*先運(yùn)算再自增,p1獲得地址&a1,指針8.3指針的運(yùn)算8.3.3指向一維數(shù)組的指針運(yùn)算p增1,指向了a2的地址&a2*/printf(%dn,*p1); /*等同于 *(&a1),輸出5*/p=+p; /*先自增再運(yùn)算,*p在前面已指向了&a2,這里再增1,則指向了&a3*/printf(%dn,*p); /*等同于*(&a3),輸出6*/printf(%dn,*(+p); /*指針p再增1,指向了&a4

17、,*(&a4)運(yùn)算,結(jié)果為8*/printf(%d,*(p-2); /*p指向的是&a4,p-2意為指針向后退2位,到&a2,*(&a2)運(yùn)算,結(jié)果為0*/p=&a4;/*強(qiáng)制指針p直接指向&a4*/printf(%d,*p); /*等同于*(&a4),輸出8*/8.3指針的運(yùn)算8.3.3指向一維數(shù)組的指針運(yùn)算示例2:#include int main() int a5=4,5,0,6,8,*p; p=a+1;/*指針初始化指向地址&a1*/printf(%dn,*(a+3); /*數(shù)組名是首元素首地址,向右移3,到&a3 這個(gè)地址,取內(nèi)容,即6*/printf(%dn,a3);/*直接輸出a

18、3這個(gè)元素的值,即6*/printf(%dn,*(&a3); /*對(duì)a3地址取內(nèi)容運(yùn)算,即6*/printf(%dn,*(p+3); /*指針向右移3到 &a4,取內(nèi)容即8*/8.3指針的運(yùn)算8.3.3指向一維數(shù)組的指針運(yùn)算上面兩個(gè)例子充分體現(xiàn)了指向一維數(shù)組的指針運(yùn)算,可以歸納如下:(1)數(shù)組名、數(shù)組指針和首元素地址都指向同一個(gè)內(nèi)存單元,運(yùn)算時(shí)可得以下等價(jià)關(guān)系(每一列對(duì)應(yīng)的內(nèi)容是等價(jià)的,見(jiàn)表8-1)。在“int a10,*p=a;”中:取一例說(shuō)明(前提是保證指針p指向數(shù)組名a):等價(jià)地址:a+1=p+1=&a0+1=&a1;等價(jià)取值:*(a+1)=*(p+1)=*(&a0+1)=*(&a1)。

19、表8-1指向一維數(shù)組的指針運(yùn)算8.3指針的運(yùn)算8.3.3指向一維數(shù)組的指針運(yùn)算(2)根據(jù)上述知識(shí),對(duì)數(shù)組的賦值便有三種方法,即元素賦值法、地址法和指針?lè)ā?.3指針的運(yùn)算8.3.4指向二維數(shù)組的指針運(yùn)算掌握了一維數(shù)組指針的運(yùn)算,學(xué)習(xí)二維數(shù)組指針的運(yùn)算就比較容易了。因?yàn)槎S數(shù)組本質(zhì)上是多個(gè)一維數(shù)組的集合。1.二維數(shù)組元素地址取值運(yùn)算假設(shè)有34矩陣b,指針p指向這個(gè)矩陣,即“int b34,(*p)4=b;”,i代表行變量,j代表列變量。二維數(shù)組行列地址取法過(guò)程及取值過(guò)程如下:(1)二維數(shù)組的數(shù)組名代表二維數(shù)組的首地址,這個(gè)首地址具體來(lái)說(shuō)就是第0行的首地址。例如,在本例中,數(shù)組名b代表b+0(第0

20、行)的首地址。以此類(lèi)推,可知:第0行首地址:b+0 (首組名b);第1行首地址:b+1;第2行首地址:b+2;第i行首地址:b+i。8.3指針的運(yùn)算8.3.4指向二維數(shù)組的指針運(yùn)算(2)對(duì)行地址進(jìn)行“*”運(yùn)算,得到第x行第0列的元素地址:第0行第0列的元素地址:*(b+0),即b0;第1行第0列的元素地址:*(b+1),即b1;第2行第0列的元素地址:*(b+2),即b2;第i行第0列的元素地址:*(b+i),即bi。(3)二維數(shù)組的元素地址由行+列構(gòu)成:第0行第0列的元素地址:*(b+0)+0,即b0+0,即&b00;第0行第1列的元素地址:*(b+0)+1,即b0+1,即&b01;第1行第

21、1列的元素地址:*(b+1)+1,即b1+1,即&b11;第1行第2列的元素地址:*(b+1)+2,即b1+2,即&b12;第i行第j列的元素地址:*(b+i)+j,即bi+j,即&bij。8.3指針的運(yùn)算8.3.4指向二維數(shù)組的指針運(yùn)算(4)對(duì)地址進(jìn)行“*”運(yùn)算(取內(nèi)容運(yùn)算)即可得到該地址指向的元素的值:對(duì)第1行第1列的元素地址取值:*(*(b+1)+1),即*(b1+1),即*(&b11);對(duì)第2行第2列的元素地址取值:*(*(b+2)+2),即*(b2+2),即*(&b22);對(duì)第i行第j列的元素地址取值:*(*(b+i)+j),即*(bi+j),即*(&bij)。用二維數(shù)組指針變量取代

22、數(shù)組名,對(duì)第i行第j列的元素地址取值,即為:*(*(p+i)+j),即*(pi+j),即*(&pij);完全等同于*(*(b+i)+j),即*(bi+j),即*(&bij)。以下列34矩陣為例(int b34,(*p)4=b;),對(duì)元素取值舉例(見(jiàn)表8-2)8.3指針的運(yùn)算8.3.4指向二維數(shù)組的指針運(yùn)算表8-2元素取值舉例8.3指針的運(yùn)算8.3.4指向二維數(shù)組的指針運(yùn)算指針數(shù)組,意即數(shù)組的元素均為指針。(1)指針數(shù)組的定義方法。類(lèi)型 *指針數(shù)組名數(shù)組長(zhǎng)度例如,“int*p4;”定義了一個(gè)名為p的帶4個(gè)整型指針元素的指針數(shù)組。一定要把它和數(shù)組指針區(qū)別開(kāi)來(lái)。“int (*p)4;”定義了一個(gè)名為

23、p的數(shù)組指針,4為所指向數(shù)組的列數(shù)。2.指針數(shù)組8.3指針的運(yùn)算8.3.4指向二維數(shù)組的指針運(yùn)算(2)指針數(shù)組的初始化。給指針數(shù)組初始化時(shí),如果指向二維數(shù)組,賦的是二維數(shù)組每一行的首地址。例如:static int a33=1,2,3,4,5,6,7,8,9;int *p=a0,a1,a2;其元素值如下:(3)指針數(shù)組的運(yùn)算。8.3指針的運(yùn)算8.3.4指向二維數(shù)組的指針運(yùn)算【例8-1】指針數(shù)組元素取值運(yùn)算示例。#include int main() static int a33=1,2,3,4,5,6,7,8,9;int *p=a0,a1,a2;printf(%d-%dn,*p0,*p1);

24、/*這里*p0等價(jià)于*a0,*p1等價(jià)于*a1,意為對(duì)一、二行首元素首地址進(jìn)行取值運(yùn)算,輸出14*/printf(%d-%d,*(p0+1),*(p1+2); /*這里*(p0+1)等價(jià)于*(a0+1),從第1行首元素地址右移1位進(jìn)行取值,即值2;*(p1+2)等價(jià)于*(a1+2),從第2行首元素地址右移2位進(jìn)行取值,即值6,輸出26*/由上可知,由于指針數(shù)組里存放了每一行的首地址,在對(duì)數(shù)組元素進(jìn)行取值時(shí),只需將指針數(shù)組元素移動(dòng)到相應(yīng)的元素位置,再對(duì)該地址進(jìn)行“*”取值運(yùn)算即可。8.3指針的運(yùn)算8.3.4指向二維數(shù)組的指針運(yùn)算3.數(shù)組指針和指針數(shù)組取值示例 #include int main(

25、)static int a34=1,2,3,4,5,6,7,8,9,10,(*p1)4=a;int *p2=&a00;int *p3=a0,a1,a2;printf(%d ,*(*(p1+1)+1); /*p1數(shù)組指針,等同于*(&a11),輸出6*/printf(%d ,(*(p1+1)2); /*p1數(shù)組指針,等同于a12,輸出7*/ printf(%d ,*(p2+7); /*p2元素指針,初值為指向第1個(gè)元素地址,移動(dòng)7個(gè)位置,到8*/8.3指針的運(yùn)算8.3.4指向二維數(shù)組的指針運(yùn)算 printf(%d ,*(p32+1); /*指針數(shù)組元素,從第3行首地址右移一個(gè),輸出10*/ pr

26、intf(%d ,*(a+1)1);/*變址運(yùn)算符高于取值運(yùn)算符*,對(duì)地址(a+1)變址,加1,實(shí)際變成了a+2,*(a+2)為第3行首地址,輸出9/要注意上例中的變址運(yùn)算符,它排在最高級(jí),其運(yùn)算就是在原址上加減。上例中:“printf(%d ,*(a+1)1);”就是在原址(a+1)的基礎(chǔ)上加1,變?yōu)?a+2)?!皃rintf(%d ,*(a+1)-1);”就是在原址(a+1)的基礎(chǔ)上減1,變?yōu)?a+0),即a。8.3指針的運(yùn)算8.3.5指向字符串的指針運(yùn)算字符串指針與其他指針的運(yùn)算最大的差別就在于:(1)無(wú)須用“*”取內(nèi)容運(yùn)算符。因?yàn)橐粋€(gè)字符就是一個(gè)存儲(chǔ)單元,而且是連續(xù)的。(2)取得了某個(gè)

27、地址,便可輸出該地址后面的字符串(字符串以0結(jié)束為準(zhǔn))。例如:#include int main()char str1=We are all students,*p1=str1;char str2=s,o,r,r,y,0,*p2=str2;char str3=A, ,b,o,y,0,*p3=str3;char *p4=This is a book;static char str420=good,year,book,high school;char *p=str40,str41,str42,str43;8.3指針的運(yùn)算8.3.5指向字符串的指針運(yùn)算printf(%sn,str1); /*數(shù)組名為

28、首元素首地址,輸出“We are all students”這個(gè)串*/printf(%sn,p1); /*p1指針指向str1,輸出“We are all students”這個(gè)串*/printf(%sn,p1+3); /*從首地址右移3個(gè)位置到a這個(gè)元素值地址,輸出“are all students”*/printf(%sn,str1+3); /*從首地址右移3個(gè)位置到a這個(gè)元素值地址,輸出“are all students”*/printf(%sn,str2);/*輸出首地址后面的串,即“sorry”*/printf(%sn,p2); /*p2指針指向str2,輸出“sorry”*/pri

29、ntf(%sn,p2+2); /*p2指針右移2位到r這個(gè)位置,輸出“rry”*/printf(%sn,str3); /*首地址,輸出“A boy”*/printf(%sn,p3); /*首地址,輸出“A boy”*/printf(%sn,p3+2); /*指針右移2位到b,輸出“boy”*/printf(%sn,p4); /*指針p4代表首元素首地址,輸出“This is a book”*/8.3指針的運(yùn)算8.3.5指向字符串的指針運(yùn)算printf(%sn,p4+5); /*從首地址右移5個(gè)位置到i,輸出“is a book”*/printf(%sn,p3); /*指針數(shù)組元素,指向str4

30、3,輸出“high school”*/printf(%sn,p3+5); /*指針數(shù)組元素,從第4行首地址向右移動(dòng)5個(gè)位置到s,輸出“school”*/printf(%sn,p1+1); /*指針數(shù)組元素,從第2行首地址向右移動(dòng)1個(gè)位置到e,輸出“ear”*/說(shuō)明:(1)字符串指針變量存放的是字符串首元素首地址,而不是整個(gè)字符串。這一點(diǎn)一定要注意理解。(2)在沒(méi)有指定字符數(shù)組長(zhǎng)度時(shí),以單個(gè)字符賦值給字符數(shù)組時(shí),末尾必須加0,以示賦值完整。若指定了長(zhǎng)度且進(jìn)行了完整賦值,就不必賦0。8.3指針的運(yùn)算8.3.6二級(jí)間址1.二級(jí)間址的含義前面的指針學(xué)習(xí)均是單級(jí)間址,也就是一級(jí)指針,一個(gè)指針變量中存放一

31、個(gè)目標(biāo)變量地址。例如,“int *p=&a;”指針p只存放變量a的地址。所謂二級(jí)間址,其意是通過(guò)一個(gè)指針指向另一個(gè)指針達(dá)到訪(fǎng)問(wèn)變量地址的目的,也可稱(chēng)為二級(jí)指針。更通俗地講就是指向指針的指針。要注意的是:二級(jí)指針不能跳過(guò)一級(jí)指針直接取值,表示如下:p是一級(jí)指針,pp是二級(jí)指針,pp指向p,p指向數(shù)組a。2.二級(jí)指針的定義類(lèi)型 *指針變量名例如,“int *p;”。8.3指針的運(yùn)算8.3.6二級(jí)間址3.二級(jí)指針運(yùn)算示例通過(guò)二級(jí)指針運(yùn)算循環(huán)輸出數(shù)組元素值。#include int main()int a5=8,6,7,9,10,i,*p=a; /*定義p為一級(jí)指針,指向數(shù)組a*/int *pp=&p

32、; /*定義pp為二級(jí)指針,指向p的地址*/for(i=0;i5;i+)printf(%d ,*(*pp+i);/*這里*pp取得p地址,+i則是對(duì)地址位移,最后*取內(nèi)容*/putchar(n);for(i=0;i5;i+,p+)printf(%d ,*pp);/*對(duì)上面的p+進(jìn)行循環(huán)取地址、取內(nèi)容運(yùn)算*/由上可知:二級(jí)指針的運(yùn)算是先通過(guò)對(duì)一級(jí)指針進(jìn)行“*”取地址內(nèi)容運(yùn)算,再進(jìn)行一次“*”取元素值內(nèi)容運(yùn)算。以上面的二級(jí)指針pp為例進(jìn)行說(shuō)明:*pp: 取得一級(jí)指針的地址;*pp: 對(duì)一級(jí)指針指向的元素地址取內(nèi)容。8.3指針的運(yùn)算8.3.6二級(jí)間址8.3指針的運(yùn)算8.3.7指向函數(shù)的指針運(yùn)算函數(shù)指

33、針指向函數(shù)名。關(guān)于函數(shù)名,在前面已有敘述。函數(shù)名是函數(shù)的入口地址,同數(shù)組名一樣,是常量。有時(shí)需要交換函數(shù)名來(lái)進(jìn)行運(yùn)算,這時(shí)就要用到函數(shù)指針了。因?yàn)楹瘮?shù)名是常量,是不能直接交換的,而函數(shù)指針是變量,因而可以通過(guò)函數(shù)指針進(jìn)行函數(shù)名的交換。下例就是通過(guò)函數(shù)指針交換了函數(shù)名,從而改變了運(yùn)算結(jié)果。#include float fm(float n) returnn*n;float fn(float n) return2*n;int main()8.3指針的運(yùn)算8.3.7指向函數(shù)的指針運(yùn)算float (*p1)(float),(*p2)(float),(*t)(float),x,y; /*定義三個(gè)函數(shù)指針

34、,其中t作為臨時(shí)指針*/p1=fm;p2=fn;x=p2(p1(2); /*先p1(2)調(diào)用,即fm(2),得4。再p2(4),即fn(4),得8*/t=p1;p1=p2;p2=t;/*通過(guò)函數(shù)指針交換了函數(shù)名,即p1指向了fn,p2指向了fm*/y=p2(p1(2); /*交換后的運(yùn)算,p1(2)即fn(2),得4。p2(4)即fm(4),得16*/printf(x=%.0f,y=%.0f,x,y);/*輸出:x=8,y=16*/8.3指針的運(yùn)算8.3.8函數(shù)調(diào)用中的地址傳遞在函數(shù)調(diào)用過(guò)程中,當(dāng)作為形參的指針調(diào)用實(shí)參時(shí),獲取的是地址,或者說(shuō)傳遞的只能是地址。因此,形參和實(shí)參指向的都是同一個(gè)地

35、址,具體來(lái)說(shuō),就是相同的內(nèi)存單元。因而,如果有值的變化,不分形參和實(shí)參,本質(zhì)上就是同一段內(nèi)存值的變化。比較下面地址傳遞和值傳遞的運(yùn)算結(jié)果:8.3指針的運(yùn)算8.3.8函數(shù)調(diào)用中的地址傳遞8.3指針的運(yùn)算8.3.8函數(shù)調(diào)用中的地址傳遞在下面的程序中,分多種情況在主函數(shù)中輸出x,y的值,查看其變化。#include int fun(int *x,int *y) int t;t=*x;*x=*y;*y=t; /*x=5,y=3,通過(guò)t交換了值*/y=x;*x=*y;*y=*x; /*x=3,y=5,x地址給了y,此時(shí)只有x這一段內(nèi)存在活動(dòng),仍然為3,y沒(méi)有參加活動(dòng),不變,仍為5*/x=y;*y=*x;

36、*x=*y; /*x=3,y=5,y地址給了x,此時(shí)只有y這一段內(nèi)存在活動(dòng),仍然為5,x沒(méi)有參加活動(dòng),仍然為3*/*x=*y;*y=*x;/*x=5,y=5*/ int main() int x=3,y=5,*p1=&x,*p2=&y;fun(p1,p2);printf(x=%d y=%dn,x,y);putchar(n);8.4指針的應(yīng)用【例8-2】提取字符串中的數(shù)字字符。提取字符串2you38are85a12student6l9中的數(shù)字字符。#include void f(char *p)char ch100;/*用于存放數(shù)字字符*/long a100;/*用于存放轉(zhuǎn)化后的數(shù)學(xué)字符*/in

37、t k=0,sign=0,j=0;static long s;do s=0;if(*p&*p=0&*p=9)sign=1;/*數(shù)字字符標(biāo)記為1 */chk+=*p; /*數(shù)字字符保存到字符數(shù)組ch中,注意k運(yùn)算后會(huì)再增1*/else if(sign=1)/*對(duì)數(shù)字字符進(jìn)行求和運(yùn)算*/8.4指針的應(yīng)用int i;for(i=0;ik;i+)/*不能寫(xiě)成i=k,因?yàn)閗+自增了1位,超出了數(shù)組ch的下標(biāo)范圍*/s=s*10+chi-0;/*把字符轉(zhuǎn)化為數(shù)學(xué)數(shù)字(如38轉(zhuǎn)為38)*/aj+=s;/*保存到long數(shù)組a中,j也要自增1 */k=0;/*必須重新賦0,回到上面的if中*/sign=0;

38、/*標(biāo)記復(fù)位 */p+;/*最后一個(gè)字符參與了運(yùn)算后,p+意味著指針p實(shí)際上已移到了0符處。 因至少還要做一次循環(huán),故指針p到了結(jié)尾符0后面*/ while(*(p-1)!=0);/*所以此處只能寫(xiě)p-1*/for(k=0;kj;k+)printf(%ld ,ak);int main()char *p=2you38are85a12student6l9;f(p);輸出結(jié)果:2388512698.4指針的應(yīng)用【例8-3】插入字符串。把字符串good插入字符串luck之前。其原理是通過(guò)指針移動(dòng)、對(duì)指針取元素值等移動(dòng)相應(yīng)位置的元素,騰出內(nèi)存單元,再在這個(gè)內(nèi)存單元中插入字符。#include #incl

39、ude void f(char ch,char *p)int i;char *q,*t=ch;for(i=0;istrlen(ch)/2;i+)t+;/*i=t)/*向后移動(dòng)字符,騰出一個(gè)空間*/*(q+1)=*q;/*先移動(dòng)0符*/8.4指針的應(yīng)用【例8-3】插入字符串。把字符串good插入字符串luck之前。其原理是通過(guò)指針移動(dòng)、對(duì)指針取元素值等移動(dòng)相應(yīng)位置的元素,騰出內(nèi)存單元,再在這個(gè)內(nèi)存單元中插入字符。#include #include void f(char ch,char *p)int i;char *q,*t=ch;for(i=0;istrlen(ch)/2;i+)t+;/*i=t)/*向后移動(dòng)字符,騰出一個(gè)空間*/*(q+1)=*q;/*先移動(dòng)0符*/8.4指針的應(yīng)用q-; /*指針前移一個(gè),上面又移動(dòng)一個(gè)字符,當(dāng)q=t時(shí),q-到了a6處,以此類(lèi)推*/q+; /*q重到a7處,以此類(lèi)推*/*q=*p; /*在a7處放入1個(gè)字符,以此類(lèi)推*/t+;/*數(shù)組ch下移1個(gè)位置到ch8,仍然是l處,以此類(lèi)推*/p+;/*串good下移1個(gè)位置到o處,以此類(lèi)推*/printf(%s,ch);int main() char ch20=Its a luck day;char *p=good;f(ch,p);8.4指

溫馨提示

  • 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)論