四、表达式
14、类型转换
有时候我们对不同类型的值进行运算时,编译器会自动将小类型转换成大类型【不损失精度的准则】,而不会报错。如果是左值和右值,右值会被转换成左值的类型。
隐式转换:C++内置类型对象之间的标准转换,无需编程者介入。
隐式转换典型场景:
1、算术表达式中:在算术表达式里面有不同的类型,编译器会自动将小类型转换成大类型。【int-->double】
2、赋值表达式中:将右值的类型转换成左值的类型,中间可能会涉及到精度损失。
3、传参给函数时:此时传递的参数的类型会自动转换成函数设计时的参数类型。
4、函数返回值:函数返回值也会将返回的函数值转换为声明函数时的类型。
在算术表达式中的类型转换叫做算术转换,它有两个通用的指导原则:
1、防止精度损失的原则。【如果存在一个最大的操作数类型,那么在算术表达式里面,其他的操作数类型都会被转换成最长的类型。】
2、所有小于整型的有序类型的算术表达式会先转换成整型。比如类型char、signed char、unsigned char和short int 都会被先转换成int再进行运算。【在枚举类型和wchar_t类型中,底层类型如果小于int也会被提升为int储存】
long类型有一个例外:一个数是long型,另一个数是unsigned int型,只有满足long型足够长储存unsigned int时才会进行类型转换。
显式转换:强制类型转换。
何时需要显式转换?
1、void*类型指针,它通常被用作“对象类型未知”的情况,因为它可以指向任意数据类型的指针【非const类型,如果要被const修饰,那么在定义void*之前也要加上const修饰】。虽然void*类型指针能够指向任意数据类型的指针,但是它不能够直接被解引用,而必须要先显式转换成特定的数据类型之后,才能够被解引用。
pc = static_cast< char* >( pv );
2、希望改变通常的标准转换。隐式转换会不以精度损失为标准,可以通过显式转换来将高精度类型转换成低精度类型。
3、避免多种转换可能的歧义情况。
显式转换的一般形式:
cast-name< type >( expression );
cast-name有以下几种:
static_cast【隐式执行的类型转换都可以通过static_cast转换,可以消除编译器对于行为不佳的静态转换的警告】、const_cast【可以转换掉表达式的常量性,譬如可以去掉const修饰符】、dynamic_cast【用于在运行时执行多态类型的安全向下转换】和reinterpret_cast【对于操作数位模式执行低层次的重新解释,是一个很强大的操作符,可以无视种族隔离,虽然强大但是很可能造成错误】。
C++中的旧式强制类型转换:
// C++强制转换符号
type (expr);
// C 语言强制转换符号
(type) expr;