「C/C++ 01」类型转换与整型提升

目录

一、类型转换和截断问题

1. 隐式类型转换

2. 强制类型转换

3. 截断问题 

二、整型提升

0. 算数表达式的计算过程

1. 整型提升是什么?

2. 为什么要整型提升?

3. 如何进行整型提升

4. 唯一的注意事项

5. 通过在vs中的监视窗口来观察整型提升 

6. 整型提升会不会引发线程安全问题?  

7. 整型提升是隐式类型转换吗 


一、类型转换和截断问题

1. 隐式类型转换

隐式类型转换是指编译器算数、比较、赋值、传参、传返回值时,遇到与要求不符合类型时,编译器就会自动执行类型转换以使得操作数具有符合条件的类型。


C/C++中有以下四种情况会进行隐式转换:

  • 算数或比较时,低类型转换为高类型。
  • 赋值时,右边表达式的值自动隐式转换为左边变量的类型,并赋值。
  • 传参时,系统将实参转换为形参的类型后,赋给形参。
  • 传返回值时,系统将返回值的类型转换为返回值类型。

隐式类型转换的例子包括:

算数或比较时:

  • 整型提升:小于intunsigned int的整数类型(如charshort)在表达式中会自动提升为intunsigned 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-------------------------

才疏学浅,谬误难免,欢迎各位批评指正。

  • 29
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烛火萤辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值