C語言程序設(shè)計教程(第2版)-課件 第8章 指針_第1頁
C語言程序設(shè)計教程(第2版)-課件 第8章 指針_第2頁
C語言程序設(shè)計教程(第2版)-課件 第8章 指針_第3頁
C語言程序設(shè)計教程(第2版)-課件 第8章 指針_第4頁
C語言程序設(shè)計教程(第2版)-課件 第8章 指針_第5頁
已閱讀5頁,還剩52頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

8.1指針的概念一、變量的地址

計算機(jī)中,數(shù)據(jù)存儲在內(nèi)存中,內(nèi)存可劃分為若干存儲單元,每個單元可以存放8位二進(jìn)制數(shù),即1個字節(jié),每個單元具有唯一的一個地址。(內(nèi)存區(qū)的每一個字節(jié)有一個編號,即地址)變量的地址:系統(tǒng)為變量分配的內(nèi)存單元的地址。(一個無符號的整型數(shù))inta;floatb;a=3;b=5;二、變量的訪問方式1)直接訪問2)間接訪問定義一個變量p,存放a的地址,通過p訪問a,若將變量p的值改為3AB8(b的地址),則可通過p訪問b。三、指針變量:存放地址的變量如:p為指針變量,它存放整型變量a的首地址,稱指針變量p指向整型變量a。8.2指針變量的定義與引用一、定義方法類型符*指針變量名如:int*p1,*p2;char*ps;float*pf;指針變量的類型:所指向的內(nèi)存中存放的數(shù)據(jù)的類型。二、指針變量的賦值指針變量的值是地址,是個無符號整數(shù)。(不能直接將整型常量賦給指針變量)1)用變量的地址給指針變量賦值(求地址運(yùn)算符&)變量的類型必須與指針變量的類型相同如:inta,b,*p;p=&a;2)用相同類型的指針變量賦值如:inta;int*p1,*p2;p1=&a;p2=p1;3)賦空值NULLp=NULL;或p=0;指針變量初始化方法:賦空值NULL用已定義的變量的地址int*p1=NULL;floata;float*p2=&a;三、指針變量的應(yīng)用1)兩個運(yùn)算符:*、&

形式:&任意變量

/*取地址運(yùn)算符*/

*指針變量

/*指針運(yùn)算符*/&a表示變量a所占據(jù)的內(nèi)存空間的首地址;*p表示指針變量p所指向的內(nèi)存中的數(shù)據(jù)。應(yīng)用:通過指針變量訪問所指變量將指針變量指向被訪問的變量如:inta=5,*p,b;p=&a;訪問所指變量取內(nèi)容:b=*p;存內(nèi)容:*p=100;注意:*p若出現(xiàn)在“=”的右邊或其他表達(dá)式中則為取內(nèi)容;*p若出現(xiàn)在“=”的左邊為存內(nèi)容。#include<stdio.h>intmain(){inta=5,b=3;int*p;p=&a;b=*p+5;printf(“%d\n”,b);*p=4;printf(“%d,%d”,a,*p);}104,4例:讀程序?qū)懡Y(jié)果。#include<stdio.h>intmain(){inta=3,b=5;int*p=&a;printf(“%d\n”,*p);*p=4;p=&b;printf(“%d\n”,*p);*p=6;printf(“%d,%d\n”,a,b);}354,62)運(yùn)算規(guī)則*、&:優(yōu)先級相同,且右結(jié)合,與++、--、!等單目運(yùn)算符優(yōu)先級相同。下列表達(dá)式的含義:

&*p*&a等價于pa2)運(yùn)算規(guī)則*、&:優(yōu)先級相同,且右結(jié)合,與++、--、!等單目運(yùn)算符優(yōu)先級相同。寫出下面各表達(dá)式的結(jié)果,并找出具有等價關(guān)系的對子。inta=5,*p=&a;&*p*&a(*p)++&aa*p++*(p++)a++下列表達(dá)式的含義:

&*p*&a等價于pa#include<stdio.h>intmain(){inta,b,c;int*pa,*pb,*pc;pa=&a,pb=&b,pc=&c;scanf(“%d%d”,pa,pb);c=a+b;printf(“c=%d\n”,*pc);*pc=a+*pb;printf(“c=%d\n”,c);c=++*pa+(*pb)++;printf(“c=%d\n”,c);}例:交換兩個數(shù)a、b的值#include<stdio.h>intmain(){inta=5,b=8;intt;printf(“a=%d,b=%d\n”,a,b);t=a;a=b;b=t;printf(“a=%d,b=%d\n”,a,b);}例:交換兩個數(shù)a、b的值#include<stdio.h>intmain(){inta=5,b=8;intt;int*pa=&a,*pb=&b;printf(“a=%d,b=%d\n”,a,b);t=*pa;*pa=*pb;*pb=t;printf(“a=%d,b=%d\n”,a,b);}指針變量作函數(shù)參數(shù)例:編寫一個函數(shù)實現(xiàn)兩個數(shù)的交換。#include<stdio.h>intswap(intx,inty){intt;t=x;x=y;y=t;}main(){inta=3,b=5;swap(a,b);printf(“%d%d”,a,b);}#include<stdio.h>intswap(int*x,int*y){intt;t=*x;*x=*y;*y=t;}main(){inta=3,b=5;swap(&a,&b);printf(“%d%d”,a,b);}例:輸入a,b,c三個數(shù),按大小順序輸出。#include<stdio.h>intswap(int*x,int*y){intt;t=*x;*x=*y;*y=t;}intmain(){inta,b,c;printf(“enterdataa,b,c:”);scanf(“%d%d%d”,&a,&b,&c);if(a<b)swap(&a,&b);if(a<c)swap(&a,&c);

if(b<c)swap(&b,&c);printf(“%d%d,%d”,a,b,c);}8.3指針和數(shù)組一、一維數(shù)組與指針1)數(shù)組是連續(xù)存放的若干個元素的集合2)數(shù)組名就是指向此數(shù)組第1個元素的指針(首地址)如:inta[10],*p;則p=a;等價于p=&a[0];3)某一元素的地址:p=&a[i]

用指針引用該元素:*pa[i]4)數(shù)組元素的下標(biāo)在內(nèi)部實現(xiàn)時,統(tǒng)一按“基地址+位移”的方式處理,即:aa+1a+i故表示數(shù)組元素的地址可用:p+i、a+i

表示數(shù)組元素的內(nèi)容可用:a[i]、*(p+i)、*(a+i)數(shù)組名a(數(shù)組的指針)與指向數(shù)組首地址的指針變量p不同,a不是變量。例:讀程序?qū)懡Y(jié)果。#include<stdio.h>intmain(){inti,a[5];int*p;for(i=0;i<5;i++){p=&a[i];a[i]=i;printf(“%3d”,*p);}printf(“\n”);}#include<stdio.h>intmain(){inti,a[5];int*p=a;for(i=0;i<5;i++,p++){*p=i;printf(“%3d”,*p);}printf(“\n”);}數(shù)組指針、指針變量與數(shù)組元素之間的關(guān)系:設(shè)有inta[10],*p=a;則例:數(shù)組的使用intmain(){inti,a[5],*p=a;printf(“Input5numbers:\n”);for(i=0;i<5;i++)scanf(“%d”,&a[i]);printf(“Outputthesenumbers:\n”);for(i=0;i<5;i++)printf(“%d”,a[i]);printf(“\n”);}scanf(“%d”,a+i);scanf(“%d”,p+i);printf(“%d”,*(a+i));printf(“%d”,*(p+i));二、指針的運(yùn)算1)賦值運(yùn)算如:p=&x;p=a;p=NULL;2)加減運(yùn)算如:a+i、p+i(只能用于數(shù)組元素的引用,注意下標(biāo)的有效范圍)3)指針相減運(yùn)算:求兩地址的間距如:p-a(兩個指針的類型相同,并指向同一連續(xù)的存儲區(qū)域)4)移動指針(++、--)如:p++

(對數(shù)組名不能實施該運(yùn)算)例:將數(shù)組a的數(shù)據(jù)復(fù)制到數(shù)組b中并輸出#include<stdio.h>#defineM7intmain(){inti,a[M]={23,15,50,3,21,20,35},b[M];for(i=0;i<M;i++)b[i]=a[i];printf(“Outputthesenumbers:\n”);for(i=0;i<M;i++)printf(“%d”,b[i]);printf(“\n”);}#include<stdio.h>#defineM7intmain(){inti,a[M]={23,15,50,3,21,20,35},b[M];int*p=a,*q=b;for(i=0;i<M;i++){*q=*p;q++;p++;}printf(“Outputthesenumbers:\n”);for(i=0;i<M;i++)printf(“%d”,b[i]);printf(“\n”);}例:將數(shù)組a的數(shù)據(jù)復(fù)制到數(shù)組b中并輸出#include<stdio.h>#defineM7intmain(){inti,a[M]={23,15,50,3,21,20,35},b[M];for(i=0;i<M;i++)b[i]=a[i];printf(“Outputthesenumbers:\n”);for(i=0;i<M;i++)printf(“%d”,b[i]);printf(“\n”);}#include<stdio.h>#defineM7intmain(){inti,a[M]={23,15,50,3,21,20,35},b[M];int*p=a,*q=b;for(i=0;i<M;i++){*q=*p;q++;p++;}printf(“Outputthesenumbers:\n”);for(i=0;i<M;i++)printf(“%d”,b[i]);printf(“\n”);}printf(“%d”,*q++);三、數(shù)組的指針與函數(shù)實參例:編寫一函數(shù)求一維數(shù)組的最大元素及其下標(biāo)位置(要求使用指針)已知:數(shù)組首地址p,元素個數(shù)n;(作函數(shù)參數(shù))結(jié)果:下標(biāo)k;(作返回值)intmax_array(int*p,intn)設(shè)最大值放在max中,則初始狀態(tài)為:

max=*p,k=0如果*(p+i)>max則max=*(p+i)且k=i#include<stdio.h>intmax_array(int*p,intn){intk=0,max=*p,i;for(i=0;i<n;i++)if(*(p+i)>max){max=*(p+i);k=i;}returnk;}intmain(){inta[10]={23,43,52,23,5,22,33,35,96,34};inti,*p=a,k;for(i=0;i<10;i++)printf(“%5d”,*(p+i));k=max_array(a,10);printf(“\nmax=a[%d]=%d\n”,k,*(p+k));}例:編寫一函數(shù)求一維數(shù)組的元素倒置存放。已知:一維數(shù)組,元素個數(shù)n;結(jié)果:倒置后的一維數(shù)組函數(shù)定義:intinverse(int*p,intn)算法:1、令p指向數(shù)組的開始,q指向結(jié)束2、交換兩單元的內(nèi)容3、兩指針向中間靠攏4、重復(fù)上述2和3,直到p>=q#include<stdio.h>intinverse(int*p,intn){int*q,t;q=p+n-1;while(p<q){t=*p;*p=*q;*q=t;p++;q--;}}intmain(){inta[]={1,3,5,7,9};intk,*p;for(p=a,k=0;k<5;k++)printf(“%5d”,*p++);printf(“\n”);inverse(a,5);for(p=a,k=0;k<5;k++)printf(“%5d”,*p++);}四、多維數(shù)組與指針

用指針變量可以指向一維數(shù)組中的元素,也可以指向多維數(shù)組中的元素。1.多維數(shù)組元素的地址可以認(rèn)為二維數(shù)組是“數(shù)組的數(shù)組”,例:定義inta[3][4]={{1,3,5,7},{2,4,6,8},{9,1,0,1}};則二維數(shù)組a是由3個一維數(shù)組所組成的。135724689101a[0]a[1]a[2]a此二維數(shù)組可以看作三個一維數(shù)組

a為二維數(shù)組的首地址

a[0]或*a為第一個一維數(shù)組的首地址

a[0][0]或*(*a+0)為第一個一維數(shù)組的第一個元素135724689101a[0]a[1]a[2]aa[i][j]*(a[i]+j)*(*(a+i)+j)數(shù)組元素

a[i]&a[i][0]*(a+i)數(shù)組元素地址a+i&a[i]a是二維數(shù)組名,不同于一維數(shù)組,如:

staticinta[3][4]={{1,3,5,7},{2,4,6,8},{9,1,0,1}};

int*p;可以p=a[0];而p=a錯誤。不要把&a[i]理解為a[i]單元的物理地址,因為a[i]不是一個變量,&a[i]和a[i]的值是相等的。但含意不一樣。前者指向行,后者指向列;

&a[i]:第i行的首地址a[i]:第i行0列地址

&a[i]+1:第i+1行的首地址a[i]+1:第i行1列的地址表示形式含義a

二維數(shù)組名,指向一維數(shù)組a[0],即0行首地址a[0],*(a+0),*a0行0列元素地址a+1,&a[1]1行首地址a[1],*(a+1)1行0列元素a[1][0]的地址a[1]+2,*(a+1)+2,&a[1][2]1行2列元素a[1][2]的地址*(a[1]+2),*(*(a+1)+2),a[1][2]1行2列元素a[1][2]的值2.指向多維數(shù)組元素的指針變量(1)指向數(shù)組元素的指針變量例:用指針變量輸出二維數(shù)組元素的值

#include<stdio.h>intmain(){

inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

int*p;

for(p=a[0];p<a[0]+12;p++)

{if((p-a[0])%4==0)

printf(″\n″);

printf(″%4d″,*p);

}}

運(yùn)行結(jié)果如下:1357911131517192123

(2)指向由m個元素組成的一維數(shù)組的指針變量例:出二維數(shù)組任一行任一列元素的值#include<stdio.h>intmain(){inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

int(*p)[4],i,j;

p=a;

scanf(“i=%d,j=%d”,&i,&j);printf(“a[%d,%d]=%d\n”,i,j,*(*(p+i)+j));}

運(yùn)行情況如下:i=1,j=2↙a[1,2]=138.4指針與字符串1)C語言中字符串以‘\0’作結(jié)束符;2)用字符數(shù)組存放字符串;3)字符串指針就是字符數(shù)組的首地址。如:chara[]=“Apple”;charb[]={‘C’,’h’,’i’,’n’,’a’,’\0’};一、字符串指針變量定義:char*指針變量如:char*p,*q=“Language”;p=“Thisisabook.”;如:char*p,c[10];p=c;注意:p指向字符串的首地址,不是存放字符串。例:逆序打印字符串算法:設(shè)字符串為q;令p指向串尾;打印字符*p,并將p前移,直到p指向串首。#include<stdio.h>intmain(){char*p,*q=“Language”;for(p=q;*p!=‘\0’;)p++;for(p--;p>=q;p--)putchar(*p);putchar(‘\n’);}例:逆序打印字符串算法:設(shè)字符串為q;令p指向串尾;打印字符*p,并將p前移,直到p指向串首。#include<stdio.h>intmain(){char*p,*q=“Language”;n=strlen(q);p=q+n;for(p--;p>=q;p--)putchar(*p);putchar(‘\n’);}例:編寫一函數(shù)判斷一個字符串是否回文。(順讀與逆讀相同)已知:字符串指針變量p(作參數(shù));結(jié)果:是或否算法:1、令q指向最后一個字符2、*p==*q,則兩指針向里靠攏,直到p>=q,則return1;否則return0intishuiwen(char*p){char*q=p;while(*q!=‘\0’)q++;q--;while(p<q)if(*p==*q){p++;q--;}elsereturn0;return1;}三、字符數(shù)組與字符指針變量比較

chara[]=“Ilovethisgame”,*p=a;1)存儲的內(nèi)容不同字符數(shù)組可以存字符串,存的是字符;字符指針變量存的是字符串在內(nèi)存的首地址。2)賦值方式不同字符數(shù)組只能對各個元素賦值;字符指針變量只賦值一次,賦的是地址。如:chara[10],*p;p=“China”;a=“Hello”;(錯誤)3)當(dāng)沒有賦值時字符數(shù)組名代表了一個確切的地址;字符指針變量中的地址是不確定的。如:chara[10],*p;scanf(“%s”,a);scanf(“%s”,p);(錯誤)4)字符數(shù)組名不是變量,不能改變值;字符指針變量可以改變值。如:a++;(錯誤)p++;8.5指向函數(shù)的指針變量

一個函數(shù)在編譯時被分配給一個入口地址,這個入口地址就稱為函數(shù)的指針。可以定義一個指針變量指向函數(shù),該指針稱為指向函數(shù)的指針變量。其定義形式如下:例如:int(*p)(int,int);p=max;mainmaxmin定義p為指向函數(shù)的指針變量,p指向一個帶整型返回值的函數(shù).數(shù)據(jù)類型(*指針變量名)(參數(shù)列表)maxp例:求a和b中的大者。intmain(){intmax(int,int);inta,b,c,(*p)(int,int);

p=max;scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d",a,b,c);}注意:對函數(shù)指針變量p進(jìn)行p++,p+n,p--等運(yùn)算無意義.intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}當(dāng)每次調(diào)用的函數(shù)不是固定的時,用指針變量就比較方便。#include<stdio.h>intmain(){inta,b,c,d,(*p)(int,int);a=3,b=5;p=max;c=(*p)(a,b);p=min;d=(*p)(a,b);printf("c=%d,d=%d\n",c,d);}intmax(intx,inty){ returnx>y?x:y;}intmin(intx,inty){ returnx<y?x:y;}intmain(){intmax(int,int),min(int,int),add(int,int);intprocess(intx,inty,int(*fun)(int,int));inta,b;scanf(“%d,%d”,&a,&b);printf(“max=”);process(a,b,max);printf(“min=”);process(a,b,min);printf(“sum=”);process(a,b,add);}例:設(shè)一個函數(shù)process,在調(diào)用它的時候,每次實現(xiàn)不同的功能。輸入a,b,分別求a,b中的大數(shù),a,b中的小數(shù)和a,b之和。intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}intmin(intx,inty){intz;if(x<y)z=x;elsez=y;return(z);}intadd(intx,inty){intz;z=x+y;return(z);}intprocess(intx,inty,int(*fun)(int,int)){intresult;result=(*fun)(x,y);printf(“%d\n”,result);}例:設(shè)一個函數(shù)process,在調(diào)用它的時候,每次實現(xiàn)不同的功能。輸入a,b,分別求a,b中的大數(shù),a,b中的小數(shù)和a,b之和。8.6返回指針值的函數(shù)一般定義形式為:

類型名*函數(shù)名(參數(shù)表)例如:int*a(intx,inty);8.6返回指針值的函數(shù)一般定義形式為:

類型名*函數(shù)名(參數(shù)表)例如:int*a(intx,inty);例:有若干個學(xué)生的成績(每個學(xué)生有4門課程),要求在用戶輸入學(xué)生序號以后,能輸出該學(xué)生的全部成績。intmain(){staticfloatscore[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};float*search(float(*pointer)[4],intn);float*p;inti,m;scanf("%d",&m);p=search(score,m);for(i=0;i<4;i++)printf("%5.2f\t",*(p+i));}float*search(float(*pointer)[4],intn){float*pt;pt=*(pointer+n);return(pt);}607080905689678834789066pointerpt【例】輸入一個字符串和一個字符,如果該字符在已知字符串中,從該字符第一次出現(xiàn)位置開始輸出字符串中剩余部分。要求定義如下函數(shù)找出該字符第一次出現(xiàn)的位置并返回主函數(shù)進(jìn)行剩余字符串的輸出。char*match(char*s,charch){}#include<stdio.h>intmain(){ char*match(char*s,charch); charch,str[20],*p; p=NULL; printf(“請輸入字符串”); scanf(“%s”,str); getchar(); printf(“請輸入一個字符”); scanf(“%c”,&ch); if((p=match(str,ch))!=NULL) printf(“%s\n”,p); else printf(“字符不在已知字符串中\(zhòng)n”);}char*match(char*s,charch){ while(*s!=’\0’) {if(*s==ch) returns; else s++; }returnNULL;}8.7指針數(shù)組和指向指針的指針指針數(shù)組的概念

一個數(shù)組,其元素均為指針類型數(shù)據(jù),稱為指針數(shù)組。定義形式為:類型名*數(shù)組名[數(shù)組長度]

例如:int*p[5];char*name[5];name[0]name[1]name[2]name[3]name[4]FollowmebasicgreatWallFORTRANComputerdesign利用指針數(shù)組求一維數(shù)組的最大值。#include<stdio.h>intmain(){ inta[5]={20,56,80,70,90},i,max; int*p[5];for(i=0;i<=4;i++) p[i]=&a[i]; max=*p[0]; for(i=1;i<=4;i++) if(*p[i]>max) max=*p[i]; printf(“max=%d\n”,max);}intmain(){staticchar*name[]={"followme","basic","greatwall","fortran","computerdesign"};intn=5;sort(name,n);print(name,n);}intsort(char*name[],intn){char*temp;inti,j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=name[i];name[i]=name[k];name[k]=temp;}}}intprint(char*name[],intn){inti;for(i=0;i<n;i++)printf(“%s\n”,name[i]);}指向指針的指針定義形式為:類型名**標(biāo)識符例如:char**p;p=name+2;

name[0]name[1]name[2]name[3]name[4]FollowmebasicgreatWallFORTRANComputerdesignnamename+2pprintf("%o\n",*p);printf("%s\n",*p);結(jié)果為?例main(){staticchar*name[]={"Followme","BASIC","

溫馨提示

  • 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論