本课时有配套视频讲解,购买后即可观看(永久有效)
计算机编码
一、课上练习
编程练习
二、知识总结
✨ 计算机编码的核心思想
编码是信息处理中的基本操作:
- 广义:把信息从一种格式转换为另外一种格式
- 狭义:把信息用二进制数表示
- 作用:方便存储、传输、解析
编码的主要分类:
- 数字编码:用二进制表示数字(原码、反码、补码)
- 字符编码:用二进制表示字符(ASCII、Unicode)
- 多媒体编码:用二进制表示图像、音频、视频
- 压缩编码:减小数据体积的编码方式
✨ 数字编码
计算机内部使用原码、反码和补码三种方式来表示数字。正数的三种编码完全相同,区别在于负数的表示方式。
原码
原码是最直观的二进制表示方式:
- 正数的原码就是其二进制表示
- 负数的原码是在正数的原码基础上将最高位变成 1
以 8 位原码为例:
| 编码类型 | 数值 | 编码 |
|---|---|---|
| 原码 | 5 | 00000101 |
| 原码 | -5 | 10000101 |
反码
反码的规则如下:
- 正数的反码就是其二进制表示(与原码相同)
- 负数的反码是将其对应正数的二进制每一位都取反
以 8 位反码为例:
| 编码类型 | 数值 | 编码 |
|---|---|---|
| 反码 | 5 | 00000101 |
| 反码 | -5 | 11111010 |
补码
补码是计算机中最常用的数字编码方式:
- 正数的补码就是其二进制表示(与原码相同)
- 负数的补码是其反码加 1
以 8 位补码为例:
| 编码类型 | 数值 | 编码 |
|---|---|---|
| 补码 | 5 | 00000101 |
| 补码 | -5 | 11111011 |
三种数字编码总结
记忆口诀:
- 正数三码均相同
- 原码负数最左边(最高位置 1)
- 反码正负恰相反(逐位取反)
- 补码负数反加一(反码 + 1)
以 8 位编码为例,完整对比如下:
| 编码类型 | 数值 | 编码 |
|---|---|---|
| 原码 | 5 | 00000101 |
| 原码 | -5 | 10000101 |
| 反码 | 5 | 00000101 |
| 反码 | -5 | 11111010 |
| 补码 | 5 | 00000101 |
| 补码 | -5 | 11111011 |
✨ 位运算
位运算是对二进制数中的位进行操作的方式,是计算机内部高效的运算方式。可以与赋值运算符结合成为位运算赋值运算符。
| 运算 | 符号 | 操作 | 含义 | 示例 |
|---|---|---|---|---|
| 与 | & | 逐位与(双目) | 两个对应位都为1时为1 | 5 & 6 = (100)₂ = 4 |
| 或 | `\ | ` | 逐位或(双目) | 两个对应位中有一个为1时就为1 |
| 异或 | ^ | 逐位异或(双目) | 两个对应位不同时才为1 | 5 ^ 6 = (011)₂ = 3 |
| 取反 | ~ | 逐位非(单目) | 将补码中的0和1全部取反 | ~5 = -6,~(-5) = 4 |
| 左移 | << | 逐位左移(双目) | 将二进制向左移动 i 位 | 5 << 1 = (00001010)₂ = 10 |
| 右移 | >> | 逐位右移(双目) | 将二进制向右移动 i 位 | 5 >> 1 = (00000010)₂ = 2 |
✨ 字符编码
字符编码用于将字符映射为数字,常见的字符编码标准包括:
| 编码标准 | 覆盖范围 | 编码数量 | 说明 |
|---|---|---|---|
| ASCII | 英文字母、数字、符号 | 128 个 | 最基础的字符编码,1 个字节 |
| GBK | 简体中文 | 约 21000 个汉字 | 国标编码,2 个字节表示一个汉字 |
| BIG5 | 繁体中文 | 约 13000 个汉字 | 港台地区使用 |
| Unicode | 世界上大多数文字 | 超过 14 万字符 | 统一码,UTF-8/UTF-16/UTF-32 是其编码方案 |
ASCII 常用编码值:
| 字符 | ASCII 值 | 字符 | ASCII 值 | 字符 | ASCII 值 |
|---|---|---|---|---|---|
\0(空字符) | 0 | 0 | 48 | A | 65 |
| 空格 | 32 | 9 | 57 | Z | 90 |
\n(换行) | 10 | a | 97 | z | 122 |
记忆技巧:0<A<a,即数字 < 大写字母 < 小写字母。大写字母和对应小写字母之间相差 32(例如A(65) 和a(97))。
✨ 多媒体编码
编码格式
| 类型 | 格式 | 特点 |
|---|---|---|
| 图像 | jpg(jpeg) | 有损压缩,适合照片 |
| 图像 | png | 无损压缩,支持透明 |
| 图像 | gif | 支持动画,颜色有限(256色) |
| 音频 | mp3 | 有损压缩,文件小,最常用 |
| 音频 | aac | 有损压缩,比 mp3 音质更好 |
| 音频 | wav | 无损格式,文件大,音质最好 |
| 视频 | mp4 | 最通用的视频格式 |
| 视频 | avi | 较老的格式,兼容性好 |
| 视频 | mkv | 开放格式,支持多音轨/字幕 |
编码标准
| 标准 | 代表格式 | 应用场景 |
|---|---|---|
| MPEG-1 | mp3 | 音频压缩 |
| MPEG-4 | mp4 | 视频压缩 |
| H.264/AVC | - | 高清视频传输(4K、8K) |
| H.265/HEVC | - | 超高清视频,压缩率比 H.264 提升约 50% |
✨ 压缩编码
压缩编码通过特定算法减小数据体积,便于存储和传输:
| 压缩算法 | 对应格式 | 压缩类型 | 说明 |
|---|---|---|---|
| DEFLATE | ZIP | 无损压缩 | 最常见的通用压缩算法 |
| RAR | RAR | 无损压缩 | 压缩率通常比 ZIP 略高 |
| 哈夫曼编码 | - | 无损压缩 | 基于字符出现频率,高频字符用短编码 |
| LZ77/LZ78 | - | 无损压缩 | 基于重复字符串的替换,DEFLATE 的基础 |
✨ 计算机编码的执行示例
求 -13 的原码、反码、补码(8位)
第1步:求原码
- 先写出 13 的二进制:13 = 8 + 4 + 1 = 00001101
- -13 的原码:最高位改为 1 → 10001101
第2步:求反码
- 将 13 的二进制每一位取反:00001101 → 11110010
第3步:求补码
- 反码加 1:11110010 + 1 = 11110011
完整对比表:
| 编码 | +13 | -13 |
|---|---|---|
| 原码 | 00001101 | 10001101 |
| 反码 | 00001101 | 11110010 |
| 补码 | 00001101 | 11110011 |
位运算执行过程:以 5 & 6、5 | 6、5 ^ 6 为例
先将 5 和 6 转为二进制:
- 5 = 101
- 6 = 110
按位与(&):两位都为 1 才为 1
101 (5)
& 110 (6)
-----
100 (4)按位或(|):至少一位为 1 就为 1
101 (5)
| 110 (6)
-----
111 (7)按位异或(^):两位不同才为 1
101 (5)
^ 110 (6)
-----
011 (3)左移右移执行过程
5 << 1:将 101 左移 1 位 → 1010 = 10(相当于乘以 2)5 >> 1:将 101 右移 1 位 → 10 = 2(相当于除以 2,向下取整)5 << 2:将 101 左移 2 位 → 10100 = 20(相当于乘以 4)
规律: 左移 k 位相当于乘以 2^k,右移 k 位相当于除以 2^k(向下取整)。
✨ 计算机编码的解题步骤
例题:求 -20 的 8 位补码
解题步骤:
- 求 20 的二进制:20 = 16 + 4 = 00010100
- 求反码(每位取反):00010100 → 11101011
- 反码加 1 得补码:11101011 + 1 = 11101100
验证方法: 用补码还原回十进制
- 补码 11101100,最高位是 1,说明是负数
- 取反:00010011,加 1:00010100 = 20
- 所以原数是 -20
例题:用位运算判断一个整数是奇数还是偶数
if (n & 1) {
cout << "奇数" << endl;
} else {
cout << "偶数" << endl;
}原理: 任何整数的二进制最低位为 1 则是奇数,为 0 则是偶数。n & 1 取出最低位进行判断,比 n % 2 更高效。
✨ 计算机编码的常见错误
- 原码和反码混淆:原码是"最高位变1",反码是"每一位取反"。例如 -5 的原码是 10000101(只改最高位),反码是 11111010(全部取反),两者完全不同
- 补码计算时忘记进位:反码加 1 时可能产生进位,例如反码 11111111 + 1 = 100000000,8 位补码只保留低 8 位为 00000000
- 正数的三码不同:正数的原码、反码、补码完全相同,只有负数才需要转换
- 位运算优先级陷阱:在 C++ 中,
&、|、^的优先级低于比较运算符。if (a & 1 == 1)实际上是if (a & (1 == 1)),应该写成if ((a & 1) == 1) - 左移溢出:左移位数过多可能导致数据溢出,例如
1 << 31在 int 类型中会变成负数
✨ 格雷码
概念
格雷码(Gray Code)是由贝尔实验室的弗兰克·格雷在 1947 年发明的,又称反射二进制码,是一种特殊的二进制编码系统。
格雷码的特点:
- 单步变化性:两个连续的数值编码仅有一位二进制数不同
- 循环性:最大值和最小值之间编码也仅有一位二进制数不同
主要应用:数字系统错误检测、模拟数字转换、位置编码。
格雷码构造方法
手动构造法
k 位格雷码,从全 0 开始交替执行以下两步:
- 翻转最低位得到下一个格雷码
- 翻转最右边的 1 的左边一位得到下一个格雷码
重复操作 1 和 2 共 2^k - 1 次后,完成编码。
镜像构造法
从 1 位格雷码 0、1 开始,逐步扩展:
- 将 k-1 位格雷码上下镜像复制
- 前 k 个格雷码左边补 0
- 后 k 个格雷码左边补 1
重复 k-1 次补位操作后完成编码。
镜像构造过程示例:
| 1位(起始) | 2位(镜像+补位) | 3位(镜像+补位) |
|---|---|---|
| 0 | 00 | 000 |
| 1 | 01 | 001 |
| 11 | 011 | |
| 10 | 010 | |
| 110 | ||
| 111 | ||
| 101 | ||
| 100 |
格雷码与二进制编码之间的转换
二进制码转格雷码
工作原理:
- 保留二进制的最高位作为格雷码的最高位
- 对于二进制数后面的每一位:该位与它左边的一位异或得到格雷码的下一位
二进制转格雷码代码示例
g(n) = n ^ (n >> 1);格雷码转二进制码
工作原理:
- 保留格雷码的最高位作为二进制码的最高位
- 对于格雷码后面的每一位:将该位与二进制码左边的一位异或得到二进制码这一位
格雷码转二进制代码示例
bin[0] = gray[0];
for (int i = 1; i < k; ++i) {
bin[i] = bin[i - 1] ^ gray[i];
}