当前位置: 首页 > news >正文

C语言中的整型提升

整型提升

什么是整型提升?为什么要使用整型提升?整型提升是如何进行的?

1.整型提升

在c语言中,一些表达式在求值的过程中,操作数可能需要转换为其他类型,这种转换,我们程序员是看不见的,称其为隐式类型转换,而整型提升就是之一

1.1什么是整型提升

在C语言中计算整数的时候,会将整型家族中小于4字节的类型(char ,short),自动变为4字节也就是int类型,而这个自动转换的过程,我们称作整型提升

1.2为什么使用整型提升

使用原因和硬件有关,CPU中负责整数运算的部件整数运算器ALU以及通用寄存器,能够一次性处理的数据的大小为4byte也就是32位的二进制数,刚好是C语言中一个int的大小(这是32位cpu的一次性处理数据的大小,64位是8字节),为了能保证CPU的高效运算,C语言会默认把小于四个字节的整型数据提升到四个字节(64位的CPU同样会先提升到int,而int在主流编译器中依旧是4字节,不知道有没有8字节的,无论是32位CPU还是64位CPU,只有当操作数本身无法用int存放时,才会使用更长字节的整型)

举个例子
long long a = 100;
int b = 200;
long long c =a + b;
//此时,我们在计算a+b时,编译器就会对b进行整型提升,以便于和8byte的long long 类型计算
char d = 20;
b = d + b;
//同理在计算d+b时,会对d进行整型提升,提升为四字节的int
1.3截断

你可能会问,如果上面的例子中我c不是long long类型怎么办,计算结果是8byte难道我用int型也能装下吗?
并非如此,因为此时会发生截断。

1.3.1什么是截断

在数据类型中,大字节数的数值放到小字节数的变量中时,超出变量存储范围的二进制位(高位)将会被直接丢弃,这个行为被称为截断

举个例子
char a = 10;
int b = 10;
int c = 10;
a = b + c;
//此时就会发生截断
//00000000 00000000 00000000 00010100  20的32位补码
//当放进1byte的char中时,会发生截断,变为00010100,但结果依旧是20
但是,当被截断的数值过大,就有可能会导致数值丢失

2.整型提升的过程

对于有符号数,符号位为1时(负数),在补码的高位补1,直至补到想要提升到的字节数(bit位数)
对于有符号数,符号位为0时(正数),在补码的高位补0,直至补到想要提升到的字节数(bit位数)
对于无符号数,在补码的高位补0,直至补到想要提升到的字节数(bit位数)

举个例子
#include<stdio.h>
int main(void)
{char a = 0;int b = 10;int c = 10;a = b + c;printf("%d",a);return 0;
}
//b+c的值为20,补码为00000000 00000000 00000000 00010100
//赋值给a时,会发生截断,所以a存的补码为00010100,但值依旧是20
//由于printf函数在打印时打印的是int,但a却是char,此时会发生整型提升
//20是正整数(char默认为signed char),所以在高位补0,补码为00000000 00000000 00000000 00010100
再举一个例子
#include<stdio.h>
int main(void)
{char a = 0;int b = 100;int c = 100;a = b + c;printf("%d",a);return 0;
}
//此时计算结果为200,补码为00000000 00000000 00000000 11001000
//赋值给a,发生截断,补码为11001000
//由于a为signed char,所以最高位为符号位
//当我们将它以int类型打印时,会发生整型提升,最高位为1,我们补1
//11111111 11111111 11111111 11001000  补码
//原码就等于补码加1再按位取反(先求反码和直接求补码的结果是一样的,区别就是一个减一取反,一个取反加一)
//10000000 00000000 00000000 00111000(记住符号位不变)原码
我们发现此时的结果变为了-56

上面的例子数据就发生了问题,原本是200,结果变成了-56,这也是使用整型提升时要注意的

http://www.jsqmd.com/news/35850/

相关文章:

  • 完整教程:Hive 知识点梳理
  • OZI-Project代码注入漏洞分析与修复方案
  • 创建第一个pygame游戏窗口
  • 常量的二元图景:C 语言的刚性契约与 Python 的柔性表达
  • Swift 进行验证码识别:集成 Tesseract OCR
  • 700.二叉搜索树中的搜索(二叉树算法) - 实践
  • egg-passport 的原理, 是否依赖数据库
  • P10194 [USACO24FEB] Milk Exchange G 做题记录
  • egg-sequelize 原理, 访问 sequelize 的方式, 支持情况
  • 创建conda环境时将要安装的一些软件包分析
  • 图书馆管理系统需求规格说明书
  • 含错方程与非线性滤波模型的逼近攻击
  • 重生之我在大学自学鸿蒙构建第一天-《基础篇》
  • 点云配准基础知识
  • 完整教程:Android监听第三方播放获取音乐信息及包名
  • git的各种HEAD以及使用示例
  • OneDrive上传和下载速度慢?有什么解决办法吗? - 指南
  • 详细介绍:深入浅出MATLAB数据可视化:超越plot()
  • 既然道可道相当道,那么传道授业解惑的根基是什么?
  • P10592 BZOJ4361 isn
  • 阿道夫
  • 软件开发公司常犯的5个设计误区,看看你中招了吗?
  • 使用jmeter做压力测试 - 实践
  • CSP2025游记总结
  • 连续出现的字符
  • 详解WebSocket及其妙用 - 指南
  • 2025 csp_j 游忌
  • 利用序列ID漏洞下载整个公司用户数据库的技术分析
  • 详细介绍:STM32 定时中断逻辑拆解:为什么 “每 2 次中断翻一次 LED”,却是 1 秒亮 1 秒灭?
  • 11.8 NOIP模拟4 改题记录