关于”整型提升“的浅薄解释

整型提升是什么:

性质

"整型提升" 是C语言程序设计中的一项规定。即——在进行表达式计算时,先将涉及的相关整型转换(提升)成int(整型)类型 或 unsigned int(无符号整型)类型。

为什么会有整型提升:

📉原因

整型运算要在CPU内的运算器件执行,CPU中整型运算器(ALU)的操作数的字节长度一般就是int的字节长度(4字 节),同时也是CPU的通用寄存器的长度。因此,即使两个char类型(1字节)的数相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度4字节之后才执行运算操作。

整型提升的规则:

若变量类型为unsigned(无符号)类型,则在内存中存储的二进制补码前添‘0’,直至补齐32位。

若变量类型为signed类型,则在内存中存储的二进制补码前添该二进制补码最高位(不一定是符号位),直至补齐32位。

即——遵循什么提升规则是看变量本身的类型,而不是输出类型

整型提升的实际运用:

📂例1:

#include<stdio.h>
int main()
{
    unsigned char a = 200;
    unsigned char b = 100;
    unsigned char c;
    c = a + b;

    printf("%d\n",a+b);
    printf("%d\n",c);
    return 0;
}

🎅分析:

  1. 首先写出 a 和 b的值在内存中存储的二进制补码,由于是正数,原码 反码 补码相同。

内存中:

00000000 00000000 00000000 11001000 --- 200

00000000 00000000 00000000 01100100 --- 100

变量类型中:

11001000 --- a

01100100 --- b

  1. a + b 是计算过程,直接对a和b的二进制补码执行运算操作,存储在内存中,内存有32位,所以a+b的二进制补码有32位

c 存储的是a+b的计算结果,但该结果不是存储在内存中,而是存储在已经声明了类型的变量(即unsigned char c)中,即c的二进制补码只有8位存储空间,只存储 a+b 的二进制补码结果的前8位,高位舍弃

因此可以认为二者的二进制补码存储格式分别为

00000000 00000000 00000001 00101100 ——> a+b

-------- -------- -------- 00101100 ——> c (只有8位

存储后的二进制数都是补码!

  1. 变量a,b,c是unsigned char类型,而输出是整型

!!当变量类型输出类型不同时,要对变量进行整型提升

如何进行整型提升规则要看该变量在定义时的类型是否是unsigned类型:

若是unsigned型,则求得的补码等于原码,直接输出

若不是,则要将求得的补码转换成原码再输出


因为a+b都是unsigned char 型,故整型提升时在最高位前补‘0’ 且unsigned类型求得补码即原码:

00000000 00000000 00000001 00101100 ——> a+b

故unsigned char (a+b)以%d形式输出值为300

——————————————————————————————————————————

因为 c 是unsigned char 型,故整型提升时在最高位前补‘0’ 且unsigned类型求得补码即原码:

00000000 00000000 00000000 00101100 ——> c (补齐32位)

故unsigned char c以%d形式输出值为 44


📂例2:

int main()
{
    char a = 128;
    printf("%u\n", a);
    printf("%d\n", a);

//分析:
//00000000 00000000 00000001 00000000   char128
//11111111 11111111 11111111 00000000   提升后
// 
//%u:
//11111111 11111111 11111111 00000000  
//输出————  4294967168
//%d:
//11111111 11111111 11111111 00000000             补码
//11111111 11111111 11111110 11111111             反码 == 补码-1
//10000000 00000000 00000001 00000000             原码 == (对反码进行取反)
//输出——   -128
    return 0;
}

📂例3:

#include<stdio.h>
int main()
{
    unsigned char  b = 200;
    printf("%d\n",b);
    printf("%u\n",b);

//分析:
//00000000 00000000 00000000 11001000    200
//                           11001000    b
//00000000 00000000 00000000 11001000    unsigned char  b正数
//                                       以%d %u输出的补码均是原码,输出都是200
return 0;
}

📂例4:

#include<stdio.h>
int main()
{
    signed char  c = 200;
    printf("%d\n", c);
    printf("%u\n", c);

//分析:
//00000000 00000000 00000000 11001000    200
//                           11001000    c
//11111111 11111111 11111111 11001000    提升后:signed char c 补码
//
//  %d :> 将最高位看作符号位,补码为负,要转换
//11111111 11111111 11111111 11001000    补
//11111111 11111111 11111111 11000111    反
//10000000 00000000 00000000 00111000    原
// 输出:-56
// 
// 
//  %u :> 将最高位看作数值位,则补码等于原码
// 11111111 11111111 11111111 11001000    即为原码
// 输出:4294967240
return 0;
}

总结:

发生整型提升的简略过程:

首先写出对应变量的‘值’的二进制补码,

然后根据变量在定义时的类型,截取对应类型的字节长度的二进制补码

再看变量类型是否是unsigned型,是则在截取后的值的最高位前补‘0’,至补齐32位;不是则用截取后的值的最高位补齐32位。补齐后求得待输出的值的补码

最后根据输出类型判断求得的补码的最高位是符号位还是数值位,转换成原码后输出

求值”——“截取”——“提升”——“输出

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值