2.5 类型转换

    C++中有整型、浮点型、布尔型和字符型等基本类型,在后面的章节中还会介绍到复杂数据类型和用户自定义的类型。在进行运算,尤其是对不同的类型进行运算时,可能会引发混乱,为此,C++引入了类型转换机制,一种数据类型能够被转换为另一种数据类型。

    2.5.1 赋值转换

    赋值转换指的是将一种类型的值赋给另一种类型的变量,这时,值将会转换为接收变量的类型,如下面的语句所示。


    A=B;

    如果A是long型,B是short型,则程序会将16位(short占两字节)的B提升为32位(long占4字节),并赋给A。直观上讲,类型的表达能力取决于该类型所占的内存位数,从表达能力低的类型转换为表达能力高的类型,即进行字节的扩充通常不会带来什么弊端,将short型值赋值给long型变量并不会改变这个值,只是占用的字节多了而已,但是在其他的一些情况下可能会出现转换问题。

    1.将较大的整型(表达能力强)转换为较小的整型

    当原来的值不超出目标类型的取值范围时是没有问题的,否则,只能将右侧较低字节赋值给较小的整型,超出的高端部分将被舍弃,见示例代码2.16。

    代码2.16 赋值转换:较大整型转换为较小整型AssigmentConversion1


    <———————————————文件名:example216.cpp————————————> 01 #include<iostream> 02 int main() 03 { 04 using namespace std; 05 long x=0X12345678;//声明一个长整型变量x 06 short y=x;//将x赋值给一个短整型变量y,转换 07 short z=0X5678; 08 cout<<"y is"<<y<<endl; 09 cout<<"z is"<<z<<endl; 10 return 0; 11 }

    【代码解析】代码第6行,即将变量x的值,转换并赋值给短整型变量y。

    输出结果如下所示。


    y is 22136 z is 22136

    可见,只有低端的两个字节0X5678复制给了变量y,高端字节0X1234被舍弃了。

    2.浮点型转换为整型

    此时,浮点型的小数部分会丢失,将整数部分复制给目标整型,当浮点型的整数值不超过目标整型的表示范围时,没有转换问题,否则,整型的结果将是不确定的,见代码2.17。

    代码2.17 类型转换:浮点型转换为整型AssigmentConversion2


    <——————————-文件名:example217.cpp————————————————-> 01 #include<iostream> 02 int main() 03 { 04 using namespace std; 05 int x;//声明一个int型变量x 06 float y=2. 7;//声明一个float型变量y 07 double z=5E15;//声明一个double型变量z 08 x=y;//赋值转换 09 cout<<"x is"<<x<<endl; 10 x=z;//赋值转换 11 cout<<"x is"<<x<<endl; 12 return 0; 13 }

    【代码解析】代码第8和第10行都是浮点型转换为整型数据。

    输出结果如下所示。


    x is 2 x is 937459712

    C++采取截取(直接将小数部分丢弃)而不是四舍五入,当浮点型值过大时(代码2.17为5×1015),这是,整型量的值是不确定的,在不同的系统中可能为不同的值。

    注意

    发现代码中可能存在精度缺失时,编译器可能会给出相关警告,关于浮点型的精度和表述范围,参见表2.3。

    3.较大的浮点型转换为较小的浮点型

    不同的浮点型精度不同,这里的精度可通俗地理解成小数的位数,所以,用较大的浮点型给较小的浮点型赋值时(如用double型值赋给float型变量),数据的精度(有效位数)降低,而且,如果较大浮点型的值超出目标浮点型的表示范围,将得到一个不确定的结果,见代码2.18。

    代码2.18 较大的浮点型转换为较小的浮点型AssigmentConversion3


    <—————————————文件名:example218.cpp——————————————> 01 #include<iostream> 02 int main() 03 { 04 using namespace std; 05 double x=2E50;//较大的浮点数 06 float z=x;//转换 07 cout<<"z is"<<z<<endl; 08 return 0; 09 }

    【代码解析】代码第6行是较大的浮点型数据转换为较小的浮点型数据。

    输出结果如下所示。


    z is 1.#INF

    4.整型转换为浮点型

    受浮点型的精度限制,将一个很大的整型,如long型的123456789赋值给float型变量时,同样会发生数据丢失,降低精度,见代码2.19。

    代码2.19 类型转换:整型转换为浮点型AssigmentConversion4


    <—————————————文件名:example219.cpp——————————————> 01 #include<iostream> 02 int main() 03 { 04 using namespace std; 05 long x=123456789;//声明一个长整型变量x 06 float y=x;//赋值转换 07 cout<<"y is"<<y<<endl; 08 return 0; 09 }

    【代码解析】代码第6行,是整型数据转换为浮点型数据。

    输出结果如下所示。


    y is 1.23457e+008

    可见,y的实际值为123457000,这可能会给运算带来很大的误差。

    5.对bool类型进行赋值

    将0赋给bool变量时,将被转换为false,而非零值将转换为true。

    注意

    赋值转换是由编译器自动完成的,比较隐蔽,在丢失数据时,有的编译器可能会给出警告,有的却不会,理解不同类型在内存中的表示规律,有助于克服弊端,写出高质量的代码。