在具体的讲述中英文字符的显示与存储以前,我们可以先了解下面的一个示例:这里有256个学生,我们按照从0到255的顺序每人给一个学号,对于每个学生来讲,这个学号是唯一确定的。但是只是从这个学号上,我们看不出来一个学生具体的长相特点。为了能够知道这个学生的长相信息,我们又为每个学生拍了照片,并且对照片进行M行N列的扫描,对某一点来讲,如果该点是亮点,则在该位置标志为1,如果该点是暗点,则该位置标志为0。这样对整个照片扫描完毕,我们就得到了一长串的二进制数。这一长串二进制数就是描述学生照片的信息,也可以说我们已经把这张照片数字化了。然后我们把这些照片信息按照学号的顺序存放到一个文件中,这个文件就是我们的照片库。在日常的学生管理中,比如说在学生的成绩单上,住宿登记册上等,我们只是使用学生的学号,因为学号能够唯一的确定一个学生,而且其信息量比照片的信息量要小得多;但在档案上等需要知道学生长相的位置则需要根据学号到照片库中把该生的照片信息提取出来,然后根据这串二进制数码描画出这个学生的照片。在我们的微机操作系统中,正是利用这种方法来实现中英文文字的显示与存储的。
在微机中常用的英文字母及其他符号共有256个。就象前边管理学生的方法一样,在微机的存储器中存储这些英文符号有两种不同的方式:组成每个符号的点阵和对每个符号的特定编码。
在计算机设计初期,人们把最常用的128个英文符号(包括26个英文字母,0至9的数码以及其他的常用符号)按一定的顺序给予一个编码,目前这套编码是国际通用的,那就是ASCII码,把另外的利用率相对较低的128个符号作为扩展的ASCII码。
同时在微机的字符发生器中按编码顺序存储了每个符号的字符点阵,也就是他们的字模,供显示或者打印用。一般情况下,显示用的这些点阵通常是8×8点阵,即每个符号要占用8个字节的存储空间。
例如英文字母A的ASCII码是65,即41H(在这里H代表16进制数),它的字符点阵可以参看下图:
对英文符号来说,只有在字符发生器和打印的时侯才使用其字符点阵。我们在键盘上键入字符A,事实上在内存传递的只是一个数值41H,即这个字符的ASCII码,只有当这个数值41H被送往显示缓冲区或者送往打印机时,系统才从其点阵库中抽取出它的点阵信息,根据这些信息把它的模样描述出来。也就实现了符号A的显示或者打印。如图1-4所示。
图1- 4英文字母A的点阵结构及其各点对应的二进制值
综上所述,微机存储器中存储256个英文字母、符号以及它们的ASCII码总计需要2304个字节:其中存储256个字符点阵需要8×256=2048个字节,存储256个字符的编码(ASCII码及扩展ASCII码)需要1×256=256个字节。这对于一般的微机系统来讲都是微不足道的。在实际上,人们是将它们固化到主机显示卡上的ROM中。表1-2 列出了英文字符的ASCII值。(水平方向的数码为编码的高3位)。
表1-2 ASCII码对应字符表
从上表可以看出,十进制码值0~32和127共34个字符称非图形字符(又称为控制字符),其余94个字符又称为图形字符,或者可打印字符。在这些字符中,我们应该记忆下列几个关键字符的ASCII码值。
空格符:字符的二进制编码为0100000B,对应的十进制数为32,十六进制值为20H。
字符0:字符的二进制编码为0110000B,对应的十进制数为48,十六进制值为30H。
字符1:字符的二进制编码为0110001B,对应的十进制数为49,十六进制值为31H。
字母A:字符的二进制编码为1000001B,对应的十进制数为65,十六进制值为41H。
字母B:字符的二进制编码为1000010B,对应的十进制数为66,十六进制值为42H。
字母a:字符的二进制编码为1100001B,对应的十进制数为97,十六进制值为61H。
字母b:字符的二进制编码为1100010B,对应的十进制数为98,十六进制值为62H。
ASCII码值为13(即0001101B)的字符是回车符(标记为CR),ASCII码值为10(即0001010B)的字符是换行符(标记为LF)。
和英文符号相同,汉字字符的存储和显示也有两种不同的形式:组成每个字符的点阵和每个字符的编码。
同英文字符点阵一样,尽管汉字的字形有多种变化,但由于汉字都是方块字。而且汉字的大小相同,无论汉字的笔划多少,都能够写在大小相同的方块中,因此我们可以把这个方块分成X行Y列的X×Y个小方格,这就是点阵。每个块可以看作是有墨点或者无墨点,一个由点阵中的墨点组成汉字的笔划,描绘出汉字的字型,就是点阵型汉字。如果我们对这些小方块进行数字化处理,用二进制数1表示点阵中的墨点,用二进制数0表示该点无墨,我们就能得到一个数字串,这个数字串就是该汉字的图形信息,即汉字的字模信息。把我们经常使用的所有汉字符号的字模都存放在一个文件中,这个文件就是我们通常使用的汉字库。
根据精密度和字体大小的要求,我们可以做出点阵大小不同的字库。16×16点阵是我们通常使用的显示字库,每个汉字块被分为16行16列共256个小块,然后用16×16=256位的二进制数来表示,也就是说,16×16点阵的汉字的每个汉字字模要占用32个字节的存储空间。
下面是“大”字的16×16点阵结构及其对应的二进制值(见图1-5)。
和处理英文字符一样,在计算机内存的处理中,我们不是直接传递和处理汉字的字模,而是使用汉字的编码,因为字模的信息量太大。和英文符号不同的是汉字本身是一种图形文字,其图形符号比较多,不象作为拼音文字的英语只有26个不同字母,即使区分大小写,也只有52种状态,对西文字符的编码只需用8位二进制数,能够表示256个符号就足够了。因此对汉字符号的编码应该能够表示比较多的状态。目前在微机内部汉字一般使用16位二进制数编码,也就是两字节编码,这个编码就是汉字的内码,也称为机内码。
图1- 5英文字母A的点阵结构及其各点对应的二进制值
综上所述,在微机存储器中存储8000个16×16点阵汉字字模及其内码总计需要约272KB存储空间:因为对16×16点阵字库来讲,每个汉字或符号占用的存储空间是(16×16)bit,即(16×16)÷8=32B,存储8000个汉字和符号的点阵需要32×8000B,大约为256KB,又因为中文符号的内码是双字节的,因此存储8000个中文符号的内码应该用2×8000B,大约为16KB。总共272KB的空间对于常规内存只有640KB的微机系统来讲是一个非常可观的数字。为了节省微机的内存空间,现在的大部分汉字系统尽量把汉字库放置在扩展内存,或者放置在专用汉卡的只读存储器中。
16×16点阵的字库一般只用于显示,如果用于打印,其效果非常差。打印一般使用高点阵的打印字库,考虑到打印机自身工作比较慢和节省内存等因素,在大多数汉字系统中高点阵打印字库并不装入微机内存,而是由汉字系统直接在硬盘上的汉字库中查找并输出。
当前国家标准(GB2312-80)共收集7475个图形字符,其中一般符号202个(包括间隔符号、标点符号、运算符号、单位符号、列表符号)、序号60个、数字22个、拉丁字母52个(26个拉丁字母区分大小写),日文平假名83个,片假名86个,希拉字母48个,俄文字母66个,汉语拼音26个,汉语注音符号37个,汉字6763个。按照国家标准,我们将这7475个汉字与其他符号分为两级存放:首先我们规定放置中文符号的空间共有94个区,每个区中又有94个位,分别按其排列的顺序编码为01-94,我们将区号和位号合称为区位码。区位码和区位码表中的位置唯一对应。区位码的大小范围是0101-9494,可以表示94×94=8836个符号。一般的汉字系统中,除去常用符号,共有6763个汉字的字模被分为两级存放在不同的区中,其中一级汉字共3755个,置于16-55区,按照他们的拼音字母顺序排放,二级汉字共3008个,置于56-87区,按它们的偏旁部首顺序排放。这样汉字系统中使用的每一个符号,对应唯一的号码,这个号码就是区位码,它直接反应了该符号的字模在汉字库中的存储位置。例如“大”字的区号是20,位号是83,那么“大”字的区位码就是2083。能否在微机系统内部直接使用中文符号的区位码呢?答案是否定的。事实上汉字的区位码和英文符号的ASCII编码是有重叠的。如果在微机系统内部直接使用汉字的区位码,显示和打印系统对编码的解释将会无所适从。例如“忖”字的区位码是6666,即16进制数4242(对区号和位号分别化为16进制),系统将不知道是要调用“忖”字的字模呢,还是在屏幕上显示出两个英文字母“B”。为了避免与ASCII的冲突,系统对每个中文符号的区码和位码分别加上16进制数A0,得到一个二字节的数值,这个数值被称为微机系统中汉字的内码,也叫机内码,表示的只是汉字在汉字库中的物理位置,或者说该汉字在计算机内的序号。同时由于它和区位码之间有直接的换算关系,显示打印系统通过内码可以很快地找到内码对应的字模。
国家标准规定了信息交换用的标准汉字交换码(GB2312-80),也就是国标码,从根本上讲,区位码只是在国标码的基础上针对于中文符号存放的区位号提出来的。国标码的高字节减去20H得到区位码的区号,低字节减区20H后就是区位码的位号。国标码的两个字节的最高位都是0,只要分别把它们的最高位变为1,这个编码就是该汉字的内码。国标码的编码考虑到了尽量避开ASCII码表中的控制符号,由于ASCII符号表中只有94个可打印的符号,所以国家标准把汉字符号分放在94个区,每个区又安排了94个位。
下面我们仍以“大”字为例说明这个问题。
“大”字的区位码是:2083,将其区号和位号分别化为16进制就是:1453H 那么机内码是:1453H+A0A0H=B4F3H
对应的国标码:B4F3H-8080H=3473H 或者利用下面的公式计算1453H+2020H=3473H。
中文电脑主要处理对象是汉字,国家标准对汉字的编码具有唯一性,也就是说每个编码对应唯一的一个汉字,一个汉字也只能有唯一的一个码。这样避免了编码的二义性,但同时我们也发现,直接利用国标码,或者说以内码和区位码向微机系统中输入汉字几乎是不可能的。因为人们不可能记下每个汉字的区位码。为了输入的方便,汉字系统对每个汉字规定了输入计算机的代码──外部码。人们通过键盘输入汉字都是使用汉字的外部码。同时为了让计算机能识别用户输入的汉字,计算机的汉字系统必须把汉字的外部码转化为汉字的内部码,以便于处理和存储。为了将汉字以点阵的形式输出,还要将汉字的内部码转化为汉字的字形码,也就是通过内码找到汉字的区位码然后确定汉字的数字化点阵结构(字模)。
(1)外部码
汉字主要从键盘输入,外部码是汉字从键盘输入时的代码,也叫汉字输入编码。根据汉字的属性(汉字字形,字音,使用频率),现在已经提出了数百种的编码方案,供我们在工作中选用。双拼双音、智能拼音、五笔字型是目前比较受欢迎的编码方案。
外部码在输入过程中,由汉字操作系统负责转化为内码(也叫机内码)进行存储和处理。
(2)内码
又称内部码或者机内码。在计算机内存中是汉字的代表,计算机内部使用和处理汉字实际上就是在处理汉字的内码,从键盘上输入的外码也要通过查表的方式转化为内码后才能存储和处理。我们把使用文字处理软件写的一些文章存储在磁盘上,也是存储的汉字内码。
目前除二字节内码外,还有三字节、四字节内码,但使用的较少。
(3)汉字输出码
又称字形码,是根据汉字的字形或者说字模进行的编码。上面我们曾经讲过的点阵就是一种汉字输出码。汉字输出码只是在显示汉字或者打印汉字的时候使用。这个编码信息量大,对于同一个汉字可能对应多个大小不同,字体相异的编码。
(1) BIG5码
除了中华人民共和国大陆地区制定的GB-2312标准编码外,香港和台湾地区也制定了自己的汉字编码方案。因为香港和台湾地区的汉字编码是以繁体字为标准的,称为BIG5码。在我们以后使用Windows系统过程中,如果接收香港和台湾地区的信件和资料,一般需要按照BIG5码的方式解析
(2) UCS码
为了统一地表示世界各国、各地区的文字,便利全球范围内的信息交换,1993年,国际标准化组织公布了“通用多八位编码”字符集的国际标准,即UCS编码方案。
(3) GBK码
为了表示汉语言文字中众多的异体字和生僻字,与国际的UCS接轨,我国发布了新一代的中文编码方案——扩充汉字内码方案(GBK)。
最近发布并成为新标准的GB18030-2000是对GB2312编码方案的扩展,共收录了2.7万多个汉字,总码位超过150万个。其第1个和第2个字节的A1H-FEH与GB2312内码完全一致,使得新编码方案能完全兼容旧的GB2312内码,过去制作的以GB2312为标准的文本不加任何转化就能够使用在新的GBK方案下。
GBK编码方案采用单/双/四字节混合编码,该标准与现有的绝大多数操作系统、中文操作平台在计算机内码一级兼容,较好地解决了汉语言文字的大字符集问题,并为中文信息在国际互联网上的传输与交换提供了保障。