发生隐式转换的情形
指定转换的类型
- 赋值运算
- 变量初始化
- 调用函数时的参数
- return语句返回的数值
未指定转换的类型
- 算数
转换原则
指定转换的类型
在可以明确转换后的类型时,会隐式转换到该类型,并且若类型缩小,则会直接截断高位,仅保留低位,符号位也由新的低位决定,这一过程类似于强制类型转换。
uint16_t a = -1;//a=0xffff(65535)
uint16_t a = 0xffffffff;//a=0xffff(65535)
int16_t a = 0xffff0001;//a=0x0001(1)
int16_t a = 0x0000ffff;//a=0xffff(-1)
未指定转换的类型
- 首先会进行整数提升,整数提升是任何等级小于或等于
int
等级的整数类型到int
类型值的隐式转换,而unsigned int
将保持。 - 同符号时,低等级向高等级转换
- 符号不同且有符号数等级比无符号数低或相同时,有符号数转换为无符号数。
- 符号不同且有符号数等级比无符号数高时,无符号数转换为有符号数。
(uint32_t)1 > (int16_t)(-1);//无符号0x00000001>0xffffffff,false
(uint16_t)1 > (int16_t)(-1);//有符号0x00000001(1)>0xffffffff(-1),true
(uint32_t)1 > (int64_t)(-1);//true
总的来说,就是在整数类型比int小时会先转换为int,无符号数等级更大或相同时有符号数转换为无符号数,其他情况下,由于等级更高的有符号数可以完整包含低等级无符号数的值域,因此无符号数向有符号数转换。
更多参考
请参阅隐式转换。
例子
关于隐式转换的一个经典例子就是size_t,在标准中size_t是一个无符号数,但是很多时候我们都会定义一个有符号数与它进行比较,当定义的值为整数的时候一切正常,为负数的时候就会出现一些意外的情况,例如:
string s("123456");
for(int i = -1; i < s.size();)
{
i++;
cout << 1;
}
看起来应该会输出6个1,但实际上并不会进入循环。这是由于i
首先初始化为了一个负数,在和s.size()
比较的时候发生了隐式转换,在大部分环境下,size_t是8字节的无符号数,而int为4字节的有符号数,因此比较结果不符合预期。