这个专栏不从“如何画逻辑门电路”开始,而是从 C/C++ 程序员每天都在用、却容易一知半解的几个关键问题出发:
- 一个值在机器里到底长什么样?
- 为什么有 32 位、64 位之分,它们影响了什么?
- 为什么有的
int溢出直接绕回去了? - 为什么
0.1 + 0.2在机器里算不出“刚好是 0.3”? - 结构体的成员顺序为什么会影响内存占用?
每篇文章都尽量和实际 C/C++ 代码、调试器里的现象对应起来,成为 C++ 基础 / 类型系统 / 指针 / RAII 等专栏的“底层配套讲义”。
第一部分:比特、字节与进制
- 比特与字节:最小存储单位
- 把内存类比成一块巨大的字节数组:地址是下标,字节是格子,bit 是格子里的 8 个小灯;连接到
sizeof的直观含义。
- 把内存类比成一块巨大的字节数组:地址是下标,字节是格子,bit 是格子里的 8 个小灯;连接到
- 二进制、十六进制与人眼友好的表示 (🚧 计划中)
- 进制转换的直觉理解(不做刷题式练习),为什么调试器喜欢用十六进制;如何从转储的十六进制中看出整型/指针/字符的大致形状。
- 字长与机器字:8/16/32/64 位到底指什么 (🚧 计划中)
- CPU 位宽的直观含义;寄存器宽度、一次运算/一次访存能处理的位数;
int/指针大小与字长之间的关系。
- CPU 位宽的直观含义;寄存器宽度、一次运算/一次访存能处理的位数;
第二部分:整数的机器表示
- 无符号整数:自然数的二进制表示 (🚧 计划中)
0、1、255在一个字节里的二进制形态;std::uint8_t、unsigned int的取值范围;模 2^N 加减法的直观模型。
- 有符号整数与补码 (Two's Complement) (🚧 计划中)
- 正数与负数的编码方式;原码/反码/补码对比但不死记;以 8 位/16 位为例推导 -1、-128、-32768 的机器表示;为什么整数加减在硬件里可以统一处理。
- 整数溢出:从二进制加法看 undefined behavior (🚧 计划中)
- 有符号溢出 vs 无符号“环绕”;
std::size_t与int混算的经典坑;结合《C++ 类型系统速览:从 int 到 auto》中的日志计数示例,画出真实的二进制过程。
- 有符号溢出 vs 无符号“环绕”;
第三部分:浮点数与实数近似
- IEEE 754 浮点数总览:float / double 是怎么存的 (🚧 计划中)
- 符号位、指数位、尾数位的概念;以
float为例手算一个简单值的编码;为什么 0.1 无法被精确表示。
- 符号位、指数位、尾数位的概念;以
- 舍入误差与比较策略 (🚧 计划中)
0.1 + 0.2经典例子在二进制层面的具体原因;==比较的风险;ε 比较(almostEqual)的直觉解释;和 C++ 类型系统文章中的示例双向链接。
- 特殊值:±0、NaN 与无穷大 (🚧 计划中)
- IEEE 754 中的特殊编码;
1.0 / 0.0、0.0 / 0.0等表达式在机器和 C++ 中的行为。
- IEEE 754 中的特殊编码;
第四部分:内存、地址与对齐
- 线性地址空间与字节地址 (🚧 计划中)
- 把内存想象成一条有门牌号的街;指针就是门牌号;32 位与 64 位进程的可寻址空间上限;从
sizeof(void*)看指针大小。
- 把内存想象成一条有门牌号的街;指针就是门牌号;32 位与 64 位进程的可寻址空间上限;从
- 对齐 (Alignment) 与结构体布局 (🚧 计划中)
- 为什么
struct的大小可能大于成员之和;典型例如struct { char c; int i; };的内存排布;编译器插入填充字节(padding)的直观示意图。
- 为什么
- 大小端这点事:字节顺序为什么能坑你一整天
- 同样的
0x12345678,放进内存里可能长成两种样子;小端 / 大端、网络字节序与主机字节序,顺手把那些“写文件/发结构体”的坑点也点出来。
- 同样的
第五部分:指针大小、类型与地址空间
- 指针的本质:带类型的地址 (🚧 计划中)
- 回顾 C/C++ 中的指针概念;为什么
int*和double*在机器里大小相同但含义不同;和《C++ 指针入门》专栏的关系。
- 回顾 C/C++ 中的指针概念;为什么
- 32 位与 64 位程序中的指针差异 (🚧 计划中)
- 指针大小变化对内存占用、数据结构(如链表、树、哈希表)空间效率的影响;何谓“指针膨胀”。
- 虚拟内存的直观模型 (🚧 计划中)
- 只讲“地址空间”的直觉,不深入到页表实现:进程看到的是一条连续的地址线,实际上由操作系统映射到物理内存与磁盘。
第六部分:与 C++ 类型系统的连接
- 从机器视角重新看 C++ 基本类型 (🚧 计划中)
- 把
int/long long/std::size_t等映射回本专栏讲过的“位宽”和“补码”;如何根据平台特性选择合适的整数类型。
- 把
- 从补码到有符号/无符号混用的坑 (🚧 计划中)
- 用本专栏中的二进制图示重新解释《C++ 类型系统速览》中的
std::size_t日志示例、int与unsigned int比较示例。
- 用本专栏中的二进制图示重新解释《C++ 类型系统速览》中的
- 浮点实现与 C++ 行为的对应关系 (🚧 计划中)
- 把
0.30000000000000004背后的 IEEE 754 表示画出来,解释为什么 C++ 代码里推荐用误差区间来比较。
- 把
阅读建议:
- 如果你已经在看 C++ 基础 / C++ 类型系统速览,可以把本专栏当作“遇到概念就回来翻一眼”的参考手册。
- 如果你刚从 C 语言课堂走出来,不想被复杂电路图吓到,也可以直接从这里开始,先把“数据是如何被表示和存储”的那条线走通。