所谓的整形提升的关键:
-
- 一个char类型、short类型、位域(不论是有符号还是无符号)或是一个枚举体,都可以在int或是unsinged int可以使用的表达式中使用。
-
- 换句话就是上述的类型可以替换表达式中的int或是unsigned int
1. 整形提升的几种情况
1.1 在函数调用时发生整形提升
#include <iostream>
enum colorA{redA,blueA,grayA,blackA};
void go(unsigned int a){std::cout<<"called"<<std::endl;}
int main(){
//枚举类型
colorA ca(redA);
go(ca);//枚举类型提升为无符号整型
//char 类型
char a('a');
go(a);//char 提升为无符号整型
std::cin.get();
return 0;
}
运行结果:
called
called
1.2 算数表达式中的整形提升
算数中的整形提升有几个特点(这里不考虑浮点):当操作数类型不同时,会发生类型的自动转换,有时,即使在类型相同的情况下也会发生整形提升。
#include <iostream>
int main() {
char a('a'), b('0'), c;
c = a + b;
std::cout << "a + b : " << sizeof(a + b) << std::endl;
std::cout << "c : " << sizeof(c) << std::endl;
std::cin.get();
return 0;
}
运行结果为:
a + b : 4
c : 1
从运行结果来看在下面几处地方都发生了整形提升:
- 当执行a+b的时候,char类型自动转换为4字节的整形
- 当执行c=a+b 也就是,将(a+b)的结果赋给c的时候,又发生了从4字节整形到char类型的隐式转换(截断)。
- 所以说,即使数据类型相同,也可能发生整形提升。
2. 整形提升的原理
当我们从1字节整形向4字节整形提升时,对位的填充可能发生两种情况:
如果是有符号数据类型:正数填充0,负数填充1
如果是无符号数据类型:填充0
3.数据溢出
例子如下:
#include <iostream>
int main() {
unsigned char test(255 + 1);
std::cout << static_cast<int>(test) << std::endl;//转换成整形输出,避免以字符输出
std::cin.get();
return 0;
}
运行结果为0
转换过程如下:
255 二进制:0000 0000 0000 0000 0000 0000 1111 1111
1二进制:0000 0000 0000 0000 0000 0000 0000 0001
256二进制:0000 0000 0000 0000 0000 0001 0000 0000
转换为unsigned char类型:从低位开始(从右边开始)截取8个bit:0000 0000