📄 一句话概括
计算机只认数字,文字必须先变成数字——字符编码就是那张【字到数字】的对照表;字符串是字符排成的序列,C 语言还要在末尾放一个 NULL 字符(\0)当句号,告诉程序【到这儿为止】。
📝 本节和前面几节的关系
3-1 的二进制能表示数,这一篇让它表示字。回收 C++ 课 2.2.3 字符变量(char 一个字节的老规矩)与树莓派课 6-6(Python 字符串按字符不按字节)——两课的落差正是编码演化史。
一、字符编码:字与数字的对照表
- ASCII(1963):最早的通用对照表,7 位二进制、128 个字符——英文字母、数字、常用符号刚好够;
A是 65、a是 97、0是 48(记住 48 这个锚点:字符5减字符0得数值 5); - 各国分家:128 个位置装不下汉字,各国各自续表(中文 GB 系列、日文 JIS、繁体 BIG5)——续出 3-10 的乱码乱世;
- Unicode(3-10 展开):给全世界每个字发唯一编号。
二、字符串:字符的数组
字符串就是字符排成一串——本质就是 3-8 的数组,元素是字符:
s = "Hello"
print(s[0], s[4]) # H o
print(len(s)) # 5
Python 与 C 的两处关键不同:
- C 字符串以 NULL 字符收尾:C 里
"Hi"实际占 3 个字节——H、i、\0。\0(数值 0)就是那个【句号】,函数靠扫描它才知道字符串到哪结束。忘了给句号留位置,函数会一路读到内存深处——C 最经典的越界事故源。Python/Java 的字符串自带长度信息,不需要这个句号; - Python 字符串按【字符】算不按【字节】算:
len("你好")是 2 不是 4(回收树莓派课 6-6 的坑)——Python 3 的字符串是 Unicode 字符序列,字节是编码(3-10)之后的事。
三、字符与数字互转
print(ord("A")) # 65 字 -> 编号
print(chr(66)) # B 编号 -> 字
每个字符背后就是一个数字——文字与数字在这里打通。
四、动手 Demo:句号、锚点与长度
print(ord("0"), ord("5")) # 48 53
print(ord("5") - ord("0")) # 5 字符数字转真数值的经典招
s = "Hi"
print(len(s), len(s.encode())) # 2 2 ASCII:2 字符 2 字节
print(len("你好"), len("你好".encode())) # 2 6 UTF-8 下每个汉字 3 字节
看到什么算成功:48 53、5、2 2、2 6。
读结果:第一对是【字符 5 减字符 0 得数值 5】——ASCII 编号设计成连续整数的红利(C 老代码里天天用);最后一对比出【字符数】与【字节数】的落差——中文一个字 UTF-8 占 3 字节,长度有两个口径,永远先问清是哪个。
五、30 秒实验
跑 print(chr(97), chr(98), chr(99))——得 a b c。再猜 chr(97 + 1) 是什么?字母表的编号是连续的,字符能当数字算——30 秒体会【文字就是数】。
六、常见误区
- 【一个字符就是一个字节】——错。ASCII 时代对,Unicode 时代错:一个汉字 UTF-8 占 3 字节、UTF-16 占 2 或 4 字节;char 一个字节的 C 语言因此处理不了中文。
- 【空字符串和 NULL 是一回事】——错。空字符串是【有盒子、零个字符】(Python 的
"",len 为 0);C 的 NULL 是【根本没有盒子】(指针指向空)——前者能安全调用方法,后者一碰就崩。 - 【字符串可以像列表一样原地改】——Python 里错。字符串不可变,
s[0] = "X"直接报错;所有【修改】其实都造了个新字符串(回收树莓派课 6-6)。
自测三问(点开对答案)
1. **C 字符串为什么需要 NULL 字符?** 答:C 不单独存字符串长度,函数靠扫描结尾的 \0 才知道字符串边界——缺了它就会读越界。 2. **len("你好") 和 len("你好".encode()) 为什么不同?** 答:前者数字符(2 个 Unicode 字符),后者数 UTF-8 编码后的字节(每个汉字 3 字节共 6)——字符与字节是两个口径。 3. **为什么 ord("5") - ord("0") 能得到 5?** 答:ASCII 里数字字符的编号连续(0 是 48、5 是 53),相减正好得出字符所代表的数值。- ☐ 下一节(3-10 BIG5、GBK、JIS编码、乱码、Unicode)
相关笔记
- 编码割据与 Unicode —— 对照表分家与统一的下一课
- C++ 2.2.3 · 字符常量 —— char 一个字节的世界
- 树莓派 6-6 · Python 列表与字符串 —— Python 按字符不按字节的坑
- ⌨️ 编程原理 · 索引 —— 全课路线图