本文内容:计算机为什么用二进制,以及如何用二进制存储文字、图片、声音、视频。整数的二进制/八进制/十六进制表示及相互转换。四种整数类型(short/int/long/long long)的内存占用、取值范围。sizeof 运算符的使用。常见误区与代码风格建议。
计算机内部由无数个晶体管组成,它们就像一个个微小的开关,只有“开”(通电)和“关”(断电)两种状态。
这两种状态天然对应二进制的 1 和 0。
所有数据 —— 数字、文字、图片、声音、视频 —— 最终都会被转换成 0 和 1 的序列存储在计算机中。
计算机不能直接存储字母或汉字,只能存储数字。因此我们需要一张 编码表(字符集),为每个字符分配一个唯一的编号(码点),存储时存编号,显示时根据编号画出字形。
| 字符 | 十进制 | 二进制 (8位) |
|---|---|---|
A | 65 | 01000001 |
B | 66 | 01000010 |
C | 67 | 01000011 |
a | 97 | 01100001 |
b | 98 | 01100010 |
c | 99 | 01100011 |
0 | 48 | 00110000 |
1 | 49 | 00110001 |
2 | 50 | 00110010 |

文字存储就是查码表。计算机里存的是二进制编号,显示时根据字体引擎把编号画成可见字形。
一张图片由无数个极小的 像素(pixel)组成。每个像素用若干 bit 表示颜色。
图片存储 = 按像素网格记录每个像素的颜色值(二进制)。像素越密、颜色深度越大,图片越清晰,文件也越大。
声音本质是 声波(空气压强的连续变化)。计算机无法直接存储连续波形,而是 每隔很短时间测一次声波的振幅,并记录下来。这个过程叫做 采样。
为什么声音能用二进制存?因为振幅被离散化成了整数,计算机只需要存储这一串整数(二进制形式),播放时把整数转换回电压推动喇叭,就能大致还原原声。
| 数据类型 | 数字化方法 | 核心概念 |
|---|---|---|
| 文字 | 查码表(ASCII、GBK、Unicode / UTF-8) | 字符 → 编号 |
| 图片 | 分割成像素,记录每个像素的颜色值 | 像素 → RGB / 灰度 |
| 声音 | 对声波定时采样,记录振幅值 | 采样率、量化位数 |
| 视频 | 连续图片(帧) + 同步声音 | 帧率、压缩算法 |
C 语言允许我们直接在代码中写二进制、八进制、十六进制常量,编译器会自动转换成十进制数存储。
| 进制 | 前缀 | 数字范围 | 示例 | 对应的十进制 |
|---|---|---|---|---|
| 二进制 | 0b 或 0B | 0,1 | 0b1010 | 10 |
| 八进制 | 0(数字零) | 0~7 | 012 | 10 |
| 十六进制 | 0x 或 0X | 0~9, a~f | 0xA | 10 |
int a = 0b1010; // 二进制 1010 = 8+2 = 10
printf("%d\n", a); // 输出 10int b = 012; // 八进制 12 = 1×8 + 2 = 10
printf("%d\n", b); // 输出 10int c = 0xA; // 十六进制 A = 10
int d = 0x10; // 0x10 = 16(不是10!)
printf("%d %d\n", c, d); // 输出 10 16方法:按位权相加。位权从右往左依次是 2⁰, 2¹, 2², 2³, …
例子:0b1011
计算:1×2³ + 0×2² + 1×2¹ + 1×2⁰ = 8 + 0 + 2 + 1 = 11

记住二进制从右到左的权重:8 4 2 1。
例如 1101 = 8+4+0+1 = 13。
方法:除 2 取余一直除到商0为止,倒序排列。
例子:13 转二进制
13 ÷ 2 = 6 余 1
6 ÷ 2 = 3 余 0
3 ÷ 2 = 1 余 1
1 ÷ 2 = 0 余 1
从下往上读:1101
| 类型 | 典型大小 | 取值范围(有符号) | 占位符 |
|---|---|---|---|
short | 2 字节 | -32,768 ~ 32,767 | %hd |
int | 4 字节 | -2,147,483,648 ~ 2,147,483,647 | %d |
long | Windows 4 字节;Linux 64 位 8 字节 | 依系统 | %ld |
long long | 8 字节 | -9.22×10¹⁸ ~ 9.22×10¹⁸ | %lld |
因为默认整数类型是 有符号数(signed),最高位(最左边一位)被用来表示正负:0 为正,1 为负。
sizeof 运算符 —— 测量内存大小sizeof 可以测类型或变量占用的字节数。
printf("short: %zu\n", sizeof(short)); // 2
printf("int: %zu\n", sizeof(int)); // 4
printf("long: %zu\n", sizeof(long)); // 4 或 8
printf("long long: %zu\n", sizeof(long long)); // 8
int x;
printf("x 的大小: %zu\n", sizeof(x)); // 和 sizeof(int) 一样sizeof 的常见用途int arr[10];
int len = sizeof(arr) / sizeof(arr[0]); // 10malloc(10 * sizeof(int)); // 申请 40 字节| 错误现象 | 原因 | 正确写法 |
|---|---|---|
int a = 010; 以为是 10,结果是 8 | 前导 0 表示八进制 | 想写 10 就直接写 10 |
printf("%d", 0x10); 以为是 10 | 不熟悉十六进制 | 记住 0x10 = 16 |
short s = 50000; 输出负数 | 超出范围(溢出) | 改用 int |
printf("%d", long_var); 警告 | 占位符与类型不匹配 | long 用 %ld,long long 用 %lld |
sizeof 写成 sizeof int 不加括号 | 对变量可以不加括号,但对类型必须加 | sizeof(int) 或 sizeof x |
整数类型有四种,short int long 和 long long。进制前缀记清楚:0b 二进制,0 开头八进制,0x 十六进制。sizeof 测字节,范围匹配不溢出。无符号用 %u,有符号用 %d,long 对应 %ld,long long 用 %lld。
二进制基本原理 ──┬── 数据存储(文字/图片/声音/视频)
├── 进制写法(二、八、十六)
├── 进制转换(权相加、除2取余)
├── 整数类型(short/int/long/long long)
├── sizeof 运算符
└── 常见误区(溢出、前缀混淆、占位符错误)