收藏 分销(赏)

C语言教学课件:14-2_指针与数组.ppt

上传人:可**** 文档编号:10290065 上传时间:2025-05-16 格式:PPT 页数:44 大小:877.50KB
下载 相关 举报
C语言教学课件:14-2_指针与数组.ppt_第1页
第1页 / 共44页
C语言教学课件:14-2_指针与数组.ppt_第2页
第2页 / 共44页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,1,地址与指针,指针变量的定义和使用,指针与数组,指针数组,多维数组作为参数的通用函数,动态存储管理,定义类型,指向函数的指针,第十四部分指针,2,要点回顾,如何定义一个指针变量?,指针变量在使用时为什么一定要指定指向的数据类型?,指针变量在使用时为什么一定要初始化?,未经初始化的指针变量称为?,指针变量上的两种主要操作是什么?,变量的两种访问方式是什么?,指针变量做函数参数时传递的是什么?,通过使用指针变量做为函数参数可以返回多于一返回值,改变函数调用时的环境变量,空指针有什么用?,3,地址与指针,指针变量的定义和使用,指针与数组,指针数组,多维数组作为参数的通用函数,动态存储管理,定义类型,指向函数的指针,第十四部分指针,指针(数值型,/,字符型)与一维数组,(数值型数组,/,字符串)的关系,4,3,指针与数组,C,指针与数组关系密切,以指针为媒介可以完成各种数组操作,用指针做数组操作同样要,特别注意,越界错误。,指针和数组的关系是,C,语言特有的,除了由,C,派生出的语言(如,C+,),一般语言中没有这种关系。,如何利用指针访问数组。,5,int*p1,*p2,*p3,*p4;,int a10=1,2,3,4,5,6,7,8,9,10;,指向数组元素的指针,可以写:,p1=,p3=,p4=,这个地址存在,但写*,p4,是错误的。,P4,没有指向合法元素,p1=,可简写为:,p1=a;,数组名,是表示数组,首地,址的,地址常量,区别?,6,当指针,p,指向数组元素时说,p,指到了数组里,。这时由,p,可以访问被,p,指的元素,还可访问数组的其他元素。,例:,p1=&a0,,,则,p1+1,合法,为,a1,的地址,p1+2,、,p1+3,、,也合法,分别为,a2,、,a3,的地址,使用:,*,(p1+2)=3;/*,给,a2,赋值*,/,p2=p1+5;/*,使,p2,指向,a5*/,*(p2+2)=5;/*,给,a7,赋值*,/,*(p2-2)=4;/*,给,a3,赋值*,/,p2=p2-2;/*,这使,p2,改指向,a3*/,通过指针访问数组元素时必须保证不越界。,指针运算,7,指针运算原理,一个指针指向某数组里的元素时,为什么能算出下一元素位置?(这是指针运算的基础),指针有,指向类型,,,p,指向数组,a,时,由于,p,的指向类型与,a,的元素类型一致,数据对象的大小可以确定。,p+1,的值可根据,p,的值和数组元素大小算出,。由一个数组元素位置可以算出下一元素位置,或几个元素之后的元素位置。指针运算的基础。,通用指针即使指到数组里,因没有确定指向类型,因此不能做一般指针计算,只能做指针比较。,8,可进行增,/,减量操作(,指针应指在数组里,):,p3=p2;+p3;,-p2;p3+=2;,如果两指针指在同一个数组里,可以求差,得到它们间的数组 元素个数(带符号整数)。,n=p3 p2;/*,也可以求,p2 p3*/,在同一个数组里的指针,可以比较大小:,if(p3 p2).,当,p3,所指的元素在,p2,所指的元素之后时条件成立,(值为,1,),否则不成立(值为,0,)。两个指针不指在同一数组里时,比较大小没有意义。,其他常用指针运算,:,9,两个,同类型指针,可用,=,和,!=,比较相等或不等;,任何指针都能与,通用指针,比较相等或不等;,任何指针可与,空指针,值(,0,或,NULL,)比较相等或不等,两指针指向,同一数据,元素,或同为,空值,时它们相等,。,当一个指针指向数组时的数组写法与指针写法:指针的两种用法,设,p1=&a0,,,p3=&a5,p1,和,p3,相当于数组名,可写:,p13=5;,相当于*(,p1+3)=5,;或,a3=5,;,p32=8;,相当于*(,p3+2)=8,;或,a7=8,;,p13,称为,数组写法,,*,(p1+3),称为,指针写法,两类写法有等价效力,可以自由选用。,10,a0,a1,a2,a3,a9,.,a,a+9,a+1,a+2,地址,元素,下标法,a0,a1,a2,a9,a0,a1,a2,a3,a9,.,p,p+9,p+1,p+2,地址,元素,指针法,*p,*(p+1),*(p+2),*(p+9),变址运算符,a,i,*(a+i),ai,pi,*(p+i),*(a+i),*a,*(a+1),*(a+2),*(a+9),p0,p1,p2,p9,11,对数组名求值得到指向数组首元素的指针值,数组名,可以,“看作”,常量指针,可参与一些指针运算,,与其他指针比大小,比较相等与不相等。,通过数组名的元素访问也可以采用指针写法。,a3,可写为*,(a+3),。,注意:,数组名不是指针变量,,特别是不能赋值,不能更改。,若,a,为数组,下面操作都是错误的:,a+;,a+=3;,a=p;,有些运算虽不赋值但也可能没意义。如,a3,不可能,得到合法指针值,因其,结果超出数组界限,12,a0,a1,a2,a3,a4,int main(),int a5,*pa,i;,for(i=0;i 5;i+),ai=i+1;,pa=a;,for(i=0;i 5;i+),printf(*(pa+%d):%dn,i,*(pa+i),);,/,通过指针找,地址法,for(i=0;i 5;i+),printf(*(a+%d):%dn,i,*(a+i),);,/,通过指针找,地址法,for(i=0;i 5;i+),printf(pa%d:%dn,i,pai,);,/,下标法,for(i=0;i 5;i+),printf(a%d:%dn,i,ai,);,/,下标法,return 0;,1,2,3,4,5,pa,例 数组元素的引用方法(,1,),13,基于指针的数组程序设计,指针运算是处理数组元素的一种有效方式。设有,int,数组,a,和指针,p1,p2,,下面代码都打印,a,的元素:,for(p1=a;p1 a+10;+p1),printf(%dn,*p1);,for(p1=a;p1-a 10;+p1),printf(%dn,*p1);,for(p1=a,p2=a+10;p1 p2;+p1),printf(%dn,*p1);,for(p1=p2=a;p1-p2 10;+p1),printf(%dn,*p1);,14,数组参数的意义,C,规定,数组参数就是相应类型的指针参数:,int f(int n,int d).,和,int f(int n,int*d).,意义相同。,数组参数就是利用指针实现的!,这也使采用数组参数的函数能修改实参数组。,15,函数里也可用指针方式做元素访问。,int intsum(int n,int a),int i,m=0;,for(i=0;i n;+i),m+=*(a+i),;,return m;,函数里不能用,sizeof,确定数组实参大小:,函数的数组形参实际是指针,求,sizeof,算出的是指针的大小。,另一方面,,sizeof,的计算是在编译中完成的。实参是动态运行中确定的东西。,m+=ai;,int intsum(int n,int*a),int i,m=0;,for(i=0;i n;+i),m+=*(a+i),;,return m;,16,使用数组的一段元素,以数组为参数的函数可处理一段元素。求元素和:,double sum(int n,double a);,设有双精度数组,b,,,40,个元素已有值:,用,sum,可求,b,所有元素之和,/,前一段元素之和:,x=sum(40,b);,y=sum(20,b);,sum,不知道,b,的大小,它由参数得到数组首元素地址,从这里开始求连续,40,或,20,个元素的和。,也可用,sum,求,b,中,下标,12,到,24,的一段元素之和。,z=sum(13,b+12);,17,例,1,下面的程序的输出结果是什么,?,#include,int a=2,4,7,8,9;,int main(),int i,*p=a;,for(i=0;i 4;i+),ai=*(+p);,printf(%dn,a2);,return 0;,运行结果为:,8,18,例,2 int a=1,2,3,4,5,6,7,8,9,10,*p=a,i;,数组元素地址的正确表示:(,A,),&(a+1),(,B,),a+,(,C,),&p,(,D,),&pi,数组名是,地址常量,p+,p-(,),a+,a-(,),a+1,*(a+2)(,),19,例,int main(),int a=5,8,7,6,2,7,3;,int y,*p=&a1,;,y=(*-p)+;,printf(“%d ”,y);,printf(“%d”,a0);,return 0;,输出:,5 6,p,p,5,8,7,6,2,7,3,0,1,2,3,4,5,6,a,6,例,3,注意指针变量的运算,*p+,*(p+),*p+,、*,+p,、,(*p)+,作用不同,*,p+,先取,p,指向变量的值再指针变量加,1,*,+p,先使指针变量加,1,再取*,p,(*p)+,使,p,指向的元素值加,1,20,int main(),int i,*p,a7;,p=a;,for(i=0;i 7;i+),scanf(%d,p+,);,printf(n);,for(i=0;i 7;i+,p+),printf(%d,*p,);,return 0;,p=a;,p,p,5,8,7,6,2,7,3,0,1,2,3,4,5,6,a,p,p,p,p,p,p,指针变量可以指到,数组后,的内存单元,例,4,注意指针的当前值,21,要点:,1,、指针变量可以实现自身值的改变:,如:,p+;,但数组名则不能进行改变:,a+,是错误的用法。,2,、应注意指针变量的当前值。,3,、指针变量可以指向数组以后的内存单元。,4,、注意以下的指针运算:,若:,int a10,*p=a;,则:,p+,等价于,&a1,*p+,等价于,*,(p+),但,*,(p+),与,*,(+p),却不同,(*,p,),+,等价于,a0+,22,例,1,利用指针,输出,int,数组里一段元素:,void prt_seq(int*begin,int*end),for(;begin!=end;+begin),printf(%dn,*begin);,prt_seq(a,a+10);,prt_seq(a+5,a+10);,prt_seq(a,a+3);,prt_seq(a+2,a+6);,prt_seq(a+4,a+4);,prt_seq(a+10,a+10);,最后两个调用对应空序列。,23,“,设置,”,函数:,void set_seq(int*b,int*e,int v),for(;b!=e;+b)*b=v;,把序列中每个元素都用其平方根取代:,void sqrt_seq(double*b,double*e),for(;b!=e;+b)*b=sqrt(*b);,求平均值:,double avrg(double*b,double*e),double,*p,x=0.0;,if(b=e)return 0.0;,for(p=b;p!=e;+p)x+=*p;,return x/(e-b);,24,数组名作函数参数,是,地址传递,数组名作函数参数,实参与形参的对应关系,实参,形参,数组名,指针变量,数组名,指针变量,数组名,数组名,指针变量,指针变量,数组名作函数参数,25,i,j,3 7 9 11 0 6 7 5 4 2,0 1 2 3 4 5 6 7 8 9,i,j,i,j,i,j,j,i,11,7,6,0,5,9,4,7,2,3,实参与形参均用数组,void inv(int x,int n),int t,i,j,m=(n-1)/2;,for(i=0;i=m;i+),j=n-1-i;,t=xi;xi=xj;xj=t;,int main(),int i,a10=3,7,9,11,0,6,7,5,4,2;,inv(a,10);,printf(The array has been,reverted:n);,for(i=0;i 10;i+),printf(%d,ai);,printf(n);,return 0;,m=4,例,5,将数组,a,中的,n,个整数按相反顺序存放(,1,),26,void inv(int *x,int n),int t,*p,*i,*j,m=(n-1)/2;,i=x;j=x+n-1;p=x+m;,for(;i=p;i+,j-),t=*i;*i=*j;*j=t;,int main(),int i,a10=3,7,9,11,0,6,7,5,4,2;,inv(a,10);,printf(The array has been,reverted:n);,for(i=0;i 10;i+),printf(%d,ai);,printf(n);,return 0;,实参用数组,形参用指针变量,3,7,9,11,0,6,7,5,4,2,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,x,p=x+m,a,数组,6,0,7,11,5,9,4,7,2,3,i,j,i,j,i,j,j,i,j,i,例,5,将数组,a,中的,n,个整数按相反顺序存放(,2,),27,void inv(int*x,int n),int t,*i,*j,*p,m=(n-1)/2;,i=x;j=x+n-1;p=x+m;,for(;i=p;i+,j-),t=*i;*i=*j;*j=t;,int main(),int i,a10,*p=a,;,for(i=0;i 10;i+,p+),scanf(%d,p,);,p=a;,inv(p,10);,printf(The array has been reverted:n);,for(p=a;p a+10;p+),printf(%d,*p,);,return 0;,实参与形参均,用指针变量,例,5,将数组,a,中的,n,个整数按相反顺序存放(,3,),28,void inv(int x,int n),int t,i,j,m=(n-1)/2;,for(i=0;i=m;i+),j=n-1-i;,t=xi;xi=xj;xj=t;,int main(),int i,a10,*p=a;,for(i=0;i 10;i+,p+),scanf(%d,p);,p=a;,inv(p,10);,printf(The array has been reverted:n);,for(p=a;p a+10;p+),printf(%d,*p);,return 0;,实参用指针变量,形参用数组,例,5,将数组,a,中的,n,个整数按相反顺序存放(,4,),29,#include,#define MAX 5,void fun1();,void fun2(int);,int aMAX;,int main(),fun1();,fun2(a);,printf(n);,return 0;,void fun1(),int k,t=0;,for(k=0;k MAX;k+,t+)ak=t+t;,void fun2(int b),int k;,for(k=0;k MAX;k+=2),printf(%4d,*(b+k);,例,6,分析程序写出结果,运行结果为:,0 4 8,30,#include,void fun(int*s),static int j=0;,do,sj+=sj+1;,while(+j 2);,int main(),int k,a10=1,2,3,4,5;,for(k=1;k 3;k+),fun(a);,for(k=0;k 5;k+),printf(,“,%4d,”,ak);,return 0;,例,7,分析程序写出结果,运行结果为:,3 5 7 4 5,31,int *p,与,int q10,数组名是指针(地址),常量,p=q;p+i,是,qi,的地址,数组元素的表示方法,:,下标法,和,指针法,,即若,p=q,则,pi,qi,*(p+i),*(q+i),形参数组,实质上是,指针变量,,即,int q,int*q,在定义指针变量(不是形参)时,,不能把,int *p,写成,int p;,系统只给,p,分配能保存一个指针值的内存区,(,一般,4,字节);而给,q,分配,sizeof(int)*10,字节的内存区,一级指针变量与一维数组的关系,32,定义字符指针时可用字符串常量初始化,如:,char*p=Programming;,1,)定义了指针,p,2,)建立了一个字符串常量,内容为,Programming,3,)令,p,指向该字符串常量。图,(a),char a=Programming;,1,)定义了一个,12,个字符元素的数组,2,)用,Programming,各字符初始化,a,的元素,图,(b),字符指针与字符数组,常用字符指针指向字符数组元素,33,1,),指针,p,可重新赋值(,数组不能赋值,:a=“”,):,p=Programming Language C;,2,),p,和,a,类型不同,大小不同。,a,占,12,个字符的空间。,3,),a,的元素,可以重新赋值。如:,a8=e;a9=r;a10=0;,a,的内容现在变成“,Programmer”,34,I,l,o,v,e,C,h,i,string0,string1,string2,string3,string4,string5,string6,string7,string8,string9,string,string10,string11,string12,string13,n,!,a,0,/,字符串用字符数组实现,int main(),char string=“I love China!”;,printf(“%sn”,string);,printf(“%sn”,string+7,);,return 0;,/,字符串用字符指针实现,int main(),char *string=“I love China!”;,printf(“%sn”,string);,string+=7;,while(*string),putchar(string0);,string+;,return 0;,I love China!,China!,35,#include,int main(),char arr=ABCDE;,char*ptr;,for(ptr=arr;ptr arr+5;ptr+),printf(%sn,ptr);,return 0;,运行结果:,ABCDE,BCDE,CDE,DE E,例,1,分析以下程序的运行结果,36,#include,int main(),char*p1=programming,*p2=language;,int i;,for(i=0;i 7;i+),if(*(p1+i)=*(p2+i),printf(%c,*(p1+i);,return 0;,运行结果:,ga,例,2,分析以下程序的运行结果,37,例,3,,输入一行到数组里:,enum NLINE=256;,char line,NLINE,;,int count;char*p;,/*-*/,p=line;,while(plineNLINE-1&(*p=gerchar()!=n),+p;,*p=0;/*,做成字符串*,/,/*-*/,for(count=0,p=line;*p!=0;+p),if(*p=e)+count;/*,统计,e,的个数,*,/,38,例,1,,用指针方式实现字符串长度函数。,一种方式,:,int strLength(const char*s),int n=0;/*,通过局部指针扫描串中字符*,/,while(*s!=0)s+;n+;,return n;,另一实现:,int strLength(const char*s),char*p=s;,while(*p!=0)p+;,return p-s;,参数类型,(char*),,,实参应是字符串或存字符串的数组,指针与数组操作函数实例,指针使用非常灵活,39,void strCopy(char*s,const char*t),while(*s=*t)!=0),s+;t+;,把指针更新操作也写在循环测试条件里,,void strCopy(char*s,const char*t),while(*s+=*t+);/,空语句,赋值表达式有值,,0,就是,0,,可简化:,void strCopy(char*s,const char*t),while(*s=*t)s+;t+;,例,2,,用指针实现字符串复制函数。,40,例 用函数调用实现字符串复制,(,1,)用字符数组作参数,a,I,a,m,a,t,e,a,c,e,h,0,r,.,from,a,b,y,u,a,r,a,s,u,t,n,d,e,to,b,o,e,t,.,0,I,a,a,e,c,e,h,0,r,.,t,.,0,m,t,a,void copy_string(char from,char to),int i=0;,while(fromi!=0),toi=fromi;,i+;,toi=0;,int main(),char a=I am a teacher.;,char b=You are a student.;,printf(string_a=%sn string_b=%sn,a,b);,copy_string(a,b);,printf(nstring_a=%snstring_b=%sn,a,b);,return 0;,字符指针作函数参数,41,例 用函数调用实现字符串复制,(,2,)用字符指针变量作参数,a,I,a,m,a,t,e,a,c,e,h,0,r,.,from,a,b,y,u,a,r,a,s,u,t,n,d,e,to,b,o,e,t,.,0,I,a,a,e,c,e,h,0,r,.,t,.,0,m,t,a,void copy_string(char*from,char *to),for(;*from!=0;from+,to+),*to=*from;,*to=0;,int main(),char a=I am a teacher.;,char b=You are a student.;,printf(string_a=%snstring_b=%sn,a,b);,copy_string(a,b);,printf(nstring_a=%snstring_b=%sn,a,b);,return 0;,字符指针作函数参数,char*b=You are a student.;,字符串是一个常量,,b,中存放这个常量的首地址。常量不允许被修改。,这里字符串用指针变量会出错,42,#include,#include,void fun(char*);,int main(),char str=abcdefghi;,char*a=str;,fun(a);,puts(a);,return 0;,void fun(char*s),int x,y;,char c;,for(x=0,y=strlen(s)-1;x y;x+,y-),c=sy;sy=sx;sx=c;,运行结果:,ihgfedcba,例,3,分析以下程序的运行结果,43,char *cp;,与,char str20;,str,由若干元素组成,每个元素放一个字符;而,cp,中存放字符串首地址,char str20;str=“I love China!”;(,),char *cp;cp=“I love China!”;(,),str,是地址,常量,;,cp,是地址,变量,cp,接受键入字符串时,必须,先开辟存储空间,例,char str10;,scanf(“%s”,str);(,),而,char *cp;,scanf(“%s”,cp);(,),改为,:char *cp,str10;,cp=str;,scanf(“%s”,cp);(,),或为:,char *cp;,cp=(char*)calloc(10,sizeof(char);,scanf(,“,%s,”,cp);(,),字符指针变量与字符数组,44,Q&A!,
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 通信科技 > 开发语言

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服