我知道任何字符都由一个或多个字节组成。
如果我没记错的话,至少在 *nix 操作系统中,一个字符通常(或完全?)仅由一个字节组成。
字节和字符之间有什么区别(至少*nixwise)?
答案1
POSIXly,强调我的:
3.87 字符
序列一个或多个字节代表单个图形符号或控制代码。
实际上,确切的含义取决于有效的语言环境,例如在“C”语言环境下,printf '\xc3\xa4\xc3\xb6' |wc -m
给出 4,因为它有效地计算字节;而在 UTF-8 语言环境下则给出 2,因为这是两个 UTF-8 编码的字符äö
。假设您的终端也设置为 UTF-8,您当然可以只写printf 'äö'
.
(请注意,它wc -c
被定义为计算字节数,而不是字符数,这很容易令人困惑。)
更糟糕的是,字符支持还取决于实用程序,并不是所有东西都能干净地处理多字节字符(更不用说 Unicode 的所有怪癖了)。例如,GNU tr 处理字节,无论其手册页内容如何:
$ printf ä | tr ä xy; echo
xx
$ printf ö | tr ä xy; echo
x�
第一个与 相同tr '\303\244' 'xy'
,因此 的两个字节都ä
被替换,而第二个发生是因为两者 的第一个字节ä
相同ö
。当然,如果它真的处理字符,那些应该打印x
和ö
。
答案2
按照惯例,一个字节是POSIX 定义八位。位是二进制数字(即基本数字1
或0
几乎所有数字计算的基础)。
一个字符是经常一个字节并且在某些上下文中(例如ASCII)可以被定义为一个字节长度。然而,Unicode、UTF-8 和 UTF-16 定义了扩展字符集,其中单个字符(或字形)可以由长度超过一个字节的数据有效负载定义。
单个字符:
Q̴̢̪̘̳̣̞̩̪̑̍̉̆̉͛̑̂̕͝
是单个字符,但它是通过将多个重音符号(或变音符号)应用于基本字形(简单的Q
.这种编码的字节数比长度多得多:仅将该字符放入文件中并使用hexdump
而不是cat
在我的区域设置上显示内容会产生:
$ hexdump -C demo
00000000 51 cc b4 cc 91 cc 8d cc 89 cc 86 cc 89 cd 9d cd |Q...............|
00000010 9b cc 91 cc 95 cc 82 cc aa cc 98 cc b3 cc a3 cc |................|
00000020 a2 cc 9e cc a9 cc aa 0a |........|
00000028
答案3
A字节是基本元素,通常为 8 位长(也称为八位位组),尽管已经有(并且可能仍然有)其他尺寸。使用 8 位字节,可以编码 256 个不同的值(从 0 到 255)。
对于字符,情况因所使用的编码和字符集而异。
最简单最常见的编码/字符集是ASCII码。每个角色都使用一字节(实际上更少,只有7位)。它包括不带变音符号(重音符号等)的英文字母的小写和大写字母、数字、常用标点符号和控制字符。
然后我们就有了一系列 8 位字符集,例如ISO-8859系列、MS-DOS 和 Windows代码页,Mac 字符集, ETC。
这些是 ASCII 的超集(前 128 个值与 ASCII 相同),另外 128 个值用于特定于区域设置的字符(重音字符、替代脚本,例如希腊语或西里尔语...)。
在计算机之间甚至程序之间传输文件时,这会引起各种麻烦,因为并非所有计算机都使用相同的字符集。
在这种情况下,仍然有一个角色一字节。
然后是统一码family,它试图将所有内容统一在一个集合中,该集合显然大于 256,因此无法容纳单个字节。
起初,人们认为 16 位就足够了,于是设计了 UCS-2,使用2字节每个字符(这意味着最多 65536 个可能的字符,尽管并未分配所有字符,这允许 UTF-16)。
然后很明显 2 个字节并不总是足够,因此引入了 UTF-16,它使用代理对对附加字符进行编码。对于BMP(基本多语言平面)中的字符,他们仍然使用2字节确切地说,但对于“额外”字符,它们使用 2 个代码单元,每个代码单元 2 个字节,总共4字节。
UTF-16 是 Windows NT 及其后续版本的本机编码。然而,即使 UTF-16 也存在问题,因为并非每个人都同意两个字节的顺序:小端或大端,所以我们有 UTF-16LE 和 UTF-16BE。有或没有 BOM。
还有 UCS-4 和 UTF-32 使用4字节每个字符(UTF-32 仅限于可以表示为 UTF-16 的值),但这种情况非常罕见。
UTF-8 是一种可变长度编码,可能正在成为最常见的编码。字符可以编码为任何地方1 到 4 个字节之间。
UTF-8 的天才之处在于 Unicode 的 ASCII 部分(代码点 0 到 127)仍然被编码为单个字节,并且保证超出该范围的代码点永远不会包含 0 到 127 之间的字节。这允许一定程度的与具有特殊含义的特定字符的软件兼容,包括路径的
/
(或\
或:
)、编程语言和 shell 的大量标点符号(!=+-*/^"'<>[]{}
等)、控制字符(例如 CR、LF 或制表符、空格等)。
但在 Unicode 中,还有一个额外的复杂性:代码点可以组合。您可以编码é
为单个字符é
(U+00E9 LATIN SMALL LETTER E AND ACUTE),或编码为e
(U+0065 LATIN SMALL LETTER E) 后跟◌́
(U+0301 COMBINING ACUTE ACCENT)。如图所示多普戈蒂的回答,您可以在一个字母上堆叠相当多的组合标记!
变音符号并不是唯一的组合代码点。有很多用于制作变体,尤其是表情符号。你可以改变他们的肤色(