`
比深蓝还要蓝
  • 浏览: 14866 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

C语言:关于溢出

 
阅读更多
对于变量的值超出其定义的数据类型的表示范围,这种情况称为溢出。

书上以shot型变量为例画出了溢出的二进制原理,如图1。
图1:

图中变量a换算成十进制为32767,变量b换算成十进制为3,本意想得到32770,不过由于溢出,得到的结果变量c换算成十进制为-2。

上机演示后,计算机输出的结果却和理论上的不一样,变量c为-32767,并不是原理上的-2,如图2。
图2:


为什么会有这种情况?难道是溢出的原理不是书上那样?
带着这个疑问,我又试验了a=32766时,b=1、b=2和b=3三种情况。变量c对应的值为32767、-32768和-32767。如图3、图4、图5:
图3:

图4:

图5:

当b=1时,变量c刚好达到shot型的临界范围;当b=2和b=3时,变量c的结果已经和理论值不一样。但是联系图2,我发现,计算机得到的溢出的值也是有规律的,即从shot型的最小值开始递增。

由此猜想:计算机在内存中为每个变量单独且连续分配了65535个字节的空间,里面存储了从-32768到32767的数值,计算机在做加法时,是先找到变量a的值的对应内存地址,然后按照变量b的值查找内存地址,最后再将那个地址里的值赋予变量c(例如变量b的值为1,则在变量a当前值往下找一格,得到的值再赋予变量c)。

为了证明我的猜想,做了如下试验:当a=32766,b=32770时,c=?
如果猜想是正确的,那么变量c的值应该是从a=32766这一值所在的内存地址,往下移动32770格后,其内存地址存储的值,即为0,如图6。
图6:

值得注意的是:变量b的值,并不是输入的32770,显示的是-32766。由于变量abc都是short型,所以32770已经超出了范围,按照猜想,由于32770=32767+3,b此时的值应该是b=32767所在的内存地址往下移三格后,其内存地址存储的值。

至此,我没发现任何与猜想相悖的情况,但为了保险起见,又做了如下试验:当a=32766,b=65537时,c=?
由于65537=32767+32770已经超出了short的范围,所以b的值应该是b=32767所在的内存地址往下移动32770格后,其内存地址存储的值,即为1。
而变量c的值应该是从a=32766这一值所在的内存地址,往下移动65537格后,其内存地址存储的值,为32767,如图7。
图7:


由此可见,猜想是符合实际情况的。

另外,对比图3和图7,虽然变量c的值都为32767,但是两图中32767的来源却不一样。在图3中,计算机是在内存地址中把short型变量a的最大值32767赋予变量c;而在图7中,计算机是在内存地址中把short型变量b的最大值32767赋予变量c。

结论:书上溢出的原理是正确的,只是由于计算机的工作方式等原因,才会使计算机输出的结果和理论上不一样。

以上观点均为个人看法,如有错误,欢迎大家批评指正。
  • 大小: 13.1 KB
  • 大小: 22.8 KB
  • 大小: 23.2 KB
  • 大小: 22.4 KB
  • 大小: 22.9 KB
  • 大小: 22.4 KB
  • 大小: 23.6 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics