怎么样才算是一个字符呢?这就要各自的语言给出解释了。比如对于英语来说,一个字母就是一个字符;对于汉语来说,一个汉字就是一个字符。
常见的字符有文字、标点符号、图形符号、数字等。
把字符按照一定的顺序排列在一起,就是字符序列。
字符集(charset
)一词是由字符(char
)和集合(set
)组合而成的。顾名思义,就是由一些字符组成的集合。
字符集就如同由不同的人形成的不同的圈子一样。世界上存在着很多的圈子,每个人也可以同时在多个圈子里。类似的, 也有很多的字符集。因为,人类的语言非常丰富,不同的国家的语言通常不同、不同民族有自己的语言等。
计算机中常用的字符集:
在计算机中,所有的数据在存储和运算时都要使用二进制数表示,字符也不例外,例如,像a、b、c、d这样的52个字母(包括大写)、 以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪个二进制数字表示哪个符号, 当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则。 字符编码(Character coding
)就是一套通用规则。
大多数字符集只有一种编码方式,这时候我们说的字符集也指对应的字符编码,然而,一个字符集可以有多种编码方式。 如果你个字符集有多个编码方式,这时候就要严格区分什么是字符集,什么是字符编码了。
一般的,字符集中字符的个数会影响这个字符集的编码方式。
有些时候,我们只能使用特定字符集中的某些个字符,而不能使用这个字符集中的全部字符, 也就是,我们需要缩小范围,此时就需要使用特殊字符编码。
常用的对字符的特殊字符编码方法有如下这些:
BOM
(Byte Order Mark
,字节顺序标记)
BOM
就是一个特殊的标记,告诉数据的使用者,字节序
是小端模式
还是大端模式
。
对于,通过多个字节合起来表示一个东西的时候,就会出现字节序的问题。
比如,在C语言中,对于32
位的操作系统, 一个short
类型占用2byte
;一个int
类型占用4byte
; 一个long
类型占用8byte
。那么,对于一个short
、int
、long
等类型的数据在内存中的存储顺序应该是什么样子的呢?
更具体一点:假设我们限定环境是32
位的操作系统,现在有如下的定义:
short a = 1;
那么a
逻辑上可以表示为00000000 00000001
。我们人类习惯上将高位写在左边,低位写在右边。
实际存储的时候,按照从低位到高位的顺序:a
就有2
种存储的方案:
00000000 00000001
00000001 00000000
00000000 00000001
这种存储方案与我们人类的习惯正好是反着的,这种称为大端模式
。
00000001 00000000
这种存储方案与我们人类的习惯是一样的,这种称为小端模式
。
那么,如何验证C语言中short
、int
、long
等类型的数据在内存中 是以哪种字节序存储的呢?
从上面的例子,我们已经看出来了,对于32
位的操作系统,short
类型的数据占用2byte
, 我们把这两个字节重新转换成short
类型的数据,看看哪个与a相等,如果是低位与a相等,就表示是小端模式
,否则就是大端模式
。
示例代码:
int isLittleEndian() {
short a = 1;
unsigned char *p = (unsigned char *)(&a);
return *p == a ? 0 : 1;
}
绝大多数的操作系统都采用小端模式
。
TCP/IP
首部中所有的整数在网络中传输时都要求使用大端模式
,因此它又称作网络字节序。 比如,以太网头部中2字节的“以太网帧类型”,表示后面数据的类型。对于ARP请求或应答的以太网帧类型来说,在网络传输时,发送的顺序是0x08,0x06。
有时候,BOM
不仅仅指示字节序,还指示何种字符编码。这对于纯文本文件特别有用。比如, 对于Windows中的记事本
这个程序,它就是用BOM
区分使用哪种编码格式的。
文件直接以数据开头,无头信息,该文件为ASCII编码;
文件头两个字节依次是FF FE
,为UTF-16LE编码, 也就是Unicode编码;
文件头两个字节依次是FE FF
,为UTF-16BE编码;
文件头三个字节依次是EF BB BF
,为UTF-8编码;
可以通过hexdump -C xx.txt | less
命令查看十六进制表示的字节序。
UCS
规范建议我们在传输字节流前,先传输字符U+FEFF
, 如果接收者收到FEFF
,就表明这个字节流是大端模式
的; 如果收到FFFE
,就表明这个字节流是小端模式
的。
UTF-8
编码不需要用BOM
来表明字节顺序,但可以用BOM
来表明编码方式。 如果接收者收到以EF BB BF
开头的字节流,就知道这是UTF-8
编码了。
Linux和UNIX并没有使用BOM
, 但这些系统中的文本编辑器在读取并显示的时候一般会忽略掉BOM
,而不是把他们当成正文。 而Windows中的记事本
在保存文件的时候插入对应的BOM
。
XML
的编码可以进行设置,类似于如下:
<?xml version="1.0" coding="UTF-8"?>
这个元数据必须放在XML
内容的第一行,用来告诉XML
解析器,该XML
的内容是如何编码的。 如果没有指明coding
,就使用默认的UTF-8
进行编码。
常用的结构化文本包含如下这些: