news 2026/5/28 23:43:28

【每周分享】C语言的整型提升是什么概念

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【每周分享】C语言的整型提升是什么概念
在介绍C语言的整型提升概念之前,我们先来看一段实际的代码例子和仿真结果。
主要代码如下:
复制
  1. intmain()
  2. {
  3. unsignedchari=0;
  4. unsignedchartemp=0;
  5. unsignedchardat=0x89;
  6. unsignedcharSER=0;
  7. printf("===========method 1=============\r\n");
  8. //方式1
  9. dat=0x89;
  10. for(i=0; i<8; i++)
  11. {
  12. temp = dat<<i;
  13. SER = temp>>7;
  14. printf("%d\r\n", SER);
  15. }
  16. printf("===========method 2=============\r\n");
  17. //方式2
  18. dat=0x89;
  19. for(i=0; i<8; i++)
  20. {
  21. SER = dat >>7;
  22. dat<<=1;
  23. printf("%d\r\n", SER);
  24. }
  25. printf("===========method 3=============\r\n");
  26. //方式3
  27. dat=0x89;
  28. for(i=0; i<8; i++)
  29. {
  30. SER = (dat<<i)>>7;
  31. printf("%d\r\n", SER);
  32. }
  33. return0;
  34. }
上面的代码主要是为了实现获取8位无符号数据dat的每一位并写入SER和打印出来,理论上分析似乎都可以实现吧?我们来实际运行看下结果:

但从上面的实际运行结果来看,只有方式1和方式2的结果是符合预期的,方式3的结果为什么是这样的呢?这是为什么呢?估计很多同仁就比较喜欢以这样一步到位的方法实现功能代码。其实在这里,就涉及到了C语言的整型提升的概念。
如果把代码段:
复制
  1. SER= (dat<<i)>>7;
改成:
复制
  1. SER = (unsigned char)(dat<<i)>>7;//显式类型转换

再运行看下:

这个时候方式3的代码执行结果也符合预期了。
如果再把代码段:
复制
  1. SER= (dat<<i)>>7;
改成:
复制
  1. SER = (unsigned int)(dat<<i)>>7;//显式类型转换
再运行看下:

这个时候就和第一次运行的结果一样了,也是不符合预期的。
然后在KeilMCU中运行的结果也是如此:

通过以上的代码和实测对比,估计很多同仁应该知道了何为整型提升了。
接下来我们就从理论上说一下C语言的整型提升吧,也算是再复习一次。
C语言整型提升(Integer Promotion)的原意是一种隐式类型转换规则,它规定了在表达式中当不同类型的数据进行运算时,较小的整型数据类型会自动转换为较大的整型数据类型。
为什么需要整型提升呢?主要基于下面三个方面的考虑:
效率考虑:CPU通常对int大小的数据操作效率最高;
避免溢出:提升到更大的类型可以减少中间结果溢出的风险;
一致性:确保表达式求值结果的一致性,不受平台差异影响。
那整型提升一般会发生在哪些情况呢?主要包括如下:
当一个表达式中包含比int小的整数类型(如char、short等)时;
在使用位运算符(~、&、|、^)时;
在使用算术运算符(+、-、*、/)时。
提升规则主要如下:
如果原始类型的所有值都可以用int表示,则转换为int;
否则转换为unsignedint。
在代码语句SER= (dat<<i)>>7; 中,涉及了先左移后右移运算,系统按照规则判断dat的最高位是有用的,所以在执行dat<<i时,将dat的最高位保留了。比如dat<<1的值其实变成了unsigned int类型的0000 0001 0001 0010,整个过程通过下图一目了然:

如果在语句前面加了显示类型强制转换unsigned char,则dat<<1变成了0001 0010,再右移7位后,即为0,与预期结果符合。
综上所述,虽然有时候将几条运算语句合并成一条语句执行运算的操作能够精简代码量,但是因为C语言在数据类型转换这块,其实是比较复杂的,对于类似这种多个运算符参与的逻辑运算,分开多条语句实现比全部用一条语句实现更好,不仅代码可读性更强,也不容易出错。如果你确实需要一步到位,那一定要将变量的数据类型定义正确,或者掌握并灵活运用C语言的显式类型转换和隐式类型转换,否则在项目开发上你一定会吃大亏的~~。
因此,理解整型提升对于避免C语言中的一些微妙错误非常重要,特别是在涉及位操作和混合类型运算时。


---------------------
作者:dffzh
链接:https://bbs.21ic.com/forum.php?mod=viewthread&tid=3477066&_dsign=775d7d07
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 23:43:28

自媒体人必看:OpenClaw+Gemma-3-12b-it全平台内容一键分发方案

自媒体人必看&#xff1a;OpenClawGemma-3-12b-it全平台内容一键分发方案 1. 为什么我需要自动化内容分发 作为一个小型工作室的内容负责人&#xff0c;我每天需要将同一篇文章同步发布到微信公众号、知乎和头条号三个平台。最让我头疼的不是写作本身&#xff0c;而是每个平台…

作者头像 李华
网站建设 2026/5/23 2:05:00

如何用Kafka和RabbitMQ打造高并发的消息推送中台?实战经验分享

高并发消息推送中台实战&#xff1a;Kafka与RabbitMQ的架构抉择 当App的日活突破百万量级&#xff0c;每秒数千条推送通知涌向用户设备时&#xff0c;技术团队往往会面临一个关键抉择&#xff1a;该用Kafka还是RabbitMQ作为消息引擎的脊柱&#xff1f;三年前我们重构电商大促系…

作者头像 李华
网站建设 2026/5/23 2:05:13

OBS-NDI插件完全配置指南:从依赖解决到多场景应用

OBS-NDI插件完全配置指南&#xff1a;从依赖解决到多场景应用 【免费下载链接】obs-ndi DistroAV (formerly OBS-NDI): NDI integration for OBS Studio 项目地址: https://gitcode.com/gh_mirrors/ob/obs-ndi 问题导入&#xff1a;为什么你的OBS直播总是遇到设备连接难…

作者头像 李华
网站建设 2026/5/23 2:05:13

从模型到文档:基于快马ai实现solidworks设计数据自动下游处理

在机械设计领域&#xff0c;SolidWorks作为主流的三维建模工具&#xff0c;经常需要将设计数据转化为下游生产文档。最近我在一个设备开发项目中&#xff0c;就遇到了如何高效处理装配体数据的问题。传统手工整理零件清单、计算材料用量、编写采购单和装配说明的过程既耗时又容…

作者头像 李华
网站建设 2026/5/26 8:38:33

HoRain云--Julia流程控制全解析:从基础到协程

&#x1f3ac; HoRain云小助手&#xff1a;个人主页 &#x1f525; 个人专栏: 《Linux 系列教程》《c语言教程》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 推荐 前些天发现了一个超棒的服务器购买网站&#xff0c;性价比超高&#xff0c;大内存超划算&#xff01;…

作者头像 李华