3.9.2 不安全类型转换

2013-10-07 12:56:28 · 作者: · 浏览: 78

3.9.2 不安全类型转换

安全的转换对程序员通常是一个福音, 它可以简化编写代码的过程。不幸的是, C++(www.cppentry.com)也允许(隐式的)不安全转换。所谓的不安全, 我们指的是一个值可以转换成一个其他类型的值, 这个值不等于原始的值。例如:

 

这种转换又称为“缩小”转换, 这是由于它们将一个值放入一个对象, 而这个对象大小难以存放这个值。不幸的是, 只有少数编译器会警告将char初始化为int的不安全。问题是一个int通常比一个char大, 因此(在这种情况下)它可以保存一个int值, 但是这个值并不能表示为一个char。尝试执行这个程序, 查看你计算机中的值b(常见的结果是32)。更进一步, 完成实验:

 

我们使用while语句允许尝试很多值, 这个语句将在4.4.2.1节中解释。

试一试输入各种各样的值来运行这个程序。尝试小的值(例如2和3); 尝试大的值(大于127和大于1000); 尝试负值; 尝试56; 尝试89; 尝试128; 尝试非整数值(例如56.9和56.2)。另外, 如何在你的机器中从double转换成int, 以及如何从int转换成char。本程序将显示, 对一个给定的整数值, 你的机器将打印什么字符(如果存在的话)。

你将发现很多输入值产生“不合理”的结果。基本上, 我们是在尝试将1加仑水倒入容量为1品脱的桶中(大约是将4升水倒入一个500毫升的杯子)。

 
所有这些转换被编译器接受, 即使它们是不安全的。所谓不安全是指它们保存的值可能与被赋予的值不同。为什么这会是个问题?这是由于我们经常不会怀疑一个不安全的转换会发生。考虑:
 
在我们定义y时可能忘记x是一个double, 或者我们临时忘记double到int转换会截短(总是去掉小数点后的尾数), 而不是使用常用的四舍五入。发生的事情是完全可以预测的, 但是在int y=x;处没有任何东西能提醒我们信息(.7)被丢掉了。从int到char的转换不会出现截短的问题, int和char都不能表示一个整数的一部分。但是, 一个char只能保存非常小的整数值。在一台PC机中, 一个char占用1个字节, 而一个int占用4个字节, 如右图所示。因此, 我们不能将一个大的数(例如1000)放入一个int而不丢失任何信息: 这个值是“缩小的”。例如:
 
 

不是所有的int值都有等价的char, 而char值的确切范围依赖于特定的实现。在一台PC机中, char值的范围是[-128: 127], 但是只有[0, 127]可以方便地移植。这是由于并不是每台计算机都是PC机, 不同计算机的char值的范围不同, 例如[0: 255]。

为什么人们接受缩小转换的问题?主要原因是历史性的: C++(www.cppentry.com)从它的前辈语言C继承了缩小转换, 因此从C++(www.cppentry.com)出现时很多代码就依赖于缩小转换。很多这种转换实际上不会引起问题, 这是由于它们所涉及的值碰巧在范围内, 并且很多程序员反对编译器“告诉它们做什么”。特别是对有经验的程序员来说, 这些不安全转换问题在小的程序中是可管理的。它们在大的程序中可能是错误的来源, 并且是一个新程序员出现问题的重要原因。但是, 编译器可以对多数的缩小转换发出警告。

如果你认为转换可能导致一个错误值, 那么你需要做什么?在我们做本节中的第一个例子时, 你在赋值之前要简单检查这个值。5.6.4节与7.5节介绍做这种检查的简单方式。