C语言整型提升

欠伸展肢体,吟咏心自愉。这篇文章主要讲述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;

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

文章图片

分析如图:
C语言整型提升

文章图片

我们可以分成几步来看:
  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.为什呢?
C语言整型提升

文章图片

结合下图分析:
C语言整型提升

文章图片

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

    推荐阅读