《c语言教学资料》6指针_第1页
《c语言教学资料》6指针_第2页
《c语言教学资料》6指针_第3页
《c语言教学资料》6指针_第4页
《c语言教学资料》6指针_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

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

文档简介

第6章指针,第6章指针,本章内容,6.2变量的指针和指针变量,6.3指针运算,6.4一维数组与指针,6.1地址与指针,6.5二维数组与指针,第6章指针,本章内容,6.7指针变量作函数的参数,6.8函数与指针,6.9指向指针的指针变量,6.6字符数组与指针,6.10指针应用举例,6.1地址与指针,内存就是计算机内部存储器,是由存储单元组成的。存储单元的编号就是内存地址。在程序中定义一个变量,在对程序进行编译时,系统就会给这个变量分配具体的内存单元。这个单元有个地址,变量名和其地址对应。,6.1地址与指针,在程序中我们是通过变量名来对内存单元进行存取操作的。这种按变量名存取变量值的方式称为“直接访问”方式。例如:a=5;b=a;其实程序经过编译以后已经将变量名转换为变量的地址,对变量值的存取都是通过地址进行的。,b,5,2004H,6.1地址与指针,还有一种“间接访问”变量值的方法:将a变量的地址存放在另一个专门存放地址的变量pa中,通过pa变量存取a变量的值。例如:变量a存放数值5;变量pa存放a变量的地址2000H。b=*pa;什么是指针呢?变量的地址(编号)就是变量的指针。存放地址的变量就是指针变量。在这里的pa就是指针变量。,pa,3020H,2000H,b,5,6.1地址与指针,指针变量用来指向另一个变量。为了表示指针变量和它所指向的变量之间的联系,在程序中用“*”符号表示指向(取指针内容),它实际执行的是“间接访问”运算,如果已定义pa为指针变量且存放a变量的地址,则*pa是pa所指向的变量。*pa等价于a。若a变量存放的值为5,则a代表5,pa代表a的地址,*pa代表a,就是5。,6.2变量的指针和指针变量,本节内容,6.2.2指针变量的引用,6.2.1指针变量的定义,6.2.1指针变量的定义,定义指针变量的一般形式为基类型*指针变量名;下面都是合法的定义:float*pf;charc,*pc;可以用赋值语句使一个指针变量得到另一个变量的地址,从而使它指向该变量。例如:pc=将变量c的地址存放到pc中,因此pc就“指向”了变量c。,6.2.1指针变量的定义,在定义指针变量时要注意两点:在定义指针变量时,指针变量名前面加“*”表示该变量的类型为指针型变量。但在使用指针变量时,指针变量名前面加“*”表示进行间接寻址操作(取指针内容)。如有:inti=3,j,*pi;“*”表示pi的类型为指针型变量pi=“*”表示取指针pi所指变量的值结果:j的值为3。一个指针变量只能指向定义时指定的基类型的变量,不能忽而指向一个整型变量,忽而指向一个实型变量。,6.2.2指针变量的引用,指针变量同普通变量一样,在使用之前要先定义,但需注意的是指针变量定义后,变量值不确定,应用前还必须先赋予具体的值。未经赋值的指针变量是不能使用的。未经赋值的指针变量叫做“野指针”,它的初始值是随机的。如果未经赋值而对它随机指向的内存单元进行操作,可能产生严重后果。指针变量只能赋予地址,绝不能赋予任何其他数据,否则将引起错误。,6.2.2指针变量的引用,6.2.2.1指针变量的初始化指针变量初始化的一般形式为:基类型*指针名=初始地址值;变量的地址是由编译系统内部分配的,用户不知道变量的具体地址,所以不能直接给出地址值,只能通过运算获得。有两个有关指针的运算符:/给pa所指向的变量(a)赋值,6.2.2指针变量的引用,#includemain()charx,y;char*p1,*p2;x=a;y=b;p1=,【例6-1】通过指针变量访问字符型变量。,6.2.2指针变量的引用,“等价。如果p2原来指向y,经过重新赋值后它已不再指向y了,而指向了x。,6.2.2指针变量的引用,(*p1)+相当于x+。p1仍指向x。结果x的值加1。X的值变为b。*p1+,相当于*(p1+)。由于+在p1的右侧,是“后加”,因此首先对p1的原值进行*运算,得到x的值。式子的取值为:a。然后使p1的值改变,这样p1不再指向x了,而是指向了y变量。,p1,3020H,2000H,y,b,2001H,6.2.2指针变量的引用,是值,值的几种形式,是地址,地址的几种形式,是赋值操作,6.2.2指针变量的引用,#includemain()int*p1,*p2,*p,x,y;scanf(%d,%d,【例6-2】输入x和y两个整数,按从小到大的顺序输出x和y。,6.2.2指针变量的引用,6.2.2指针变量的引用,6.2.2.2指针变量的赋值intx;int*p;若需要通过指针变量p来操作x,那么可以先让p指向x,这只要将x的地址赋予pp=,6.2.2指针变量的引用,在对指针变量赋值时,要注意以下问题:在将一个普通变量的地址赋值给指针变量时,普通变量必须先定义,再使用。例如:int*p=/错误,6.2.2指针变量的引用,可以将一个指针的值赋给另一个指针变量;intx=3,y,*p1,*p2;p1=可以避免因为误引用没有被初始化的指针变量造成的严重问题。,6.3指针运算,本节内容,6.3.2指针的逻辑运算,6.3.1指针的算数运算,6.3.1指针的算数运算,指针除了可以参与赋值和间接访问之外,只能进行加减运算和比较运算。在这些运算中,基类型起着决定性的作用。6.3.1.1自加和自减运算指针变量可以进行自加和自减运算。floatx,*p;p=循环输入10个数for(i=0;i10;i+)以下四种循环体效果相同printf(“%3d”,ai);printf(“%3d”,pi);printf(“%3d”,*(a+i);printf(“%3d”,*(p+i);,6.4.1通过指针引用一维数组元素,for(i=0;i3;i+),1,2000,3,5,2,0,1,a,2004,2008,printf(%dn,ai);,*(a+i),=2000,6.4.1通过指针引用一维数组元素,for(i=0;i3;i+),1,2000,3,5,2,0,1,a,2004,2008,printf(%dn,=2000,p,p=a;,ai);,pi);,*(p+i),6.4.1通过指针引用一维数组元素,1,2000,3,5,2,0,1,a,2004,2008,printf(%dn,p0);,=2000,p,p=a+1;,printf(%dn,*(p+0);,printf(%d,%dn,p1,p-1);,6.4.1通过指针引用一维数组元素,a0,a1,a2,a,2000,2004,2008,6.4.1通过指针引用一维数组元素,与地址运算有关的总结:如果:inti,x=5,*px=那么:x、*px、ai、*a、*(a+i)、*p、*(p+i)、pi是值。为叙述方便不妨称其为“0级地址”。而:int*p=a,i;for(i=0;i9;i+)printf(%4d,*(a+i);printf(n);for(i=0;i9;i+)printf(%4d,*p+);printf(n);,6.5二维数组与指针,本节内容,6.5.2通过指针引用二维数组元素,6.5.3指针数组,6.5.1二维数组元素的地址,6.5.1二维数组元素的地址,我们定义二维数组:intb24;b是二维数组名,是一个地址常量,是数组第一行的首地址。b、b+1、b+2是指向各行的指针,不妨看成“二级指针”(通常的叫法是:行指针),它们指向了各行的首地址。可以认为b0、b1、b2是b的各个元素,用指针表示,就是*b、*(b+1)、*(b+2);只不过这些“元素”都是一维数组。既然它们都是一维数组名,不妨看成“一级指针”(通常的叫法是:列指针),它们指向了各行的第一列。,6.5.2通过指针引用二维数组元素,指针b、b0和*b都是指针且都指向数组的首地址,但它们的基类型不同:因为b的“元素”为一维数组,它的基类型是一维数组,故b是指向一维数组的指针而不是指向整数的指针。由于一维数组名也是指针,故b本质上是一种指向指针的指针(不妨称为二级指针)。b0是利用数组b的下标引用得到的变量,*b是指针b间接引用得到的变量,b0和*b都是b的第一个元素,都表示第一行的一维数组名,此刻它的元素为int类型,故b0和*b是指向int类型的指针(不妨称为一级指针)。,6.5.2通过指针引用二维数组元素,intb24,*p;p=b;语句“p=b”表示把二维数组中b00元素的地址赋给指针变量p。p指向数组b的第一行第0号元素,即第一个元素。对于二维数组中第i+1行第j+1列的元素即bij我们可以看作是b数组中“元素”bi的j号元素,bi是一个一维数组,可以看作是一个指针,指向一维数组bi0的首地址,则元素bij的地址为bi+j,其基类型为int类型;再看数组b,其“元素”bi的地址为b+i,但其基类型为一维数组类型。,6.5.2通过指针引用二维数组元素,如果将二维数组名a看成一个行地址(第0行的地址),则a+i代表二维数组a的第i行的地址,ai可看成一个列地址,即第i行第0列的地址。行地址a每次加1,表示指向下一行列地址ai每次加1,表示指向下一列,6.5.2通过指针引用二维数组元素,*(*(a+i)+j),a:第0行的地址,a+i:第i行的地址,*(a+i):即ai,第i行第0列的地址,*(a+i)+j:即int*p;for(p=a0;py?x:y);returnz;main()inta,b,max;int(*p)(int,int);printf(pleaseinputa,b:);scanf(%d,%d,原程序改写如左:,6.8.2函数指针作函数参数,【例6-8】用函数指针作参数,计算两数之和、差、积、商。,#includevoidmain()inta,b,add(int,int),dif(int,int),pro(int,int),quo(int,int);voidprocess(int,int,int(*fun)(int,int);scanf(%d,%d,6.8.2函数指针作函数参数,add(intx,inty)printf(add=);return(x+y);dif(intx,inty)printf(dif=);return(xy?x-y:y-x);pro(intx,inty)printf(pro=);return(x*y);quo(intx,inty)printf(quo=);return(xy?x/y:y/x);,6.8.3返回指针值的函数,返回指针值的函数也被称为指针函数。其定义形式为:类型标识符*函数名(参数表);例如int*f(intx,inty);其中f是函数名,调用f后返回一个指向整型数据的指针值(地址),x、y是函数f的形参。需注意的是:指针函数定义时指针运算符“*”和函数名f两侧没有括号“()”。,#include#includechar*fun(char*s,char*t)char*p,*r,*a;a=NULL;while(*s)/遍历s串,查找子串tp=s;r=t;while(*r)if(*r=*p)r+;p+;elsebreak;if(*r=0)/条件成立表明已经在主串s中找到子串ta=s;/a指向子串t最后一次出现在主串s中的位置s+;returna;,【例6-9】分析以下程序运行结果。,main()chars100,t100,*p;printf(PleaseenterstringS:);scanf(%s,s);printf(PleaseentersubstringT:);scanf(%s,t);p=fun(s,t);if(p)printf(Theresultis:%sn,p);elseprintf(Notfound!n);,6.9指向指针的指针变量,如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。通过指向指针的指针变量来访问变量则构成了二级或多级间接寻址。指向指针的指针变量说明的一般形式为:类型说明符*指针变量名;例如:int*pp;表示pp是一个指针变量,它指向另一个指针变量,而这个指针变量指向一个整型量。下面举一个例子来说明这种关系。,6.9指向指针的指针变量,#includemain()intx,*p,*pp;x=5;p=,【例6-10】分析以下程序运行结果。,6.9指向指针的指针变量,#include#defineNULL0voidmain()char*p;char*name=hello,good,world,bye,;p=name+1;printf(%o:%s,*p,*p);p+=2;while(*p!=NULL)printf(%sn,*p+);,【例6-11】用二级指针处理字符串。,6.10指针应用举例,#defineN10#includemain()intaN,*pp,*p,*q,t;for(p=a;p*q)pp=q;if(pp!=p)t=*p;*p=*pp;*pp=t;for(p=a;pa+N;p+)printf(%d,*p);printf(n);,【例6-12】输入10个整数,使用指针变量将这10个数按从小到大排序后输出。,【例6-13】写一函数,将一个33的矩阵

温馨提示

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

评论

0/150

提交评论