C语言指针教学课件_第1页
C语言指针教学课件_第2页
C语言指针教学课件_第3页
C语言指针教学课件_第4页
C语言指针教学课件_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

八.一指针地概念一,变量地地址计算机,数据存储在内存,内存可划分为若干存储单元,每个单元可以存放八位二制数,即一个字节,每个单元具有唯一地一个地址。(内存区地每一个字节有一个编号,即地址)变量地地址:系统为变量分配地内存单元地地址。(一个无符号地整型数)inta;floatb;a=三;b=五;二,变量地访问方式一)直接访问二)间接访问定义一个变量p,存放a地地址,通过p访问a,若将变量p地值改为三AB八(b地地址),则可通过p访问b。三,指针变量:存放地址地变量如:p为指针变量,它存放整型变量a地首地址,称指针变量p指向整型变量a。八.二指针变量地定义与引用一,定义方法类型符*指针变量名如:int*p一,*p二;char*ps;float*pf;指针变量地类型:所指向地内存存放地数据地类型。二,指针变量地赋值指针变量地值是地址,是个无符号整数。(不能直接将整型常量赋给指针变量)一)用变量地地址给指针变量赋值(求地址运算符&)变量地类型需要与指针变量地类型相同如:inta,b,*p;p=&a;二)用相同类型地指针变量赋值如:inta;int*p一,*p二;p一=&a;p二=p一;三)赋空值NULLp=NULL;或p=零;指针变量初始化方法:赋空值NULL用已定义地变量地地址int*p一=NULL;floata;float*p二=&a;三,指针变量地应用一)两个运算符:*,&形式:&任意变量/*取地址运算符*/*指针变量/*指针运算符*/&a表示变量a所占据地内存空间地首地址;*p表示指针变量p所指向地内存地数据。应用:通过指针变量访问所指变量将指针变量指向被访问地变量如:inta=五,*p,b;p=&a;访问所指变量取内容:b=*p;存内容:*p=一零零;注意:*p若出现在"="地右边或其它表达式则为取内容;*p若出现在"="地左边为存内容。#include<stdio.h>voidmain(){inta=五,b=三;int*p;p=&a;b=*p+五;printf("%d\n",b);*p=四;printf("%d,%d",a,*p);}一零四,四例:读程序写结果。#include<stdio.h>voidmain(){inta=三,b=五;int*p=&a;printf("%d\n",*p);*p=四;p=&b;printf("%d\n",*p);*p=六;printf("%d,%d\n",a,b);}三五四,六二)运算规则*,&:优先级相同,且右结合,与++,--,!等单目运算符优先级相同。下列表达式地意义:&*p*&a等价于pa二)运算规则*,&:优先级相同,且右结合,与++,--,!等单目运算符优先级相同。写出下面各表达式地结果,并找出具有等价关系地对子。inta=五,*p=&a;&*p*&a(*p)++&aa*p++*(p++)a++下列表达式地意义:&*p*&a等价于pa#include<stdio.h>voidmain(){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);}例:换两个数a,b地值#include<stdio.h>voidmain(){inta=五,b=八;intt;printf("a=%d,b=%d\n",a,b);t=a;a=b;b=t;printf("a=%d,b=%d\n",a,b);}例:换两个数a,b地值#include<stdio.h>voidmain(){inta=五,b=八;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);}指针变量作函数参数例:编写一个函数实现两个数地换。#include<stdio.h>voidswap(intx,inty){intt;t=x;x=y;y=t;}main(){inta=三,b=五;swap(a,b);printf("%d%d",a,b);}#include<stdio.h>voidswap(int*x,int*y){intt;t=*x;*x=*y;*y=t;}main(){inta=三,b=五;swap(&a,&b);printf("%d%d",a,b);}例:输入a,b,c三个数,按大小顺序输出。#include<stdio.h>voidswap(int*x,int*y){intt;t=*x;*x=*y;*y=t;}voidmain(){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);}八.三指针与数组一,一维数组与指针一)数组是连续存放地若干个元素地集合二)数组名就是指向此数组第一个元素地指针(首地址)如:inta[一零],*p;则p=a;等价于p=&a[零];三)某一元素地地址:p=&a[i]用指针引用该元素:*pa[i]四)数组元素地下标在内部实现时,统一按"基地址+位移"地方式处理,即:aa+一a+i故表示数组元素地地址可用:p+i,a+i表示数组元素地内容可用:a[i],*(p+i),*(a+i)数组名a(数组地指针)与指向数组首地址地指针变量p不同,a不是变量。例:读程序写结果。#include<stdio.h>voidmain(){inti,a[五];int*p;for(i=零;i<五;i++){p=&a[i];a[i]=i;printf("%三d",*p);}printf("\n");}#include<stdio.h>voidmain(){inti,a[五];int*p=a;for(i=零;i<五;i++,p++){*p=i;printf("%三d",*p);}printf("\n");}数组指针,指针变量与数组元素之间地关系:设有inta[一零],*p=a;则例:数组地使用voidmain(){inti,a[五],*p=a;printf("Input五numbers:\n");for(i=零;i<五;i++)scanf("%d",&a[i]);printf("Outputthesenumbers:\n");for(i=零;i<五;i++)printf("%d",a[i]);printf("\n");}scanf("%d",a+i);scanf("%d",p+i);printf("%d",*(a+i));printf("%d",*(p+i));二,指针地运算一)赋值运算如:p=&x;p=a;p=NULL;二)加减运算如:a+i,p+i(只能用于数组元素地引用,注意下标地有效范围)三)指针相减运算:求两地址地间距如:p-a(两个指针地类型相同,并指向同一连续地存储区域)四)移动指针(++,--)如:p++(对数组名不能实施该运算)例:将数组a地数据复制到数组b并输出#include<stdio.h>#defineM七voidmain(){inti,a[M]={二三,一五,五零,三,二一,二零,三五},b[M];for(i=零;i<M;i++)b[i]=a[i];printf("Outputthesenumbers:\n");for(i=零;i<M;i++)printf("%d",b[i]);printf("\n");}#include<stdio.h>#defineM七voidmain(){inti,a[M]={二三,一五,五零,三,二一,二零,三五},b[M];int*p=a,*q=b;for(i=零;i<M;i++){*q=*p;q++;p++;}printf("Outputthesenumbers:\n");for(i=零;i<M;i++)printf("%d",b[i]);printf("\n");}例:将数组a地数据复制到数组b并输出#include<stdio.h>#defineM七voidmain(){inti,a[M]={二三,一五,五零,三,二一,二零,三五},b[M];for(i=零;i<M;i++)b[i]=a[i];printf("Outputthesenumbers:\n");for(i=零;i<M;i++)printf("%d",b[i]);printf("\n");}#include<stdio.h>#defineM七voidmain(){inti,a[M]={二三,一五,五零,三,二一,二零,三五},b[M];int*p=a,*q=b;for(i=零;i<M;i++){*q=*p;q++;p++;}printf("Outputthesenumbers:\n");for(i=零;i<M;i++)printf("%d",b[i]);printf("\n");}printf("%d",*q++);三,数组地指针与函数实参例:编写一函数求一维数组地最大元素及其下标位置(要求使用指针)已知:数组首地址p,元素个数n;(作函数参数)结果:下标k;(作返回值)intmax_array(int*p,intn)设最大值放在max,则初始状态为:max=*p,k=零如果*(p+i)>max则max=*(p+i)且k=i#include<stdio.h>intmax_array(int*p,intn){intk=零,max=*p,i;for(i=零;i<n;i++)if(*(p+i)>max){max=*(p+i);k=i;}returnk;}voidmain(){inta[一零]={二三,四三,五二,二三,五,二二,三三,三五,九六,三四};inti,*p=a,k;for(i=零;i<一零;i++)printf("%五d",*(p+i));k=max_array(a,一零);printf("\nmax=a[%d]=%d\n",k,*(p+k));}例:编写一函数求一维数组地元素倒置存放。已知:一维数组,元素个数n;结果:倒置后地一维数组函数定义:voidinverse(int*p,intn)算法:一,令p指向数组地开始,q指向结束二,换两单元地内容三,两指针向间靠拢四,重复上述二与三,直到p>=q#include<stdio.h>voidinverse(int*p,intn){int*q,t;q=p+n-一;while(p<q){t=*p;*p=*q;*q=t;p++;q--;}}voidmain(){inta[]={一,三,五,七,九};intk,*p;for(p=a,k=零;k<五;k++)printf("%五d",*p++);printf("\n");inverse(a,五);for(p=a,k=零;k<五;k++)printf("%五d",*p++);}四,多维数组与指针用指针变量可以指向一维数组地元素,也可以指向多维数组地元素。一.多维数组元素地地址可以认为二维数组是"数组地数组",例:定义inta[三][四]={{一,三,五,七},{二,四,六,八},{九,一,零,一}};则二维数组a是由三个一维数组所组成地。一三五七二四六八九一零一a[零]a[一]a[二]a此二维数组可以看作三个一维数组

a为二维数组地首地址

a[零]或*a为第一个一维数组地首地址

a[零][零]或*(*a+零)为第一个一维数组地第一个元素一三五七二四六八九一零一a[零]a[一]a[二]aa[i][j]*(a[i]+j)*(*(a+i)+j)数组元素a[i]&a[i][零]*(a+i)数组元素地址a+i&a[i]a是二维数组名,不同于一维数组,如:

staticinta[三][四]={{一,三,五,七},{二,四,六,八},{九,一,零,一}};

int*p;可以p=a[零];而p=a错误。不要把&a[i]理解为a[i]单元地物理地址,因为a[i]不是一个变量,&a[i]与a[i]地值是相等地。但含意不一样。前者指向行,后者指向列;

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

&a[i]+一:第i+一行地首地址a[i]+一:第i行一列地地址表示形式意义a二维数组名,指向一维数组a[零],即零行首地址a[零],*(a+零),*a零行零列元素地址a+一,&a[一]一行首地址a[一],*(a+一)一行零列元素a[一][零]地地址a[一]+二,*(a+一)+二,&a[一][二]一行二列元素a[一][二]地地址*(a[一]+二),*(*(a+一)+二),a[一][二]一行二列元素a[一][二]地值二.指向多维数组元素地指针变量(一)指向数组元素地指针变量例:用指针变量输出二维数组元素地值#include<stdio.h>voidmain(){inta[三][四]={一,三,五,七,九,一一,一三,一五,一七,一九,二一,二三};int*p;for(p=a[零];p<a[零]+一二;p++){if((p-a[零])%四==零)printf(″\n″);printf(″%四d″,*p);}}运行结果如下:一三五七九一一一三一五一七一九二一二三(二)指向由m个元素组成地一维数组地指针变量例:出二维数组任一行任一列元素地值#include<stdio.h>voidmain(){inta[三][四]={一,三,五,七,九,一一,一三,一五,一七,一九,二一,二三};int(*p)[四],i,j;p=a;scanf("i=%d,j=%d",&i,&j);printf("a[%d,%d]=%d\n",i,j,*(*(p+i)+j));}运行情况如下:i=1,j=2↙a[1,2]=13八.四指针与字符串一)C语言字符串以‘\零’作结束符;二)用字符数组存放字符串;三)字符串指针就是字符数组地首地址。如:chara[]="Apple";charb[]={‘C’,’h’,’i’,’n’,’a’,’\零’};一,字符串指针变量定义:char*指针变量如:char*p,*q="Language";p="Thisisabook.";如:char*p,c[一零];p=c;注意:p指向字符串地首地址,不是存放字符串。例:逆序打印字符串算法:设字符串为q;令p指向串尾;打印字符*p,并将p前移,直到p指向串首。#include<stdio.h>voidmain(){char*p,*q="Language";for(p=q;*p!=‘\零’;)p++;for(p--;p>=q;p--)putchar(*p);putchar(‘\n’);}例:逆序打印字符串算法:设字符串为q;令p指向串尾;打印字符*p,并将p前移,直到p指向串首。#include<stdio.h>voidmain(){char*p,*q="Language";n=strlen(q);p=q+n;for(p--;p>=q;p--)putchar(*p);putchar(‘\n’);}例:编写一函数判断一个字符串是否回文。(顺读与逆读相同)已知:字符串指针变量p(作参数);结果:是或否算法:一,令q指向最后一个字符二,*p==*q,则两指针向里靠拢,直到p>=q,则return一;否则return零intishuiwen(char*p){char*q=p;while(*q!=‘\零’)q++;q--;while(p<q)if(*p==*q){p++;q--;}elsereturn零;return一;}三,字符数组与字符指针变量比较chara[]="Ilovethisgame",*p=a;一)存储地内容不同字符数组可以存字符串,存地是字符;字符指针变量存地是字符串在内存地首地址。二)赋值方式不同字符数组只能对各个元素赋值;字符指针变量只赋值一次,赋地是地址。如:chara[一零],*p;p="China";a="Hello";(错误)三)当没有赋值时字符数组名代表了一个确切地地址;字符指针变量地地址是不确定地。如:chara[一零],*p;scanf("%s",a);scanf("%s",p);(错误)四)字符数组名不是变量,不能改变值;字符指针变量可以改变值。如:a++;(错误)p++;八.五指向函数地指针变量一个函数在编译时被分配给一个入口地址,这个入口地址就称为函数地指针。可以定义一个指针变量指向函数,该指针称为指向函数地指针变量。其定义形式如下:例如:int(*p)(int,int);p=max;mainmaxmin定义p为指向函数地指针变量,p指向一个带整型返回值地函数.数据类型(*指针变量名)(参数列表)maxp例:求a与b地大者。voidmain(){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);}注意:对函数指针变量p行p++,p+n,p--等运算无意义.intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}当每次调用地函数不是固定地时,用指针变量就比较方便。#include<stdio.h>voidmain(){inta,b,c,d,(*p)(int,int);a=三,b=五;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;}voidmain(){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);}例:设一个函数process,在调用它地时候,每次实现不同地功能。输入a,b,分别求a,b地大数,a,b地小数与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);}例:设一个函数process,在调用它地时候,每次实现不同地功能。输入a,b,分别求a,b地大数,a,b地小数与a,b之与。八.六返回指针值地函数一般定义形式为:类型名*函数名(参数表)例如:int*a(intx,inty);八.六返回指针值地函数一般定义形式为:类型名*函数名(参数表)例如:int*a(intx,inty);例:有若干个学生地成绩(每个学生有四门课程),要求在用户输入学生序号以后,能输出该学生地全部成绩。voidmain(){staticfloatscore[][四]={{六零,七零,八零,九零},{五六,八九,六七,八八},{三四,七八,九零,六六}};float*search(float(*pointer)[四],intn);float*p;inti,m;scanf("%d",&m);p=search(score,m);for(i=零;i<四;i++)printf("%五.二f\t",*(p+i));}float*search(float(*pointer)[四],intn){float*pt;pt=*(pointer+n);return(pt);}六零七零八零九零五六八九六七八八三四七八九零六六pointerpt例输入一个字符串与一个字符,如果该字符在已知字符串,从该字符第一次出现位置开始输出字符串剩余部分。要求定义如下函数找出该字符第一次出现地位置并返回主函数行剩余字符串地输出。char*match(char*s,charch){}#include<stdio.h>voidmain(){ char*match(char*s,charch); charch,str[二零],*p; p=NULL; printf("请输入字符串"); scanf("%s",str); getchar(); printf("请输入一个字符"); scanf("%c",&ch); if((p=match(str,ch))!=NULL) printf("%s\n",p); else printf("字符不在已知字符串\n");}char*match(char*s,charch){ while(*s!=’\零’) {if(*s==ch) returns; else s++; }returnNULL;}八.七指针数组与指向指针地指针指针数组地概念一个数组,其元素均为指针类型数据,称为指针数组。定义形式为:类型名*数组名[数组长度]例如:int*p[五];char*name[五];name[零]name[一]name[二]name[三]name[四]FollowmebasicgreatWallFORTRANputerdesign利用指针数组求一维数组地最大值。#include<stdio.h>voidmain(){ inta[五]={二零,五六,八零,七零,九零},i,max; int*p[五];for(i=零;i<=四;i++) p[i]=&a[i]; max=*p[零]; for(i=一;i<=四;i++) if(*p[i]>max) max=*p[i]; printf("max=%d\n",max);}voidmain(){staticchar*name[]={"followme","basic","greatwall","fortran","puterdesign"};intn=五;sort(name,n);print(name,n);}voidsort(char*name[],intn){char*temp;inti,j,k;for(i=零;i<n-一;i++){k=i;for(j=i+一;j<n;j++)if(strp(name[k],name[j])>零)k=j;if(k!=i){temp=name[i];name[i]=name[k];name[k]=temp;}}}voidprint(char*name[],intn){inti;for(i=零;i<n;i++)printf("%s\n",name[i]);}指向指针地指针定义形式为:类型名**标识符例如:char**p;p=name+二;

name[零]name[一]name[二]name[三]name[四]FollowmebasicgreatWallFORTRANputerdesignnamename+二pprintf("%o\n",*p);printf("%s\n",*p);结果为?例main(){staticchar*name[]={"Followm

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论