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

    【教学课件】第7章间接访问-指针.ppt

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

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

    【教学课件】第7章间接访问-指针.ppt

    程序设计 cs.sjtu 2011.9程序设计-1第第7章章 间接访问间接访问指针指针v指针的概念指针的概念v指针运算与数组指针运算与数组v动态内存分配动态内存分配v字符串再讨论字符串再讨论v指针作为函数参数和返回值指针作为函数参数和返回值v指针数组与多级指针指针数组与多级指针v指向多维数组的指针指向多维数组的指针v指向函数的指针指向函数的指针程序设计 cs.sjtu 2011.9程序设计-2指针介绍 本章将介绍本章将介绍C+C+语言的一个重要的特性:指针,为了语言的一个重要的特性:指针,为了成为一个优秀的成为一个优秀的C+C+语言程序员,你必须掌握指针并语言程序员,你必须掌握指针并熟练地使用它们。熟练地使用它们。指针指针是内存的是内存的地址地址并可作为数据并可作为数据是一个灵活和危险的机制是一个灵活和危险的机制允许允许共享共享处理数据处理数据允许内存允许内存动态动态分配(只要需要,而非预先定义)分配(只要需要,而非预先定义)程序设计 cs.sjtu 2011.9程序设计-3指针的概念指针的概念v指针就是把地址作为数据处理指针就是把地址作为数据处理v指针变量:存储地址的变量指针变量:存储地址的变量v变量的指针:当一个变量存储另一个变量的变量的指针:当一个变量存储另一个变量的地址时,那我们说它就是那个变量的指针地址时,那我们说它就是那个变量的指针v使用指针的目的:提供间接访问使用指针的目的:提供间接访问程序设计 cs.sjtu 2011.9程序设计-4指针的概念指针的概念 续续续续v如在某一程序中定义了如在某一程序中定义了 int x=2;v如系统给如系统给x分配的空间是分配的空间是1000号单号单元,则指向元,则指向x的指针是另一个变量的指针是另一个变量p,p中存放的数据为中存放的数据为1000v1000号单元的内容有两种访问方号单元的内容有两种访问方式:式:访问变量访问变量x(直接访问)(直接访问)访问变量访问变量p指向的单元的内容(间接指向的单元的内容(间接访问)访问)1000 21000 xp程序设计 cs.sjtu 2011.9程序设计-5定义指针变量定义指针变量v定义指针变量要告诉编译器该变量中存放的是一定义指针变量要告诉编译器该变量中存放的是一个地址。个地址。v指针变量的主要用途是提供间接访问,因此也需指针变量的主要用途是提供间接访问,因此也需要知道指针指向的单元的数据类型要知道指针指向的单元的数据类型v指针变量的定义指针变量的定义 类型标识符类型标识符 *指针变量;指针变量;如:如:int int *intp;intp;double double*doublep;doublep;int*p,x,*q;int*p,x,*q;程序设计 cs.sjtu 2011.9程序设计-6指针变量的操作指针变量的操作v如何让指针指向某一变量?因为我们不知道系统分如何让指针指向某一变量?因为我们不知道系统分配给变量的真正地址是什么。配给变量的真正地址是什么。用地址运算符用地址运算符 “&”解决。如表达式解决。如表达式 “&x”返回的是返回的是变量变量 x 的地址。如:的地址。如:intp=&x;&运算符后面不能跟常量或表达式。如运算符后面不能跟常量或表达式。如&2 是没有意义的,是没有意义的,&(m*n+p)。也是没有意义的。也是没有意义的v如何通过指针变量处理和改变它所指向的单元的值如何通过指针变量处理和改变它所指向的单元的值?用引用运算符用引用运算符 “*”解决。如解决。如 *intp 表示的是表示的是 intp 指指向的这个单元的内容。如:向的这个单元的内容。如:*intp=5 intp=5 等价于等价于 x=5x=5在对在对 intp 使用引用运算之前,必须先对使用引用运算之前,必须先对 intp 赋值赋值程序设计 cs.sjtu 2011.9程序设计-7指针实例指针实例如有:如有:int X,*intp,Y;X=3;Y=4;intp=&X;1000intp10044Y10003X如执行:如执行:*intp=Y+4;1000intp10044Y10008X注意:不能用注意:不能用 intp=100;intp=100;因为我们永远不知道变量存储的因为我们永远不知道变量存储的 真实地址,而且真实地址,而且程序每次运行变量地址可能都不同。程序每次运行变量地址可能都不同。程序设计 cs.sjtu 2011.9程序设计-8指针使用指针使用v指针变量可以指向不同的变量。如上例中指针变量可以指向不同的变量。如上例中intp指向指向x,我们可以通过对,我们可以通过对intp的重新赋值改变指针的指向。的重新赋值改变指针的指向。如果想让如果想让intp指向指向y,只要执行,只要执行intp=&y就可以了。就可以了。这时,这时,intp与与x无任何关系。无任何关系。v同类的指针同类的指针变量之间可相互赋值,表示二个指针指变量之间可相互赋值,表示二个指针指向同一内存空间。向同一内存空间。v空指针空指针指针没有指向任何空间指针没有指向任何空间空指针用常量空指针用常量NULLNULL表示,表示,NULLNULL的值一般赋为的值一般赋为0 0不能引用空指针指向的值不能引用空指针指向的值程序设计 cs.sjtu 2011.9程序设计-9指针变量的使用指针变量的使用设有定义设有定义 int x,y;int*p1,*p2;1000 x1004y1008p11012p2执行语句:执行语句:x=23;y=234;1000 23x1004 234y1008p11012p2执行语句:执行语句:p1=&x;p2=&y;1000 23x1004 234y1008 1000p11012 1004p2执行语句:执行语句:*p1=34;p2=p1;1000 34x1004 234y1008 1000p11012 1000p2程序设计 cs.sjtu 2011.9程序设计-10指针实例指针实例有以下结构有以下结构 Ap1aBp2b比较执行比较执行 p1=p2和和*p1=*p2后的不同结果。后的不同结果。解:解:Ap1aBp2bBp1aBp2b程序设计 cs.sjtu 2011.9程序设计-11指针的初始化指针的初始化v指针在使用前必须初始化。指针在使用前必须初始化。v和别的变量一样,定义指针不初始化是一个比和别的变量一样,定义指针不初始化是一个比较普通的错误。较普通的错误。v没有初始化的指针可能指向任意地址,对这些没有初始化的指针可能指向任意地址,对这些指针作操作可能会导致程序错误。指针作操作可能会导致程序错误。vNULLNULL是一个特殊指针值,称为空指针。它的值是一个特殊指针值,称为空指针。它的值为为0 0。它可被用来初始化一个指针,表示不指。它可被用来初始化一个指针,表示不指向任何地址。向任何地址。v思考:思考:int*p;*p=5;int*p;*p=5;有什么问题?有什么问题?程序设计 cs.sjtu 2011.9程序设计-12第第7章章 间接访问间接访问指针指针v指针的概念指针的概念v指针运算与数组指针运算与数组v动态内存分配动态内存分配v字符串再讨论字符串再讨论v指针作为函数参数和返回值指针作为函数参数和返回值v指针数组与多级指针指针数组与多级指针v指向多维数组的指针指向多维数组的指针v指向函数的指针指向函数的指针程序设计 cs.sjtu 2011.9程序设计-13指针运算和数组指针运算和数组v指向数组元素的指针指向数组元素的指针数组元素是一个独立的变量,因此可以有指针数组元素是一个独立的变量,因此可以有指针指向它。如:指向它。如:p=&a1,p=&ai数组元素的地址是通过数组首地址计算的。如数组元素的地址是通过数组首地址计算的。如数组的首地址是数组的首地址是 1000,则第,则第i 个元素的地址是个元素的地址是1000+i*每个数组元素所占的空间长度每个数组元素所占的空间长度程序设计 cs.sjtu 2011.9程序设计-14指针与数组指针与数组v在在C+C+中,指针和数组关系密切,几乎可以互中,指针和数组关系密切,几乎可以互换使用换使用v数组名可以看成是常量指针,对一维数组来说,数组名可以看成是常量指针,对一维数组来说,数组名是数组的起始地址,也就是第数组名是数组的起始地址,也就是第0 0个元素个元素的地址的地址v如执行了如执行了p=arrayp=array,则,则p p与与arrayarray是等价的,对是等价的,对该指针可以进行任何有关数组下标的操作该指针可以进行任何有关数组下标的操作程序设计 cs.sjtu 2011.9程序设计-15例如:有定义例如:有定义 int a10,*pint a10,*p 并且执行了并且执行了 p=ap=a,那么可用下列语句访问数组那么可用下列语句访问数组a a的元素的元素for (i=0;i10;+i)for (i=0;i10;+i)cout pi;cout pi;程序设计 cs.sjtu 2011.9程序设计-16指针运算指针运算v指针指针+1表示数组中指针指向元素的下一元素表示数组中指针指向元素的下一元素地址;地址;v指针指针-1表示数组中指针指向元素的上一元素地表示数组中指针指向元素的上一元素地址;址;v合法的指针操作:合法的指针操作:p+k,p-k,p1-p2指针保存的是一个地址,地址是一个整型数,因此可指针保存的是一个地址,地址是一个整型数,因此可以进行各种算术运算,但仅有加减运算是有意义的。以进行各种算术运算,但仅有加减运算是有意义的。指针运算与数组有密切的关系指针运算与数组有密切的关系程序设计 cs.sjtu 2011.9程序设计-17数组元素的指针表示数组元素的指针表示v当把数组名,如当把数组名,如 intarray,赋给了一个同类指针,赋给了一个同类指针intp 后,后,intarray 的元素可以通过的元素可以通过intp访问。第访问。第i个元素的地址可表示为个元素的地址可表示为 intp+i,第,第i个元素的值个元素的值可表示为可表示为*(intp+i)。v通过指针访问数组时,下标有效范围由程序员自通过指针访问数组时,下标有效范围由程序员自己检查。己检查。v如输出数组如输出数组 a 的十个元素的十个元素程序设计 cs.sjtu 2011.9程序设计-18方法方法3:for (p=a;pa+10;+p)cout *p;方法方法2:for (i=0;i10;+i)cout *(a+i);方法方法1:for (i=0;i10;+i)cout ai;方法方法4:for (p=a,i=0;i10;+i)cout *(p+i);方法方法5:for (p=a,i=0;i10;+i)cout pi;下列程序段下列程序段 有无问题?有无问题?for (i=0;i10;+i)cout *a;+a;程序设计 cs.sjtu 2011.9程序设计-19指针和数组的区别指针和数组的区别v虽然通过指针可以访问数组,但两者本质是不同的。虽然通过指针可以访问数组,但两者本质是不同的。v在定义数组时为数组的各个元素分配了全部的存储区,在定义数组时为数组的各个元素分配了全部的存储区,而在定义指针时,仅仅分配四个字节的存储区存放指而在定义指针时,仅仅分配四个字节的存储区存放指针地址。只有把一个数组名付给了对应的指针后,指针地址。只有把一个数组名付给了对应的指针后,指针才能当作数组使用针才能当作数组使用v如有:如有:int array5,*intp;int array5,*intp;arrayintp当执行了当执行了 intp=arrayintp=array后后程序设计 cs.sjtu 2011.9程序设计-20第第7章章 间接访问间接访问指针指针v指针的概念指针的概念v指针运算与数组指针运算与数组v动态内存分配动态内存分配v字符串再讨论字符串再讨论v指针作为函数参数和返回值指针作为函数参数和返回值v指针数组与多级指针指针数组与多级指针v指向多维数组的指针指向多维数组的指针v指向函数的指针指向函数的指针程序设计 cs.sjtu 2011.9程序设计-21动态分配动态分配v在在C+C+语言中,每个程序需要用到几个变量,语言中,每个程序需要用到几个变量,在写程序前就应该知道。每个数组有几个元素在写程序前就应该知道。每个数组有几个元素也必须在写程序时就决定。也必须在写程序时就决定。v有时我们并不知道我们需要多大的数组元素直有时我们并不知道我们需要多大的数组元素直到程序开始运行。因此希望能在程序中根据某到程序开始运行。因此希望能在程序中根据某一个当前运行值来决定数组的大小。如设计一一个当前运行值来决定数组的大小。如设计一个打印魔阵的程序,我们希望先输入魔阵的阶个打印魔阵的程序,我们希望先输入魔阵的阶数,然后根据阶数定义一个矩阵数,然后根据阶数定义一个矩阵程序设计 cs.sjtu 2011.9程序设计-22动态分配方法动态分配方法v这些问题的解决方案就是内存的动态分这些问题的解决方案就是内存的动态分配。我们定义一个指针,并让它指向一配。我们定义一个指针,并让它指向一个合适的内存。如:个合适的内存。如:int*scores;int*scores;scores=scores=内存的起始地址;内存的起始地址;程序设计 cs.sjtu 2011.9程序设计-23动态内存分配与回收动态内存分配与回收v中由中由new new 和和 deletedelete两个运算符替代两个运算符替代-运算符运算符newnew用于进行内存分配:用于进行内存分配:申请动态变量:申请动态变量:p=new type;p=new type;申请动态数组:申请动态数组:p=new typesize;p=new typesize;申请动态变量并初始化:申请动态变量并初始化:p=new type(p=new type(初值初值);-运算符运算符delete delete 释放释放 newnew分配的内存:分配的内存:释放动态变量:释放动态变量:delete p;delete p;释放动态数组:释放动态数组:delete p;delete p;程序设计 cs.sjtu 2011.9程序设计-24动态内存分配与回收动态内存分配与回收/为简单变量动态分配内存,并作初始化为简单变量动态分配内存,并作初始化int main()int main()int*p;int*p;p=new int(99);p=new int(99);/动态分配内存,并将动态分配内存,并将9999作为初始化值赋给它作为初始化值赋给它 cout*p;cout*p;delete p;delete p;return 0;return 0;程序设计 cs.sjtu 2011.9程序设计-25动态内存分配与回收动态内存分配与回收/动态字符串的使用动态字符串的使用int main()int*p;char*q;p=new int(5);q=new char10;strcpy(q,abcde);cout *p endl;cout q endl;delete p;delete q;return 0;输出结果:输出结果:5abcde程序设计 cs.sjtu 2011.9程序设计-26动态分配的检查动态分配的检查vnew操作的结果是申请到的空间的地址操作的结果是申请到的空间的地址v当系统空间用完时,当系统空间用完时,new操作可能失败操作可能失败vnew操作失败时,返回空指针操作失败时,返回空指针程序设计 cs.sjtu 2011.9程序设计-27动态内存分配与回收动态内存分配与回收/动态分配检查动态分配检查int main()int main()int*p;int*p;p=new int;p=new int;if(!p)if(!p)cout allocation failuren;cout allocation failuren;return 1;return 1;*p=20;cout *p;*p=20;cout *p;delete p;return 0;delete p;return 0;程序设计 cs.sjtu 2011.9程序设计-28assert宏宏 vassert()宏在标准头文件()宏在标准头文件cassert中中 vassert()有一个参数,表示断言为真的表有一个参数,表示断言为真的表达式,预处理器产生测试该断言的代码。达式,预处理器产生测试该断言的代码。如果断言不是真,则在发出一个错误消如果断言不是真,则在发出一个错误消息后程序会终止。息后程序会终止。程序设计 cs.sjtu 2011.9程序设计-29#include#include /包含包含assert宏的头文件宏的头文件using namespace std;int main()int*p;p=new int;assert(p!=0);/p等于等于0,则退出程序,则退出程序 *p=20;cout *p;delete p;return 0;程序设计 cs.sjtu 2011.9程序设计-30内存分配的进一步介绍内存分配的进一步介绍v静态分配:对全局变量和静态变量,编静态分配:对全局变量和静态变量,编译器为它们分配空间,这些空间在整个译器为它们分配空间,这些空间在整个程序运行期间都存在程序运行期间都存在v自动分配:函数内的局部变量空间是分自动分配:函数内的局部变量空间是分配在系统的栈工作区。当函数被调用时,配在系统的栈工作区。当函数被调用时,空间被分配;当函数执行结束后,空间空间被分配;当函数执行结束后,空间被释放被释放v动态分配:在程序执行过程中需要新的动态分配:在程序执行过程中需要新的存储空间时,可用动态分配的方法向系存储空间时,可用动态分配的方法向系统申请新的空间,当不再使用时用显式统申请新的空间,当不再使用时用显式的方法还给系统。这部分空间是从被称的方法还给系统。这部分空间是从被称为堆的内存区域分配。为堆的内存区域分配。OSProgramHeap动态分配动态分配Stack自动分配自动分配Globe variables静态分配静态分配程序设计 cs.sjtu 2011.9程序设计-31内存泄漏内存泄漏v动态变量是通过指针间接访问的。如果该指针被修改,这动态变量是通过指针间接访问的。如果该指针被修改,这个区域就被丢失了。堆管理器认为你在继续使用它们,但个区域就被丢失了。堆管理器认为你在继续使用它们,但你不知道它们在哪里,这称为内存泄露。你不知道它们在哪里,这称为内存泄露。v为了避免出现孤立的区域,应该明白地告诉堆管理器这些为了避免出现孤立的区域,应该明白地告诉堆管理器这些区域不再使用。可以采用区域不再使用。可以采用deletedelete操作,它释放由操作,它释放由newnew申请申请的内存。的内存。v当释放了内存区域,堆管理器重新收回这些区域,而指针当释放了内存区域,堆管理器重新收回这些区域,而指针仍然指向堆区域,但不能再使用指针指向的这些区域。仍然指向堆区域,但不能再使用指针指向的这些区域。v要确保在程序中同一个区域释放一次。要确保在程序中同一个区域释放一次。v释放内存对一些程序不重要,但对有些程序很重要。如果释放内存对一些程序不重要,但对有些程序很重要。如果你的程序要运行很长时间,而且存在内存泄漏,这样程序你的程序要运行很长时间,而且存在内存泄漏,这样程序会耗尽所有内存,直至崩溃。会耗尽所有内存,直至崩溃。程序设计 cs.sjtu 2011.9程序设计-32动态空间分配示例动态空间分配示例v输入一批数据,计算它们的和。数据个数在设输入一批数据,计算它们的和。数据个数在设计程序时尚无法确定。计程序时尚无法确定。v存储一批数据应该用数组,但存储一批数据应该用数组,但C+语言的数组语言的数组大小必须是固定的。该问题有两个解决方案:大小必须是固定的。该问题有两个解决方案:开设一个足够大的数组,每次运行时只使用一部开设一个足够大的数组,每次运行时只使用一部分。缺点:浪费空间分。缺点:浪费空间用动态内存分配根据输入的数据量申请一个动态用动态内存分配根据输入的数据量申请一个动态数组数组程序设计 cs.sjtu 2011.9程序设计-33#include using namespace std;int main()int*p,i,n,sum=0;cout An array will be created dynamically.nn;cout n;if(!(p=new int n)exit(1);for(i=0;i pi;for(i=0;in;+i)sum+=pi;delete p;cout Number of elements:n endl;cout Sum of the elements:sum endl;return 0;可改为:可改为:p=new int n;assert(p!=NULL);程序设计 cs.sjtu 2011.9程序设计-34第第7章章 间接访问间接访问指针指针v指针的概念指针的概念v指针运算与数组指针运算与数组v动态内存分配动态内存分配v字符串再讨论字符串再讨论v指针作为函数参数和返回值指针作为函数参数和返回值v指针数组与多级指针指针数组与多级指针v指向多维数组的指针指向多维数组的指针v指向函数的指针指向函数的指针程序设计 cs.sjtu 2011.9程序设计-35字符串再讨论字符串再讨论v字符串的另一种表示是定义一个指向字符的字符串的另一种表示是定义一个指向字符的指针。然后直接将一个字符串常量或字符串指针。然后直接将一个字符串常量或字符串变量赋给它变量赋给它 v如如 char*String,ss =“abcdef”;String=“abcde”;String =ss;程序设计 cs.sjtu 2011.9程序设计-36 String“abcde”ProgramOS数据段数据段或代码区或代码区栈栈堆堆String=“abcde”;的执行结果的执行结果字符串常量存储在一字符串常量存储在一个称为数据段的内存区个称为数据段的内存区域里域里 将存储字符串将存储字符串”abcdeabcde”的内存的首的内存的首地址赋给指针变量地址赋给指针变量StringString。程序设计 cs.sjtu 2011.9程序设计-37 String “abcdef0”ProgramOS数据段数据段栈栈堆堆String =ss的执行过程的执行过程将字符数组将字符数组ss的起的起始地址存入始地址存入String程序设计 cs.sjtu 2011.9程序设计-38String=new char5;strcpy(String,“aaa”)String ProgramOS数据段数据段栈栈堆堆“aaa0”动态变量存储在堆工动态变量存储在堆工作区作区 将存储字符串将存储字符串”aaaaaa”的内存的首地址赋给指的内存的首地址赋给指针变量针变量StringString。程序设计 cs.sjtu 2011.9程序设计-39用指针表示的字符串的操作用指针表示的字符串的操作v可以直接作为字符串操作函数的参数。但必须可以直接作为字符串操作函数的参数。但必须注意,如果该指针指向的是一个字符串常量时注意,如果该指针指向的是一个字符串常量时,则使用是受限的。如不能作为,则使用是受限的。如不能作为strcpy的第一的第一个参数个参数v由于在由于在C+中,数组名被解释成指向数组首地中,数组名被解释成指向数组首地址的指针。因此,字符串是用一个指针变量表址的指针。因此,字符串是用一个指针变量表示,我们可以把此指针变量解释成数组的首地示,我们可以把此指针变量解释成数组的首地址,通过下标访问字符串中的字符。如址,通过下标访问字符串中的字符。如string3的值是的值是d。程序设计 cs.sjtu 2011.9程序设计-40用指针处理串用指针处理串v目的:编写一个记录串中单词的个数的目的:编写一个记录串中单词的个数的函数。函数。v关键技术:要传递一个字符串给函数关键技术:要传递一个字符串给函数程序设计 cs.sjtu 2011.9程序设计-41字符串作为函数的参数字符串作为函数的参数v字符串作为函数的参数和数组名作为参数传递字符串作为函数的参数和数组名作为参数传递一样,可以有两种方法一样,可以有两种方法作为字符数组传递作为字符数组传递作为指向字符的指针传递作为指向字符的指针传递v两种传递方式的本质是一样的,都是传递了字两种传递方式的本质是一样的,都是传递了字符串的首地址符串的首地址v字符串作为字符数组传递时不需要指定长度。字符串作为字符数组传递时不需要指定长度。因为字符串操作的结束是依据因为字符串操作的结束是依据0程序设计 cs.sjtu 2011.9程序设计-42#include Using namespace std;int word_cnt(const char*s)int cnt=0;while(*s!=0)while(isspace(*s)+s;/跳过空白字符跳过空白字符if(*s!=0)+cnt;/找到一个单词找到一个单词 while(!isspace(*s)&*s!=0)+s;/跳过单词跳过单词 return cnt;统计字符串中单词数的函数程序设计 cs.sjtu 2011.9程序设计-43第第7章章 间接访问间接访问指针指针v指针的概念指针的概念v指针运算与数组指针运算与数组v动态内存分配动态内存分配v字符串再讨论字符串再讨论v指针作为函数参数和返回值指针作为函数参数和返回值v指针数组与多级指针指针数组与多级指针v指向多维数组的指针指向多维数组的指针v指向函数的指针指向函数的指针程序设计 cs.sjtu 2011.9程序设计-44指针作为函数参数和返回值指针作为函数参数和返回值v指针作为函数参数指针作为函数参数v数组名作为函数参数数组名作为函数参数v返回指针的函数返回指针的函数v引用和引用传递引用和引用传递v返回引用的函数返回引用的函数程序设计 cs.sjtu 2011.9程序设计-45指针作为函数参数指针作为函数参数例:编一函数,交换二个参数值。例:编一函数,交换二个参数值。void swap(int a,int b)int c;c=a;a=b;b=c;希望通过调用希望通过调用swap(x,swap(x,y)y)交换变量交换变量x x和和y y的值的值新手可能会编出如下的函数:新手可能会编出如下的函数:因为因为C+C+采用的是值传递机制,函数中采用的是值传递机制,函数中a a、b b值的值的交换不会影响实际参数交换不会影响实际参数x x和和y y的值的值程序设计 cs.sjtu 2011.9程序设计-46void swap(int *a,int*b)int c;c=*a;*a=*b;*b=c;3 4xyab交换交换x x和和y y的值,可以调用的值,可以调用swap(&x,&y)swap(&x,&y)用指针作为参数可以在函数中修改主调程序用指针作为参数可以在函数中修改主调程序的变量值,即实现变量传递。必须小心使用!的变量值,即实现变量传递。必须小心使用!正确的方法程序设计 cs.sjtu 2011.9程序设计-47能解一元二次方程的函数能解一元二次方程的函数v目前为止我们了解到的函数只能有一个返目前为止我们了解到的函数只能有一个返回值,由回值,由return 语句返回。语句返回。v一个一元二次方程有二个解,如何让此函一个一元二次方程有二个解,如何让此函数返回二个解。答案是采用指针作为函数数返回二个解。答案是采用指针作为函数的参数。的参数。v由调用程序准备好存放两个根的变量,将由调用程序准备好存放两个根的变量,将变量地址传给函数。在函数中将两个根的变量地址传给函数。在函数中将两个根的值分别放入这两个地址值分别放入这两个地址程序设计 cs.sjtu 2011.9程序设计-48函数原型函数原型v函数原型可设计为:函数原型可设计为:void SolveQuadratic(double a,double b,double c,double*px1,double*px2)v函数的调用函数的调用 SolveQuadratic(1.3,4.5,2.1,&x1,&x2)SolveQuadratic(a,b,c,&x1,&x2)v函数的参数有两类:输入参数和输出参数。一般,输入参函数的参数有两类:输入参数和输出参数。一般,输入参数用值传递,输出参数用指针传递。在参数表中,输入参数用值传递,输出参数用指针传递。在参数表中,输入参数放在前面,输出参数放在后面。数放在前面,输出参数放在后面。程序设计 cs.sjtu 2011.9程序设计-49原型的改进原型的改进v并不是每个一元二次方程都有两个不同根,并不是每个一元二次方程都有两个不同根,有的可能有两个等根,有的可能没有根。函有的可能有两个等根,有的可能没有根。函数的调用者如何知道数的调用者如何知道x1和和x2中包含的是否是中包含的是否是有效的解?有效的解?v解决方案:让函数返回一个整型数。该整型解决方案:让函数返回一个整型数。该整型数表示解的情况数表示解的情况 程序设计 cs.sjtu 2011.9程序设计-50完整的函数完整的函数int SolveQuadratic(double a,double b,double c,double*px1,double*px2)double disc,sqrtDisc;if(a=0)return 3;/不是一元二次方程不是一元二次方程 disc=b*b-4*a*c;if(disc 0)return 2;/无根无根 if(disc=0)*px1=-b/(2*a);return 1;/等根等根 /两个不等根两个不等根 sqrtDisc=sqrt(disc);*px1=(-b+sqrtDisc)/(2*a);*px2=(-b-sqrtDisc)/(2*a);return 0;程序设计 cs.sjtu 2011.9程序设计-51函数的调用函数的调用int main()double a,b,c,x1,x2;int result;cout a b c;result=SolveQuadratic(a,b,c,&x1,&x2);switch(result)case 0:cout 方程有两个不同的根:方程有两个不同的根:x1=x1 x2=x2;break;case 1:cout 方程有两个等根:方程有两个等根:x1;break;case 2:cout 方程无根方程无根;break;case 3:cout 不是一元二次方程不是一元二次方程;return 0;程序设计 cs.sjtu 2011.9程序设计-52指针作为函数参数和返回值指针作为函数参数和返回值v指针作为函数参数指针作为函数参数v数组名作为函数参数数组名作为函数参数v返回指针的函数返回指针的函数v引用和引用传递引用和引用传递v返回引用的函数返回引用的函数程序设计 cs.sjtu 2011.9程序设计-53数组传递的进一步讨论数组传递的进一步讨论v数组传递的本质是地址传递,因此形参和实参可数组传递的本质是地址传递,因此形参和实参可以使用数组名,也可以使用指针。以使用数组名,也可以使用指针。数组传递是函数原型可写为:数组传递是函数原型可写为:type fun(type a,int size);也可写为也可写为 type fun(type*p,int size);但在函数内部,但在函数内部,a和和p都能当作数组使用都能当作数组使用调用时,对这两种形式都可用数组名或指针作为实参调用时,对这两种形式都可用数组名或指针作为实参v建议:如果传递的是数组,用第一种形式;如果建议:如果传递的是数组,用第一种形式;如果传递的是普通的指针,用第二种形式传递的是普通的指针,用第二种形式程序设计 cs.sjtu 2011.9程序设计-54#include using namespace std;void f(int arr,int k)cout sizeof(arr)sizeof(k)endl;void main()int a10=1,2,3,4,5,6,7,8,9,0;cout sizeof(a)endl;f(a,10);输出:输出:4C+将数组名作为参数传递处理成指针的传递将数组名作为参数传递处理成指针的传递即在即在mainmain中,中,a a是数是数组,占用了组,占用了4040个字个字节。而在函数节。而在函数f f中,中,arrarr是一个指针是一个指针程序设计 cs.sjtu 2011.9程序设计-55数组传递的灵活性数组传递的灵活性void sort(int p ,int n)void sort(int p ,int n).main()main()int a100;int a100;.sort(a,100);/sort(a,100);/排序整个数组排序整个数组 sort(a,50);/sort(a,50);/排序数组的前排序数组的前5050个元素个元素 sort(a+50,50);/sort(a+50,50);/排序数组的后排序数组的后5050个元素个元素 .程序设计 cs.sjtu 2011.9程序设计-56实例实例v设计一函数用分治法在一个整数数组中找出最大设计一函数用分治法在一个整数数组中找出最大和最小值和最小值v具体方法是:具体方法是:如果数组只有一个元素,则最大最小都是他。如果数组只有一个元素,则最大最小都是他。如果数组中只有两个元素,则大的一个就是最大数,如果数组中只有两个元素,则大的一个就是最大数,小的就是最小数。这种情况不需要递归。小的就是最小数。这种情况不需要递归。否则,将数组分成两半,递归找出前一半的最大最小否则,将数组分成两半,递归找出前一半的最大最小值和后一半的最大最小值。取两个最大值中的较大者值和后一半的最大最小值。取两个最大值中的较大者作为最大值,两个最小值中的较小值作为最小值。作为最大值,两个最小值中的较小值作为最小值。程序设计 cs.sjtu 2011.9程序设计-57设计考虑设计考虑v函数的参数是要查找的数组,传递一个数组要两个参函数的参数是要查找的数组,传递一个数组要两个参数:数组名和数组规模数:数组名和数组规模v函数返回的是数组中的最大值和最小值,将它们作为函数返回的是数组中的最大值和最小值,将它们作为指针传递的参数指针传递的参数v查找数组的前一半就是递归调用本函数,传给他的参查找数组的前一半就是递归调用本函数,传给他的参数是当前的数组名,数组的规模是原来的一半数是当前的数组名,数组的规模是原来的一半v查找数组的后一半也是递归调用本函数,传给它的参查找数组的后一半也是递归调用本函数,传给它的参数是数组后一半的起始地址,规模也是原来的一半数是数组后一半的起始地址,规模也是原来的一半程序设计 cs.sjtu 2011.9程序设计-58伪代码伪代码void minmax(int a ,int n,int*min_ptr,int*max_ptr)switch(n)case 1:最大最小都是最大最小都是a0;case 2:大的得放入大的得放入*max_ptr,小的放入,小的放入*min_ptr;Default:对数组对数组a的前一半和后一般分别调用的前一半和后一般分别调用minmax;取两个最大值中的较大者作为最大值;取两个最大值中的较大者作为最大值;取两个最小值中的较小值作为最小值取两个最小值中的较小值作为最小值 程序设计 cs.sjtu 2011.9程序设计-59void minmax(int a,int n,int*min_ptr,int*max_ptr)int min1,max1,min2,max2;switch(n)case 1:*min_ptr=*max_ptr=a0;return;case 2:if(a0 a1)*min_ptr=a0;*max_ptr=a1;else *min_ptr=a1;*max_ptr=a0;return;default:minmax(a,n/2,&min1,&max1);minmax(a+n/2,n-n/2,&min2,&max2);if(min1 min2)*min_ptr=min1;else *min_ptr=min2;if(max1 max2

    注意事项

    本文(【教学课件】第7章间接访问-指针.ppt)为本站会员(wuy****n92)主动上传,得力文库 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知得力文库 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

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




    关于得利文库 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

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

    工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

    © 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

    黑龙江省互联网违法和不良信息举报
    举报电话:0468-3380021 邮箱:hgswwxb@163.com  

    收起
    展开