先来看一个例子
int ival = 3.541 + 3; // 部分编译器会告警该运算损失了精度
C++规定运算的类型必须是一样的,而这个表达式中两个运算常量的类型却不同。
这个时候就需要通过类型转换来完成运算。
这里的运算会变成如下:
int ival = 3.541 + 3.0; // 将3转换为double型然后进行运算
上述表达式运算出结果然后再将结果转换为int型赋值给变量ival
而上述的运算转换过程中不需要程序员参与,甚至不需要了解。这种转换被称为隐式转换.
转换的目的是为了避免精度的损失,所以编译器将3转换为double型,而没有将3.541转换为int型。
隐式转换的发生条件大致有以下几种:
1. 在大多数表达式中,比int类型小的整型值首先提升为较大的整数类型。
2. 在条件中,费布尔值转换成布尔类型。
3.初始化过程中,初始值转换为变量的类型;在赋值语句中,右侧运算对象转换成左侧运算对象的类型
4. 如果算术运算或关系运算的运算对象有多种类型,需要转换成同一种类型。
5. 函数调用也会发生类型转换
算数转换
基本原则是将类型转换为所有参与运算类型的精度最高类型进行计算
整形提升:
bool、char、signed char、unsigned char、short和unsigned short等类型它们会被提升为int类型进行计算
char、wchar_t、char16_t、char32_t 会被提升为int、unsigned int、long、unsigned long、long long和unsigned long long 中能容纳元类型所有值的最小类型。
由于机器字长的不同所以被转换的目标类型根据所能容纳的值来决定。
有无符号之间的转换:
在大部分的情况下这种转换时无需关注的,只需要有概念性的认识,从小的类型转换到大的类型。
但是有一种情况我们需要注意:当一个带符号一个无符号并且带符号类型是负数的时候,这种转换将会产生转换副作用
详情请参考https://www.cnblogs.com/ChattyKu/p/9410757.html最后一个程序示例
int main() { bool flag; char cval; short sval; unsigned short usval; int ival; unsigned int uival; long lval; unsigned long ulval; float fval; double dval; 3.14159L + 'a'; // ‘a’被提升成int,然后该int值转换成long double dval + ival; // ival转换成double ival + fval; // fval转换成double ival = dval; // dval转换成int,舍弃小数部分 flag = dval; // 如果dval是0,则flag是false,否则flag是true cval + fval; // cval提升成int,然后该int值转换成faloat sval + cval; // sval和cval都提升成int cval + lval; // cval转换成long ival + ulval; // ival转换成unsigned long usval + ival; // 根据unsigned short和int所占控件的大小进行提升 uival + lval; // 根据unsigned int和long所占控件的大小进行转换 }
其他隐式类型转换
数组转换为指针:在大多数啊用到数组的表达式中,数组自动转换成指向数组首元素的指针:
int ia[10]; // 含有10个证书的数组 int *ip = ia; // ia转换成指向数组首元素的指针
指针的转换
0或者nullptr能转换为任意类型的指针(编程过程中主要用来标识空指针)
指向任意非常亮的指针能转换为void* 或者const void*(在一些不定类型的入参函数中进行传递参数使用,比如线程函数的入参)
具有继承关系的对象指针之间具有转换的能力。
转换为bool类型
char *cp = get_string(); if(cp) // 如果指针cp不是0,条件为真 while(*cp) // 如果*cp不是空字符串条件为真
转换成常量
无论指针或者引用,都可以将非常亮的类型转换为常量的类型,但是不能反向转换
int i; const int &j = i; // 非常亮转换为const int的引用 const int *p = &i; // 非常亮的地址转换成const的地址 // int &r = j, *q = p; // 错误:不允许const类型转换为非常亮
类类型定义的转换
string s,t = "a value"; // 字符串字面值转换成string类型 while(cin >> s) // while的条件部分吧cin转换成布尔值