计算机基础:bit/byte/KB/MB/GB 与 int/float/指针的空间占用(速查模板)
0. 这篇文章解决什么问题
当你在看性能、网络协议、文件格式、C/C++ 数据结构、对齐与缓存时,最常见的“基础卡点”就是两件事:
- 单位:bit/byte 怎么换?KB/MB/GB 到底是 1000 还是 1024?
- 类型占用:
int/float/double/指针到底占多少字节?为什么同一份代码在不同机器/编译器下会不一样?
本文目标:把这些变成一张“随手查”的速查表 + 一套“在代码里验证”的方法。
1. bit 与 byte:最基础的两条规则
- 1 byte = 8 bit
- **bit(b)**常用于带宽/速率:例如
100 Mb/s(兆比特每秒) - **byte(B)**常用于容量/大小:例如
100 MB(兆字节)
1.1 常见误读
Mb不是MB:前者是 megabit,后者是 megabyte- 带宽宣传常用 十进制(1000 体系),而操作系统文件大小显示有时更接近 二进制(1024 体系)或直接标为 GiB/MiB
2. KB/MB/GB:十进制与二进制两套体系
2.1 十进制(SI)单位:常见于磁盘/网络厂商标注
- 1 KB = 1000 B
- 1 MB = 1000 KB = 10^6 B
- 1 GB = 1000 MB = 10^9 B
- 1 TB = 10^12 B
2.2 二进制(IEC)单位:常见于内存/操作系统语境
- 1 KiB = 1024 B = 2^10 B
- 1 MiB = 1024 KiB = 2^20 B
- 1 GiB = 1024 MiB = 2^30 B
- 1 TiB = 2^40 B
2.3 速查表(建议截图收藏)
| 名称 | 十进制 | 二进制 |
|---|---|---|
| 1 KB / 1 KiB | 1000 B | 1024 B |
| 1 MB / 1 MiB | 1,000,000 B | 1,048,576 B |
| 1 GB / 1 GiB | 1,000,000,000 B | 1,073,741,824 B |
2.4 一个特别常用的换算:Mbps 到 MB/s
由于 1\text{ Byte}=8\text{ bit},所以:
- \text{MB/s} \approx \text{Mb/s} \div 8 (先不考虑协议开销)
例子:
- 100 Mb/s ≈ 12.5 MB/s
- 1 Gb/s ≈ 125 MB/s
3. “类型占用”到底由什么决定
你看到的 sizeof(T) 主要取决于:
- 目标平台:尤其是 32 位 vs 64 位(指针大小差异最大)
- 编译器 ABI:例如 LP64、LLP64 等数据模型
- 类型本身的规范:例如 IEEE-754 浮点(
float常见 4B,double常见 8B) - 对齐与填充:结构体里会为了对齐插入 padding,导致“字段相加 ≠ sizeof(struct)”
4. 常见 C/C++ 基础类型占用(经验值)
4.1 “几乎所有现代平台都这样”的部分
| 类型 | 常见大小 | 说明 |
|---|---|---|
char |
1 B | 标准只保证 sizeof(char)==1 |
float |
4 B | 多数平台 IEEE-754 binary32 |
double |
8 B | 多数平台 IEEE-754 binary64 |
4.2 容易变化的部分(一定要以 sizeof 为准)
下表是“常见 ABI 下的经验值”,不是语言标准承诺。
| 类型 | 32 位(常见) | 64 位(Linux/macOS 常见 LP64) | 64 位(Windows 常见 LLP64) |
|---|---|---|---|
short |
2 B | 2 B | 2 B |
int |
4 B | 4 B | 4 B |
long |
4 B | 8 B | 4 B |
long long |
8 B | 8 B | 8 B |
指针 T* |
4 B | 8 B | 8 B |
size_t |
4 B | 8 B | 8 B |
5. 指针“占用 8 字节”到底意味着什么
以 64 位平台为例,T* 常见 8 字节,代表:
- 它只是一个地址值的存储空间(能表示更大的虚拟地址范围)
- 不等于“它指向的对象占用 8 字节”
- 指针相关的常见误区:
sizeof(p)是指针大小(4 或 8),不是数组/对象大小sizeof(*p)才是它指向的类型大小- 数组在表达式里常“退化”为指针,但
sizeof(arr)仍然是数组总字节数(在同一作用域里)
6. 在代码里自检:一段最小可运行模板
把下面这段放到任意 C++ 工程里跑一下,你会立刻得到“你当前环境”的真实答案:
1 |
|
如果你写的是 C,也可以用 printf("%zu\n", sizeof(...)) 输出。
7. 结构体的大小:对齐(alignment)与填充(padding)
7.1 一个典型例子
1 | struct A { |
直觉相加:1+4+2=7 字节,但实际 sizeof(A) 往往是 12(也可能是 8/16,取决于 ABI 与对齐规则)。
原因:多数平台要求 int 按 4 字节对齐,编译器会在 c 后面插入 padding;结构体整体也会 padding 到最大对齐倍数,方便数组元素对齐。
7.2 实用建议
- 要“确定布局”,优先用固定宽度整数:
uint32_t、int16_t - 序列化/网络协议不要直接
memcpy(struct)(除非你完全控制 ABI、对齐、端序,并且写了静态断言)
8. float 与 int:除了大小,还差在“表示范围与精度”
这篇以“占用”为主题,但你通常也会顺带踩到:
int32_t是 离散整数,每个值精确float是 浮点近似,很多小数无法精确表示
建议你在后续文章(或本篇扩展)加入:
float的有效精度约 6~7 位十进制double的有效精度约 15~16 位十进制- 典型坑:
0.1 + 0.2 != 0.3(比较时用误差阈值)
9. 可选扩展(你可以按需要补充)
- 9.1 端序(Endianness):网络字节序与本机字节序
- 9.2 缓存行(cache line):结构体布局对性能的影响
- 9.3 malloc/new 与对象头:实际内存占用不等于
sizeof(T) - 9.4 对齐控制:
alignas、#pragma pack(以及它们的风险)
10. 小结(可直接作为结尾)
- bit/byte 是 8 倍关系,KB/MB/GB 存在 1000 与 1024 两套体系
int/long/指针的大小会随平台 ABI 变化,最稳妥的方式是:用sizeof验证 + 用固定宽度类型表达协议/文件格式- 结构体的真实占用要考虑 对齐与填充
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Never Settle!
评论
