欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    C语言第10章(谭浩强).ppt

    • 资源ID:80441156       资源大小:353KB        全文页数:80页
    • 资源格式: PPT        下载积分:11.9金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要11.9金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    C语言第10章(谭浩强).ppt

    第10章 指针 指针可以有效地表示复杂的数据结构;能动态的分配内存、使用字符串和数组;能在调用函数时获得1个以上的结果;能直接处理内存单元地址等。掌握指针的应用,可以使程序简洁、紧凑、高效。110.1地址和指针的概念地址和指针的概念一、一、变变量的地址量的地址计算机内存区的每一个字节都有一个编号。计算机内存区的每一个字节都有一个编号。在在对对程程序序进进行行编编译译时时,系系统统会会给给变变量量分分配配内内存存单单元元,这这个个内内存存单单元元的的地地址址就就是是变变量量的的地地址址。系系统统根根据据不不同同的的数数据据类类型型分分配配不同字节的空间不同字节的空间。内存单元地址内存单元地址内存单元内容内存单元内容不同不同i3jk69变量名变量名200020022004地址地址编译时是把变量名转换为变量的地址编译时是把变量名转换为变量的地址如:如:scanf(“%d”,&i);printf(“%d”,j);k=i+j;2二、变量的访问方式二、变量的访问方式1.1.直接访问直接访问 按变量地址存取变量值的方式称为按变量地址存取变量值的方式称为“直接访问直接访问”方式。方式。2.2.间接访问间接访问 假如定义变量假如定义变量j j 存放变量存放变量i i的地址。的地址。i32000变量名变量名2000地址地址 j如:如:j=&i;先找到先找到j得到变量得到变量i的地址的地址找到变量找到变量i的存储单元的存储单元对它进行存取访问对它进行存取访问3三、指针变量三、指针变量由由于于通通过过地地址址可可以以找找到到所所需需变变量量的的存存储储单单元元,所所以以c语语言言把地址称为指针。把地址称为指针。指针指针:一个变量的地址称为该变量的指针。:一个变量的地址称为该变量的指针。例如:地址例如:地址2000是变量是变量i的指针。的指针。指针变量指针变量:专门存放变量地址的变量叫指针变量。:专门存放变量地址的变量叫指针变量。注意:注意:指针指针和和指针变量指针变量的的区别区别如:如:j j 为指针变量,它存放整型变量为指针变量,它存放整型变量i i的地址的地址 我们称我们称,指针变量,指针变量 j j 指向指向整型变量整型变量i i410.2变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量变量的指针变量的指针就是变量的就是变量的地址地址。存存放放变变量量地地址址的的变变量量是是指指针针变变量量,用用来来指指向向另另一一个变量。个变量。5注意:注意:在在c程序中用程序中用*表示指向,若定义了表示指向,若定义了i_pointer为指针变量,那么为指针变量,那么*i_pointer就是就是i_pointer指向的那个变量。指向的那个变量。*i_pointer相当于相当于i都代表都代表3(值值)/*指针指针i_pointer指向了变量指向了变量i*/一一、如何定义一个指针变量、如何定义一个指针变量形式:基类型形式:基类型*指针变量名指针变量名指针只能指向基类型规定的类型变量指针只能指向基类型规定的类型变量例如:例如:inti,j;floatx;inti,j;floatx;int*i_pointer,*j_pointer;int*i_pointer,*j_pointer;那么,如何使一个指那么,如何使一个指针变针变量指向另一个量指向另一个变变量呢?量呢?可以可以:i=3;i=3;i_pointer=&i;i_pointer=&i;j_pointer=&j;j_pointer=&j;6在定义指针变量时注意:(1)定义指针变量时,变量前面的*是表示该变量是指针型的,其变量名是i_pointer,而不是*i_pointer(2)定义指针变量必须指定其类型。为什么?当i_pointer+时,加1代表多少字节才能确定。总结:一个指针变量只能指向同一类型的变量。如:floata;int*pointer;pointer=&a;(错错错错)7二、二、指针变量的引用指针变量的引用指针变量中只能存放指针变量中只能存放地址地址(指针)(指针)两个运算符:1.&:取地址运算符 如:&a/*变量a的地址*/2.*:指针运算符,取其指向的内容 *pointer表示求指针变量pointer所指向变量的内容(值)。如:inti=3,c;int*p;/*表示定义指针型变量p*/p=&i;/*指针变量p指向了变量i*/c=*p;强调*定义和引用时的区别8输出:输出:100,10100,10*pointer_1=&a;*pointer_2=&b;例10.1 通过指针变量访问整型变量main()int a,b;int*pointer_1,*pointer_2;/*区分定义和引用时的区别*/a=100;b=10;pointer_1=&a;pointer_2=&b;printf(“%d,%dn”,a,b);printf(“%d,%dn”,*pointer_1,*pointer_2);9说明:若:p1=&a;/*假设 p1 和 p2 是指针*/p2=&*p1;p2=&a /*p2也指向了a*/(1)&*p1 的含义是什么?&和*优先级相同,按自右至左的方向结合,先进行*p1的运算,就是变量a,再执行&运算。&*p1&a(2)*&a 的含义是什么?先进行&a的运算,得a的地址,再进行*运算,就是变量a。*&aa 或 *&a*p110说明:若:p1=&a;(3)(*p1)+a+(*p1)+必须有括号,若没有括号:*p1+/*优先级别相同,为右结合*/*(p1+)/*由于+在后,先使用p1,得到*p的值,p1再加1,p1指向了下一个地址*/11运行:运行:5,9a=5,b=9max=9,min=5注意:a和b并没有交换,保持原值,但是p1和p2的值改变了。例例10.2输入输入a和和b两个整数,按大小的顺序输出两个整数,按大小的顺序输出.main()int*p1,*p2,a,b;scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(ab)p1=&b;p2=&a;printf(“a=%d,b=%dn”,a,b);printf(“max=%d,min=%dn”,*p1,*p2);12 三、三、指针变量作为函数参数指针变量作为函数参数 函数的参数可以是整型、实型、字符型等数据或者是数组,还可以是指针类型的。它的作用是将一个变量的地址传送到另一个函数中。13例例10.3同例同例10.2输入输入a和和b两个整数,按大小的顺序输出两个整数,按大小的顺序输出.main()int*p1,*p2,a,b;scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(ab)swap(p1,p2);printf(“n%d,%dn”,a,b);voidswap(int*p1,int*p2)inttemp;temp=*p1;*p1=*p2;*p2=temp;/*指针变量作函数参数,把变量指针变量作函数参数,把变量a和和b的的地址传给形参,这时实参和形参都指向地址传给形参,这时实参和形参都指向变量变量a和和b*/*定义形参,所以要带定义形参,所以要带*/*把变量把变量a和和b的的值交换值交换*/注意:a和b的值改变了。14指针变量作函数参数时,指针变量作函数参数时,注意注意:1.指针变量,既可以作为函数的形参,也可指针变量,既可以作为函数的形参,也可以作函数的实参。以作函数的实参。2.指针变量作实参时,与普通变量一样,也指针变量作实参时,与普通变量一样,也是是“值传递值传递”,即将指针变量的值(,即将指针变量的值(一个地址一个地址)传递给被调用函数的形参(必须是一个指针变量)传递给被调用函数的形参(必须是一个指针变量)。注意:注意:被调用函数不能改变实参指针变量的被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。值,但可以改变实参指针变量所指向的变量的值。15 例例10.4输入输入a、b、c3个整数,按大小顺序输出。个整数,按大小顺序输出。voidswap(int*pt1,int*pt2)/*指针变量作函数形数指针变量作函数形数*/inttemp;temp=*pt1;*pt1=*pt2;*pt2=temp;/*交换变量交换变量*/voidexchange(int*q1,int*q2,int*q3)/*判断大小判断大小*/if(*q1*q2)swap(q1,q2);/*指针变量作函数实参指针变量作函数实参*/if(*q1*q3)swap(q1,q3);if(*q2*q3)swap(q2,q3);main()inta,b,c,*p1,*p2,*p3;scanf(“%d,%d,%d”,&a,&b,&c);p1=&a;p2=&b;p3=&c;exchange(p1,p2,p3);/*指针变量作函数实参指针变量作函数实参*/printf(“n%d,%d,%dn”,a,b,c);1610.3数组的指针和指向数组的指针变量数组的指针和指向数组的指针变量既然指针可以指向变量,当然也能指向数组。既然指针可以指向变量,当然也能指向数组。数组的元素是数组的元素是连续存放连续存放的的:一般,用一般,用下标法下标法表示数组元素,如:表示数组元素,如:a310.3.1指向数组元素的指针指向数组元素的指针 如何定义指向数组的指针变量?定义与指向普通变量的指针变量的定义方法一样。例如:inta10,*pointer=a;或者:或者:inta10,*pointer;pointer=a;以上是在语句中赋值,分为两步。&a0或注意:如果数组为注意:如果数组为int型,型,则指针变量也必须为则指针变量也必须为int型。型。&a0或/*数组名代表数组的首地址*/以上是在定义时赋值17int *p1,*p2,*p3;int a5=2,4,8,16,32 ;p1=&a0;p2=&a3;p3=a;2481632a0a1a2a3a4p1p2p31810.3.2通过指针引用数组元素通过指针引用数组元素如:如:inta3,*p=a;*p=1;/*相当于相当于a0=1*/(p=1;)(错错)注意:当p+1p+1时,则指针p指向同一数组的下一个元素,而不是把地址加1。当p为int型时:p+1相当于使p的值(地址)加2个字节;当p为float型时:p+1相当于使p的值(地址)加4个字节;所以:p+1代表的地址=p+1*d/*d为数组元素的类型所占的字节数*/19说明:说明:如果有如果有inta10,*p=a;,则:,则:(1)p+i和和a+i都可以表示数组元素都可以表示数组元素ai的的地址地址,或者说它们都指向或者说它们都指向a数组的第数组的第i个元素。个元素。例如:例如:p+9a+9(2)*(p+i)和和*(a+i)就是数组元素就是数组元素ai的值。的值。例如:例如:*(p+5)*(a+5)值都是值都是&a9,都指向,都指向a9/*是地址是地址*/都是都是a5/*是值是值*/实际上,在编译时,对数组元素实际上,在编译时,对数组元素ai是按是按*(a+i)处理的,若数组处理的,若数组a的首地址为的首地址为1000,a3的地址的地址=1000+3*2=1006,再到地址,再到地址1006找到找到a3的值。的值。20说明:说明:(3)指向数组的)指向数组的指针指针变量,也可将其看作是变量,也可将其看作是数组数组名名,因而也可按下标法来使用。,因而也可按下标法来使用。例如:例如:*(p+i)=pi=ai所以:引用一个数组元素,可以用多种方法所以:引用一个数组元素,可以用多种方法:1)下标法下标法,如,如ai或或pi形式;形式;2)指针法指针法,如,如*(a+i)或或*(p+i)/*p是指针变量是指针变量*/*a是数组名,是数组名,p是指针变量是指针变量*/21 例例10.5 输出数组中的全部元素。比较三种方法(1)下标法void main()int a10,i;for(i=0;i10;i+)scanf(“%d”,&ai);printf(“n”);for(i=0;i10;i+)printf(“%d”,ai);printf(“n”);(3)用指针变量指向数组元素void main()int a10,i,*p;for(i=0;i10;i+)scanf(“%d”,&ai);printf(“n”);for(p=a;p(a+10);p+)printf(“%d”,*p);printf(“n”);(2)用数组名计算数组地址,找到元素的值void main()int a10,i;for(i=0;i10;i+)scanf(“%d”,&ai);printf(“n”);for(i=0;i10;i+)printf(“%d”,*(a+i);printf(“n”);第第1、2种方法效率相同,第种方法效率相同,第3种方法的效率更高种方法的效率更高for(i=0,p=a;p(a+10);p+)for(i=0,p=a;p(a+10);p+)printf(%d,printf(%d,pipi););22使用指针变量指向数组元素时,需使用指针变量指向数组元素时,需注意注意:(1)可以通过改变指针变量的值使其指向不同的元素,可以通过改变指针变量的值使其指向不同的元素,如如p+但是不能用但是不能用数组名数组名a+(2)使用指针变量,要注意指针的当前值。使用指针变量,要注意指针的当前值。如下例如下例main()int*p,i,a5;p=a;for(i=0;i5;i+)scanf(“%d”,p+);printf(“n”);for(i=0;i5;i+,p+)printf(“%d”,*p);printf(“n”);p=a;/*输出数组元素输出数组元素*/解决办法:解决办法:?(3)由上例得出,指针变量可以指向数组以外的内存单元,系统不会)由上例得出,指针变量可以指向数组以外的内存单元,系统不会报错。报错。23*(p+)a0*(+p)a1若若pa0,则,则注意注意:(4)指针变量的运算。指针变量的运算。p=a;/*指针指针p指向了数组指向了数组a的首地址的首地址*/1)p+/*使使p指向下一个元素指向下一个元素*/2)*p+*(p+)/*先得到先得到*p的值,指针的值,指针p指向下一地址指向下一地址*/如:如:for(i=0;i5;i+,p+)printf(“%d”,*p);3)*(p+)与与*(+p)不同不同可改为:可改为:for(i=0;i5;i+)printf(“%d”,*p+);244)+(*p)/*p指向的值加指向的值加1*/若若pa0,a0=5,则则+(*p)a0=65)若)若pai,则:,则:*(p-)ai-/*先做先做*p运算,运算,p再自减再自减*/*(-p)a-i/*先做先做p自减,再做自减,再做*运算运算*/*(+p)a+i同理同理256)指针的关系运算 若两个指针指向同一个数组的元素,则可以进行关系运算,运算结果为0或1。、=、=:判断两个指针指向的数据位置的前后关系=,!=:判断两个指针是否指向同一个数据7)指针变量可以有空值,即该指针变量不指向任何变量。p=NULL;p=NULL;2610.3.3用数组名作函数参数用数组名作函数参数数组名作数组名作实参实参时:起始地址时:起始地址形参数组形参数组;数组名作数组名作形参形参时:接收实参数组的起始地址时:接收实参数组的起始地址实际上,实际上,c编译是把形参数组名作为指针变量来处理。编译是把形参数组名作为指针变量来处理。如:如:f(inta,intn)f(int*a,intn)等价等价27例例10.7请把数组请把数组a中的中的n个元素按相反的顺序存放。个元素按相反的顺序存放。1234567891010 987654321算法:算法:a0an-1a1an-2aint(n-1)/2an-int(n-1)/2)-1设循环变量设循环变量i,ji=0;j=n-1aiaj交换交换;直到;直到i=(n-1)/2。i:0(n-1)/2(n-1):j-28main()inti,a10=3,5,2,6,8,9,0,1,7,4;for(i=0;i10;i+)printf(%d,ai);printf(n);inv(a,10);/*数组名数组名a作实参作实参*/for(i=0;i10;i+)printf(%d“,ai);程序:程序:voidinv(intx,intn)/*数组名数组名x作形参作形参*/inttemp,i,j,m=(n-1)/2;for(i=0;i=m;i+)j=n-1-i;temp=xi;xi=xj;xj=temp;voidinv(int*x,intn)/*指针变量指针变量x作形参作形参*/inttemp,*i,*j,*p,m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i=p;i+,j-)temp=*i;*i=*j;*j=temp;指针变量能否作形参?指针变量能否作形参?/*ia0,ja9,pa4*/29总结:总结:数组及指向数组的指针变量作函数参数时,数组及指向数组的指针变量作函数参数时,可有种等价形式可有种等价形式P238-239(本质上是一种,即指针(本质上是一种,即指针数据作函数参数)数据作函数参数):(1)形参、实参都用数组名)形参、实参都用数组名(2)形参、实参都用指针变量)形参、实参都用指针变量(3)形参用指针变量,实参用数组名)形参用指针变量,实参用数组名(4)形参用数组名,实参用指针变量)形参用数组名,实参用指针变量3010.3.4指向多维数组的指针指向多维数组的指针1.多维数组元素的地址多维数组元素的地址2.inta34=1,3,5,7,9,11,13,15,17,19,21,231357911131517192123a0a1a2aa数组包括数组包括3个元素:个元素:a0a1a2,而每个元素又是一个一维数组。,而每个元素又是一个一维数组。因此:因此:aa0第第0行行&a00a+1a1第第1行行&a10a+2a2第第2行行&a20可看作:可看作:2000a+12008a+220161=8个字节个字节31分析:第分析:第0 0行行1 1列列的的地址地址表示表示?(&a01)(&a01)a0 a0 第第0 0行行 a0+1 a0+1 第第0 0行行1 1列列 1=2个字节(个字节(2002)第第1 1行行1 1列列的地址表示的地址表示?a1+1 a1+1再分析:再分析:ai=*(a+i)或或*(p+i)或)或pi等价等价 a0=*(a+0)a0=*(a+0)第第0 0行行(加加1=81=8个字节个字节)a0+1=*(a+0)+1 a0+1=*(a+0)+1 第第0 0行第行第1 1列列(加加1=21=2个字节个字节)结论结论:第第i i行行j j列列的地址表示方法的地址表示方法?ai+j ai+j或或*(a+i)+j*(a+i)+j分析:第分析:第0 0行行1 1列列的的值?值?地址:地址:a0+1a0+1或或*(a+0)+1*(a+0)+1值:值:*(a0+1a0+1)或)或*(*(a+0)+1*(a+0)+1)结论:结论:aijaij的值的值?*(ai+jai+j)或)或*(*(a+i)+j*(a+i)+j)总结总结:若:若a a是一唯的,则是一唯的,则aiai表示第表示第i i个元素值;个元素值;若若a a是二唯的,则是二唯的,则aiai表示第表示第i i行的首地址;行的首地址;32表示形式含义地址a a二维数组名,指向一唯数组a0,即0行首地址2000a0a0,*(a+0),*a*a*(a+0)*(a+0)0行0列元素地址2000a+1a+1,&a1&a11行首地址2008a1a1,*(a+1)*(a+1)1行0列元素a10的地址2008a1+2,*(a+1)+2,&a121行2列元素a12的地址2012*(a1+2),*(*(a+1)+2),a121行2列元素a12的值13表表10-2二维数组二维数组a的性质的性质33注意注意:对于二唯数组对于二唯数组,为什么为什么a+1a+1和和*(a+1)*(a+1)都是都是a1a1地址地址(2008 2008)?a+1 a+1 第第1 1行行 a1/*数组名数组名a是首地址是首地址*/对于二唯数组对于二唯数组 a1=*(a+1)a+1 a+1=*(a+1)*(a+1)34#defineFORMAT“%d,%dn”main()inta34=1,3,5,7,9,11,13,15,17,19,21,23;printf(FORMAT,a,*a);printf(FORMAT,a0,*(a+0);printf(FORMAT,&a0,&a00);printf(FORMAT,a1,a+1);printf(FORMAT,&a10,*(a+1)+0);printf(FORMAT,a2,*(a+2);printf(FORMAT,&a2,a+2);printf(FORMAT,a10,*(*(a+1)+0);例例10.10输出二维数组有关的值输出二维数组有关的值/*第第0行首地址,行首地址,0行行0列元素地址列元素地址*/*第第0行行0列元素地址列元素地址*/*第第0行首地址,第行首地址,第0行行0列元素地址列元素地址*/*第第1行行0列元素地址列元素地址,第,第1行首地址行首地址*/*第第1行行0列元素地址列元素地址*/*第第2行行0列元素地址列元素地址*/*第第2行首地址行首地址*/*第第1行行0列元素的值列元素的值*/352.指向多维数组的指针变量指向多维数组的指针变量(1)指向数指向数组组元素的指元素的指针变针变量量例例10.11用指针变量输出数组元素的值。用指针变量输出数组元素的值。main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int *p;for(p=a0;pa0+12;p+)if(p-a0)%4=0)printf(“n”);printf(“%4d”,*p);/*a0代表第代表第0行行0列元素地址列元素地址*/36aij在数组(在数组(n*m)中的相对位置)中的相对位置计算公式计算公式:i*m+j(m为数组的总列数为数组的总列数)如:如:a23位置位置=2*4+3(2)指向由指向由m个元素组成的一唯数组的指针变个元素组成的一唯数组的指针变量量例例10.11的指针变量的指针变量p是指向整型数据的,是指向整型数据的,p+1表示指向表示指向下一个元素。可以使下一个元素。可以使p不指向整型数据,而指向包含不指向整型数据,而指向包含m个元个元素的一唯数组,这样素的一唯数组,这样p+1就表示下一行元素的首地址。就表示下一行元素的首地址。地址?地址?&a00+(2*4+3)*d37例10.13 输出二维数组任一行任一列元素的值。main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int (*p)4,i,j;p=a;scanf(“%d,%d”,&i,&j);printf(“a%d,%d=%dn”,i,j,*(*(p+i)+j);/*表示表示p所指的对象是有所指的对象是有4个整型元素的数组,个整型元素的数组,p只能指只能指向一个包含向一个包含4个元素的一唯数组个元素的一唯数组*/*p*(p+1)输入:输入:1,1输出:输出:11更改后:输入:1,1输出:3383.用指向数组的指针作函数参数用指向数组的指针作函数参数例例10.13有一个班,有一个班,3个学生,个学生,4门成绩。求所有成绩的平均分,第门成绩。求所有成绩的平均分,第2个学生的各门成绩。个学生的各门成绩。average(float*p*p,intn)float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p=p_end;p+)sum=sum+(*p);aver=sum/n;printf(average=%5.2fn,aver);search(float(*p)4,intn)inti;for(i=0;iy)z=x;elsez=y;return(z);等价于等价于c=max(a,b);50说明:说明:(1)指向函数的指针变量的定义形式:)指向函数的指针变量的定义形式:数据类型数据类型(*指针变量名)(函数参数列表);指针变量名)(函数参数列表);/*数据类型是指函数返回值的类型数据类型是指函数返回值的类型*/(2)函数的调用可以用函数名,也可以用函数指针;)函数的调用可以用函数名,也可以用函数指针;(3)指向函数的指针变量可以先后指向)指向函数的指针变量可以先后指向同一类型同一类型的不同函数;的不同函数;(4)给函数指针变量赋值时,只需给出函数名)给函数指针变量赋值时,只需给出函数名如:如:p=max;p=max(a,b);(错)(错)(5)用指针变量调用函数时,只需用()用指针变量调用函数时,只需用(*p)代替函数名;)代替函数名;如:如:c=(*p)(a,b);(6)指向函数的指针不能作)指向函数的指针不能作p+或或p+i的操作。的操作。/*表示调用表示调用p指向的函数,实参为指向的函数,实参为a,b,函数返回值的类型,由指针变量函数返回值的类型,由指针变量p的数据的数据类型决定类型决定*/5110.5.2用指向函数的指针作函数参数用指向函数的指针作函数参数函函数数的的参参数数可可以以是是变变量量、指指向向变变量量的的指指针针变变量量、数数组组名名、指指向向数数组组的的指指针针变变量量,另另外外函函数数的的指指针针也也可可以以作作为为函函数数的的参参数数,即即指指向向函函数数的的指指针针变变量量作作函函数数参参数数,是是实实现现函函数地址的数地址的传递传递。原理:原理:假假设设,函数函数sub(x1,x2)形参)形参x1和和x2为为指向函数的指指向函数的指针变针变量;量;调调用用函函数数sub时时,假假设设实实参参为为两两个个函函数数名名f1和和f2,传传给给形形参的是函数参的是函数f1和和f2的入口地址;的入口地址;这样这样,在函数,在函数sub中就可以中就可以调调用函数用函数f1和和f2了。了。用指用指针实现针实现了函数的嵌套了函数的嵌套调调用。用。52f1()f2()voidsub(int(*x1)(int),int(*x2)(int,int)inta,b,i,j;a=(*x1)(i);b=(*x2)(i,j);main()sub(f1,f2);/*x1为形参,指向函数的指针变量,指向的为形参,指向函数的指针变量,指向的函数只有一个参数函数只有一个参数*/*相当于相当于a=f1(i),调用调用f1函数函数*/*实参为函数名,传递的是函数的入口地址实参为函数名,传递的是函数的入口地址*/*相当于相当于a=f2(i,j),调用调用f2函数函数*/例如:例如:53用指针变量可方便的调用不同函数,实现结构化程序设计。用指针变量可方便的调用不同函数,实现结构化程序设计。例例10.23用一个函数用一个函数process,第一次调用它时找出,第一次调用它时找出a和和b的大数,第二次调用的大数,第二次调用找出小数,第三次调用找出总和。找出小数,第三次调用找出总和。intmax(intx,inty)intz;if(xy)z=x;elsez=y;return(z);intmin(intx,inty)intz;if(xy)z=x;elsez=y;return(z);intadd(intx,inty)intz;z=x+y;return(z);voidprocess(intx,inty,int(*fun)(int,int)intresult;result=(*fun)(x,y);printf(“%dn”,result);voidmain()inta,b;scanf(“%d,%d”,&a,&b);process(a,b,max);process(a,b,min);process(a,b,add);/*函数的入口地址函数的入口地址*/5410.6返回指针值的函数返回指针值的函数一个函数可以返回一个一个函数可以返回一个int型、型、float型、型、char型的数据,型的数据,也可以返回一个指针类型的数据。也可以返回一个指针类型的数据。返回指针值的函数(简称指返回指针值的函数(简称指针函数)的定义格式如下:针函数)的定义格式如下:函数类型函数类型*函数名函数名(形参表形参表)floatsearch(float(*p)4,intn)float*tp;tp=*(p+n);return(tp);55 cccccint *seek(int (*pnt_row)3)int i=0,*pnt_col;/*定义一个(列)指针变量pnt_col*/pnt_col=*(pnt_row+1);/*使pnt_col指向下一行之首(作标志用)*/for(;i3;i+)if(*(*pnt_row+i)60)/*某项成绩不合格*/pnt_col=*pnt_row;/*使pnt_col指向本行之首*/break;/*退出循环*/return(pnt_col);56/*主函数主函数main()()*/main()intgrade33=55,65,75,65,75,85,75,80,90;inti,j,*pointer;/*定义一个定义一个(列列)指针变量指针变量pointer*/for(i=0;i3;i+)/*控制每个学生控制每个学生*/pointer=seek(grade+i);/*用行指针作实参,调用行指针作实参,调seek()函数函数*/if(pointer=*(grade+i)/*该学生至少有一项成绩不合格该学生至少有一项成绩不合格*/*输出该学生的序号和各项成绩输出该学生的序号和各项成绩*/printf(“No.%dgradelist:”,i+1);for(j=0;j3;j+)printf(“%d”,*(pointer+j);printf(“n”);程序运行结果:程序运行结果:No.1gradelist:55657557程序说明:程序说明:(1)主函数中的主函数中的pointer=seek(grade+i);语句语句调调用用seek()函函数数时时,将将实实参参grade+i(行行指指针针)的的值值,复复制制到到形形参参pnt_row(行行指指针针变变量量)中中,使使形形参参pnt_row指指向向grade数数组组的的第第i行。行。(2)在指针函数)在指针函数seek()中:中:1)pnt_col=*(pnt_row+1);语句语句*(pnt_row+1)将将行行指指针针转转换换为为列列指指针针,指指向向grade数数组组的的第第i+1行第列,并赋值给(列)指针变量行第列,并赋值给(列)指针变量pnt_col。2)if(*(*pnt_row+i)60)行行pnt_row是是一一个个行行指指针针,指指向向数数组组grade的的第第i行行;*pnt_row使使指指针针由由行行转转换换为为列列,指指向向数数组组grade的的第第i行行列列;*pnt_row+j的的值值还还是是一一个个指指针针,指指向向数数组组的的第第i行行第第j列列;*(*pnt_rowj)是是一一个个数据(数组元素数据(数组元素gradeij的值)。的值)。5810.7指针数组和指向指针的指针指针数组和指向指针的指针10.7.1指针数组的概念指针数组的概念一个数组,其元素均为指针类型数据,称为指针数组。数组一个数组,其元素均为指针类型数据,称为指针数组。数组的每个元素都是一个指针数据。指针数组比较适合用于指向多个的每个元素都是一个指针数据。指针数组比较适合用于指向多个字符串,使字符串处理更加方便、灵活。字符串,使字符串处理更加方便、灵活。定义格式定义格式:数据类型数据类型*数组名数组名元素个数元素个数例如例如:int*p4由由于于比比*优优先先级级高高,因因此此P先先与与4结结合合,形形成成P4形形式式,然然后后再再与与P前前面面的的“*”结结合合,“*”表表示示此此数数组组是是指指针针类类型型的的,每每个个数数组组元元素素相相当当于于一一个个指指针针变变量量,都都可指向一个整型变量。可指向一个整型变量。例例:有若干计算机图书,请按字母顺序,从小到大输出书名。有若干计算机图书,请按字母顺序,从小到大输出书名。解题要求:使用排序函数完成排序,在主函数中进行输入输出。解题要求:使用排序函数完成排序,在主函数中进行输入输出。/*程序功能:指针数组应用示例程序功能:指针数组应用示例*/59void sort(char*name,int count)void sort(char*name,int count)char*temp_p;char*temp_p;int i,j,min;int i,j,min;/*使用选择法排序使用选择法排序*/for(i=0;icount-1;i+)for(i=0;icount-1;i+)/*外循环:控制选择次数外循环:控制选择次数*/min=i;min=i;/*预置本次最小串的位置预置本次最小串的位置*/for(j=i+1;for(j=i+1;jcount;j0)if(strcmp(namemin,namej)0)/*存在更小的串存在更小的串*/min=j;min=j;/*保存之保存之*/if(min!=i)if(min!=i)/*存在更小的串,交换位置存在更小的串,交换位置*/temp_p=namei;namei=namemin;temp_p=namei;namei=namemin;namemin=temp_p;namemin=temp_p;60main()main()char*name5=“BASIC”,”FORTRAN”,”PASCAL char*name5=“BASIC”,”FORTRAN”,”PASCAL ”,”C”,”FoxBASE”;”,”C”,”FoxBASE”;int i=0;int i=0;sort(name,5);sort(name,5);/*使用字符指针数组名作实参,调用排序 函数sort()*/for(;i5;i+)printf(“%sn”,namei);for(;i5;i+)printf(“%sn”,namei);/*输出排序结果*/程序运行结果:BASICBASIC C C FORTRAN FORTRAN FoxBASE FoxBASE PASCAL PASCAL61程序说明:程序说明:(1 1)实参对形参的值传递:)实参对形参的值传递:sort(name ,5)sort(name ,5);void sort(char*name,int count)void sort(char*name,int count)(2 2)字字符符串串的的比比较较只只能能使使用用strcmp()strcmp()函函数数。形形参参字字符符指指针针数数组组namename的的每每个个元元素素,都都是是一一个个指指向向字字符符串串的的指针,所以有指针,所以有strcmp(namemin,namej)strcmp(namemin,namej)。主函数主函数main()main()的形参的形参在在以以往往的的程程序序中中,主主函函数数main()main()都都使使用用其其无无参参形形式式。实际上,主函数实际上,主函数main()main()也是可以指定形参的。也是可以指定形参的。案例案例:用同一程序实现文件的加密和解密。用同一程序实现文件的加密和解密。约约定定:程程序序的的可可执执行行文文件件名名为为lock.exelock.exe,其其用用法法为为:lock lock+|-+|-,其其中中“+”“+”为为加加密密,“-”“-”为解密。为解密。62main(intargc,char*argv)ccccccharc;if(argc!=3)printf(参数个数不对!参数个数不对!n);elsec=*argv1;/*截取第二个实参字符串的第一个字符截取第二个实参字符串的第一个字符*/switch(c)case+:/*执行加密执行加密*/printf(执行加密程序段。执行加密程序段。n);/*加密程序段加密程序段*/break;case-:/*执行解密执行解密*/printf(执行解密程序段。执行解密程序段。n);/*解密程序段解密程序段*/break;default

    注意事项

    本文(C语言第10章(谭浩强).ppt)为本站会员(wuy****n92)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

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

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开