关于《C语言深度解剖》182和415的探讨

关于《C语言深度解剖》182和415的探讨

ID:42987180

大小:52.50 KB

页数:5页

时间:2019-09-25

关于《C语言深度解剖》182和415的探讨_第1页
关于《C语言深度解剖》182和415的探讨_第2页
关于《C语言深度解剖》182和415的探讨_第3页
关于《C语言深度解剖》182和415的探讨_第4页
关于《C语言深度解剖》182和415的探讨_第5页
资源描述:

《关于《C语言深度解剖》182和415的探讨》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、《C语言深度解剖》的作者是个善于观察、思维缜密的人,在其著作中提出了许多值得思考的问题和细节,对于理解计算机系统原理具有很好的参考价值。这两天拜读了此书,今天跟大家一起探讨一下书中一个关于指针的有趣现象。如果你尚未读过原文,请先阅读原书对应的如下章节:***********************************以下是原文**************************************4.1.5,编译器的bug?另外一个有意思的现象,在VisualC++6.0调试如下代码的时候却又发现一个古怪的问题:int*p=(int*)0x12ff7c

2、;*p=NULL;p=NULL;在执行完第二条代码之后,发现p的值变为0x00000000了。按照我么上一节的解释,应该p的值不变,只是p指向的内存被赋值为0。难道我们讲错了吗?别急,再试试如下代码:inti=10;int*p=(int*)0x12ff7c;*p=NULL;p=NULL;通过调试,发现这样子的话,p的值没有变,而p指向的内存的值变为0了。这与我们前面讲解的完全一致。当然这里的i的地址刚好是0x12ff7c,但这并不能改变“*p=NULL;”这行代码的功能。为了再次测试这个问题,我又调试了如下代码:inti=10;intj=100;int*p=(

3、int*)0x12ff78;*p=NULL;p=NULL;这里0x12ff78刚好就是变量j的地址。这样的话一切正常,但是如果把“intj=100;”这行代码删除的话,又出现上述的问题了。测试到这里我还是不甘心,编译器怎么能犯这种低级错误呢?于是又接着进行了如下测试:unsignedinti=10;//unsignedintj=100;unsignedint*p=(unsignedint*)0x12ff78;*p=NULL;5p=NULL;得到的结果与上面完全一样。当然,我还是没有死心,又进行了如下测试:charch=10;char*p=(char*)0x12

4、ff7c;*p=NULL;p=NULL;这样子的话,完全正常。但当我删除掉第一行代码后再测试,这里的p的值并未变成0x00000000,而是变成了0x0012ff00,同时*p的值变成了0。这又是怎么回事呢?初学者是否认为这是编译器“良心发现”,把*p的值改写为0了。如果你真这么认为,那就大错特错了。这里的*p还是地址0x12ff7c上的内容吗?显然不是,而是地址0x0012ff00上的内容。至于0x12ff7c为什么变成0x0012ff00,则是因为编译器认为这是把NULL赋值给char类型的内存,所以只是把指针变量p的低地址上的一个字节赋值为0。至于为什么

5、是低地址,请参看前面讲解过大小端模式相关内容。测试到这里,已经基本可以肯定这是VisualC++6.0的一个bug。所以平时一定不要迷信某个编译器,要相信自己的判断。当然,后面还会提到一个我认为的VisualC++6.0的一个bug。还有,这个小小的例子,你是否可以在多个编译器上测试测试呢?************************************以上是原文*************************************到此,相信你对作者所发现的有趣现象已经有所了解,现在就让我们通过实验+观察+分析,给这一现象一个合理的解释,一起来探讨

6、一下,为什么会产生这种现象,这究竟是否是VC6.0编译器存在的bug?首先看作者给出的第一个例子:int*p=(int*)0x12ff7c;*p=NULL;p=NULL;注意0x12ff7c的由来。作者是通过在变量p之前先定义变量i,然后在调试模式下观察到i的存储地址为0x12ff7c,接着将变量i的定义去掉,令p指向地址0x12ff7c对应的存储单元。不同的系统此值一般不同,这取决于操作系统为进程分配的内存空间(主要是堆栈区)的不同,请大家自行替换成合适的值。在我的计算机系统上调试时,对应的地址是0x0013ff7c。接下来请大家测试如下代码,并对比四条pr

7、intf语句的输出:int*p;printf("&p=%x,p=%x",&p,p);p=(int*)0x0013ff7c;printf("&p=%x,p=%x",&p,p);*p=NULL;5printf("&p=%x,p=%x",&p,p);p=NULL;printf("&p=%x,p=%x",&p,p);以下是输出结果:&p=13ff7c,p=cccccccc&p=13ff7c,p=13ff7c&p=13ff7c,p=0&p=13ff7c,p=0通过观察我们可以发现,变量p自定义以来,其存储位置(&p)并未改变,始终是0x13ff7c,随着

8、对p或*p的操作发生变化的是p值。到此

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。