目录
一、类型转换和截断问题
1. 隐式类型转换
2. 强制类型转换
3. 截断问题
二、整型提升
0. 算数表达式的计算过程
1. 整型提升是什么?
2. 为什么要整型提升?
3. 如何进行整型提升
4. 唯一的注意事项
5. 通过在vs中的监视窗口来观察整型提升
6. 整型提升会不会引发线程安全问题?
7. 整型提升是隐式类型转换吗
一、类型转换和截断问题
1. 隐式类型转换
隐式类型转换是指编译器算数、比较、赋值、传参、传返回值时,遇到与要求不符合类型时,编译器就会自动执行类型转换以使得操作数具有符合条件的类型。
C/C++中有以下四种情况会进行隐式转换:
- 算数或比较时,低类型转换为高类型。
- 赋值时,右边表达式的值自动隐式转换为左边变量的类型,并赋值。
- 传参时,系统将实参转换为形参的类型后,赋给形参。
- 传返回值时,系统将返回值的类型转换为返回值类型。
隐式类型转换的例子包括:
算数或比较时:
整型提升:小于
int
或unsigned int
的整数类型(如char
、short
)在表达式中会自动提升为int
或unsigned int
。浮点提升:当
float
类型的值和double
类型的值进行算术运算时,float
值会被提升为double
类型。赋值、传参、传返回值时:
- 赋值时,右边表达式的值自动隐式转换为左边变量的类型,并赋值。
- 传参时,系统将实参转换为形参的类型后,赋给形参。
- 传返回值时,系统将返回值的类型转换为返回值类型。
- 上面三种情况都可能因为大类型转换为小类型,导致截断问题。
2. 强制类型转换
如果想把一个变量A的值强制放到另外一种类型的变量B中,我们就需要在A前面加上(B的类型)来完成强制类型转换,如:
int *A; double *B = (double *)A;
但使用强转时一定要小心大类型转换为小类型,导致截断问题。
无论是哪种类型转换,都是借助了一个临时变量,被转换的变量没有发生变化。
3. 截断问题
类型转换(无论是隐式还是显式)都可能导致数据截断问题,特别是在将较大类型的值转换为较小类型时。当源类型的表示范围大于目标类型时,如果源类型的值超出了目标类型的表示范围,或者源类型的精度高于目标类型,就会发生数据截断。这里的截断要考虑到数据类型的大小(占几个字节)和数值的二进制。
二、整型提升
0. 算数表达式的计算过程
- 值的取出:
变量在表达式中参与计算时,其变量中保存的值会被编译器取出然后保存到寄存器中。- 整型提升:
在上诉过程中从各种短整型(如 char、short、unsigned short等)中取出的值会被编译器提升成 int 或 unsigned int型【如果表达式中有 unsigned int 或 size_t型变量,表达式中所有变量的值就被提升为unsigned int型;没有就被提升为int型】- 结果的存储:
运算结果被放在一个int或unsigned int型的临时变量中- 赋值给变量:
然后将这个int或unsigned int型的临时变量赋值给接收结果的变量(看情况发生隐式类型转换或截断)。
1. 整型提升是什么?
整型提升是隐式类型转换的一种特殊情况,它发生在整型变量的算术运算或比较运算中,将整型变量中的值取出到用于计算或比较的寄存器时,对取出的数值的二进制位进行补0或补1的操作,使其变为4byte(32bit)的int 或 unsigned int 类型。
总结下来就是:
- 在执行表达式或比较大小时,各种短整型(如 char、short....等)要提升为int 或 unsigned int 类型;
- 如果表达式中存在unsigned int 或 size_t类型变量,那 短整型和int 就要提升为unsigned int类型。
- 如果只存在短整型和int,那 短整型 就要提升为int类型。
2. 为什么要整型提升?
表达式的整型运算是由CPU的整型运算器(ALU)来完成的,CPU内整型运算器的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。
3. 如何进行整型提升
- 整形提升为unsigned int:在高位补0 ,直到补满32bit。
- 整形提升为int:在高位补符号位(整数补0,负数补-1),直到补满32bit。
4. 唯一的注意事项
唯一一点要注意的是-1被整型提升为unsigned int类型时会变成42亿9千多万。其中的原理相信学过位运算后都能明白。
5. 通过在vs中的监视窗口来观察整型提升
我们可以通过在vs中的监视窗口来观察整型提升:
- 如果只存在短整型和int,那 短整型 就要提升为int类型:
- 如果表达式中存在unsigned int 或 size_t类型变量,那 短整型和int 就要提升为unsigned int类型:
6. 整型提升会不会引发线程安全问题?
不会,整型提升不是对变量进行强制类型转换,而是将变量中的值取出到用于计算或比较的寄存器时,对取出的数值的二进制位进行补0或补1的操作,使其变为4bit。
7. 整型提升是隐式类型转换吗
是的,C++中的整型提升是一种隐式类型转换(Implicit Type Conversion)。隐式类型转换是编译器自动进行的类型转换,不需要程序员显式指定,也不会对原变量造成影响,整型提升是隐式类型转换的一种特殊情况,它发生在整型变量的算术运算或比较运算中。
------------------------END-------------------------
才疏学浅,谬误难免,欢迎各位批评指正。