8指针及其应用

上传人:ning****hua 文档编号:243030393 上传时间:2024-09-14 格式:PPT 页数:74 大小:624KB
返回 下载 相关 举报
8指针及其应用_第1页
第1页 / 共74页
8指针及其应用_第2页
第2页 / 共74页
8指针及其应用_第3页
第3页 / 共74页
点击查看更多>>
资源描述
,*,36,单击此处编辑母版文本样式,第,8,章 指针及其应用,第,8,章指针及其应用,学习目标,掌握指针的概念及基本操作,指针在数组和函数中的应用。,学习内容,指针、指针变量的概念,指针变量定义及使用,指针与一维数组,指针与二维数组,指针与字符串,指针与函数。,下一页,返 回,第,8,章 指针及其应用,8.1,指针的基本用法,8.2,指针与数组,8.3,指针与函数,8.4,指针应用实例,8.5,本章小结,8.6,实训,上一页,返 回,8.1,指针的基本用法,8.1.1,指针的概念,计算机的内存是以字节为单位的一片连续的存储空间,每个字节都有一个编号,这个编号称为内存单元地址。这就如同旅馆的每个房间都有一个房间号一样,如果没有房间号,旅馆的工作人员就无法进行管理,同样没有字节编号,系统就无法对内存单元进行管理。,若在程序中定义了一个变量,系统就会根据变量的类型为变量在内存中分配若干字节的存储空间,此后这个变量的单元地址也就确定了。有了变量的地址,就可以立即找到该变量所在的存储单元并进行数据的存取操作。这种通过变量地址存取变量值的方式称为变量的直接访问。,程序中通常是通过变量名对变量进行访问,因为变量名是变量的符号地址,它与单元物理地址之间的联系由系统自动建立。,提示:注意区分变量的地址和变量的值这两个概念。,下一页,返 回,8.1,指针的基本用法,存储单元地址惟一地对应着(或指向)存储单元,因此,C,语言将存储单元地址形象地称为,指针,。,前面学习的变量,都是用来存放基本类型数据的,如存放整数或实数等,这些变量称为简单变量。在,C,语言中,还可以定义一种特殊的变量,这种变量专门用来存放另一个变量的地址(即指针),称为指针变量。,如果,p,是指针变量,而且,p,中存放着变量,a,的地址,则称,p,指向,a,,常用,图,8-1,所示的形式表示。那么可以通过指针变量,p,引用它所指向的变量,a,,这种变量访问方式称为变量的间接访问。,本章主要介绍的内容就是变量的间接访问。,下一页,返 回,上一页,8.1,指针的基本用法,8.1.2,指针变量的定义和使用,1.,指针变量的定义,任何变量在使用前都必须定义,指针变量也一样。指针变量的一般定义形式为:,基类型名 *指针变量名;,例如:,int,*p1,*p2;,说明:,(,1,)定义了两个指针变量,变量名为,p1,和,p2,,这两个变量只能用来存放地址。,(,2,)*是一个说明符用来说明定义的是指针变量,定义指针变量时必须有。,(,3,)基类型表示指针变量所指向的变量的类型,也就是说,,p1,、,p2,中只能存放整型变量的地址。,下一页,返 回,上一页,8.1,指针的基本用法,2.,指针变量的使用,(,1,)运算符“,&”,和“*”,运算符“,&”,为取地址运算符,后跟一个变量,表示取变量的地址。比如,,&a,表示变量,a,的地址。,运算符“*”为间接访问运算符,后跟一个指针变量,表示取这个指针变量所指向的变量的值。,(,2,)指针变量的赋值,通过给指针变量赋地址值,可以让指针变量指向某个变量。例如有以下定义和语句:,int,a,b,*pa,*,pb,;,pa= /*,指针变量,pa,指向变量,a */,pb,= /*,指针变量,pb,指向变量,b*/,下一页,返 回,上一页,8.1,指针的基本用法,下面的定义和语句是错误的:,float x;,int,*p;,p=,错误原因是,x,的类型和,p,的基类型不一致。,(,3,)通过指针变量引用变量,例如,有以下定义和语句:,int,i,j,*p;,p=,*p=10; /*,将,10,赋给,p,所指向的变量即变量,i,,等价于赋值语句,i=10;*/,下一页,返 回,上一页,8.1,指针的基本用法,j=*p+1; /*,取指针变量,p,所指向的存储单元中的值加,1,后赋给变量,j,j,的值为,11*/,*p=*p+1; /*,取指针变量,p,所指向的存储单元中的值,加,1,后再放入,p,所指向的存储单元中,也就是使变量,i,的值增,1,变为,11*/,小测验,int,a=11,b=22,*pa,*,pb,;,pa=,pb,=,在上面程序段的基础上,执行语句,pa=,pb,;,和执行语句*,pa=*,pb,;,有什么不同?,下一页,返 回,上一页,8.1,指针的基本用法,【,例,8-1】,通过指针变量访问整型变量。,【,程序代码,】,#include ,void main( ),int,i,j,*pi; /*,定义整型变量,i,和,j,,指针变量,pi*/,i=10;,pi= /*,使指针变量,p,指向变量,i*/,j=*pi+5; /*,通过指针变量访问变量,i,等价于,j=i+5;*/,printf(%dn,i,);,printf(%d,%dn,*,pi,j,);,下一页,返 回,上一页,8.1,指针的基本用法,程序运行结果:,【,例,8-2】,从键盘上输入任意三个实数,利用指针的方法将这三个实数按大小进行排序。,【,编程思路,】,(,1,)输入,3,个实数分别放到变量,a,、,b,、,c,中。,(,2,),3,个指针变量,p1,、,p2,、,p3,分别指向变量,a,、,b,、,c,。,(,3,)比较变量的值,最终使,p1,指向最大值,,p3,指向最小值。,(,4,)按顺序输出,p1,、,p2,、,p3,所指向的变量的值。,下一页,返 回,上一页,8.1,指针的基本用法,【,程序代码,】,#include ,void main( ),float,a,b,c,*p1,*p2,*p3,*p;,printf,(,请输入,3,个实数:,);,scanf(%f,%f,%f,&a,&b,&c,);,p1=,p2=,p3=,if(a,b),p=p1;p1=p2;p2=p;,if(a,c),下一页,返 回,上一页,上一页,8.1,指针的基本用法,p=p1;p1=p3;p3=p;,if(b,c),p=p2;p2=p3;p3=p;,printf(%.2f,%.2f,%.2fn,*p1,*p2,*p3);,程序运行结果:,该程序执行过程中,变量,a,、,b,、,c,的值始终未变,只是使指针,p1,最终指向值最大的变量,使指针,p3,最终指向值最小的变量。,返 回,8.2,指针与数组,8.2.1,指针与一维数组,1.,指针的移动,当指针变量指向一串连续的存储单元(即数组)时,可以对指针变量加上或减去一个整数来进行指针的移动和定位。例如有如下语句:,int,a5=10,20,30,40,50,*p,*q;,p=,指针,p,的指向情况如,图,8-2(a),所示。在此基础上,随着下面各个语句的执行,指针,p,和,q,的指向会发生相应变化。,q=p+1;,如图,8-2(a),所示,使指针变量,q,指向数组元素,a1,q+;,指针后移,指针变量,q,指向数组元素,a2,q+=2;,指针变量,q,指向数组元素,a4,下一页,返 回,8.2,指针与数组,q-;,指针变量,q,指向数组元素,a3,p+;,指针变量,p,和,q,的指向如,图,8-2 (b),所示,现在如果有语句,i=*,p;j,=*q;,则,i,中的值为,20,,,j,中的值为,40,。若有语句,k=,q-p,;,则,k,中的值为,2,。表达式,pq,的值为真,因为当前指针变量,p,中存的地址值小于指针变量,q,中存的地址值。,2.,数组元素的地址,C,程序中,数组名是数组的首地址,即第,1,个数组元素的地址,该地址是地址常量,因此不能被修改或重新赋值,例如,对数组名,a,来说,,a+;,或,a=,都是错误的使用方法。,虽然不能对数组名进行赋值,但可以通过数组名来表示数组元素的地址,从而也能达到引用数组元素的目的。,例如:,int,a10,*,p;p,=a;,此时指针,p,指向数组,a,的第,1,个元素,如,图,8-3,所示。数组元素地址的几种表示形式见,表,8-1,。,下一页,返 回,上一页,8.2,指针与数组,3.,数组元素的引用,针对数组元素地址的不同表示形式,数组元素的引用形式也有多种,见,表,8-2,。,下面语句通过数组名逐个输出数组,a,中各元素的值:,for(i,=0;i10;i+),printf(%5d,*(,a+i,);,这里首地址,a,始终指向数组元素,a0,,并没有移动,通过变量,i,值的变化来引用到每个元素。,下面语句通过移动指针来逐个输出数组,a,中各元素的值:,for(p,=,a;p,a+10;p+),printf(%5d,*p);,下一页,返 回,上一页,8.2,指针与数组,此语句在执行过程中,指针,p,首先指向元素,a0,输出操作输出的是第一个元素的值,执行了,p+,后,指针指向了元素,a1,,此时再做输出操作,输出的是第二个元素的值,依次下去,指针会逐个指向每个元素,再输出它们的值。当指针,p,指向最后一个元素后面的存储单元时,循环结束。,【,例,8-3】,有一个数组,score ,存放,10,个学生的成绩,求平均成绩,要求通过指针变量来访问数组元素。,【,程序代码,】,#include ,void main( ),下一页,返 回,上一页,8.2,指针与数组,float score10,*,p,sum,=0,ave;,printf,(,请输入,10,个学生成绩:,);,for(p,=,score;p,score+10;p+),scanf(%f,p,);,for(p,=,score;p,score+10;p+),sum+=*p; /*,取各成绩累加到,sum,中*,/,ave,=sum/10; /*,求平均成绩*,/,printf,(,平均成绩,%.2fn,ave);,程序运行结果:,下一页,返 回,上一页,8.2,指针与数组,【,例,8-4】,使数组中的元素逆序存放(不借助其它数组),要求用指针的方法处理。,【,编程思路,】,(,1,)定义两个指针变量,p1,、,p2,,使,p1,指向第一个元素、,p2,指向最后一个元素。,(,2,)将,p1,、,p2,所指向的数组元素的值互换,然后使,p1,指向第二个元素、,p2,指向倒数第二个元素,再做上面的互换操作,这样重复下去,直到,p1,指向了,p2,的后面或,p1,和,p2,指向了同一元素为止。,【,程序代码,】,#include ,void main( ),下一页,返 回,上一页,8.2,指针与数组,int,a10,*p1,*p2,temp;,printf,(,请输入,10,个数:,);,for(p1=a;p1a+10;p1+) /*,输入一个整数,存放在,p1,所指的存储单元中*,/,scanf(%d,p1);,for(p1=a,p2=a+9;p1p2;p1+,p2-) /*,通过交换首尾对应位置上的值实现逆置*,/,temp=*p1; *p1=*p2;*p2=temp; /*,两个指针变量所指向的元素的值互换*,/,printf,(,逆序后数组的值:,);,for(p1=a;p1a+10;p1+),下一页,返 回,上一页,8.2,指针与数组,printf(%5d,*p1);,printf(n,);,程序运行结果为:,下一页,返 回,上一页,8.2,指针与数组,8.2.2,指针与二维数组,1.,二维数组元素的地址,例如:,int,a33;,与一维数组名一样,二维数组名,a,也是数组的首地址。但是二者不同的是,二维数组名的基类型不是数组元素类型,而是一维数组类型,因此二维数组名,a,是一个行指针,其指向如,图,8-4,所示。,二维数组,a,包含三个行元素:,a0,、,a1,和,a2,,而它们又都是一维数组名,因此也是地址常量,但是它们的基类型与数组元素类型一致。,第,0,行首地址:,a0,第,1,行首地址:,a1,第,2,行首地址:,a2,下一页,返 回,上一页,8.2,指针与数组,所以,a0+1,就是数组元素,a01,的地址,,a1+1,是数组元素,a11,的地址,那么任意的数组元素,aij,的地址是,ai+j,。,二维数组元素的地址表示形式较多,每种地址形式都有对应的数组元素引用方法。比如:,数组元素地址:,&,aij, ,ai+j, *(,a+i)+j,数组元素引用:,aij, *(,ai+j,) *(*(,a+i)+j,),2.,指向二维数组元素的指针变量(列指针),例如:,int,a32,*p;,p=,二维数组在内存中是按行顺序存储的,因此,可以通过对指向数组元素的指针变量进行加减运算来达到引用任意数组元素的目的,引用方法与引用一维数组元素一样。,下一页,返 回,上一页,8.2,指针与数组,【,例,8-5】,用指向数组元素的指针访问数组。,【,程序代码,】,#include ,void main( ),int,a33=1,2,3,4,5,6,7,8,9;,int,*p;,for(p,=a0;pa0+9;p+) /*,最后一个元素的地址是,a0+8*/,if(p-a0)%3=0),printf(n,); /*,换行控制*,/,printf(%5d,*p);,下一页,返 回,上一页,8.2,指针与数组,printf(n,);,程序运行结果:,a0,是数组的第一个元素的地址,且基类型与指针,p,的基类型一致都是,int,型,所以用,p=a0,使指针,p,指向数组的第一个元素,这个表达式还可用,p=&a00,代替,同样,a0+8,也等价于,&a00+8,。,下一页,返 回,上一页,8.2,指针与数组,3.,指向二维数组的行指针变量(行指针),行指针变量就是用来存放,行,地址的变量,一般定义形式为:,数据类型名 (*指针变量名),数组长度,;,例如:,int,(*p)4;,p,是一个指针变量,它的基类型是一个包含,4,个整型元素的一维数组,因此指针变量,p,可以指向一个有,4,个元素的一维数组。,【,例,8-6】,利用行指针输出二维数组元素的值。,【,程序代码,】,#include ,void main( ) ,int,a33=1,2,3,4,5,6,7,8,9;,int,(*p)3,j; /*,指针变量,p,为行指针*,/,下一页,返 回,上一页,8.2,指针与数组,for(p,=,a;p,a+3;p+),for(j,=0;j3;j+),printf(%5d,*(*,p+j,);,printf(n,);,程序运行结果为:,在此把数组,a,看成是一维数组,它的元素有,a0,、,a1,、,a2,。由于指针,p,与数组名,a,表示的地址常量的基类型相同,所以可以用,p=a,,它使指针,p,指向了数组,a,的第一个元素,a0,,这时*,p,表示是,a0,的值,即为第,0,行的首地址,如有*,p+1,,它表示,a01,的地址,*(*,p+1,)表示数组元素,a01,。,p+,执行一次,指针,p,向后移动一行,下一页,返 回,上一页,8.2,指针与数组,4.,指针数组,比如有如下定义:,int,a34, *p3;,数组,p,是一个包含,3,个元素的一维数组,它的每个元素都是基类型为,int,的指针,所以称数组,p,为指针数组。,pi,和,ai(0i3),的基类型相同(都为,int,类型),因此赋值语句,pi,=,ai,;,是合法的。比如有以下循环语句:,for(i,=0;i3;i+),pi,=,ai,;,该语句执行完后,数组,p,的,3,个元素,p0,、,p1,和,p2,分别指向数组,a,每行的开头,如,图,8-5,所示。此时如果有语句,printf(%d,%d,*p0,*(p0+1);,,那么输出的是数组元素,a00,和,a01,的值。,下一页,返 回,上一页,8.2,指针与数组,8.2.3,指针与字符串,字符数组通常用来存放字符串,指针指向字符数组也就指向了字符串,因此通过指针可以引用它所指向的字符串。,【,例,8-7】,通过指针引用字符串。,【,程序代码,】,#include ,void main( ),char,str, =,BeiJing,*p;,p=,str,; /*,指针,p,指针字符串首部*,/,printf(%sn,p,); /*,从字符串首字符开始输出,遇,0,结束*,/,下一页,返 回,上一页,8.2,指针与数组,p+=3; /*,移动指针,p*/,printf(%sn,p,); /*,从指针,p,所指字符开始输出,遇,0,结束*,/,程序运行结果为:,指针先指向字符串首部,从此位置开始输出,遇到结束符,0,为止,然后指针向后移动了,3,个字符,从串中第,4,个字符开始输出,遇结束符,0,为止。,【,例,8-8】,利用指针实现两个字符串的连接。,【,编程思路,】,(,1,)指针,p,指向第一个串的末尾(最后一个字符后面),指针,q,指向第二个串的首部。,(,2,)将第二个串中字符依次放入第一个串后。,下一页,返 回,上一页,8.2,指针与数组,【,程序代码,】,#include ,#include ,void main( ),char str120,str210,*p,*q;,printf,(,请输入两个字符串:,);,gets(str1);,gets(str2);,p=str1+strlen(str1); /*p,指向第一个串的末尾*,/,q=str2; /*q,指向第二个串的首部*,/,下一页,返 回,上一页,8.2,指针与数组,while(*q!=0) /*,如果第二个串未结束,继续执行*,/,*p=*q;,p+; /*,指针,p,向后移动*,/,q+; /*,指针,q,向后移动*,/,*p=0; /*,串末尾加上结束标志*,/,printf,(,连接后新串为:,);,puts(str1);,程序运行结果为:,返 回,上一页,8.3,指针与函数,8.3.1,变量地址作函数参数,调用函数时,通过函数的参数不仅能够传递普通的值,而且还能传递地址值。当实参为一个地址时,形参必须是一个基类型与它相同的指针变量。,【,例,8-9】,求两数之和。,【,程序代码,】,#include ,int,add(int,*,x,int,*y) /*,形参为指针变量*,/,int,z;,z=*x+*y;,return z;,返 回,下一页,8.3,指针与函数,void main( ),int,a,b,sum,;,printf,(,请输入,2,个整数:,);,scanf(%d%d,&a,&b,);,sum=,add(&a,&b,); /*,实参为变量的地址(即指针)*,/,printf(%d+%d,=%,dn,a,b,sum,);,程序运行结果:,下一页,返 回,上一页,8.3,指针与函数,程序分析:,调用,add(),函数时,实参是变量,a,、,b,的地址,形参是两个指针变量,只有指针变量才能接收地址值。接收完毕后,形参指针,x,指向了变量,a,,形参指针,y,指向了变量,b,,实参变量和形参指针间的关系如,图,8-6,所示。这样就可以在函数中通过指针变量访问实参变量单元。,此例中通过传送地址,使形参指针指向了实参变量,这样使得在被调函数中通过形参来改变实参的值成为可能。同时,原来只能通过,return,语句返回一个函数值,利用传地址的形式,可以把两个或两个以上的值从被调函数中返回到调用函数。,【,例,8-10】,调用,swap,函数,交换主函数中变量,x,和,y,中的数据。,【,程序代码,】,#include ,下一页,返 回,上一页,8.3,指针与函数,void,swap(int,*,a,int,*b),int,t;,t=*a; *a=*b; *b=t;,void main( ),int,x,y,;,printf,(,请输入,2,个整数:,);,scanf(%d%d,&x,&y,);,printf(1)x=%,d,y,=%,dn,x,y,);,swap(&x,&y,);,printf(2)x=%,d,y,=%,dn,x,y,);,下一页,返 回,上一页,8.3,指针与函数,程序运行结果:,小测验,如果将函数改为如下形式,程序还能实现变量,x,和,y,互换吗?,void,swap(int,*,a,int,*b),int,*t;,t=a; a=b; b=t;,下一页,返 回,上一页,8.3,指针与函数,8.3.2,数组名作函数参数,数组名可以用作函数的形参和实参,例如下面程序片段:,用数组名作实参时,是把数组的首地址传送给形参数组,对应的形参数组接收传过来的是实参数组的首地址,这样形参数组与实参数组共占同一段内存区域。数组元素,a0,与,b0,共占一个存储单元,,a1,与,b1,共占一个存储单元,。引用形参数组元素的值也就是引用实参数组元素的值,因此形参数组会影响实参数组。,下一页,返 回,上一页,void main( ),int,a5;,f(a,5);,void,f(int,b5,int n),8.3,指针与函数,【,例,8-11】,数组名作函数参数。,【,程序代码,】,#include ,void,add(int,a ,int,b ) /*,函数定义*,/,int,i;,for(i,=0;i3;i+),ai,=,ai+bi,;,void main( ),int x3=1,2,3;,下一页,返 回,上一页,8.3,指针与函数,int y3=4,5,6;,int i;,add(x,y);,/*,函数调用,实参为数组名*,/,for(i,=0;i3;i+),printf(%4d,xi);,小测验,写出上面程序的输出结果。,以上将实参数组和形参数组看成是共用存储空间,这样比较形象,读者容易理解。实际上能够接收并存放地址值的只能是指针变量,,C,编译系统是将形参数组名处理成指针变量。,下一页,返 回,上一页,8.3,指针与函数,假设某函数首部为:,int,add(int,a ,int,b ),在编译时系统会处理为:,int,fun(int,*,a,int,*b),调用函数时,指针变量接收从主调函数传递过来的实参数组首地址,这样形参指针指向了实参数组,那么可以通过形参指针去访问实参数组元素。,提示:形参数组如果是一维数组,定义时大小可以不指定;如果是二维数组,第一维的大小可以不指定。,【,例,8-12】,在数组中第,k,个数前插入一个数,x,。,【,编程思路,】,(,1,)函数需要,4,个形参,分别接收:实参数组地址、实参数组大小、,k,、,x,。,下一页,返 回,上一页,8.3,指针与函数,(,2,)函数中的操作:, 指针指向最后一个元素。, 从最后一个元素一直到下标为,k-1,的元素,依次往后移。, 将,x,赋给下标为,k-1,的元素。,【,程序代码,】,#include ,void,fun(int,*,b,int,n,int,k,int,x),int,i;,for(i,=n-1;i=k-1;i-) /*,从最后一个元素到第,k,个元素,依次往后移*,/,*(b+i+1)=*(,b+i,);,下一页,返 回,上一页,8.3,指针与函数,*(b+k-1)=x; /*,将,x,插入*,/,void main( ),int,a9=1,2,3,4,5,6,7,8,k,x,i;,printf,(,数组原值:,);,for(i,=0;i8;i+),printf(%6d,ai);,printf(n,请输入在第几位插入:,);,scanf(%d,&k,);,printf,(,请输入插入的数据:,);,scanf(%d,&x,);,下一页,返 回,上一页,8.3,指针与函数,fun(a,8,k,x); /*,函数调用*,/,printf,(,插入,%d,后数组值:,x);,for(i,=0;i=k-1;i-),*(b+i+1)=*(,b+i,);,*(b+k-1)=x;,可以改写成下面语句形式,这样更清晰、简练。,for(i,=n-1;i=k-1;i-),bi+1=,bi,;,bk-1=x;,返 回,8.4,指针应用实例,【,例,8-14】,利用指针实现把数组中的奇数存入另一数组中。,【,编程思路,】,(,1,)用两个指针,p,和,q,分别指向数组,a,和,b,。,(,2,)利用指针移动逐个取出数组,a,中的每个元素,如果当前元素的值为奇数,则存入数组,b,中。,【,程序代码,】,#include ,void main( ),int,a8,b8,*p,*,q,i,;,printf,(,请给,a,数组中输入,8,个整数:,);,for(i,=0;i8;i+),下一页,返 回,8.4,指针应用实例,scanf(%d,&ai,);,q=b; /*,指针,q,指向数组,b*/,for(p,=,a;p,a+8;p+),if(*p%2!=0),*q=*p; /*,如果,p,所指向的是奇数,则存入,b,数组中*,/,q+; /*,指针,q,指向,b,数组中下一个元素*,/,printf(b,数组中的值为:,);,for(i,=0;i,q-b;i,+) /*q,当前指向,b,数组中最后一个数值的后面,,q-b,为,b,数组所存数值的个数*,/,printf(%dt,bi,);,下一页,返 回,上一页,8.4,指针应用实例,printf(n,);,程序运行结果:,b,数组虽然有个元素,但只有前个元素中有确切的值。,【,例,8-15】,先将在字符串,s,中的字符按正序存放到,t,串中,然后把,s,中的字符按逆序连接到,t,串的后面。,例如:当,s,中的字符串为:,ABCDE,时,则,t,中的字符串应为:,ABCDEEDCBA,。,下一页,返 回,上一页,8.4,指针应用实例,【,编程思路,】,通过指针先由前往后访问,s,串,并逐个字符存入,t,串中;再由后往前访问,s,串,并逐个字符存入,t,串中,最后输出,t,串即可。,#include ,#include ,void main( ),char s20,t20,*p,*q;,printf,(,请输入一个字符串:,);,gets(s,);,for(p,=,s,q,=t;*p!=0;p+,q+)/*,正序存放*,/,*q=*p;,for(p-;p,=,s;p-,q,+) /*p,由后向前访问,s,串,实现逆序连接*,/,下一页,返 回,上一页,8.4,指针应用实例,*q=*p;,*q=0;,puts(t,);,程序运行结果:,【,例,8-16】,编写函数,其功能是对传送过来的两个浮点数求出和值与差值,并通过形参传送回调用函数。,【,编程思路,】,(,1,)定义变量,a,、,b,存放两个浮点数,变量,sum,、,sub,存放两数的和与差。,下一页,返 回,上一页,8.4,指针应用实例,(,2,)被调函数,fun,中,需要两个,float,类型的形参,x,、,y,来接收两个实数,还需要两个指针,s,、,n,,一个指向,sum,,一个指向,sub,。,(,3,)函数,fun,中,计算的两数和放到,s,所指向的变量,sum,,两数差放到,n,所指向的变量,sub,中。,【,程序代码,】,#include ,void,fun(float,x,float,y,float,*,s,float,*n),*s=x+y; /*,将和放入,s,所指向的存储单元*,/,*n=x-y; /*,将差放入,n,所指向的存储单元*,/,void main( ),下一页,返 回,上一页,8.4,指针应用实例,float,a,b,sum,sub,;,a=10.5; b=20.8;,fun(a,b,&sum,&sub,);,printf(%.2f+%.2f=%.2fn,a,b,sum);,printf(%.2f-%.2f=%.2fn,a,b,sub);,程序运行结果:,下一页,返 回,上一页,8.4,指针应用实例,【,例,8-17】,将字符串从第,k,个字符起,删去,m,个字符,组成新字符串。,【,编程思路,】,(,1,)函数需要,3,个形参,分别接收串的首地址、,k,值和,m,值。,(,2,)函数中的操作:, 指针,p,指向第,k,个字符,指针,q,指向第,k+m,个字符。, 赋值*,p=*q,。, 指针,p,、,q,同时向后移,返回(,2,),直到,q,指向串结束标志。,【,程序代码,】,#include ,void,del(char,*,s,int,k,int,m),char *p,*q;,下一页,返 回,上一页,8.4,指针应用实例,p=s+k-1; /*p,指向第,k,个字符*,/,q=s+k+m-1; /*,指针,q,指向第,k+m,个字符*,/,while(*q!=0),*p+=*q+; /*,赋值并且移动指针*,/,*p=0;,void main( ),char str30;,int,k,m,;,printf,(,请输入字符串:,);,gets(str,);,下一页,返 回,上一页,上一页,8.4,指针应用实例,printf,(,请输入从第几个字符开始删除:,);,scanf(%d,&k,);,printf,(,请输入删除几个字符:,);,scanf(%d,&m,);,del(str,k,m,);,printf,(,删除后字符串:,);,puts(str,);,程序运行结果:,返 回,8.5,本章小结,1.,每个变量都有地址(即指针),指针变量用于存放其他变量的地址。,2.,指针变量与普通变量一样,要先定义后使用。如有定义语句,float *,fp,;,,则,fp,只能指向,float,类型的变量。,3.,建立指针的指向关系,可以通过以下语句完成:,(,1,)指针变量,=&,变量;,(,2,)指针变量,1=,指针变量,2,;,其中指针变量,2,为已有指向的指针变量。,4.,变量的访问。变量可以通过变量名直接访问,也可以利用指针间接访问,,*,指针变量,表示指针变量所指向的变量。,5.,指针与一维数组。当指针变量,p,指向数组时,可以通过,p,的自增和自减在数组区域内移动指针,方便地访问数组的各个元素。,下一页,返 回,上一页,8.5,本章小结,6.,指针与二维数组。二维数组的指针比较复杂,根据定义的指针类型,可分为列指针和行指针。列指针为数组元素地址,可以在数组元素间移动,行指针为各行首地址,只能在行间移动。二维数组名是行指针常量。,7.,指针与函数。用指针作函数参数时,可以在被调函数中访问调用函数中的变量,为问题的处理提供了方便。函数间参数传递方式见,表,8-3,。,运用指针编程是,C,语言主要风格之一。利用指针能方便地处理数组和字符串。不可否认指针也是,C,语言学习中最难理解和使用的部分,学习中除了要正确理解指针的基本概念外,还需要多编写程序,多上机调试。,返 回,8.6,实训,实训,1,【,实训内容,】,指针和指针变量。,【,实训目的,】,掌握指针和指针变量的使用。,【,实训题目,】,编写程序,实现以下的每一步操作,并写出输出结果,然后上机验证。,(,1,)定义整型变量,x,,并赋初值,4321,。,(,2,)定义指向整型变量的指针变量,p,和,q,,并使,p,指向变量,x,。,(,3,)通过指针变量,p,使,q,指向变量,x,。,(,4,)通过,p,对,x,中的值增加,111,。,(,5,)通过,q,求,x,中的值的个位数,并把结果存放在,p,所指向的存储单元中。,(,6,)通过,x,输出该变量中的值。,下一页,返 回,8.6,实训,实训,2,【,实训内容,】,指针作为函数参数。,【,实训目的,】,掌握函数间的地址传递。,【,实训题目,】,分析下列程序,写出输出结果,然后上机进行验证。,#include ,void,fun(int,x,int,y,int,*,cp,int,*,dp,),*cp=,x+y,;,*,dp,=,x-y,;,下一页,返 回,上一页,8.6,实训,void main( ),int,a,b,c,d,;,a=4;,b=3;,fun(a,b,&c,&d,);,printf(%d,%dn,c,d,);,下一页,返 回,上一页,8.6,实训,实训,3,【,实训内容,】,数组名作为函数参数。,【,实训目的,】,掌握数组作为函数参数的使用。,【,实训题目,】,编写程序,交换数组,a,和数组,b,中的对应元素,要求数组交换功能在函数中实现。主函数已给出,请补充,reverse( ),函数。,#include ,void,reverse(int,x ,int,y ,int,n),void main( ),int,a10,b10,i;,printf,(,请输入,10,个数给数组,a,:,);,for(i,=0;i10;i+),下一页,返 回,上一页,8.6,实训,scanf(%d,&ai,);,printf,(,请输入,10,个数给数组,b,:,);,for(i,=0;i10;i+),scanf(%d,&bi,);,reverse(a,b,10);,printf,(,互换后数组,a,的值:,);,for(i,=0;i10;i+),printf(%6d,ai);,printf(n,互换后数组,b,的值:,);,for(i,=0;i10;i+),printf(%6d,bi);,printf(n,);,下一页,返 回,上一页,8.6,实训,实训,4,【,实训内容,】,字符串与指针。,【,实训目的,】,掌握指针在字符串操作中的应用。,【,实训题目,】,给定程序中函数,fun( ),的功能是:从字符串,s,尾部开始,按逆序把在其中出现的每相邻的两个字符,紧随其后重复出现一次,放在一个新串,t,中,若字符串,s,中头部有剩余的单个字符也重复,放在,t,的最后。,例如:当,s,中的字符串为:,ABCDE,时,,则,t,中的字符串应为:,EDEDCBCBAA,。,请改正函数,fun,中的错误,使它能得出正确的结果。注意:不要改动,main,函数,不得增行或删行,也不得更改程序的结构!,#include ,下一页,返 回,上一页,8.6,实训,#include ,void,fun(char,*s, char *t),int,i,j,sl,;,sl,=,strlen(s,);,/*found*/,for(i,=,sl,j,=0;i=,0;i,-=2),tj,+=,si,;,if(i-1=0),tj,+= si-1;,tj,+=,si,;,下一页,返 回,上一页,上一页,8.6,实训,/*found*/,if(i-1=0),ti,+=si-1;,tj,=0;,void main( ),char s100, t100;,printf(nPlease,enter string s,:,);,scanf(%s,s,);,fun(s,t,);,printf(The,result is: %,sn,t,);,返 回,图,8-1 p,指向,a,返 回,图,8-2,指针移动示意,返 回,图,8-3,指针,p,指向数组,返 回,表,8-1,一维数组元素的地址,返 回,a0,地址,a1,地址,ai,地址,通过取地址符,&,&a0,&a1,&,ai,通过数组名,a,a,a+1,a+i,通过指针变量,p,p,p+1,p+i,提示:对指针变量,p,更多的是通过,p+,或,p-,移动定位。,表,8-2,一维数组元素,返 回,a0,地址,a1,地址,ai,地址,通过数组元素名,a0,a1,ai,通过数组名,a,*,a,*,(a+1),*,(,a+i,),通过指针变量,p,*,p,*,(p+1),*,(,p+i,),下标法,p0,p1,pi,图,8-4,二维数组地址示意,返 回,图,8-5,指针数组指向示意,返 回,图,8-6,函数间地址传递,返 回,表,8-3,函数间参数传递方式,返 回,实,参,形,参,传递数据,效,果,变量,常量,表达式,变量,值,形参不影响实参,指针(地址),指针变量,指针变量,地址值,形参影响实参,数组名,数组,指针变量,地址值,形参影响实参,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 小学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!