我正在读C#在char
(又名System.Char
)变量中存储unicode字符,这些变量的长度固定为16位。但是,16位不足以存储所有Unicode字符!在这种情况下,C#的char
变量如何支持Unicode? p>
答案 0 :(得分:2)
简而言之:代理人
这是一个好问题。 Unicode比大多数人想象的要复杂,因为它引入了多个新概念(字符集,代码点,编码,代码单位),但是我将尝试给出几乎完整的答案。
简介:
Unicode是一个字符集。字符集只是字符和代码点对的列表。代码点只是用于识别配对字符的数字。 UTF-8,UTF-16和UTF-32是编码。编码定义数字(代码点)以二进制形式(作为代码单位)表示的方式。代码单元可以由一个或多个字节组成。 (实际上,原始的ASCII码单元甚至只有7位长,但这又是另一回事了)
请记住:字符集由代码点组成,编码由代码单位组成。
C#char
类型表示UTF-16字符(代码单元)。 UTF-16是Unicode字符集的可变长度/多字节编码。含义字符可以由一个或两个16位代码单元表示。超出16位的Unicode代码点由两个UTF-16代码单元表示,它们等于四个字节。
现在回答您的问题:如何?
Unicode的最初概念是1 character = 1 code point
。但是,原来的UCS-2编码(现在已过时)使用两个字节(16位),并且只能编码65,536个代码点。短时间后,这对于不断增长的Unicode字符集是不够的。哦,真的,他们怎么想的?两个字节显然不够。要解决此问题,Unicode必须退出最初的想法并引入替代。
因此, UTF-16 诞生了,它是一种可变长度/多字节(16位代码单元)的编码,实现了替代。此替代物是特殊的16位代码单元,它等于Unicode中定义的代码点,而这些代码点显然不是字符。在解析文本时查找替代品只是意味着,您还必须阅读下一个16位,并将两个16位单元(替代和随后的代码单元)解释为一个组合的32位Unicode代码点。
UTF-32 是固定的四字节编码,其大小足以避免空间问题,并且可以在1个代码点上映射1个字符,但是UTF-32还必须处理代理,因为UTF编码基于Unicode标准,而替代则是Unicode字符集定义的一部分。
UTF-8 也是可变长度/多字节编码,但具有另一种插入式编码技术。简而言之:代码单元中的前导零的数目定义了最多四个后续字节的数目,这些字节必须组合为一个Unicode代码点。