欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    谭浩强C语言课件第10章.ppt

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

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

    谭浩强C语言课件第10章.ppt

    第十章 指针10.1 指针的概念,指针(pointer):是一个变量的地址。指针变量:是一个变量,其值是另一个变量的地址。任何变量都在计算机内存中占有一块内存区域,变量的值就存放在这块内存区域之中,一个变量的访问(访问是指取出其值或向它赋值)方式有两种:(1)直接访问,通过变量名访问,如通过变量名i直接访问。(2)间接访问,通过该变量的指针来访问,如通过i_pointer访问变量i。,10.2 变量的指针,一、指针变量的定义指针变量有三个属性:(1)该指针变量指向的变量的类型。如i_pointer指向的变量i是整型。(2)该指针变量在内存中占多少内存单元。如i_pointer占两个内存单元,称为“近指针”,用near表示。如果该变量在内存中占4个内存单元,称为“远指针”,用far表示。如果未指定near或far,缺省是near。(指针变量在内存中要么占2个内存单元,要么占4个内存单元)。(3)该指针变量指向哪一个变量,即该指针变量的值是多少。如i_pointer的值是2000。指针变量定义的一般形式:类型标识符*标识符 如:int*pointer_1,*pointer_2;,例、int i,j;/*定义两个整型变量*/int*pointer_1,*pointer_2;float*pointer_3;char*pointer_4;void*pointer_5;,指针变量的赋值:例、pointer_1=,注意,指针变量中只能存放地址,不能将一个非地址类型的数据(如常数等)赋给一个指针变量,如:,pointer_1=100;,也可以在定义指针变量的同时指定其初值,如:int a;int*p=,二、指针变量的引用,有两个运算符可以引用指针变量:(1)(2)*:指针运算符。用于访问指针变量所指向的变量。*和&是互逆运算,例;i=3;直接访问 ptr=间接访问,说明:,1、在定义指针变量时,还未规定它指向哪一个变量,此时不能用*运算符访问指针。只有在程序中用赋值语句具体规定后,才能用*运算符访问所指向的变量。,正确的引用:,2、区分:*运算符在不同场合的作用,编译器能够根据上下文环境判别*的作用。,int a,b,c;int*p;(*表示定义指针)p=(*表示乘法运算符),例10.2 输入a和b两个整数,按先大后小的顺序输出a和b。,main()int*p1,*p2,*p,a,b;scanf(%d,%d,p1=,if(ab)p=p1;p1=p2;p2=p;p1指向较大值,p2指向较小值.,程序说明:,三、指针变量作为函数的参数,例10.3 题目要求输入a和b两个整数,按先大后小的顺序输出a和b。,int swap(int*p1,int*p2)int p;p=*p1;*p1=*p2;*p2=p;,main()int a,b;int*pointer_1,*pointer_2;scanf(%d,%d,例10.4 输入a、b、c三个整数,按大小顺序输出。,int swap(int*pt1,int*pt2)int p;p=*pt1;*pt1=*pt2;*pt2=p;int exchange(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()int a,b,c,*p1,*p2,*p3;scanf(%d,%d,%d,10.3 数组的指针和指向数组的指针变量,指针可以指向数组和数组元素,当一个指针指向数组后,对数组元素的访问,既可以使用数组下标,也可以使用指针。并且,用指针访问数组元素,程序的效率更高。,一、指向数组元素的指针变量,指向数组元素的指针变量,其类型应与数组元素相同,例、int a10;/*元素为整型*/float b10;/*元素为实型*/int*p;/*可以指向数组a的元素*/float*pf;/*可以指向数组b的元素*/为了让指针p指向数组a,应把数组a的地址赋给指针变量p。p=a;或p=,二、通过指针引用数组元素当使指针p指向数组a后,可以用指针p访问数组的各个元素。,#includemain()int a=1,2,3,4,5,6,*p;p=a;*(p+3)+=2;printf(“%d,%dn”,*p,*(p+3);,A 0,5 B1,5C 0,6 D1,6,例10.5 输出数组的全部元素。(设10个元素,整型)。,方法一:,1、下标法(常用,很直观)main()int a10;int i;for(i=0;i10;i+)scanf(%d,方法二;,2、用数组名计算数组元素的地址。(效率与下标法相同,不常用)main()int a10;int i;for(i=0;i10;i+)scanf(%d,方法三:,3、用指针访问各元素。(常用,效率高)main()int a10;int*p,i;for(i=0;i10;i+)scanf(“%d”,注意:,1、若指针p指向数组a,虽然p+i与a+i、*(p+i)与*(a+i)意义相同,但仍应注意p与a的区别,a是地址常量,而p是指针变量。例、for(p=a;a(p+10);a+)a代表数组的首地址,是不变的,a+不合法2、指针变量可以指向数组中的任何元素,注意指针变量的当前值。,例10.6 输出数组a的10个元素。,程序:main()int*p,i,a10;p=a;for(i=0;i10;i+)scanf(%d,p+);printf(n);for(i=0;i10;i+,p+)printf(%d,*p);printf(%d,*p);,main()int*p,i,a10;p=a;for(i=0;i10;i+)scanf(%d,p+);printf(n);p=a;for(i=0;i10;i+,p+)printf(%d,*p);,3、使用指针时,应特别注意避免指针访问越界。在上例中,第二次for循环,p已经越过数组的范围,但编译器不能发现该问题。,4、指针使用的几个细节。,设指针p指向数组a(p=a),则:p+(或 p+=1),p指向下一个元素。*p+,相当于*(p+)。因为,*和+同优先级,+是右结合运算符。*(p+)与*(+p)的作用不同。*(p+):先取*p,再使p加1。*(+p):先使p加1,再取*p。(*p)+表示,p指向的元素值加1。如果p当前指向数组a的第i个元素,则:*(p-)相当于ai-,先取*p,再使p减1。*(+p)相当于a+i,先使p加1,再取*p。*(-p)相当于a-i,先使p减1,再取*p。,三、数组名作函数参数,数组名代表数组首地址,因此,它作实参在函数调用时,是把数组首地址传送给形参。这样,实参数组和形参数组共占同一段内存区域。从而在函数调用后,实参数组的元素值可能会发生变化。,例10.7 将数组a中n个元素按相反顺序存放。,算法:a0与an-1交换,a1与an-2交换,.,a(n-1)/2与an-int(n-1)/2)交换。实现:用i,j作元素位置变量,开始i=0,j=n-1。将ai与aj交换,然后i加1,j减1,直到i=(n-1)/2。,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=ai;ai=aj;aj=t;return;,main()static int i,a10=3,7,9,11,0,6,7,5,4,2;printf(the original array:n);for(i=0;i10;i+)printf(%d,ai);printf(n);inv(a,10);printf(the array hans been inverted:n);for(i=0;i10;i+)printf(%d,ai);printf(n);,函数inv()可以用指针作形参,运行情况与用数组作形参相同。,void inv(int*x,int n)int*p,t,*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;return;,例10.8 从10个数中找出其中最大值和最小值。只找出其中最大值和最小值,不能改变元素的排列顺序)。方法1、实参和形参均用数组变量。,方法2、形参和实参均使用指针变量。,小结:数组作函数的参数,实参和形参之间传送数组的首地址,首地址可以用指针表示,也可以用数组名表示,因此,实参和形参有以下四种组合情况。,若有以下调用语句,则不正确的fun函数的首部是 A)void fun(int m,int x)B)void fun(int s,int h41)C)void fun(int p,int*s)D)void fun(int n,int a)main()int a50,n;fun(n,D,四、多维数组的指针二维数组static int a34=1,3,5,7,9,11,13,15,17,19,21,23;理解为:有三个元素a0、a1、a2,每一个元素代表一行,每一个元素是一个包含4个元素的数组,数组名a代表:整个二维数组的首地址,也是元素a00的地址,同时代表第一行元素的首地址。a+1表示第二行元素的首地址,也是元素a10的地址。a+2表示第三行元素的首地址,也是元素a20的地址。,由于把a0、a1、a2看成一维数组(一维数组名),它们代表各自数组的首地址,即:,a0&a00 等价于*(a+0),a1&a10 等价于*(a+1),a2&a20 等价于*(a+2),根据一维数组的表示方法,有:,a0+1:&a01 一维数组中第二个元素的地址,a1+1:等价于*(a+1)+1,a0+2:&a02,综上所述,二维数组a的地址用下图说明,已知某元素的指针后,可以用*运算符访问该元素。例、,*(a1+2)=a12=13,二维数组元素aij 的值可用以下方式表示:*(a i+j),*(*(a+i)+j),aij二维数组元素aij的地址可用以下方式表示:a i+j,*(a+i)+j,&aij详见:P225,补充练习:,若有以下定义和语句:int s45,(*ps)5;ps=s;则对s数组元素的正确引用形式是()A)ps+1B)*(ps+3)C)ps02D)*(ps+1)+3,C,例10.11 运行,2、指向多维数组的指针变量,(1)指向数组元素的指针变量。(用列指针对二维数组进行操作),例10.12 用指针变量输出数组元素的值。,main()static 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);,注意:本例用指针顺序访问二维数组的元素。若需访问二维数组anm(n行m列)的某个元素aij,计算该元素的相对位置公式为:,i*m+j(i,j=0,1,2,.)这种方法相当于把二维数组转化为一维数组来使用。,(2)指向m个元素组成的一维数组的指针变量(用行指针对二维数组进行操作)int(*p)4;,例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(“i=%d,j=%d”,说明:(*p)4表示p为单独一个指针变量,行指针,指向含有4个元素的一维数组,即*p有4个元素,每个元素为整型。*p4为指针数组,*p数组有4个元素,每个元素中存放的是地址,即每个元素都为指针变量。,多维数组的指针作函数参数两种情况:(1)用指向变量的指针变量(2)用指向一维数组的指针变量,例10.14 运行例10.15 运行,10.4 字符串的指针,一、字符串的表现形式C语言中,有两种方式可以实现字符串:字符数组字符指针,字符数组例10.16main()static char string=I love China!;printf(%sn,string);string是数组名,代表字符数组的首地址。数组可以用下标访问,也可以用指针访问。例、string4表示一个元素其值是字符v,也可以用*(string+4)来访问,string+4是指向字符v的指针。,字符指针例10.17main()char*string=I love China!;printf(%sn,string);string是一个指针变量,“I love China!是一个字符串常量。语句:char*string=I love China!;等价于char*string;string=I love China!;它把字符串常量的首地址赋给指针string.不能理解为把字符串常量赋值给指针变量。*string=I love China!;,从以上两个例子中,可以看到:1、字符数组和字符指针的概念不同。2、字符指针指向字符串,而C语言中,字符串按数组方式处理,因此,字符数组和字符指针的访问方式相同。例如,均可以使用%s格式控制符进行整体输入输出。但应注意,如果不是字符数组,而是整型、实型等数字型数组,不能用%s,只能逐个元素处理。,例10.18 将字符串a复制到字符串b。,main()char a=I am a boy.;char b20;int i;for(i=0;*(a+i)!=0;i+)*(b+i)=*(a+i);*(b+i)=0;printf(string a is:%sn,a);printf(string b is:);for(i=0;bi!=0;i+)printf(%c,bi);printf(n);,例10.19 将字符串a复制到字符串b。(用指针处理),main()char a=I am a boy.,b20,*p1,*p2;int i;p1=a;p2=b;for(;*p1!=0;p1+,p2+)*p2=*p1;*p2=0;printf(string a is:%sn,a);printf(string b is:);for(i=0;bi!=0;i+)printf(%c,bi);printf(n);,二、字符串指针作函数参数,将一个字符串从一个函数传递到另一个函数,可以使用传地址的方式,即用字符数组名或字符指针变量作参数。有以下四种情况:,例10.20 用函数调用实现字符串的复制。,(1)用字符数组作参数。,void copy_string(char from,char to)int i=0;while(fromi!=0)toi=fromi;i+;toi=0;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(string_a=%sn string_b=%sn,a,b);,main()函数可以改写为(使用字符指针):,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(string_a=%sn string_b=%sn,a,b);,(2)形参用字符指针。,void copy_string(char*from,char*to)for(;*form!=0;from+,to+)*to=*from;*to=0;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(string_a=%sn string_b=%sn,a,b);,(3)对copy_string函数的几种简化,void copy_string(char*from,char*to)while(*to=*from)!=0)to+;from+,void copy_string(char*from,char*to)while(*to+=*from+)!=0);,当遇到*from=0时,不执行赋值运算*to+=*from+,因此,最后应加一句*to=0。,void copy_string(char*from,char*to)while(*from!=0)*to+=*from+;*to=0;,与第种简化相同,当*from=0时,表达式*to+=*from+的值等于0(假),结束while循环。,void copy_string(char*from,char*to)while(*to+=*from+);,for循环的结束条件是表达式*to+=*from+的值(即*from的值)等于0。且form中的0已被赋给to。注意0的ASCII码是不是0。,void copy_string(char*from,char*to)for(;(*to+=*from+)!=0;);或 for(;*to+=*from+;);,形参用数组,使用局部指针变量指向形参数组。,void copy_string(char from,char to)char*p1,*p2;p1=from;p2=to;while(*p2+=*p1+)!=0),补充练习:,以下程序的输出结果是():#include#includemain()char b18=“abcdefg”,b28,*pb=b1+3;while(-pb=b1)strcpy(b2,pb);printf(“%dn”,strlen(b2);A)8 B)3 C)1 D)7,D,字符数组和字符指针的比较,字符数组,组成 由若干元素组成,每个元素中放一个字符。赋初值方式 static char str=I love China!;赋值方式 char str14;str=I love China!占用内存 字符数组一个元素占一字节内存,且在编 译时分配。char str10;scanf(%s,str);,字符指针,组成 2或4字节,存放字符串的 首地址。赋初值方式 char*a=I love China!;赋值方式 char*a;a=I love China!;占用内存 指针变量中只可以放一个地址值(近指针=2字节,远指针=4 字节)。且编译时未指定。char*a;scanf(“%s”,a);a尚未指向任何变量,#include main()char strg40,*there,one,two;int*pt,list100,index;strcpy(strg,”this is a character string”);one=strg0;two=*str;printf(“第一输出的是%c%cn”,one,two);one=str8;two=*(str+8);printf(“第二输出的是%c%c”,one,two);there=strg+10;printf(“第三输出的是%cn”,strg10);printf(“第四输出的是%cn”,*there);for(inde=0;index10;index+)listindex=index+100;pt=list+27;printf(“第五输出的是%d%d”,list27,*pt);,T T,a a,c,c,127 127,补充练习:,1、若有如下图所示五个连续的int类型的存储单元并赋值如下图,a0的地址小于 a4的地址。p和s是基类型为int的指针变量。请对以下问题进行填空。a0 a1 a2 a3 a4 22 33 44 55 66(1)若p已指向存储单元a1。通过指针p,给s赋值,使s指向最后一个存储单元a4的语句是。(2)若指针s指向存储单元a2,p指向存储单元a0,表达式s-p的值是 _。,*s=*(p+3),2,2、下面函数用来求出两个整数之和,并通过形参传回两数相加之和值,请填空。int add(int x,int y,_z)_=x+y;,int*,*z,3、以下程序的功能是:将无符号八进制数字构成的字符串转换为十进制整数。例如,输入的字符串为:556,则输出十进制整数366。请填空。main()char*p,s6;int n;p=s;gets(p);n=*p-0;while(_!=0)n=n*8+*p-0;printf(%d n,n);,*(+p),4、函数 void fun(float*sn,int n)的功能是:根据以下公式计算S,计算结果 通过形参指针sn传回;n通过形参传入,n的值大于等于0。请填空。1 1 1 1 S=1-+-+3 5 7 2n+1 void fun(float*sn,int n)float s=0.0,w,f=-1.0;int i=0;for(i=0;i=n;i+)f=_*f;w=f/(2*i+1);s+=w;_=s;,-1,*sn,5、以下程序的输出结果是_,main()int x=0;sub(,7,程序运行演示:,*a=0,n=8,k=1sub(int*a,int n,int k)if(k=n)sub(a,n/2,2*k);*a+=k;,*a=0,n=4,k=2sub(int*a,int n,int k)if(k=n)sub(a,n/2,2*k);*a+=k;,*a=0,n=2,k=4sub(int*a,int n,int k)if(k=n)sub(a,n/2,2*k);*a+=k;,*a=*a+k*a=0+4=4,*a=*a+k*a=4+2=6,*a=*a+k*a=6+1=7,6、以下程序中函数sort的功能是对a所指数组中的数据进行由大到小的排序,程序运行后的输出结果是(),void sort(int a,int n)int i,j,t;for(i=0;in-1;i+)for(j=i+1;jn;j+)if(aiaj)t=ai;ai=aj;aj=t;main()int aa10=1,2,3,4,5,6,7,8,9,10,i;sort(,1,2,3,8,7,6,5,4,9,10,7、若有说明,int n=2,8p=则以下非法的赋值语句是:,A)p=q;B)*p=*q;C)n=*q;D)p=n;,D,8、有以下程序,程序运行后的输出结果是(),void fun(char*c,int d)*c=*c+1;d=d+1;printf(%c,%c,*c,d);main()char a=A,b=a;fun(,b,B A,b,9、以下程序中函数reverse的功能是将a所指数组中的内容进行逆置。程序运行后的输出结果是(),void reverse(int a,int n)int i,t;for(i=0;in/2;i+)t=ai;ai=an-1-i;an-1-i=t;main()int b10=1,2,3,4,5,6,7,8,9,10;int i,s=0;reverse(b,8);for(i=6;i10;i+)s+=bi;printf(%dn,s);,22,10、若有以下定义和语句:,int s,(*ps)5;ps=s;则对s数组元素的正确引用形式是()A)ps+1B)*(ps+1)C)ps02D)*(ps+1)+3,C,

    注意事项

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

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




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开