C语言整型提升

Posted 不知名小赖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言整型提升相关的知识,希望对你有一定的参考价值。

@TOC

1.什么是正整型提升

官方的解释是:
整型提升C程序设计语言中的一项规定:在表达式计算时,各种整型首先要提升为int类型,如果int类型不足以表示则要提升为unsigned int类型;然后执行表达式的运算。

2.整型提升的规则

整型提升分为有符号和无符号两种

  • 有符号的:整型提升时是按照变量的补码被截断时的最高位是什么进行补位的,如果截断后最高位(即最左面)的一位数为 1 则在最高位前补 1 ,如果最高位是 0 则在前面补 0 ,补够32位即int类型即可。
  • 无符号的: 直接在被截断的前面补 0 即可。

3.例题

直接看代码:

int main()

    char a = -1;
    signed char b = -1;
    unsigned char c = -1;
    printf("a=%d\\nb=%d\\nc=%d\\n", a, b, c);
    return 0;

上面代码运行结果如图:(编译器计算过程中发生了整型提升与截断)

分析如图:

我们可以分成几步来看:

  1. 数字-1的补码为:11111111111111111111111111111111 , 将数字-1交给a时,因为a,b,c的类型为char类型即只有一个字节,所以a,b,c中只能储存一个字节(即8个比特位),所以需要进行截断只保留最后的8个比特位,所以此时a中储存的比特位为:11111111 (上图中有转换过程)。此时得到的是补码(因为整型数字在计算机中都是以补码形式存储)
  2. 以%d打印需要进行整型提升。a,b都是有符号数最高位为1,则在前面(最左边)补1得到:11111111111111111111111111111111. c为无符号数在前面(最左边)补0得到:00000000000000000000000011111111.
  3. 再转换成原码打印 。a,b原码:10000000000000000000000000000001(补码减一取反得到原码). c原码为:00000000000000000000000011111111(整数无符号数原码=反码=补码)。最终得到a=-1,b=-1,c=255

再看一个例子:

int main()

    char a = 3;
    char b = 127;
    char c = a + b;
    printf("%d\\n", c);
    return 0;

不细心的老铁一看c=130,但运行后结果是-126.为什呢?

结合下图分析:

我们可以分成几步来看:

  1. 数字3的补码为:00000000000000000000000000000011 , 将数字3交给a时,因为a的类型为char类型即只有一个字节,所以a中只能储存一个字节即8个比特位,所以需要进行截断只保留最后的8个比特位,所以此时a中储存的比特位为:00000011

    数字127的补码为:00000000000000000000000001111111 同理也因为为char类型发生截断,截断后b中储存的比特位为: 01111111

  2. 执行 a+b 时先对8比特位的a,b进行整型提升,因为都为char 类型所以为有符号位,提升时补最高位的数字0,补够32位。提升后两者的补码为:

    00000000000000000000000000000011
    00000000000000000000000001111111

    将a,b相加得到补码:

    00000000000000000000000010000010

  3. 又 c 为char类型,只能存放8个比特位,所以需要截断,截断后c 中储存的比特位为:10000010

  4. 再以%d形式打印,需要32位比特位,要对 c 进行整型提升了。因为c 的最高位是 1 在最高位前面补 1 即可,补够32位,提升后补码为:11111111111111111111111110000010

  5. 将补码转化为原码的形式打印出来,转化后的原码为 : 10000000 0 00000000000000001111110为负数,原码对应的整数就为 -126

4.整型提升的意义

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

以上是关于C语言整型提升的主要内容,如果未能解决你的问题,请参考以下文章

关于整型提升(C语言)

C语言整型提升

C语言 - 隐式类型转换

C语言中整型数组的每个元素在内存中是如何存放的

C语言,输入一个整数,从高位开始逐位分割并输出它的各位数字

C语言整型转换问题?