计算机的一切都是二进制,而为了助记为了使人能直观清楚的与计算机交互,就有了ASCII码,使用一个字节表示英文以及一些控制符。当其他国家也开始使用计算机时,需要计算机显示其他的字符文字,此时一个字节已不够使用,解决的办法是增加字节数,使用两个字节来表示字符,即unicode。unicode兼容ASCII码,两者可以同时使用,此时出现一个问题,当编译器读取一个字节时,怎么能判断它是一个单独的字节,还是两个字节中的前一个?
举个例子,现在想用0-9这十个数表示3种水果:苹果、香蕉、橘子,我们可以按自己喜好(注意这点)给它们编上号,放在一张表中,比如
编号 | 水果种类 |
---|---|
0 | 香蕉 |
1 | 苹果 |
2 | 橘子 |
当后来想表示的水果种类增加时,我们就得考虑10个数可能不够用,想增加位数来表示。比如,0-6仍表示之前定义好的水果,现在约定7-8为标志位,不表示任何水果,只是表明后面的数需要和标志位一起计算,9保留以备其他用途(比如哪天我脑抽,想用它表示蔬菜了)。当读到7或8时,暂时存起来,等读到一个0-6的数后再组合起来计算值,查我们定义的表
此时71-76,81-86可以12种水果,
编号 | 水果种类 |
---|---|
0 | 香蕉 |
1 | 苹果 |
2 | 橘子 |
… | |
71 | 菠萝 |
72 | 芒果 |
… | |
9 | 保留位 |
当后来表示的规模再大些时,可以用三位数表示,此时771-886都可以用来表示水果种类。规模再大,使用位数再增加,只需遵循之前的定义遇到7和8就缓存下来,待遇到0-6的数再一起结算。
编码和上述过程类似,一个字节对应0-9的数,世界上包括字母方块字等所有的需展示的字符,对应水果种类。一个字节不够就来俩,俩不够就来三,这就是可变长度的编码,每个国家或组织按自己喜好做个表,就是不同的编码集。
由上述操作也可以很自然的联想到操作系统中分页分段的策略。将常用的数据直接存在0-6,这样访问时的速度快,将不常用且占用内存大的数据放在多段的7-8区间,保证其数据连续完整。这也就是这种方式的实践,根据不同数据的特点区分处理。在可变字节的编码集中,使用频率高的字符,在编码时尽量使用较少的字节,不常使用的字符,可以使用字节数多的,这样尽量减少最终生成的文本的大小。
当然编码工作也还有其他工作要做,比如分配标志位、保留位的区段大小,需要权衡、向前向后兼容等等。