c语言程序设计教程指针,新编C语言程序设计教程PPT第9章 指针(1)

《新编C语言程序设计教程PPT第9章 指针(1)》由会员分享,可在线阅读,更多相关《新编C语言程序设计教程PPT第9章 指针(1)(31页珍藏版)》请在人人文库网上搜索。

1、新编C语言程序设计教程 清华大学出版社,周二强 软件学院 计算机科学与工程系 配套视频: 博客:,第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 x0000 0000、0 x0000 0001、0 xffff ffff。计算机中只用内存编号(又称内存地址)标识内存单元。 如果定义并初始化了。

2、一个整型变量如int i = 5;,则计算机中的内存状态可能如图9-1所示。,如何理解“整型变量i所标识的存储单元的地址 为0 x0012 ff00,类型为整型”?,变量的值,存储单元如宿舍,其地址像宿舍号(如408),其存储的内容如住宿者(如王五),相关变量名如宿舍的雅称(如liaozhai)。 由以上分析可知,变量既标识存储单元的地址又标识其存储的内容,因此变量比如整型变量i也有两个值。整型变量i的一个值是地址0 x0012 ff00,另一个值是内容5。,例9-1分析语句i = 5; j = i;中整型变量i的值。,语句i = 5;的操作结果是把5放入变量i所标识的存储单元中,也就是把5的。

3、补码存入地址为0 x0012 ff00的存储单元中,变量i的值此时实为地址0 x0012 ff00。 语句j = i;的操作结果是把变量j所标识的存储单元的状态设置成与变量i的相同,即把变量j的值也设置成5,变量i的值在此处实为内容5。,变量的左值和右值,i = 5; j = i; 位于赋值操作符的左边时,变量的值通常表现为地址,由此称变量的地址为变量的左值;位于赋值操作符的右边时,变量的值通常表现为内容,由此称变量的内容为变量的右值。 变量的左值都为地址,而右值则可能为整数、浮点数、字符等。 指针变量的右值为?,指针变量,指针变量的特殊之处在于其右值也为某存储单元的地址!指针变量的左值和右值。

4、均为地址。 如果认为指针变量存储的是指针,则这里的指针显然为某存储单元的地址。 如何理解“存储单元的地址”? 需强调:存储单元的地址只是其首字节地址,仅仅凭地址而不知道类型(存储单元的大小、编码格式等)是无法正确访问存储单元的。,return,9.1.2 指针变量定义和初始化,指针变量用“*”号定义,但仅用*号标明变量的类型为指针还不行,必须知道指针变量存储的是何种存储单元的地址。因此,指针变量的一般定义形式为: 类型 *标识符 其中,类型规定了与指针变量存储的地址相关的存储单元是何类型,也就是说,一个指针变量只能存储规定类型的存储单元的地址。类型可以是C语言中的整型、浮点型、数组等。,指针变。

5、量的定义,如语句int *pi;定义了一个指针变量pi,pi的内容(右值)应为一个int型存储单元的地址; 语句double *pf;定义了一个指针变量pf,pf的右值应为一个double型存储单元的地址。,相关的内存状态,有int i=5, *pi;,且已知变量i的左值为0 x0012 ff00。现设指针变量pi的内容为0 x0012 ff00,则相关的内存状态可能如图9-2所示。,怎样把变量i的左值(0 x0012 ff00)赋给指针变量pi呢?,第一种作法:pi = 0 x0012 ff00; 在语句pi = 0 x0012 ff00;中,0 x0012 ff00仅被看做一个十六进制的整。

6、型字面量,指针变量要求用地址为其赋值,两者类型不匹配。 第二种作法:pi = i; 语句pi = i;中变量i表现为右值5,因此语句pi = i;相当于pi = 5;,同样类型不匹配。,强制类型转换,类型不匹配时可以用强制类型转换,正确的作法为:pi = (int *)0 x0012 ff00;。 该语句在执行时,会先定义一个临时无名指针变量(假设为int *ptemp;), 然后强制地把整型字面量0 x0012 ff00作为地址赋值给临时无名指针变量(此时整型指针变量ptemp的右值为0 x0012 ff00), 最后再用临时无名指针变量给指针变量pi赋值(pi = ptemp;),从而使指。

7、针变量pi的右值变为0 x0012 ff00。,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 。

8、= *(int *)5;可看作j=*ptemp;。 把地址为5的整型存储单元的内容赋值给变量j。 此时虽然没有了语法错误,但是地址为0 x0000 0005的存储单元通常不会分配给应用程序且不允许应用程序读写,因此在执行该语句时会因为读写不允许读写的存储单元而出现非法内存访问错误。,例9-3,如有int i = 5, *pi = 相同。,例9-4 分析下面程序的运行情况。,return,9.2.2 空指针,例9-5 下面这段程序有问题吗?,变量没有初始化时的值,指针变量pi和变量i都没有初始化。 C语言中变量没有初始化时,全局变量的值默认为0,局部变量的值则没有规定,因此指针变量pi的值在此处。

9、通常不可预知。 语句*pi = 5;执行时将向一个位置不可预知的存储单元写入数据,这样的操作可能导致非法内存访问错误或程序逻辑上的错误。,“野指针”,类似本程序中的指针变量pi,右值为不属于程序所拥有存储单元的地址的指针变量称为“野指针”。 间接引用野指针的右值将导致非法内存访问错误或其他不可预知的错误。 预防由野指针引发的错误的常用办法是把没有明确指向的指针变量设置成“空指针”,而在使用指针变量时检测它是否为空指针。,空指针,所谓空指针是指右值为0的指针变量。 地址为0的存储单元不可能分配给应用程序使用,因此约定指向此处的指针变量为空指针。空指针指向明确的存储单元不再是野指针。 此外,0是一。

10、个特殊的整数,它是唯一不用类型转换就能直接赋值给指针变量的整数。如语句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 指针作为函数参数,函数的参数可以是指针类型,当。

11、参数为指针这种特殊的数据类型时,函数的调用过程呈现出了“新”的特点。 例9-6 分析下面的函数,并编程测试。,指针作为函数参数,swap函数中指针变量px指向了变量i,py指向了变量j。,指针变量的作用,1. 指针变量通过地址实现了对存储单元的直接读写,没有了利用变量访问相关存储单元时作用域的限制。 2. 间接引用操作符*的操作结果正确与否取决于相关存储单元是否为程序所拥有。 3. 形参为指针时,由于获得了特殊的值实参相关存储单元的地址,所以在函数中可以通过指针变量对存储单元的直接写入来改变实参的值。有时也称形参为指针时函数的参数传递方式为“地址传递”,而形参为其它数据类型时称为“值传递”。,。

12、例9-7 分析下面的程序,return,9.3.2 指针作为函数返回值,例9-8分析下面的程序,例9-8的问题,程序拥有变量i所标识的存储单元仅限test函数执行期间,因为变量i的生存期仅限于此。在main函数中,指针变量pj虽然获得了变量i的地址,但由于此时相关存储单元不再为程序所拥有,故指针变量pj变成了野指针。 可是程序正确地输出了变量i的值5,这里有两个疑问:,例9-8的两个疑问,第一个疑问,程序为什么没有出现非法内存访问错误? 第二个疑问,变量i的生存期结束了,为何还能输出变量i的值5? 当存储单元不再属于程序所拥有时,即使在程序中可以通过指针访问该存储单元,也不应该再使用该存储单元了,以免出现不可预知的错误。,例9-9 分析下面的程序,return。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值