C语言uint16_t存储负数的陷阱:从二进制补码到类型提升的深度解析
1. 问题现象:为什么-1变成了65535?
在嵌入式开发中,我遇到过这样一个令人困惑的场景:当尝试用uint16_t类型存储一个int类型的负数时,读取出来的值竟然变成了65535。比如下面这段代码:
#include <stdio.h>
#include <stdint.h>
int main() {
int value = -1;
uint16_t unsigned_value = (uint16_t)value;
printf("The unsigned value is: %u\n", unsigned_value); // 输出65535
return 0;
}
这个现象看似违反直觉,但背后隐藏着C语言类型系统和二进制表示的深层原理。要理解这个问题,我们需要从计算机如何表示负数开始讲起。
2. 补码:计算机表示负数的秘密
现代计算机系统普遍采用二进制补码(Two's Complement)来表示有符号整数。这种表示方法有三个关键特点:
- 最高位为符号位:0表示正数,1表示负数
- 正数的补码与原码相同
- 负数的补码是其绝对值的原码取反后加1
让我们以16位整数为例:
| 数值 | 二进制表示(16位) |
|---|---|
| 1 | 00000000 00000001 |
| -1 | 11111111 11111111 |


被折叠的 条评论
为什么被折叠?



