一、类型转换概述
当表达式中出现了多种类型的混合运算时,往往需要进行类型转换。表达式中的类型转换分为两种:隐含转换和显式转换。
二、隐含转换
当表达式进行二元运算时,如算术运算、关系运算、逻辑运算、位运算和赋值运算等,需要保证两个操作数的类型一致。如果参与运算的两个操作数类型不一致,编译系统会自动对数据类型进行转换,这种转换称为隐含转换(也称为隐式转换)。
1. 隐含转换的基本原则
隐含转换的基本原则是将低类型数据转换为高类型数据。类型越高,数据的表示范围越大,精度也越高。
各种类型的高低顺序如下(从低到高):
char, bool → short → int → unsigned int → long → unsigned long → float → double → long double
注意:char 和 short 在参与算术运算时,会首先自动提升为 int(或 unsigned int),这称为整数提升。
2. 转换的安全性
上述隐含转换是安全的,因为在转换过程中数据的精度没有损失,或者损失在可接受范围内(如 int 转为 unsigned int 在数值范围内是安全的)。
3. 逻辑运算中的类型转换
逻辑运算符(!、&&、||)要求参与运算的操作数必须是 bool 类型。如果操作数是其他类型,编译器会自动将其转换为 bool 类型。
转换方法:非 0 数据转换为 true,0 转换为 false。
示例:
int a = 0;
bool b = a || false;
cout << b << endl; // 输出 0(false)Code language: JavaScript (javascript)
分析:a 的值为 0,转换为 false。false || false 结果为 false,即 0。
4. 位运算中的类型转换
位运算的操作数必须是整数类型。当二元位运算的操作数是不同类型的整数时,编译系统会自动进行类型转换,转换规则参照上述类型高低顺序。
5. 赋值运算中的类型转换
赋值运算要求左值和右值的类型相同。如果类型不同,编译系统会自动将右值的类型转换为左值的类型。
注意:赋值运算中的类型转换可能导致精度损失或数据截断。例如将 double 赋值给 int,小数部分会被舍弃;将 int 赋值给 short,如果 int 的值超出 short 的表示范围,结果将发生截断。
三、显式转换
显式转换也称为强制类型转换,是由程序员在代码中明确指定的类型转换。形式为:
类型名(表达式)
或
(类型名)表达式
示例:
double d = 3.14;
int i = int(d); // i 的值为 3
int j = (int)d; // j 的值为 3Code language: JavaScript (javascript)
显式转换可能导致精度损失或数据截断,使用时需谨慎。
四、代码示例
以下代码演示了混合运算中的类型转换规则:
#include <iostream>
using namespace std;
int main()
{
// 示例1:算术运算中的隐含转换
int i = 10;
double d = 3.5;
double result = i + d; // i 被转换为 double,结果为 13.5
cout << "i + d = " << result << endl;
// 示例2:关系运算中的隐含转换
char c = 'A'; // 'A' 的 ASCII 码为 65
if (c > 60)
cout << "c > 60" << endl;
// 示例3:逻辑运算中的类型转换
int flag = 5;
if (flag) // flag 非0,转换为 true
cout << "flag is true" << endl;
int a = 0;
bool b = a || false; // a 转换为 false
cout << "b = " << b << endl; // 输出 0
// 示例4:位运算中的类型转换
short s = 0x00FF;
int n = 0x0001;
int r = s << n; // s 提升为 int 后移位
cout << "r = " << hex << r << endl;
// 示例5:赋值运算中的类型转换
double pi = 3.14159;
int intPi = pi; // double 转换为 int,舍弃小数部分
cout << "intPi = " << dec << intPi << endl; // 输出 3
// 示例6:显式转换
int x = 7, y = 2;
double div1 = x / y; // 隐含转换:x/y 为 int 除法,结果为 3,再转为 double
double div2 = double(x) / y; // 显式转换:x 转为 double,结果为 3.5
cout << "div1 = " << div1 << endl; // 输出 3
cout << "div2 = " << div2 << endl; // 输出 3.5
return 0;
}Code language: PHP (php)
五、注意事项
- 隐含转换由编译器自动完成,程序员无需干预,但应了解转换规则以避免意外结果。
- 赋值运算中的类型转换方向是从右值到左值,可能与算术运算中的转换方向相反,容易导致数据丢失。
- 显式转换应谨慎使用,确保转换是合理且安全的。
- 在 C++ 中,除了上述 C 风格的强制转换外,还提供了四种命名的强制类型转换运算符:static_cast、reinterpret_cast、const_cast 和 dynamic_cast,后续章节会详细介绍。
六、小结
- 混合运算时需要进行类型转换,分为隐含转换和显式转换。
- 隐含转换将低类型数据转换为高类型数据,保证运算的一致性,通常是安全的。
- 逻辑运算中非 0 转为 true,0 转为 false。
- 位运算要求操作数为整数类型,不同类型会自动转换。
- 赋值运算将右值类型转换为左值类型,可能导致精度损失。
- 显式转换由程序员指定,形式为 类型名(表达式) 或 (类型名)表达式。