版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、1,6.1 指針的概念6.2 指針與函數(shù)6.3 指針與數(shù)組6.4 動(dòng)態(tài)內(nèi)存分配,第6章 指針,2,6.1 指針的概念,在定義變量時(shí),系統(tǒng)就給這個(gè)變量分配內(nèi)存單元。一個(gè)變量在內(nèi)存中占用一個(gè)存儲(chǔ)空間,而存儲(chǔ)空間的大?。ㄗ止?jié)數(shù))是由變量的類型決定的。,6.1.1 地址與指針,3,6.1.1 地址與指針,內(nèi)存區(qū)的每一個(gè)字節(jié)有一個(gè)編號(hào),這就是內(nèi)存單元的“地址”。根據(jù)一個(gè)內(nèi)存單元的地址(編號(hào))即可準(zhǔn)確地找到該內(nèi)存單元。如果變量占用多個(gè)字
2、節(jié)的內(nèi)存單元將對(duì)應(yīng)多個(gè)編號(hào)。為了能正確的訪問(wèn)變量所代表的存儲(chǔ)空間,C語(yǔ)言規(guī)定將一個(gè)變量所占用的存儲(chǔ)空間第1個(gè)字節(jié)的地址(即首地址)稱為該變量的地址。,4,6.1.1 地址與指針,在C語(yǔ)言中,將地址形象化地稱為“指針”。意思是通過(guò)它能找到以它為地址的內(nèi)存單元。,int a,b;,,a,,b,2000,2004,a=5;,,5,直接訪問(wèn),按變量名來(lái)訪問(wèn)變量所對(duì)應(yīng)的存儲(chǔ)空間而存取變量值的方式稱為直接訪問(wèn)。,5,6.1.1 地址與指針,int
3、 a=2,b=4,c;,2,4,值不確定,,c=a*b;,,,,8,直接訪問(wèn),6,6.1.1 地址與指針,int a;,,a,,p,13ff78,p=&a;,間接訪問(wèn),定義特殊變量p,13ff78,通過(guò)p來(lái)訪問(wèn)a,為了表示將數(shù)值3送到變量中,可以有兩種表達(dá)方法:(1) 將3直接送到變量a所代表的單元中。a=3(2) 將3送到變量p所指向的單元(即a所代表的存儲(chǔ)單元),先訪問(wèn)指針p的存儲(chǔ)空間,其中存放的是變量a的地址值,再根據(jù)
4、該地址值訪問(wèn)變量a的存儲(chǔ)空間。這種訪問(wèn)方式稱為間接訪問(wèn)。,7,6.1.1 地址與指針,一個(gè)變量的地址稱為該變量的“指針”例如,地址13ff78是變量a的指針如果有一個(gè)變量專門用來(lái)存放另一變量的地址(即指針),則它稱為“指針變量” 例如,p就是一個(gè)指針變量。指針變量就是地址變量,用來(lái)存放地址的變量,指針變量的值是地址(即指針),8,6.1.1 地址與指針,“指針”和“指針變量”是不同的概念可以說(shuō)變量a的指針是13ff78,而
5、不能說(shuō)a的指針變量是13ff78指針是一個(gè)地址,而指針變量是存放地址的變量,9,6.1.2 指針的定義與初始化,1.指針的定義定義指針的一般形式為: [存儲(chǔ)類型] 數(shù)據(jù)類型 *指針變量名;例:int *p,*q;,,與普通變量一樣相同,,表示指針?biāo)赶蚰繕?biāo)變量的類型,,表示其后定義的是指針變量,,遵循標(biāo)識(shí)符的命名規(guī)則,10,例:int *p,*q;int是為指針變量指定的“基類型”基類型指定指針變量可指向的變量類型
6、如p,q可以指向整型變量,但不能指向浮點(diǎn)型變量 例:char *s; 定義指針變量s,為指向字符變量的指針變量。,6.1.2 指針的定義與初始化,11,指針變量的地址值都是整型的,指向不同類型對(duì)象的指針變量存儲(chǔ)空間大小相同。但還是要將指針變量按其指向的對(duì)象定義為不同的類型,為什么?原因是計(jì)算機(jī)對(duì)于指針的運(yùn)算是按照定義指針變量時(shí)所指向?qū)ο箢愋蛠?lái)進(jìn)行的。指向不同類型對(duì)象的指針在內(nèi)存中進(jìn)行移動(dòng)操作時(shí),其移動(dòng)的字節(jié)數(shù)是不一
7、樣的。,6.1.2 指針的定義與初始化,12,指向不同類型對(duì)象的指針變量存儲(chǔ)空間大小相同都是4,Visual C++ 6.0環(huán)境下,不同的編譯器結(jié)果可能不同,Turbo C 2.0中是2。,6.1.2 指針的定義與初始化,int *pi; float *pf; char *pc; printf(“pint=%d\n”,sizeof(pi));printf(“pfloat
8、=%d\n”,sizeof(pf));printf(“pchar=%d\n”,sizeof(pc));,運(yùn)行結(jié)果:pint=4pfloat=4Pchar=4,13,6.1.2 指針的定義與初始化,2.指針的初始化定義指針的一般形式為: [存儲(chǔ)類型] 數(shù)據(jù)類型 *指針變量名= 初始值;例:float f,*p=&f; int *p=NULL; int *q=0;,,一個(gè)地址值、0
9、或者NULL,#define NULL 0,空指針,表示指針不指向任何目標(biāo)變量,即閑置。,,14,6.1.2 指針的定義與初始化,下面都是合法的定義和初始化:float *pointer_3;char *pointer_4;int a,b;int *pointer_1=&a,*pointer_2=&b;,*pointer_1=&a; 錯(cuò)誤,pointer_3=&a; 錯(cuò)誤,
10、pointer_1=&a; 正確,pointer_3=2000; 錯(cuò)誤,15,指針運(yùn)算是以指針?biāo)娣诺牡刂分禐檫\(yùn)算量進(jìn)行的運(yùn)算。指針運(yùn)算的實(shí)質(zhì)是地址的計(jì)算。1.基本運(yùn)算(1)取地址運(yùn)算符& 表達(dá)式一般格式為: &operand 其功能是取得操作數(shù)的地址 例: &a是變量a的地址,6.1.3 指針的運(yùn)算,16,1.基本運(yùn)算(1)取地址運(yùn)算
11、符& 注意:①取地址運(yùn)算符“&”作用在一個(gè)變量或數(shù)組元素上,就可以得到該變量或數(shù)組元素的地址。 如有如下定義: int a,d[10]; 則可用&a或&d[2] 得到變量或數(shù)組元素的地址。②取地址運(yùn)算符“&”不能作用到常量、表達(dá)式上,如&25,&(x+y)等,是錯(cuò)誤的。,6.1.3 指針的運(yùn)算,17,1.基本運(yùn)算(2)間接訪問(wèn)運(yùn)算符*
12、 表達(dá)式一般格式為: &add 其功能是用來(lái)獲取指定地址中的數(shù)據(jù)。 例: int a=3,*p=&a; k=*p; (把a(bǔ)的值賦給k) *p=1; (把1賦給a),6.1.3 指針的運(yùn)算,#include void main(){ double x=0.11,y=0.1; doubl
13、e *p=&x,*q=&y; printf(“&x=%u,&y=%u\n”,&x,&y); printf(“p=%u,q=%u\n”,p,q); printf(“x=%f,y=%f\n”,x,y); printf(“*p=%f,*q=%f\n”,*p,*q); },x,0.11,y,0.1,p,&x,,q,&y,,19,2. 指針的
14、賦值運(yùn)算指針賦值是將對(duì)象的地址存入指針變量。能夠給指針賦值的只有:0或NULL、同類型的地址值。例:int *p,n=10,*q,a[10]; double d=2.5,*pd; p=0;p=NULL; p=&n; q=a;q=&a[0];q=&a[5]; pd=&d;,6.1.3 指針的運(yùn)算,20,通過(guò)對(duì)指針賦予不同的地址值可以讓
15、指針指向不同的變量。例: int a = 1, b = 2, c = 3; int * p; p = &a; printf(“*p=%d, a=%d\n”,*p , a); p = &b; printf(“*p=%d, b=%d\n”,*p , b); p = &c;
16、 printf(“*p=%d, c=%d\n”,*p , c);,6.1.3 指針的運(yùn)算,21,多個(gè)指針也可賦相同的地址值,即同時(shí)指向同一目標(biāo)變量。例: int n=5, *p, *q; p =&n; q = p; printf(“*p=%d,*q=%d\n”,*p ,*q);,6.1.3 指針的運(yùn)算,22,指針是存放地址值的變量,C語(yǔ)言不支持把任何其它數(shù)據(jù)如整數(shù)
17、(0除外)賦予指針,也不支持類型不同的指針之間相互賦值。例: int a=5,*p=&a; //初始化可以 double q; *p=&a; //不允許 p=10000; //不允許 p=0x0012ff60; //不允許 p=a; //不允許 q=&a;
18、 //不允許 q=p; //不允許,6.1.3 指針的運(yùn)算,23,3. 指針的引用,6.1.3 指針的運(yùn)算,在引用指針變量時(shí),可能有三種情況:給指針變量賦值。如:p=&a;引用指針變量指向的變量。如有 p=&a; *p=1; 則執(zhí)行printf(“%d”,*p); 將輸出1引用指針變量的值。如:printf(“%o”
19、,p);,使p指向a,*p相當(dāng)于a,以八進(jìn)制輸出a的地址,【例6.13】用指針進(jìn)行兩個(gè)變量值的交換。,void main(){ int i1, i2, *p1, *p2, t; p1=&i1; p2=&i2; printf(“Enter two numbers:\n”); scanf(“%d%d”,p1,p2); printf(“before:i1=%d,i2=%d\n”,i
20、1, i2); t=*p1; *p1=*p2;*p2=t; printf(“after:i1=%d,i2=%d\n”,i1, i2); },利用指針變量輸入i1,i2的值,,,,,,i1,i2,p1,p2,t,4,8,&i1,&i2,4 8↙,4,8,4,【例6.14】從鍵盤輸入兩個(gè)整數(shù)賦給變量a與b,不改變a與b的值,要求按先小后大的順序輸出。,#include void main()
21、{ int a,b,*p,*p1=&a,*p2=&b; printf(“Enter two numbers:\n”); scanf("%d,%d",&a,&b); if (a>b) { p=p1; p1=p2; p2=p; } printf("a=%d\tb=%d\n",a,b); printf("
22、;min=%d\tmax=%d\n",*p1,*p2); },,,,,,a,b,p1,p2,p,8,4,成立,8,4↙,&a,&b,&a,&b,&a,26,在使用指針變量之前,一定要給該指針賦予確定的地址值、0或NULL。一個(gè)沒(méi)有賦值的指針其指向目標(biāo)是不確定的,這種指針被稱為“懸空指針”,將會(huì)出現(xiàn)指針“亂指”現(xiàn)象。 例: int *p, n = 3; *p = 2;,
23、6.1.3 指針的運(yùn)算,將2存放到指針p所指向的隨機(jī)內(nèi)存單元,程序運(yùn)行時(shí)可能會(huì)導(dǎo)致各種錯(cuò)誤,甚至危及系統(tǒng)的正常運(yùn)行。,27,6.2 指針與函數(shù),6.2.1 指針作為函數(shù)的參數(shù)6.2.2 函數(shù)返回指針6.2.3 指向函數(shù)的指針,28,6.2.1 指針作為函數(shù)的參數(shù),使用指針類型做函數(shù)的參數(shù),實(shí)際向函數(shù)傳遞的是地址值。指針作為函數(shù)參數(shù)可以把實(shí)參的地址傳入到被調(diào)函數(shù)中,被調(diào)函數(shù)中對(duì)形參的處理時(shí),可以通過(guò)指針間接訪問(wèn)到實(shí)參,而實(shí)現(xiàn)對(duì)實(shí)參的
24、處理。因此形參的改變能夠影響實(shí)參。從而達(dá)到被調(diào)函數(shù)中形參的改變能夠影響實(shí)參的目的。,【例6.16】用指針進(jìn)行兩個(gè)變量值的交換。,#includevoid main(){ void swap(int *x,int *y); //函數(shù)聲明 int a=15, b=8; printf("before swap: a=%d,b=%d\n",a,b); swap(&
25、amp;a, &b); printf("after swap: a=%d,b=%d\n",a,b);},void swap(int *x,int *y){ int temp;temp = *x;*x = *y;*y = temp;},,,a,b,15,8,,x,&a,,y,&b,,8,15,,指針作函數(shù)的參數(shù),不僅能保留函數(shù)中對(duì)實(shí)參的修改,而
26、且由于傳遞的是地址,不需要生成實(shí)參的副本,因此參數(shù)傳遞的效率較高,特別是傳遞“體積” 較大的數(shù)據(jù),如數(shù)組、結(jié)構(gòu)體等。,void swap(int *x,int *y){ int temp;temp = *x;*x = *y;*y = temp;},void swap(int *x,int *y){ int *temp;*temp = *x;*x = *y;*y =*temp;},錯(cuò)!??!無(wú)確定的指向,#incl
27、ude void main(){…… swap(a,b); printf(“max=%d,min=%d\n”,a,b); }void swap(int x,int y) { int temp; temp=x; x=y; y=temp;},錯(cuò)?。?!無(wú)法交換a,b,,,a,b,15,8,,,x,y,15,8,,8,15,,【例6.17】編寫程序,通過(guò)函數(shù)給數(shù)組輸入若干大于等于0的整數(shù),用負(fù)數(shù)作為輸入結(jié)束
28、標(biāo)志;調(diào)用函數(shù)輸出該數(shù)組中的數(shù)據(jù)。,#include#define M 100void arrout(int *,int); int arrin(int *);void main(){ int s[M],k; k=arrin(s); //數(shù)組名作函數(shù)的實(shí)參 arrout(s,k);},void arrout(int *a,int n) { int i; for(i=0;i<n;i
29、++) printf(((i+1)%5==0)?"%4d\n":"%4d",*(a+i)); printf("\n");},int arrin(int *a) { int i,x; i=0; scanf("%d",&x); while(x>=0) { *(a+i)=x; i++;
30、 scanf("%d",&x); } return i;},*(a+i)=x;a:數(shù)組首地址,即&a[0]a+i:a[i]的地址,即&a[i]*(a+i):指針&a[i]所指的元素,即a[i]。,35,6.2.2 函數(shù)返回指針,函數(shù)的返回值不僅可以整型、字符型、實(shí)型等數(shù)據(jù),還可以是指針類型,即返回值為存儲(chǔ)某種數(shù)據(jù)的內(nèi)存地址。返回指針的函數(shù)被稱為指針函數(shù)。指針函
31、數(shù)定義的一般形式: 數(shù)據(jù)類型 *函數(shù)名(形參表) { 函數(shù)體 },,表示返回值是指針,36,6.2.2 函數(shù)返回指針,一個(gè)函數(shù)也可以返回指針型的數(shù)據(jù)。 例如: int *day(int x,int y); day是函數(shù)名,*表示此函數(shù)值是指針。 最前面的int表示返回的指針是指向整型變量的。 函數(shù)day()返回一個(gè)指向int型數(shù)據(jù)的指針(地址值)
32、。 ,#include int g = 1;int *gfunc() //返回全局變量的地址{ return &g;}int *sfunc() //返回局部靜態(tài)變量的地址{ static int s = 2; return &s;},void main(){int *p;p=gfunc(); //p被賦值為全局變量的地址*p = 3;
33、 //修改全局變量的值printf("*P=%d\tg=%d\n",*p, g) ;p=sfunc() //p被賦值局部靜態(tài)變量的地址*p = 4; //修改局部靜態(tài)變量的值printf("*p=%d\t*sfunc()=%d\n", *p, *sfunc()) ;},等同于:*(sfunc()),當(dāng)返回指針變量時(shí),要求該指針是指向全局變量、靜態(tài)局部變量
34、的指針,要謹(jǐn)慎使用返回指向自動(dòng)局部變量的指針。,39,6.2.3 指向函數(shù)的指針,在程序中定義了一個(gè)函數(shù),在編譯時(shí),編譯系統(tǒng)為函數(shù)代碼分配一段存儲(chǔ)空間,這段存儲(chǔ)空間的起始地址,稱為這個(gè)函數(shù)的指針(地址)。函數(shù)名表示該函數(shù)的地址。可以定義一個(gè)指向函數(shù)的指針變量,用來(lái)存放某一函數(shù)的起始地址,這就意味著此指針變量指向該函數(shù)。這種指針變量稱為指向函數(shù)的指針,簡(jiǎn)稱為函數(shù)指針。,40,6.2.3 指向函數(shù)的指針,指向函數(shù)的指針的定義形式: 數(shù)
35、據(jù)類型 (*指針變量名)(函數(shù)參數(shù)表);例: int (*P)(); 定義了一個(gè)指向函數(shù)的指針變量p,指針p所指向函數(shù)應(yīng)有int型返回值,并沒(méi)有形參。,,函數(shù)返回值類型,,,圓括號(hào)不能省略,,函數(shù)的形參個(gè)數(shù)和類型,41,6.2.3 指向函數(shù)的指針,如果要用指針調(diào)用函數(shù),必須先使指針變量指向該函數(shù)。如: p=max; 把max函數(shù)的入口地址賦給指針變量p調(diào)用函數(shù)時(shí),只需將(*p)代替函數(shù)名即可。例如:c=
36、(*p)(a,b); 相當(dāng)于:c=max(a,b);,#include float max(float, float, float); void main( ) { float (*p)(float, float, float); float a, b, c, big; p=max; //使函數(shù)指針p指向max()函數(shù) scanf(“%f%f%f”, &a
37、,&b,&c); big=(*p)(a,b,c); printf("a=%.2f\tb=%.2f\tc=%.2f\n big=%.2f\n",a,b,c,big); },等價(jià)于:big=max(a,b,c);,float max(float x,float y,float z) { float temp=x; if(temp<y) temp=y
38、; if(temp<z) temp=z; return temp; },43,6.2.3 指向函數(shù)的指針,函數(shù)指針的主要作用是作為參數(shù)在函數(shù)間傳遞函數(shù),實(shí)際上傳遞的是函數(shù)的執(zhí)行地址,或者說(shuō)傳遞是函數(shù)的調(diào)用控制。當(dāng)函數(shù)在兩個(gè)函數(shù)間傳遞時(shí),主調(diào)函數(shù)的實(shí)參應(yīng)該是被傳遞函數(shù)的函數(shù)名,而被調(diào)函數(shù)的形參是接收函數(shù)地址的函數(shù)指針??梢越o函數(shù)指針賦予不同的函數(shù)名(函數(shù)的入口地址),而調(diào)用不同的函數(shù)。,#include int
39、minus(int,int); int add(int,int); int multiply(int,int); void process(int x,int y,int(*fun)(int,int)); void main(){ int a,b; print
40、f(“Enter a and b:”); scanf(“%d,%d”,&a,&b); printf(“a minus b=”); process(a,b,minus); printf(“a add b=”); process(a,b,add); printf(“a multiply b=”); process(a,b,multiply);},函數(shù)名表示該函數(shù)的地址,前面不要加
41、&。,,,,int minus(int x,int y) {int z; z=x-y; return (z); },int add(int x,int y) { int z; z=x+y; return (z); },int multiply(int x,int y) { int z; z=x*y; return (z); },vo
42、id process(int x,int y,int (*fun)(int,int)) { int result; result=(*fun)(x,y); printf(“%d\n”,result); },形參: 指向函數(shù)的指針變量,它可以指向的函數(shù)類型為整型且有兩個(gè)整型形參的函數(shù)。,46,6.3 指針與數(shù)組,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn)6.3.2 字符指針6.3.3 指向數(shù)組的指針
43、6.3.4 指針數(shù)組6.3.5 指向指針的指針,47,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),1.指針與一維數(shù)組的關(guān)系,數(shù)組在計(jì)算機(jī)中被存儲(chǔ)在一個(gè)連續(xù)的內(nèi)存空間。數(shù)組中的每一個(gè)元素都具有相同的數(shù)據(jù)類型并分配了相同大小的存儲(chǔ)空間。變量有地址,數(shù)組包含若干元素,每個(gè)數(shù)組元素都有相應(yīng)的地址,即該元素相對(duì)數(shù)組首地址的偏移量。 所謂數(shù)組元素的指針就是數(shù)組元素的地址??梢杂靡粋€(gè)指針變量指向一個(gè)數(shù)組元素。,48,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),
44、int *p1,*p2,*p3,*p4; int a[10]={1,2,3,4,5,6,7,8,9,10}; p1=&a[0]; P2=p1; p3=&a[5]; p4=&a[10];,p1,p2,p3,p4,,,,,a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9],,,,,,,注意:當(dāng)一個(gè)指針指向數(shù)組中的某個(gè)元
45、素時(shí),不但可以通過(guò)該指針訪問(wèn)被指數(shù)組元素,還可以通過(guò)它訪問(wèn)數(shù)組里的其他元素。,,49,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),如果指針p已指向數(shù)組中的一個(gè)元素,則p+1指向同一數(shù)組中的下一個(gè)元素。數(shù)組名表示數(shù)組首地址(即數(shù)組第一個(gè)元素的地址),這個(gè)地址是在數(shù)組定義時(shí)就已確定的且不可更改,所以數(shù)組名可以看作是一個(gè)常量指針。 例:int a[10],*p; p=a; 作用:“把a(bǔ)數(shù)組的首元素的地址賦給指針變量p”,而不
46、是“把數(shù)組a各元素的值賦給p”。,p=a; 等價(jià)于p=&a[0];,,,,等價(jià)于int a[10],*p=a;,50,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),當(dāng)指針p指向數(shù)組的首地址時(shí):,p+i和a+i:表示指向同一數(shù)組a中的第i個(gè)元素a[i]或者說(shuō)它們就是a[i]的地址。*(p+i)或*(a+i):表示指針p+i或a+i所指向的數(shù)組元素,即a[i]。指針p也可以帶下標(biāo)表示數(shù)組元素,如p[i]即表示a[i]。,51,6.3.1 指
47、針對(duì)數(shù)組元素的訪問(wèn),引用數(shù)組元素,可用下面兩種方法:下標(biāo)法:用數(shù)組名加下標(biāo) ,如a[i]; 或用指針名加下標(biāo),如p[i]。指針?lè)?,即地址法?(a+i) 或*(p+i),第i個(gè)元素:a[i] *(a+i) p[i] *(p+i)第i個(gè)元素的地址:&a[i] a+i &p[i]
48、 p+i,,,,,,,,52,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),2.指針訪問(wèn)數(shù)組元素的方法,(1)數(shù)組名指針?lè)?,即通過(guò)一維數(shù)組名+偏移量的方式訪問(wèn)數(shù)組元素。 int a[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10};*(a+3)=50; //相當(dāng)于a[3]=50 ; scanf("%d", a+5); //相當(dāng)于
49、scanf("%d",&a[5]); printf("%d\n", *(a+8) ); //相當(dāng)于printf("%d\n", a[8]) ) ;,53,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),(2)指針名指針?lè)?,即通過(guò)指向數(shù)組首地址的指針名+偏移量的方式訪問(wèn)數(shù)組元素。 int a[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 1
50、0},*p=a;*(p+3)=50; //相當(dāng)于a[3]=50 ; scanf("%d", p+5); //相當(dāng)于scanf("%d",&a[5]); printf("%d\n", *(p+8) ); //相當(dāng)于printf("%d\n", a[8]
51、) ) ;,54,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),(3)指針名下標(biāo)法,即通過(guò)指針名+下標(biāo)的方式訪問(wèn)數(shù)組元素。 int a[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10},*p=a;p[3]=50; //相當(dāng)于a[3]=50 ; scanf("%d", &p[5]); //相當(dāng)于scanf("%d&qu
52、ot;,&a[5]); printf("%d\n", p[8]) ); //相當(dāng)于printf("%d\n", a[8]) ) ;,55,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),注意:數(shù)組名a是一個(gè)常量指針,是不能修改的,任何企圖修改它的操作(如賦值、自增/自減)都是非法的。而指針p則是可以任意賦值,可以通過(guò)指針運(yùn)算在一個(gè)合法的地址范圍內(nèi)任意改變,指向數(shù)組中的任何一個(gè)
53、元素。 int a[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10},*p; a=a+1; //不合法 p=&a[5]; p[0]://相當(dāng)于a[5] p[1]: //相當(dāng)于a[6],56,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),3.指針的算術(shù)運(yùn)行,指針的算術(shù)運(yùn)算是指可以進(jìn)行指針加/減整數(shù)運(yùn)算,指針的自增/自減運(yùn)算以及同類型指針之間的減法運(yùn)算,而乘法、除法、求余運(yùn)算以
54、及指針之間的加法運(yùn)算等,并無(wú)實(shí)際意義,也不支持。,57,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),(1)指針加、減整數(shù)運(yùn)算 如果指針變量p已指向數(shù)組中的一個(gè)元素,則p+1指向同一數(shù)組中的下一個(gè)元素,p-1指向同一數(shù)組中的上一個(gè)元素。int a[10],*p=a; 假設(shè)a[0]的地址為13ff78H,則p的值為13ff78Hp+1的值為13ff7CH(13ff78H+4)。 因?yàn)閕nt型數(shù)據(jù)占4個(gè)字節(jié)。,58,6.3
55、.1 指針對(duì)數(shù)組元素的訪問(wèn),對(duì)不同數(shù)據(jù)類型的指針p,p+n(n為整數(shù))表示的實(shí)際地址值是: p中的地址值+n×數(shù)據(jù)長(zhǎng)度(字節(jié)數(shù)) 注意: 通常指針加/減整數(shù)運(yùn)算與數(shù)組相聯(lián)系才有具體的意義。,#include void main(){ int a[]={2, 4, 6, 8, 10, 12, 14, 16, 18, 20}; int *p=&a[5]; printf("*
56、(p-2)= %d\n*(p-1)= %d\n", *(p-2),*(p-1)); printf("*p=%d\n",*p); printf("*(p+1)= %d\n*(p+2)= %d\n", *(p+1),*(p+2));},,,p,,p-1,,p-2,,p+1,,p+2,//相當(dāng)于:a[3],a[4],//相當(dāng)于:a[5]
57、,//相當(dāng)于:a[6],a[7],注意:表達(dá)式*p+n表達(dá)式*(p+n)是不同的。 *p+1值為13, *(p+1)值為14。,60,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),(2)指針的自增、自減運(yùn)算 p++:指針p指向下一個(gè)對(duì)象; p--:指針p指向上一個(gè)對(duì)象。 int a[5],*p; p=a; (假設(shè)&a[0]為:13ff78) p++; p--;,,,,注意:指
58、針變量的自增、自減運(yùn)算與普通變量規(guī)則一樣。,#include void main(){ int a[]={1,2,3 ,4, 5},*p=a; printf("*p=%d\n",*p); printf("*p++=%d\n",*p++); printf("*++p=%d\n",*++p); printf("(*p)++=%d\n"
59、,(*p)++); printf("++(*p)=%d\n",++(*p));},,p,注意:指針p的自增/自減運(yùn)算與進(jìn)行p±1運(yùn)算是有區(qū)別的。,輸出:a[0],等價(jià)于:*(p++),等價(jià)于:*(++p),輸出:a[2],4,5,輸出:a[2],62,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),(3)兩個(gè)同類型指針相減 兩個(gè)同類型的指針可以相減,其運(yùn)算結(jié)果是兩個(gè)指針?biāo)赶虻牡刂肺恢弥g所包含的對(duì)象個(gè)數(shù)。
60、兩個(gè)指針相減也是地址計(jì)算,但結(jié)果值不是地址量,而是一個(gè)整數(shù)(對(duì)象個(gè)數(shù))。 設(shè)指針p和q是指向同類型的對(duì)象,則p-q運(yùn)算的結(jié)果按下面公式計(jì)算得到:,,63,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),(3)兩個(gè)同類型指針相減 float x[10];float *p,*q;p=&x[2];q=&x[8];printf("q-p=%d\n",q-p);q-p的值為:6,,p,q,只有兩個(gè)指針指向
61、同一數(shù)組中的元素時(shí)才有意義。兩個(gè)地址不能加。,64,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),4.指針的關(guān)系運(yùn)算 兩個(gè)同類型的指針,或者一個(gè)指針和一個(gè)地址量之間可以進(jìn)行比較,比較的結(jié)果反映出兩個(gè)地址位置的前后關(guān)系。兩個(gè)指針相等是指兩個(gè)指針同時(shí)指向同一位置。,65,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),int a[10];int *p=a;for (;p=a;p--) printf("%d ",*p);
62、printf("\n");,要注意指針變量的當(dāng)前值。不同類型指針之間或指針與一般的整型數(shù)據(jù)之間的比較是沒(méi)有實(shí)際意義的。指針p與整數(shù)0可以進(jìn)行等于或不等于的比較,即: p==0或p!=0 (0也可以寫成NULL),66,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),5.應(yīng)用舉例,【例6.30】將數(shù)組中所有元素的值對(duì)稱交換。,a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9],,9
63、,0,#include void main(){ int a[10]={0,1,2,3,4,5,6,7,8,9}; int *begin,*end,t; begin=&a[0]; end=&a[9]; while(begin<end) { t=*begin; *begin=*end; *end=t; begin++; end--;
64、 },begin=a; while(begin<a+10) printf("%3d",*begin++); printf("\n"); },68,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),【例6.31】若有一個(gè)數(shù)列是升序排列的,現(xiàn)插入一個(gè)數(shù)要求該數(shù)列仍保持升序排列 。,a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7
65、],x,,x<a[0]:將x插入到列頭,x>a[6]:將x插入到列尾,先查找插入位置,再插入。,#include void main(){ int a[8]={2,3,5,8,10,11,15}; int i,j,x,*p; p=a; scanf(“%d”,&x); if(x=1;i--) *(p+i)=*(p+i-1); *p=x;
66、 } else if(x>*(p+6)) //將插入的數(shù)列尾 *(p+7)=x;,else{ for(i=1;i*(p+i) && xi;j--) *(p+j+1)=*(p+j); *(p+j+1)=x; } } for(i=0;i<8;i++) printf(“%5d
67、”,*p++); printf(“\n”); },71,6.3.1 指針對(duì)數(shù)組元素的訪問(wèn),【例6.32】將數(shù)組元素按降序排列,并輸出。,a[0] a[1] a[2] a[3] a[4],14 6 23 3 35,,,,35 6 23 3 14,,,,35 23 6 3 14,,,,
68、35 23 14 3 6,,,,35 23 14 6 3,選擇法,#include void main(){ int a[8]={34,56,45,57,69,48,89,61}; int *p=a,i=0,j=0,k=0,t=0;for(i=0; i<7; i++){ k=i; for(j=
69、i+1; j<8; j++) if(p[k]<p[j]) k=j; if(k!=i) {t=p[i]; p[i]=p[k]; p[k]=t;}}for(i=0; i<8; i++) printf("%5d",*(p+i));printf("\n");},if (*(p+k)<*(p+j)) k
70、=j;,{t=*(p+i);*(p+i)=*(p+k);*(p+k)=t;},73,6.3.2 字符指針,1.用字符指針處理字符數(shù)組,【例6.33】編寫程序,對(duì)具有10個(gè)元素的字符數(shù)組,從下標(biāo)為4的元素開(kāi)始,全部設(shè)置為“*”,保持前4個(gè)元素不變。,#include void setstr(char *,int);void arrout(char *,int);void main(){ char c[10]={'A
71、9;,'B','C','D','E','F','G','H','I','J'}; setstr(&c[4],6); arrout(c,10); },void setstr(char *a,int n){ int i; fo
72、r(i=0;i<n;i++) *(a+i)='*';}void arrout(char *a,int n){ int i; for(i=0;i<n;i++) printf("%c",a[i]); printf("\n");},c[0]c[1]c[2]c[3]c[4]c[5]c[6]c[7]c[8]c[9],,c[0]c[1]c[2]c
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(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)論