• c语言表达式求值--整型提升


    什么是整型提升?

    C的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。

    什么叫缺省整数类型?缺省在计算机里面是默认的意思。

    这句话大概意思就是,在c语言的整数运算中,如果有精度小于整型的非自定义类型数,就需要先转换为一个整数类型。

    比如char和short int类型,它们的字节数分别为1、2,如果它们参与整数表达式的运算就会先转换成整数类型,再参与运算。

    这里我们只谈论char和short int

    代码举例:

    1. int main()
    2. {
    3. char a = 0x80;
    4. short b = 0x8000;
    5. int c = 0x86000000;
    6. if (a == 0x80)
    7. printf("a");
    8. if (b == 0x8000)
    9. printf("b");
    10. if (c == 0x86000000)
    11. printf("c");
    12. return 0;
    13. }

    看结果:

    0d54d9484a714f45bd0b199538fb437f.png只输出了一个c。

    为什么会这样呢?a、b变量被赋予的值也没有超出它们的字节大小代表的最大值,为什么a==0x80和b==0x8000会为假呢?

    这其中就发生了整型提升。

     

    整型提升的规则

    1、操作数为int的时候,高位补充符号位

    2、操作数为unsigned int(无符号整数)的时候,高位补充0

     分析例子

    1.变量a整型提升:

    首先,a占一个字节,在转换前被赋值0x80(十六进制),二进制(补码)表示为1000 0000。

    符号位是1.

    整型提升变成四个字节,前面补充1,就转换成了:

    1111 1111 1111 1111 1111 1111 1000 0000

    所以这个时候的a就不等于原来的数了,很明显这都变成了一个负数。

    2.变量b整型提升:

    首先,b占两个字节,在转换前被赋值0x8000(十六进制),二进制(补码)表示为:

    1000 0000 0000 0000

    符号位是1.

    整型提升变成四个字节,前面补充1,就转换成了:

    1111 1111 1111 1111 1000 0000 0000 0000

    所以这个时候的b就不等于原来的数了,很明显这都变成了一个负数。

    而c是int,不需要转换。

    代码1:

    1. int main() {
    2. char a = 0x80;
    3. char b = 0x80;
    4. int c = a + b;
    5. printf("%d", c);
    6. return 0;
    7. }

    这里又会输出什么结果呢?

    因为运算涉及到整数,所以字符a和b在参与计算的时候会先整数提升,而根据上面我们知道,a整型提升之后是一个负数,所以得到:

    edeec9cb8fed4fedbedfe75677c67981.png

     

    代码2:

    1. int main()
    2. {
    3. char c = 1;
    4. printf("%u\n", sizeof(c));
    5. printf("%u\n", sizeof(+c));
    6. printf("%u\n", sizeof(-c));
    7. return 0;
    8. }

    这里我们要注意,我前面已经强调过,只有在参与运算的时候才会考虑是否要整型提升,而sizeof(c)里的c并没有参与运算,所以不需要整型提升,得到的还是一个字节。

    那么sizeof(+c)和sizeof(-c)呢?c语言会认为(+c)和(-c)都是参与了运算,所以需要整型提升,得到的也就是一个整型的字节大小。

    1a2e9b63568d46a69bc44b9d61712b7c.png

     

    整型提升的意义?

    表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。 因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长 度。 通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。

    总的来说,整型提升的目的是为了保持表达式中操作数的一致性。当不同大小的整数类型参与运算时,较小的类型会被提升为较大的类型,以避免精度丢失和数据溢出的问题

     

  • 相关阅读:
    不知道图片加文字水印怎么弄?这3个方法自媒体达人必学
    OpenCV 04(通道分离与合并 | 绘制图形)
    LVS+Keepalived群集实验
    代码随想录算法训练营第三十四天| LeetCode1005. K 次取反后最大化的数组和、LeetCode134. 加油站、LeetCode135. 分发糖果
    既要便捷、安全+智能,也要颜值,萤石发布北斗星人脸锁DL30F和极光人脸视频锁Y3000FV
    LeetCode 2365. 任务调度器 II 模拟+哈希
    Linux 下的 /proc 目录介绍
    面试:谈一下你对Nginx的理解
    Allegro172版本DFM功能介绍
    阿里面试官:聊聊如何格式化Instant
  • 原文地址:https://blog.csdn.net/qq_62987647/article/details/133803134