新编C语言程序设计教程PPT第9章指针_第1页
新编C语言程序设计教程PPT第9章指针_第2页
新编C语言程序设计教程PPT第9章指针_第3页
新编C语言程序设计教程PPT第9章指针_第4页
新编C语言程序设计教程PPT第9章指针_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

新编C语言程序设计教程清华大学出版社,周二强zeq软件学院计算机科学与工程系配套视频:博客:,第9章指针,9.1指针类型9.1.1变量的左值和右值9.1.2指针变量定义和初始化9.2指针操作符和空指针9.2.1指针操作符9.2.2空指针9.3指针与函数9.3.1指针作为函数参数9.3.2指针作为函数返回值,内存地址,变量用于标识存储单元。计算机中的内存以字节为单位编号。编号多为32位的二进制数,从0号开始,即0 x00000000、0 x00000001、0 xffffffff。计算机中只用内存编号(又称内存地址)标识内存单元。如果定义并初始化了一个整型变量如inti=5;,则计算机中的内存状态可能如图9-1所示。,如何理解“整型变量i所标识的存储单元的地址为0 x0012ff00,类型为整型”?,变量的值,存储单元如宿舍,其地址像宿舍号(如408),其存储的内容如住宿者(如王五),相关变量名如宿舍的雅称(如liaozhai)。由以上分析可知,变量既标识存储单元的地址又标识其存储的内容,因此变量比如整型变量i也有两个值。整型变量i的一个值是地址0 x0012ff00,另一个值是内容5。,例9-1分析语句i=5;j=i;中整型变量i的值。,语句i=5;的操作结果是把5放入变量i所标识的存储单元中,也就是把5的补码存入地址为0 x0012ff00的存储单元中,变量i的值此时实为地址0 x0012ff00。语句j=i;的操作结果是把变量j所标识的存储单元的状态设置成与变量i的相同,即把变量j的值也设置成5,变量i的值在此处实为内容5。,变量的左值和右值,i=5;j=i;位于赋值操作符的左边时,变量的值通常表现为地址,由此称变量的地址为变量的左值;位于赋值操作符的右边时,变量的值通常表现为内容,由此称变量的内容为变量的右值。变量的左值都为地址,而右值则可能为整数、浮点数、字符等。指针变量的右值为?,指针变量,指针变量的特殊之处在于其右值也为某存储单元的地址!指针变量的左值和右值均为地址。如果认为指针变量存储的是指针,则这里的指针显然为某存储单元的地址。如何理解“存储单元的地址”?需强调:存储单元的地址只是其首字节地址,仅仅凭地址而不知道类型(存储单元的大小、编码格式等)是无法正确访问存储单元的。,return,9.1.2指针变量定义和初始化,指针变量用“*”号定义,但仅用*号标明变量的类型为指针还不行,必须知道指针变量存储的是何种存储单元的地址。因此,指针变量的一般定义形式为:类型*标识符其中,类型规定了与指针变量存储的地址相关的存储单元是何类型,也就是说,一个指针变量只能存储规定类型的存储单元的地址。类型可以是C语言中的整型、浮点型、数组等。,指针变量的定义,如语句int*pi;定义了一个指针变量pi,pi的内容(右值)应为一个int型存储单元的地址;语句double*pf;定义了一个指针变量pf,pf的右值应为一个double型存储单元的地址。,相关的内存状态,有inti=5,*pi;,且已知变量i的左值为0 x0012ff00。现设指针变量pi的内容为0 x0012ff00,则相关的内存状态可能如图9-2所示。,怎样把变量i的左值(0 x0012ff00)赋给指针变量pi呢?,第一种作法:pi=0 x0012ff00;在语句pi=0 x0012ff00;中,0 x0012ff00仅被看做一个十六进制的整型字面量,指针变量要求用地址为其赋值,两者类型不匹配。第二种作法:pi=i;语句pi=i;中变量i表现为右值5,因此语句pi=i;相当于pi=5;,同样类型不匹配。,强制类型转换,类型不匹配时可以用强制类型转换,正确的作法为:pi=(int*)0 x0012ff00;。该语句在执行时,会先定义一个临时无名指针变量(假设为int*ptemp;),然后强制地把整型字面量0 x0012ff00作为地址赋值给临时无名指针变量(此时整型指针变量ptemp的右值为0 x0012ff00),最后再用临时无名指针变量给指针变量pi赋值(pi=ptemp;),从而使指针变量pi的右值变为0 x0012ff00。,return,9.2.1指针操作符,取地址操作符就可把变量i的地址赋值给指针变量pi,从而使整型指针变量pi指向整型变量i。间接引用操作符*也是单目操作符,操作对象是一个地址型的量(如指针变量),操作结果为该地址所标识的存储单元的内容。,例9-2,设有如图9-2所示的i和pi,则对于整型变量j,分析语句j=*pi;和语句j=*i;。,改正j=*i;的错误有两种方法,第一种,用取地址操作符。,如何分析(int*)5?,int*ptemp;ptemp=(int*)5;强制类型转换操作把整数5强制转换成编号为5的地址。j=*(int*)5;可看作j=*ptemp;。把地址为5的整型存储单元的内容赋值给变量j。此时虽然没有了语法错误,但是地址为0 x00000005的存储单元通常不会分配给应用程序且不允许应用程序读写,因此在执行该语句时会因为读写不允许读写的存储单元而出现非法内存访问错误。,例9-3,如有inti=5,*pi=相同。,例9-4分析下面程序的运行情况。,return,9.2.2空指针,例9-5下面这段程序有问题吗?,变量没有初始化时的值,指针变量pi和变量i都没有初始化。C语言中变量没有初始化时,全局变量的值默认为0,局部变量的值则没有规定,因此指针变量pi的值在此处通常不可预知。语句*pi=5;执行时将向一个位置不可预知的存储单元写入数据,这样的操作可能导致非法内存访问错误或程序逻辑上的错误。,“野指针”,类似本程序中的指针变量pi,右值为不属于程序所拥有存储单元的地址的指针变量称为“野指针”。间接引用野指针的右值将导致非法内存访问错误或其他不可预知的错误。预防由野指针引发的错误的常用办法是把没有明确指向的指针变量设置成“空指针”,而在使用指针变量时检测它是否为空指针。,空指针,所谓空指针是指右值为0的指针变量。地址为0的存储单元不可能分配给应用程序使用,因此约定指向此处的指针变量为空指针。空指针指向明确的存储单元不再是野指针。此外,0是一个特殊的整数,它是唯一不用类型转换就能直接赋值给指针变量的整数。如语句int*pi=0;double*p=0;等均合法。,NULL宏,直接用整数0给指针变量赋值容易让人误解,为此在stdio.h中定义了一个值为0的NULL宏来取代0。如int*pi=NULL;和float*pf=NULL;语句定义了两个指针变量pi和pf,并且它们被初始化成空指针。把没有明确赋值的指针变量设置成空指针(p=NULL),在使用时检测指针是否为空指针(if(p=NULL))可以有效地避免野指针带来的问题。,return,9.3.1指针作为函数参数,函数的参数可以是指针类型,当参数为指针这种特殊的数据类型时,函数的调用过程呈现出了“新”的特点。例9-6分析下面的函数,并编程测试。,指针作为函数参数,swap函数中指针变量px指向了变量i,py指向了变量j。,指针变量的作用,1.指针变量通过地址实现了对存储单元的直接读写,没有了利用变量访问相关存储单元时作用域的限制。2.间接引用操作符*的操作结果正确与否取决于相关存储单元是否为程序所拥有。3.形参为指针时,由于获得了特殊的值实参相关存储单元的地址,所以在函数中可以通过指针变量对存储单元的直接写入来改变实参的值。有时也称形参为指针时函数的参数传递方式为“地址传递”,而形参为其它数据类型时称为“值传递”。,例9-7分析下面的程序,return,9.3.2指针作为函数返回值,例9-8分析下面的程序,例9-8的问题,程序拥有变量i所标识的存储单元仅限test函数执行期间,因为变量i的生存期仅限于此。在main函数中,指针变量pj虽然获得了变量i的地址,但由于此时相关存储单元不再为程序所拥有,故指针变量pj变成了野指针

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论