当前位置:C++技术网 > 资讯 > 字符集与字符编码的关系详细分析

字符集与字符编码的关系详细分析

更新时间:2015-06-27 00:01:43浏览次数:1+次

    在《 轻松彻底理解符号、字符和字符集(ASCII、Unicode) 》一文中,已经对字符集进行详细的分析了。我想你应该一直在想一个问题,就是字符集与编码的关系。下面就来好好探讨一下他们的关系如何?
    常见的字符集有ASCII字符集、GB2312字符集、BIG5字符集、 GB18030字符集、Unicode字符集,当然,不仅仅有这些。每个国家区域的人,都可能有自己的一套字符集。字符集和语言类似。然而,在后来,出现了机器,比如打印机传真机,后面的计算机等,也就导致人与人的交流,不仅仅是写字那么简单的交流。我们需要远程交流,或者对已有的文字信息进行处理,比如像Word那样对文字进行处理,如果只是停留在手写上,那么是几乎不可能的。
    当然,如果不是机器处理,字符集根本就不用编码,人类只需要知道有这些字,像字典那样,了解到了每个单词每个汉字就够了。然后就是使用了,都可以用手写解决。这是的字符集,就是字符的简单集合,也就是把所有的字符放在一起就行了。当然,归类后更容易查找,比如字典。这个就够了。如果只是这样,我们也就不用将文字编码,更不用写程序了,压根就不会遇见乱码的情况了。
    然而,世界要发展。所以我们不得不想出更多的办法,让人与人的交流更加方便,以及对信息的处理更加快捷。这样我们就需要用机器来处理。要让机器理解各种字符,直接存储各种字符,是不可能的。当今的计算机,是基于图灵的二进制计算机,机器存储只能是0和1,因此,不可能存放字符的。这样就带来了困难。然而我们可以将二进制转换成十进制、十六进制等,这样便于人类阅读。为了让文字能很好的存储在计算机中,以及让计算机处理,就需要将文字对应成一个数字,只要计算机输出了这个数字,就要解释成这个文字。这里把计算机看做是所有机器的代名词,比如打印机也是一样。那么这个与文字对应的数字就是字符编码了。
    如果你不对文字字符进行编码,计算机不知道如何表示一个文字,也不能对这些字符进行显示和处理。将这些字符与一个数字对应起来的整个映射,就是对字符的编码,也是文字编码。文字编码不是给人用的,而是给机器用的,这点需要很清楚。至于如何将字符与一个数字对应,则是各个编码规定的。不同的编码标准是不一样的。
    然而,计算机在看到的永远只是一些0和1。也就是说,在计算机中内部看到的100这个数字,可以是任何一种文字。这就要看你怎么去解释这个数字了。如果你将这个数字根据ASCII字符集的编码来解释,可能就是字母A,而按照GB2312字符集的编码来解释可能就是“好”。当然,这里只是随便举个例子,这个数字实际上是哪个字符,要参考具体的编码表。如果按照其他的字符集编码来解释,那就是其他的文字。当然具体是哪个字符,就要看给计算机时用的是哪个字符集编码,然后用这个编码才能解释正确。所以,一台计算机可以用好多种字符编码,也可以存储很多种字符编码的文字,要正确的解释这些文字,就要用存储时的字符集编码去解释,否则就是乱码。我们在编程中看到的乱码,都属于这个问题。
    然而,将一个字符集编码,也就是使用一个编码标准,就形成一系列编码规则,将一个个的字符对应成一个数字,这个数字就是字符编码值。这样编码后,就形成了一个编码表,比如ASCII字符集的编码,编码标准的名称叫做ASCII编码。前面的ASCII是字符集,罗列了所有相关的字符。而ASCII编码,则是对ASCII字符集进行编码,让字符集中的每一个字符都一应一个数字,这样的一个对应表就是ASCII编码表。具体的ASCII编码表,请参考 维基百科 .
    为了方便编码,人们才将字符集严谨的归类编码,而之前可能就是比较散的,没有做过字符集标准化。直到需要编码时,才一起将字符集以及字符集编码一起处理,因为字符集编码是对一个字符集来说的,不存在对一个字符来说的,所以,通常就既叫做字符集也叫做字符集编码,比如ASCII字符集和ASCII编码。严格来说是两回事,但是大家都理解为一个东西了。实际上,字符集只是字符的简单集合,至于如何排列,那是另外一回事。而编码就是对字符进行排列编码,所以,我们现在一般看到的带有横纵数字格子的字符集都是含字符集编码的字符集。也就是说,一个字符集就代表了一个字符集编码,当然,为了特定的需要,可能对一个字符集进行多种编码。所以说,字符集和字符集编码并不是一一对应的。但是在计算机中一个字符集至少是有一个字符集编码的,否则这个字符集无法处理。而多种字符集编码则是对不同场合对这个字符集的表示不一样罢了,比如可以加快解释编码对应的文字的速度或者存储起来比较节省内存等。
    ASCII字符集只有ASCII字符集编码一种,GB2312等也只有一种编码,而Unicode则有多种编码。因为Unicode涵盖全世界的字符,所以在计算机中表示起来,可能会比较占内存和存储空间,而一般在一个特定的区域,只需要使用一部分的区段,比如在中国,我们不需要其他国家的字符,所以,在解释时根本就不用考虑其他国家的字符,所以就不必用整个范围的来表示,只需要将其中的一段的大小编码成一种标准,使用这个编码就只解释到这个区段,比如UTF-8。这个和内存寻址是一样的原理,要表示很大的区段,一个数字对应一个单元,在此就是一个字符,那么范围越大,需要的字节数就越多,这样存储在计算机中就需要很多的地方存储,就很费空间,并且处理速度上可能会慢点。而是用特定的编码,比如UTF8,对中文等在内的日常需要的字符单独编码,解释时只需要从对应的区域的起点开始查找就可以快速找到,而不是从头到尾,将全世界的字符拿来比较。而UTF-8、UTF-16等数字越大,一个字符需要的字节数就越大,然而将Unicode全部一起编码,在处理上就非常简单,而UTF-8等的编码在处理上,就稍微要麻烦一点。每一种编码的具体表示方法,在网上一查,很多资料都解释了,就不赘述了。
    本文重点就是帮助读者,理解字符集和字符集编码之间的关系,什么是字符集什么是字符集编码。还有一种特别的编码,叫做内码,比如ANSI编码,因为这种编码和本文所讲的编码不太一样,所以后面单独说明。对于各种字符集的具体编码,如果有兴趣可以了解一下。个人觉得,只要理解到字符集和字符集编码之间的关系,遇见这些编码类的问题,就OK了。如果想了解,推荐了解Unicode编码。具体的编码规范,如果不是从事相关的工作,也没必要深入研究。