c语言善于利用指针.ppt
《c语言善于利用指针.ppt》由会员分享,可在线阅读,更多相关《c语言善于利用指针.ppt(213页珍藏版)》请在咨信网上搜索。
1、第8章善于利用指针8.1指针是什么8.2指针变量8.3通过指针引用数组8.4通过指针引用字符串8.5 指向函数的指针8.6返回指针值的函数8.7指针数组和多重指针8.8动态内存分配与指向它的指针变量8.9有关指针的小结18.1指針是什么如果在程序中定义了一个变量,在对程序进行编译时,系统就会给该变量分配内存单元编译系统根据程序中定义的变量类型,分配一定长度的空间例如,VC+为整型变量分配4个字节,对单精度浮点型变量分配个字节,对字符型变量分配个字节28.1指针是什么内存区的每一个字节有一个编号,这就是“地址”,它相当于旅馆中的房间号。在地址所标识的内存单元中存放数据,这相当于旅馆房间中居住的旅
2、客一样。由于通过地址能找到所需的变量单元,我们可以说,地址指向该变量单元。将地址形象化地称为“指针”3务必弄清楚存储单元的地址和存储单元的内容这两个概念的区别例如:4int i=3,j=6,k;printf(“%d”,i);通过变量名通过变量名i找到找到i的地址的地址2000,从而,从而从从存存储单元储单元读读取取35int i=3,j=6,k;k=i+j;从这里取从这里取3将将9送到这里送到这里从这里取从这里取6直接存取直接存取6int i=3,j=6,k;定义特殊变量定义特殊变量i_pointer将将i的地址的地址存到这里存到这里间接存取间接存取i_pointer=&i;*i_pointe
3、r=50;50507i200032000i_pointer*i_pointer20003直接存取直接存取间接存取间接存取8为了表示将数值送到变量中,可以有两种表达方法:(1)将3直接送到变量i所标识的单元中,例如:i=3;(2)将3送到变量i_pointer所指向的单元(即变量i的存储单元),例如:*i_pointer=3;其中*i_pointer表示i_pointer指向的对象9指向就是通过地址来体现的假设i_pointer中的值是变量的地址(2000),这样就在i_pointer和变量之间建立起一种联系,即通过i_pointer能知道i的地址,从而找到变量i的内存单元10由于通过地址能找到
4、所需的变量单元,因此说,地址指向该变量单元将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元11一个变量的地址称为该变量的“指针”例如,地址2000是变量的指针如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量”i_pointer就是一个指针变量。指针变量就是地址变量,用来存放地址的变量,指針变量的值是地址(即指针)12“指针”和“指针变量”是不同的概念可以说变量i的指针是2000,而不能说i的指针变量是2000指针是一个地址,而指针变量是存放地址的变量138.2指针变量8.2.1使用指针变量的例子8.2.2怎样定义指针变量8.2.3怎样引用指针变量8.2.
5、4指针变量作为函数参数148.2.1使用指针变量的例子例8.1通过指针变量访问整型变量。解题思路:先定义2个整型变量,再定义2个指针变量,分别指向这两个整型变量,通过访问指针变量,可以找到它们所指向的变量,从而得到这些变量的值。15#includeintmain()inta=100,b=10;int*pointer_1,*pointer_2;pointer_1=&a;pointer_2=&b;printf(“a=%d,b=%dn”,a,b);printf(“*pointer_1=%d,*pointer_2=%dn”,*pointer_1,*pointer_2);return0;定义两个指针变量
6、定义两个指针变量使使pointer_1指向指向a使使pointer_2指向指向b直接直接输出变量输出变量a和和b的值的值间接间接输出变量输出变量a和和b的值的值16#includeintmain()inta=100,b=10;int*pointer_1,*pointer_2;pointer_1=&a;pointer_2=&b;printf(“a=%d,b=%dn”,a,b);printf(“*pointer_1=%d,*pointer_2=%dn”,*pointer_1,*pointer_2);return0;此处此处*与与类型名类型名在一起。在一起。此时共同定义指针变量此时共同定义指针变量此
7、处此处*与指针变量一起使用。此与指针变量一起使用。此时时代表指针变量所指向的变量代表指针变量所指向的变量178.2.2怎样定义指针变量定义指针变量的一般形式为:类型 *指针变量名;如:int*pointer_1,*pointer_2;int是为指针变量指定的“基类型”基类型指定指针变量可指向的变量类型如pointer_1可以指向整型变量,但不能指向浮点型变量188.2.2怎样定义指针变量下面都是合法的定义和初始化:float*pointer_3;char*pointer_4;inta,b;int*pointer_1=&a,*pointer_2=&b;*pointer_1&a;错误错误point
8、er_3&a;错误错误pointer_1&a;正确正确pointer_32000;错误错误198.2.3怎样引用指针变量在引用指针变量时,可能有三种情况:给指针变量赋值。如:p=&a;引用指针变量指向的变量。如有p=&a;*p=1;则执行printf(“%d”,*p);将输出1引用指针变量的值。如:printf(“%o”,p);使使p指向指向a*p相当于相当于a以以八八进制输进制输出出a的地址的地址208.2.3怎样引用指针变量要熟练掌握两个有关的运算符:(1)取地址运算符。&a是变量a的地址(2)*指针运算符(“间接访问”运算符)如果:p指向变量a,则*p就代表a。k=*p;(把a的值赋给k
9、)*p=1;(把1赋给a)21例8.2 输入a和b两个整数,按先大后小的顺序输出a和b。解题思路:用指针方法来处理这个问题。不交换整型变量的值,而是交换两个指针变量的值。22#includeintmain()int*p1,*p2,*p,a,b;printf(“integernumbers:);scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(ab)p=p1;p1=p2;p2=p;printf(“a=%d,b=%dn”,a,b);printf(“%d,%dn”,*p1,*p2);return0;abp1p2p59&a&b成立成立23#includeintmain()int*
10、p1,*p2,*p,a,b;printf(“integernumbers:);scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(ab)p=p1;p1=p2;p2=p;printf(“a=%d,b=%dn”,a,b);printf(“%d,%dn”,*p1,*p2);return0;abp1p2p59&a&b&b&a24#includeintmain()int*p1,*p2,*p,a,b;printf(“integernumbers:);scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(ab)p=p1;p1=p2;p2=p;printf(“a=%d,b
11、=%dn”,a,b);printf(“%d,%dn”,*p1,*p2);return0;abp1p2p59&a&b&b&a25#includeintmain()int*p1,*p2,*p,a,b;printf(“integernumbers:);scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(ab)p=p1;p1=p2;p2=p;printf(“a=%d,b=%dn”,a,b);printf(“%d,%dn”,*p1,*p2);return0;abp1p2p59&a&b&b&a可否改为可否改为p1=&b;p2=&a;?26注意:a和b的值并未交换,它们仍保持原值但p1和
12、p2的值改变了。p1的值原为&a,后来变成&b,p2原值为&b,后来变成&a这样在输出*p1和*p2时,实际上是输出变量b和a的值,所以先输出9,然后输出5278.2.4指针变量作为函数参数例8.3题目要求同例8.2,即对输入的两个整数按大小顺序输出。现用函数处理,而且用指针类型的数据作函数参数。解题思路:定义一个函数swap,将指向两个整型变量的指针变量作为实参传递给swap函数的形参指针变量,在函数中通过指针实现交换两个变量的值。28#includeintmain()voidswap(int*p1,int*p2);inta,b;int*pointer_1,*pointer_2;printf
13、(pleaseenteraandb:);scanf(“%d,%d”,&a,&b);pointer_1=&a;pointer_2=&b;if(ab)swap(pointer_1,pointer_2);printf(“max=%d,min=%dn”,a,b);return0;abpointer_159&a&bpointer_229voidswap(int*p1,int*p2)inttemp;temp=*p1;*p1=*p2;*p2=temp;abpointer_159&a&bpointer_2p1&ap2&b9530voidswap(int*p1,int*p2)inttemp;temp=*p1;*
14、p1=*p2;*p2=temp;void swap(int*p1,int*p2)int*temp;*temp=*p1;*p1=*p2;*p2=*temp;错!错!无确定的指向无确定的指向31#includeintmain()if(ab)swap(a,b);printf(“max=%d,min=%dn”,a,b);return0;voidswap(intx,inty)inttemp;temp=x;x=y;y=temp;错!错!无法交换无法交换a,bab59xy599532如果想通过函数调用得到个要改变的值:在主调函数中设个变量,用个指针变量指向它们 设计一个函数,有n个指针形参。在这个函数中改变
15、这个形参的值 在主调函数中调用这个函数,在调用时将这n个指针变量作实参,将它们的地址传给该函数的形参 在执行该函数的过程中,通过形参指针变量,改变它们所指向的个变量的值主调函数中就可以使用这些改变了值的变量33例8.4对输入的两个整数按大小顺序输出。解题思路:尝试调用swap函数来实现题目要求。在函数中改变形参(指针变量)的值,希望能由此改变实参(指针变量)的值34#includeintmain()voidswap(int*p1,int*p2);inta,b;int*pointer_1,*pointer_2;scanf(%d,%d,&a,&b);pointer_1=&a;pointer_2=&
16、b;if(ab)swap(pointer_1,pointer_2);printf(max=%d,min=%dn,a,b);return0;void swap(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;错!错!只交换形参指向只交换形参指向35注意:函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作参数,可以得到多个变化了的值。如果不用指针变量是难以做到这一点的。要善于利用指针法。36例8.5输入3个整数a,b,c,要求按由大到小的顺序将它们输出。用函数实现。解题思路:采用例8.3的方法在函数中改变这3个变量的值。用swap函数交换两个变量的值,
17、用exchange函数改变这3个变量的值。37#includeintmain()voidexchange(int*q1,int*q2,int*q3);inta,b,c,*p1,*p2,*p3;scanf(%d,%d,%d,&a,&b,&c);p1=&a;p2=&b;p3=&c;exchange(p1,p2,p3);printf(“%d,%d,%dn,a,b,c);return0;调用结束后不会调用结束后不会改变指针的指向改变指针的指向38voidexchange(int*q1,int*q2,int*q3)voidswap(int*pt1,int*pt2);if(*q1*q2)swap(q1,q
18、2);if(*q1*q3)swap(q1,q3);if(*q2*q3)swap(q2,q3);voidswap(int*pt1,int*pt2)inttemp;temp=*pt1;*pt1=*pt2;*pt2=temp;交换指针指交换指针指向的变量值向的变量值398.3通过指针引用数组8.3.1数组元素的指针8.3.2在引用数组元素时指针的运算8.3.3通过指针引用数组元素8.3.4用数组名作函数参数8.3.5通过指针引用多维数组408.3.1数组元素的指针一个变量有地址,一个数组包含若干元素,每个数组元素都有相应的地址指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中)所谓数组元素
19、的指针就是数组元素的地址41可以用一个指针变量指向一个数组元素inta10=1,3,5,7,9,11,13,15,17,19;int*p;p=&a0;等价于等价于p=a;等价于等价于int*p=a;或或int*p=&a0;注意注意:数组名数组名a不代表整个数组,不代表整个数组,只代表数组首元素的地址。只代表数组首元素的地址。“p=a;”的作用是的作用是“把把a数组的首数组的首元素的地址赋给指针变量元素的地址赋给指针变量p”,而不,而不是是“把数组把数组a各元素的值赋给各元素的值赋给p”。428.3.2在引用数组元素时指针的运算在指针指向数组元素时,允许以下运算:加一个整数(用+或+=),如p+
20、1减一个整数(用-或-=),如p-1自加运算,如p+,+p自减运算,如p-,-p两个指针相减,如p1-p2(只有p1和p2都指向同一数组中的元素时才有意义)43(1)如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素。floata10,*p=a;假设a0的地址为2000,则p的值为2000p+1的值为2004P-1的值为1996越界越界44(2)如果的初值为&a0,则p+i和a+i就是数组元素ai的地址,或者说,它们指向a数组序号为i的元素a0a1a2a3a4a5a6a7a8a9pp+1,a+1 p+i,a+i p+9,a+9 45(3)
21、*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即ai。a0a1a2a3a4a5a6a7a8a9pp+1,a+1 p+i,a+i p+9,a+9*(p+i)46(4)如果指针p1和p2都指向同一数组p2-p1的值是4 不能p1+p2a0a1a2a3a4a5a6a7a8a9p1p2 478.3.3通过指针引用数组元素引用一个数组元素,可用下面两种方法:()下标法,如ai形式()指针法,如*(a+i)或*(p+i)其中a是数组名,p是指向数组元素的指针变量,其初值p=a488.3.3通过指针引用数组元素例8.6有一个整型数组a,有10个元素,要求输出数组中的全部元素。解题思路:引用数组
22、中各元素的值有3种方法:(1)下标法;(2)通过数组名计算数组元素地址,找出元素的值;(3)用指针变量指向数组元素分别写出程序,以资比较分析。49(1)下标法。#includeintmain()inta10;inti;printf(“enter10integernumbers:n);for(i=0;i10;i+)scanf(%d,&ai);for(i=0;i10;i+)printf(“%d”,ai);printf(%n);return0;50(2)通过数组名计算数组元素地址,找出元素的值#includeintmain()inta10;inti;printf(“enter10integernum
23、bers:n);for(i=0;i10;i+)scanf(%d,&ai);for(i=0;i10;i+)printf(“%d”,*(a+i);printf(n);return0;scanf(%d,a+i);51(3)用指针变量指向数组元素#includeintmain()inta10;int*p,i;printf(“enter10integernumbers:n);for(i=0;i10;i+)scanf(%d,&ai);for(p=a;p(a+10);p+)printf(“%d”,*p);printf(n);return0;for(p=a;p(a+10);p+)scanf(%d,p);for
24、(p=a;p(a+10);a+)printf(“%d”,*a);错!错!523种方法的比较:第(1)和第(2)种方法执行效率相同编译系统是将ai转换为*(a+i)处理的,即先计算元素地址。因此用第(1)和第(2)种方法找数组元素费时较多。533种方法的比较:第(3)种方法比第(1)、第(2)种方法快用指针变量直接指向元素,不必每次都重新计算地址,像p+这样的自加操作是比较快的这种有规律地改变地址值(p+)能大大提高执行效率543种方法的比较:用下标法比较直观,能直接知道是第几个元素。用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。55例8.7通过指针变量输出整型数组a的
25、10个元素。解题思路:用指针变量p指向数组元素,通过改变指针变量的值,使p先后指向a0到a9各元素。56#includeintmain()int*p,i,a10;p=a;printf(“enter10integernumbers:n);for(i=0;i10;i+)scanf(“%d”,p+);for(i=0;i10;i+,p+)printf(“%d”,*p);printf(n);return0;退出循环时退出循环时p指向指向a9后面的存储单元后面的存储单元因此执行此循因此执行此循环出问题环出问题重新执行重新执行p=a;578.3.4用数组名作函数参数用数组名作函数参数时,因为实参数组名代表该
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 善于 利用 指针
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【精***】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【精***】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。