编译器将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而被误解成负数

相关推荐
inrichtt5 小时前
第八课时:SPI总线揭秘:四线全双工通信的奥
c语言·数据结构·stm32·单片机·嵌入式硬件
wuminyu9 小时前
JMM学习总结:深入理解happens-before关系
java·linux·c语言·jvm·c++
Zwawa11 小时前
让电机走到指定位置:编码器位置环 PID
c语言·单片机·嵌入式
fensnote12 小时前
西门子 S7 PLC 内部寄存器读写 Demo(C 语言)
c语言·开发语言
Logic10114 小时前
C语言/数据结构位运算题解:异或XOR找出被挑选一次的果子编号——只出现一次的数字
c语言·数据结构·算法·数组·位运算·时间复杂度·空间复杂度
dear_bi_MyOnly15 小时前
栈和队列:从原理到应用全解析
c语言·开发语言·c++·学习·分类
从小白到软工16 小时前
4-3 项目-学生成绩管理系统(上)
c语言·开发语言·数据结构·经验分享·ai编程
Code_Solitude17 小时前
c语言:指针(3)+冒泡排序
java·c语言·算法
巴巴媛66617 小时前
【Debug1】程序死机,while(1)循环,怎么办?
c语言·笔记·stm32·嵌入式硬件·bug
Lxx_Zw17 小时前
PID 用顺了,然后呢:增强手术与前馈
c语言·stm32·单片机·嵌入式硬件