数组实现字符集映射本质是用索引结构存储字符与编码的双向关系,适用于小范围固定字符集,支持O(1)正向(字符→编码)和反向(编码→字符)查表,需注意符号处理、越界校验及不连续字符集的替代方案。

用数组实现字符集映射,本质是把“字符 → 编码值”或“编码值 → 字符”的关系存成索引可查的线性结构。它轻量、高效,适合小范围、固定字符集(如 ASCII、GB2312 常用字、自定义符号表)的快速转换,不依赖外部库,也便于调试和定制。
用索引数组做正向映射:字符 → 索引(即编码)
适用于字符范围连续、数量可控的情况(如 ASCII 0–127)。声明一个足够大的数组,以字符的 ASCII 码为下标,存入目标编码值(如 UTF-8 序列首字节、自定义 ID、或 GBK 高字节等)。
- 例如,将小写字母 'a'–'z' 映射为 1–26:声明 map[256],初始化为 0;遍历 'a' 到 'z',设 map['a'] = 1,map['b'] = 2…
- 查映射时直接写 int code = map[ch];,O(1) 完成,比 if-else 或 switch 更简洁。
- 注意:char 是有符号还是无符号取决于平台,建议强制转为 unsigned char 再作数组下标,避免负索引越界。
用值数组做反向映射:编码 → 字符
当已知编码值是小整数(如状态码、枚举 ID、GB2312 区位码),可用数组下标直接对应字符。例如,定义常用标点的显示字符:
- const char* punct[8] = {"(", ")", "[", "]", "{", "}", ""};
- 收到协议字段值 2,就取 punct[2] 得到 "[";无需 strcmp 或查找表。
- 数组长度必须覆盖所有可能编码值,空缺位置可填空字符串或 NULL,并在使用前判断。
实战:GB2312 区位码 → Unicode 的简易查表转换
GB2312 中汉字由区号(0xA1–0xF7)和位号(0xA1–0xFE)组成。区位码可转为 16 位整数:code = (qu - 0xA1) * 94 + (wei - 0xA1),最大约 7445 个汉字。可预先生成一个大小为 7446 的数组,按区位顺序存对应 Unicode 码点(uint16_t)。
- 编译期生成该数组(用脚本解析 GB2312 映射表),或运行时静态初始化。
- 转换时先校验区位是否合法,再计算 index,最后查表得 Unicode:uint16_t u = gb2312_to_unicode[index];
- 比实时计算或哈希查找更快,内存开销仅约 15KB,适合嵌入式或高性能文本解析场景。
注意事项与边界处理
数组映射不是万能的,需主动规避常见陷阱:
- 字符集不连续(如 Unicode 中文散落在多个区段)不适合纯索引数组,应改用二分查找有序对数组,或结合哈希辅助。
- 数组越界是高频错误——务必校验输入字符是否在有效范围内,或用 memset 初始化全为 -1,查到 -1 即表示未定义映射。
- 若需支持多字节输出(如 UTF-8 编码),数组元素类型可设为 struct { uint8_t bytes[4]; uint8_t len; },查表后按 len 复制字节。

















