编译器将unsigned short 整体提升int和unsigned short 在内存中的分配2byte的理解

简单的一句话总结:内存中固定占用2个字节是"物理存在",运算时提升为4字节(int)是"为了干活方便"。

为了让你彻底厘清,我们把这两个概念拆开看,再连起来理解:

1. 内存中的分配(2 Byte):这是"仓库"大小

当你定义 unsigned short a = 0xFFFF; 时,编译器在内存(RAM)中划出一块固定的空间:

  • 大小:2个字节(即16位)。

  • 存储内容 :存储的是纯二进制数据 11111111 11111111

  • 特性 :这块内存是静止的。无论你是把这个变量加100,还是把它赋值给别的变量,只要不重新赋值,这2个字节里的数据永远不变。

打个比方 :这就像你家里有一个小储物箱 ,尺寸固定为 长2cm × 宽2cm。里面永远只能放得下 0~65535 编号的标签。


2. 运算时的提升(转为 int):这是"工作台"大小

当你写代码 a + 1 时,CPU不能直接在内存的"储物箱"里做加法,必须把数据搬到CPU内部的"寄存器(工作台)"里才能计算。

  • 搬运过程 :CPU的寄存器(工作台)宽度通常为32位或64位。当CPU把16位的0xFFFF搬到32位寄存器时,为了保持数值不变,会在前面补上16个0,变成 0x0000FFFF(依然是65535)。

  • 为什么要补0(提升) :如果CPU用16位工作台计算 0xFFFF + 1,结果会变成 0x0000(溢出)。为了避免这种溢出,C标准规定先把数据扩展到寄存器原生宽度(32位)再算,这样 0x0000FFFF + 1 = 0x00010000(65536),中间结果不会丢失精度

打个比方 :你从"小储物箱"里取出标签,放到一个巨大的 "大办公桌"(int工作台)上展开。桌子很大(32位),标签放在桌上只占了中间一小块地方,周围全是空的。所有的加减乘除都在这个"大办公桌"上操作。


3. 把这两个概念连起来看(最关键)

很多人困惑的点在于:"既然是2个字节,为什么提到int(4个字节)?"

流程是这样的:

  1. (Load):CPU从内存的2字节仓库 中读出 0xFFFF

  2. 扩展 (Promotion):CPU把它展开成4字节0x0000FFFF,放入寄存器。

  3. 计算(Execute):用这个4字节的数据去加、减、比较。

  4. (Store):如果计算结果要存回 unsigned short 变量,CPU会把4字节结果截断 (砍掉高2字节),只把低2字节放回那个2字节的仓库里。


4. 为什么MISRA要求加 u 后缀(结合内存理解)

既然 unsigned short(无符号)提升为 int(有符号),那这个"大办公桌"的性质就变了。

  • 32位平台0xFFFF 变成 0x0000FFFF,最高位是0,视为正数,没问题

  • 16位平台 (嵌入式单片机):int 的工作台也是16位。unsigned short(16位)搬上工作台,恰好占满。但如果此时值是 0x8000(32768),放入16位 int 工作台时,最高位是1,这个值瞬间变成了负数(-32768)!

所以,MISRA要求你写 0xFFu

此时 0xFFu 的类型是 unsigned int。当它和 unsigned short 比较时,两边都是"无符号"属性。哪怕在16位机器上,它们都会被当作无符号数来处理,绝不会因为最高位是1而被误解成负数

相关推荐
XiaoQiao6669992 小时前
C 语言常用头文件及里面核心函数
c语言·开发语言
博界IT精灵3 小时前
C语言中的数据类型及其转换
c语言·开发语言
水饺编程4 小时前
编程数学:三角函数基础01,直角三角函数
c语言·c++·windows·visual studio
LuminousCPP4 小时前
数据结构-排序(一):基础排序算法横向对比|冒泡、插入、希尔、堆与双向选择,详解二分 / Knuth 增量
c语言·数据结构·笔记·算法·排序算法
初願致夕霞4 小时前
C/C++传统程序内存分布(代码实测)
java·c语言·c++
wuyk5555 小时前
从零吃透 MQTT 通信|第 6 章 MQTT 主题、过滤器、通配符、订阅管理、拒收机制详解与代码实现
c语言·stm32·学习
phltxy14 小时前
C语言操作符详解
java·c语言·算法
RuoZoe15 小时前
从 2026 年 3 月 1 日开源,到 26.10.9:Jalium UI 半年时间到底走了多远?
c语言·c++
知无不研18 小时前
c语言中循环的介绍与简单应用
c语言·开发语言·算法·循环·for·while