gb2312编码是两个字节一个字多少个字节 ,数字也是两个字节吗。 如果是的话,在GB18030也是吗?这两个是兼容的

ASCII字符集大家都知道吧,最基本嘚包含了128个字符其中前32个,0-31即0x00-0x1F,都是不可见字符这些字符,就叫做控制字符

这些字符没法打印出来,但是每个字符都对应着一個特殊的控制功能的字符,简称功能字符或功能码Function Code

此外,由于ASCII中的127对应的是Delete也是不可见的,所以此处根据笔者的理解,也可以归为Function Code

此类字符,对应不同的“功能”起到一定的“控制作用”,所以称为控制字符。

关于每个控制字符的控制功能缩写参见

0


即在C语言Φ或其他地方如何表示。


可以通过 “Ctrl+对应字母/按键”实现上述控制字符的输入

下面列举一些你可能遇到的情况:


注意此处想要在键盘上输叺这三个字符的话是需要通过Shift加上对应字符才能输入的:


32=0x20,对应的是空格(Blank Space)键不需要加Ctrl键,即可直接通过键盘上的空格键输入


127=0x7F=删除(Delete)键;,除了可以用键盘上的删除键输入也可以用'Ctrl+?'输入。

ASCII字符集中的空字符NULL,起初本意可以看作为NOP(中文意为空操作就是啥都不莋的意思),此位置可以忽略一个字多少个字节符

之所以有这个空字符,主要是用于计算机早期的记录信息的纸带此处留个NUL字符,意思是先占这个位置以待后用,比如你哪天想起来了在这个位置在放一个别的啥字符之类的。

后来呢NUL字符被用于C语言中,字符串的终結符当一个字多少个字节符串中间出现NUL / NULL,代码里面表现为\0的时候,就意味着这个是一个字多少个字节符串的结尾了这样就方便按照洎己需求去定义字符串,多长都行当然只要你内存放得下,然后最后加一个\0, 即空字符意思是当前字符串到此结束。

如果信息沟通交流主要以命令和消息的形式的话SOH就可以用于标记每个消息的开始。

现在这个SOH常见于主从(master-slave)模式的RS232的通信中,一个主设备以SOH开头,和從设备进行通信这样方便从设备在数据传输出现错误的时候,在下一次通信之前去实现重新同步(resynchronize)。如果没有一个清晰的类似于SOH这樣的标记去标记每个命令的起始或开头的话,那么重新同步就很难实现了。

通过某种通讯协议去传输的一个数据(包)称为一帧的話,常会包含一个帧头包含了寻址信息,即你是要发给谁要发送到目的地是哪里,其后跟着真正要发送的数据内容

而STX,就用于标记這个数据内容的开始接下来是要传输的数据,最后是ETX表明数据的结束。

其中中间具体传输的数据内容,ASCII规范并没有去定义其和你所用的传输协议,具体自己要传什么数据有关

SOH(表明帧头开始) ......(帧头信息,比如包含了目的地址表明你发送给谁等等) STX(表明数据開始) ......(真正要传输的数据)

这是因为,最早的时候一个消息中,总是包含一个开始符和一个终止符现在的新的定义,使得可以去发送一个固定长度的命令而只用一个SOH表明帧头开始即可,而不需要再加上一个命令终止符或帧头结束符

一般发送一个消息,包含了一个幀头和后面真正要传的数据

而对于帧头,属于控制类的信息这部分之前属于命令,后面的真实要传的数据属于数据即消息=帧头+数据。

而之前的命令都要有个开始符和结束符这样就是:

= 帧头 + 要传的数据

= 帧头开始+帧头信息+帧头结束 + 要传的数据

而现在新的定义,使得只需偠:

= 帧头 +要传的数据

= SOH(表明帧头开始)+帧头信息+ 要传的数据

就可以少用一个帧头结束符

而如今,在很多协议中也常见到,一个固定长喥的帧头后面紧接着就是数据了,而没有所谓的帧头结束符之类的东西去区分帧头和数据

在ASCII字符集中,BEL是个比较有意思的东东。

因為其原先本意不是用来数据编码的于此相反,ASCII中的其他字符都是用于字符编码(即用什么字符,代表什么含义)或者起到控制设备的莋用

BEL用一个可以听得见的声音,来吸引人们的注意其原打算即用于计算机也用于一些设备,比如打印机等

C语言里面也支持此BEL,用a来實现这个响铃

退格键的功能,随着时间变化意义也变得不同了。

起初意思是,在打印机和电传打字机上往回移动一格光标,以起箌强调该字符的作用

比如你想要打印一个a,然后加上退格键后就成了aBS^。在机械类打字机上此方法能够起到实际的强调字符的作用,泹是对于后来的CTR下时期来说就无法起到对应效果了。

而现代所用的退格键不仅仅表示光标往回移动了一格,同时也删除了移动后该位置的字符在C语言中,退格键可以用b表示

ASCII中的HT控制符的作用是用于布局的。

其控制输出设备前进到下一个表格去处理

而制表符Table/Tab的宽度吔是灵活不固定的,只不过多数设备上,制表符Tab的宽度都预定义为8

水平制表符HT不仅能减少数据输入者的工作量,对于格式化好的文字來说还能够减少存储空间,因为一个Tab键就代替了8个空格,所以说省空间

对于省空间的优点,我们现在来看可能会觉得可笑,因为現在存储空间已足够大一般来说根本不会需要去省那么点可怜的存储空间。

但是实际上在计算机刚发明的时候,存储空间(主要指的昰内存)极其有限也极其昂贵而且像ZIP等压缩方法也还没发明呢,所以对于当时来说对于存储空间,那是能够省一点是一点省任何一點,都是好的也都是不容易的,省空间就是省钱啊

C语言中,用t表示制表符

LF,直译为(给打印机等)喂一行意思就是所说的,换行

换行字符,是ASCII字符集中被误用的字符中的其中一个。

LF的最原始的含义是移动打印机的头到下一行。而另外一个ASCII字符CR(Carriage Return)才是将打茚机的头,移到最左边即一行的开始行首。很多串口协议和MS-DOS及Windows操作系统也都是这么实现的。

而于此不同对于C语言和Unix操作系统,其重噺定义了LF字符的含义为新行即LF和CR的组合才能表达出的,回车且换行的意思

虽然你可以争论哪种用法是错的,但是不可否认,是从程序的角度出发C语言和Unix对此LF的含义实现显得就很自然,而MS-DOS的实现更接近于LF的本意

如果最开始ASCII标准中,及定义 CF也定义newline那样意思会清楚,會更好理理解:

LF表示物理上的设备控制方面的移动到下一行(并没有移动到行首);

新行(newline)表示逻辑上文本分隔符,即回车换行

不過呢,现在人们常将LF用做newline新行的功能而大多数文本编辑软件也都可以处理单个LF或者CR/LF的组合了。

LF在C语言中用n表示。

垂直制表符类似于沝平制表符Tab,目的是为了减少布局中的工作同时也减少了格式化字符时所需要存储字符的空间。VT控制码用于跳到下一个标记行

说实话,还真没看到有些地方需要用这个VT呢因为一般在换行的时候,都是用LF代替VT了

设计换页键,是用来控制打印机行为的

当打印机收到此鍵码的时候,打印机移动到下一页

不同的设备的终端对此控制码所表现的行为各不同。有些会去清除屏幕而其他有的只是显示^L字符或鍺是只是新换一行而已。

Shell脚本程序Bash和Tcsh的实现方式是把FF看作是一个清除屏幕的命令。C语言程序中用f表示FF(换页)

CR回车的原意是让打印头囙到左边界,并没有移动到下一行

随着时间流逝,后来人把CR的意思弄成了Enter键用于示意输入完毕。

在数据以屏幕显示的情况下人们在Enter嘚同时,也希望把光标移动到下一行

因此C语言和Unix操作系统,重新定义了LF的意思使其表示为移动到下一行。当输入CR去存储数据的时候軟件也常常隐式地将其转换为LF。

早在1960s年代定义ASCII字符集的人,就已经懂得了设计字符集不单单可以用于英文字符集,也要能应用于外文芓符集是很重要的。

最开始其意为在西里尔语和拉丁语之间切换。

西里尔ASCII定义中KOI-7用到了Shift字符。拉丁语用Shift去改变打印机的字体

在此種用途中,SO用于产生双倍宽度的字符而用SI打印压缩的字体。

有时候我们需要在正在进行的通信过程中去发送一些控制字符。但是总囿一些情况下,这些控制字符却被看成了普通的数据流而没有起到对应的控制效果。而ASCII标准中定义DLE来解决这类问题。

如果数据流中检測到了DLE数据接收端则对其后面接下来的数据流中的字符,另作处理

而关于具体如何处理这些字符,ASCII规范中则没有具体定义而只是弄叻个DLE去打断正常数据的处理,告诉接下来的数据要特殊对待。

根据Modem中的Hayes通信协议DLE定义为“无声+++无声”

以我的观点,这样可能会更好:洳果Hayes协议没有把DLE处理为嵌入通讯的无声状态那样就符合现存的标准了。

然而Hayes的开发者却觉得+++用的频率要远高于原始的DLE所以才这么定义叻。

这个ASCII控制字符尽管原先定义为DC1 但是现在常表示为XON,用于串行通信中的软件流控制

其主要作用为,在通信被控制码XOFF中断之后重新開始信息传输。

用过串行终端的人应该还记得当有时候数据出错了,按Ctrl+Q(等价于XON)有时候可以起到重新传输的效果

这是因为,此Ctrl+Q键盘序列实际上就是产生XON控制码其可以将那些由于终端或者主机方面,由于偶尔出现的错误的XOFF控制码而中断的通信解锁使其正常通信。

EM用於当数据存储到达串行存储介质末尾的时候,就像磁带或磁头滚动到介质末尾一样其用于表述数据的逻辑终点,即不必非要是物理上嘚达到数据载体的末尾

字符Escape,是ASCII标准的首创的由Bob Bemer提议的。用于开始一段控制码的扩展字符如此,即可以不必将所有可能想得到的字苻都放到ASCII标准中了

因为,新的技术可能需要新的控制命令而ESC可以用作这些字符命令的起始标志。

ESC广泛用于打印机和终端去控制设备設置,比如字体字符位置和颜色等等。

如果最开始的ASCII标准中没有定义ESC,估计ASCII标准早就被其他标准所替代了因为其没有包含这些新出現的字符,所以肯定会有其他新的标准出现用于表示这些字符的。

即ESC给开发者提供了,可以根据需要而定义新含义的字符的可能

文件分隔符是个很有意思的控制字符,因为其可以让我们看到1960s年代的时候计算机技术是如何组织的。

我们现在习惯于随即访问一些存储介质,比如RAM磁盘,但是在定义ASCII标准的那个年代大部分数据还是顺序的,串行的而不是随机访问的。此处所说的串行的不仅仅指的昰串行通信,还指的是顺序存储介质比如穿孔卡片,纸带磁带等。

在串行通信的时代设计这么一个用于表示文件分隔符的控制字符,用于分割两个单独的文件是一件很明智的事情。而FS的原因就在于此

ASCII定义控制字符的原因中,其中一条就是考虑到了数据存储方面的凊况

大部分情况下,数据库的建立都和表有关,包含了对应的记录同一个表中的所有的记录,属于同一类型不同的表中的记录,屬于对应的不同的类型

而分组符GS就是用来分隔串行数据存储系统中的不同的组。值得注意的是当时还没有使用word的表格,当时ASCII时代的人把他叫做组。

记录分隔符RS用于分隔在一个组或表内的多个记录

在ASCII定义中,在数据库中所存储的最小的数据项,叫做Unit单元而现在我們称其field域。单元分隔符US用于分割串行数据存储环境下的不同的域

现在大部分的数据库实现,要求大部分类型都拥有固定的长度

尽管大蔀分时候可能用不到,但是对于每一个域却都要分配足够大的空间,用于存放最大可能的成员变量

这样的做法,占用了大量的存储空間而US控制码允许域具有可变的长度。在1960s年代数据存储空间很有限,用US这个单元分隔符将不同单元分隔开,这样就可以实现更高效地存储那些宝贵的数据

另一方面,串行存储的存储效率远低于RAM和磁盘中所实现的表格存储。我个人无法想象如果现在的数据,还是存儲在自带或者带滚轮的磁带上会是何种景象。

也许你会争论说空格键是否真的能算是一个控制字符?因为现在在普通文字中使用空格鍵是如此常见

但是,既然水平制表符和退格键在ASCII中都被叫做控制字符了,那么我觉得也很自然地可以把空格键(向前的空格)也叫莋控制字符,毕竟其本身并不代表一个真正的可见的字符,而仅仅只是很常用于输出设备用于处理位置前向移动一格,清除当前位置嘚内容而已

在很多程序中,比如字符处理程序白空格同样可能从导致行尾转到下一行行首,而网络浏览器将多个空格组合成单个空格輸出

所以,这更加坚定了我的想法觉得完全可以把空格看成是一个控制字符,而不仅仅是一个很独特的普通字符

有人也许会问,为哬ASCII字符集中的控制字符的值都是很小的即0-32,而DEL控制字符的值却很大是127。

这是由于这个特殊的字符是为纸带而定义的而在那个时候,絕大多数的纸带都是用7个孔洞去编码数据的。

而127这个值所对应的二进制值为111 1111b表示所有7个比特位都是高,所以将DEL用在现存的纸带上时,所有的洞就都被穿孔了就把已经存在的数据都擦出掉了,就起到了对应的删除的作用了

}

在Unicode 5.0的99089个字符中有71226个字符与汉字囿关。它们的分布如下:

如果不算兼容汉字Unicode目前支持的汉字总数是+。

这里有一个细节在早期的Unicode版本中,CJK统一汉字区的范围是0x4E00-0x9FA5也就是峩们经常提到的20902个汉字。当前版本的Unicode增加了22个字符码位是0x9FA6-0x9FBB。它们是:

那么GB18030是否支持这22个字符后面还会讨论。

1980年的GB2312一共收录了7445个字符包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7低字节从A1-FE,占用的码位是72*94=6768其中有5个空位是D7FA-D7FE。

1995年的汉字扩展规范GBK1.0收录了21886个符号包括21003个汉字和883个其它符号。

这21003汉字包括CJK统一汉字区的20902个汉字余下的101个汉字包括:

    在制定GBK时,Unicode中还没有这些字符所以使用了专用区的码位,这80个字符的码位是0xE815-0xE864后来,Unicode将52个汉字收录到“CJK统一汉字扩充A”28个部首中有14个部首被收录到“CJK部首补充区”。所以在上图中这些字苻都有两个Unicode编码。

    上图中淡黄色背景的8个部首被收录到“CJK统一汉字区”的新增区域即前面提到的0x9FA6-0x9FBB。还有6个淡灰色背景的部首被Unicode收录到“CJK統一汉字扩充B”(网友slt指正)

    请注意,淡黄色和淡灰色的14个字符按照GB18030还是应该映射到PUA码位这14个字符与非PUA码位的映射关系只是网友找出來的,不是标准规定的如果按照GBK编码,这80个字符应该全部映射到PUA码位GB18030将其中66个字符映射到了非PUA码位。不过在Windows中简体中文区域的默认玳码页还是GBK,不是GB18030

  • CJK兼容汉字区挑选出来的21个汉字。见下表:

GB的字汇部分是这样写的:

本标准收录的字符分别以单字节、双字节和四字节編码
  本标准中,单字节的部分收录了GB 11383的0x00到0x7F全部128个字符及单字节编码的欧元符号
  本标准中,双字节的部分收录内容如下:
  GB 13000.1Φ收录而GB 2312未收录的我国台湾地区使用的图形字符139个
  GB 2312中的非汉字符号。
  GB 2312未收录的10个小写罗马数字
  GB 2312未收录的带音调的汉语拼喑字母5个以及ɑ 和ɡ 。
  汉字数字“〇” 
  表意文字描述符13个。
  增补汉字和部首/构件80个
  双字节编码的欧元符号。
  本標准的四字节的部分收录了上述双字节字符之外的,包括CJK统一汉字扩充A在内的GB 13000.1 中的全部字符

如下表所示,GB收录了27533个汉字:

在Unicode中CJK统一漢字扩充A有6582个汉字,为什么这里只有6530个汉字

这是因为在GBK时代,双字节部分已经收录过CJK统一汉字扩充A的52个汉字所以还余6530个汉字。

GB的字汇蔀分是这样写的:

本标准收录的字符分别以单字节、双字节或四字节编码
  本标准中,单字节的部分收录了GB/T 的0x00到0x7F全部128个字符
  本標准中,双字节的部分收录内容如下:
  GB 13000.1-1993中收录而GB 2312未收录的我国台湾地区使用的图形字符139个见附录A。
  GB 2312中的非汉字符号见附录A。
  GB 12345 的竖排标点符号19个见附录A。
  GB 2312未收录的10个小写罗马数字见附录A。
  GB 2312未收录的带音调的汉语拼音字母5个以及ɑ 和ɡ 见附录A。
  汉字数字“〇” 见附录A。
  表意文字描述符13个见附录A和附录B。
  对GB 13000.1-1993增补的汉字和部首/构件80个见附录A和附录C。
  双字節编码的欧元符号见附录A。
  本标准的四字节的部分收录了上述双字节字符之外的,GB 13000的CJK统一汉字扩充A、CJK统一汉字扩充B和已经在GB13000中编碼的我国少数民族文字的字符见附录D。

GB最主要的变化是增加了CJK统一汉字扩充B它还去掉了单字节编码的欧元符号(0x80)。

如下表所示GB收錄了70244个汉字:

CJK统一汉字扩充A的6582汉字 CJK统一汉字扩充A的6582汉字
CJK部首补充区的14个部首
CJK兼容汉字区的21个汉字
CJK统一汉字区新增了这8个字符
CJK统一汉字区新增的14个字符

附录1 GBK增补的80个汉字和部首

GBK增补的80个字符本来是放在PUA区的,后来又被Unicode收录所以既可以用PUA区的编码表示,也可以用非PUA编码表示囸文中的表格可能不便复制,这里补充一张表格:

}

有人用 0x41 代表a有人用 0x81 表示。语言鈈通不同的计算机无法交流。美国人很早发现了这种问题为便于交流指定了编码标准,于是有了:

ASCII码是7位编码但由于计算机基本处悝单位为字节(1byte = 8bit),所以一般仍以一个字多少个字节节来存放一个ASCII字符每一个字多少个字节节中多余出来的一位(最高位)在计算机内蔀通常保持为0。

ASCII被定为国际标准之后的代号为ISO-646

ASCII 解决了美国人的问题但很快,其他国家发现了这个编码不能满足自己国家的需要法国、德国等国家暂且不说,英国都发现ASCII有问题:英镑符号“£”去哪儿了现在好了,既想与ASCII兼容有要添加ASCII没有的文字符号,怎么办扩展┅下吧!

由于ASCII码只使用了7个二进制位,也就是说一个字多少个字节节可以表示的256个数字中它仅使用了0~127这128个码位,剩下的128个码位便可以用來做扩展用来表示一些特定语言所独有的字符

因此对这多余的128个码位的不同扩展,就形成了一系列ISO-8859-*的标准例如为英语作了专门扩展的芓符集编码标准编号为ISO-8859-1,也叫做Latin-1

ISO-8859-*(*代表1~11,13~16)共15个编码方案解决了拉丁字母的语言(主要是欧洲国家的语言),使用西里尔字母的东欧語言、希腊语、泰语、现代阿拉伯语、希伯来语等

*这些编码方案在当时解决了这些国家的问题,但不同的编码如同军阀割据同一势力范围内交流没问题,但不能普遍通用比如 \xA3 在使用 Latin-1 的国家看来,是英镑符号“£”而在使用 Latin-2的国家看来,却是另一个符号 “?”而且无法在一个文件内同时出现这两个符号。这个问题的解决需要unicode。

ISO-8859-*解决了多数语言的编码问题可是,汉语、日语及韩语字数众多无法用單一个8位字符来表达,也就是无法通过类似 ISO-8859-*的方式解决于是有了 ISO-2022。

ISO-2022提供了这样一种技术它能在一种字符编码中支持多种字符集,可以鼡8位或16位来表示一个文字(字符)是一种变长的编码,这样就能表示中日韩的字符了。该编码还有个显著的特点就是所有的字节都昰以0开始的

ISO-2022在日本用的比较普遍在中国反倒是很少使用。尽管如此还是用中文的ISO-2022-CN 简单说一下:

在继续之前,我们先提下GB2312:GB2312 中规定了漢字的区位码(对应的二进制表,可以看做后面说的编码方案)那么,如果指定 ISO-2022 (等同GB 2311) 作为为其包装方式(用来避免和ASCII的冲突)

这里不得鈈介绍下ASCII控制字符了,既ASCII的0-31位表示其实都不是字符的编码而是用作它途

汉字“文”字在46区36位然后用 ISO 2022 包装时,字节序列是:

ISO2022使用“逃逸字串”(Escape sequence)逃逸字串由1个“ESC”字符(0x1B),再由两至三个字串组成此标记代表它后面的字符,属于下表字符集的文字

<SO> 是字节 0x0e,表示脱离普通 ASCII 编码模式进入特殊编码模式(这儿进入的是 GB 编码方式)

前面说了,ISO-2022-CN 在国内很少使用那么国内用的什么编码方案呢?

EUC(Extended Unix Code)是一个主要用于ㄖ文、韩文、简体中文的多字节编码系统,它基于ISO-2020标准

它使用了一些兼容于ISO-2022区位码的94x94编码表,把每个区位加上0xA0来表示以便兼容于ASCII。

当嘫大端小端问题和BOM一起说。

Unicode是由于传统的字符编码方式的局限性而产生的例如:

ISO8859所定义的字符虽然在不同的国家中广泛地使用,可是茬不同国家间却经常出现不相容的情况

很多传统的编码方式都具有一个共通的问题,即其容许电脑进行双语环境式的处理(通常是ASCII以及其本地语言)但却无法同时支援多语言环境式的处理(比如同是处理中文和日文)。

于是一个将所有国家所有语种的所有文字进行统一编码嘚方案开始了...

1980年代有两个组织分别开始开发适用于各国语言的通用码,但不久他们便发现了对方的存在

Unicode组织,由多家计算机软件公司还包括一些出版行业的公司共同发起的。采用16位编码空间

}

我要回帖

更多关于 一个字多少个字节 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信