经常使用编辑器的小伙伴应该经常能看到右下角会有这么两个选项,下图是VScode中的示例,那么这两个到底是啥作用呢?
目录
- 字符编码
-
- [ASCII 字符集](#ASCII 字符集)
- [GBK 字符集](#GBK 字符集)
- [Unicode 字符集](#Unicode 字符集)
- [UTF-8 编码](#UTF-8 编码)
- 换行
字符编码
在计算机中,所有数据都是以二进制数的形式存储的,字符 char 也不例外。通过建立一套"字符集",规定每个字符和二进制数之间的一一对应关系,这样计算机就可以通过查表完成二进制数到字符的转换。
ASCII 字符集
使用 7 位二进制数(一个字节的低 7 位)表示一个字符,最多能够表示 128 个不同的字符。ASCII 码包括英文字母的大小写、数字 0 ~ 9、一些标点符号,以及一些控制字符(如换行符和制表符)。(无中文字符)
GBK 字符集
GBK 字符集是在 GB2312 的基础上扩展得到的,它共收录了 21886 个汉字。在 GBK 的编码方案中,ASCII 字符使用一个字节表示,汉字使用两个字节表示。
Unicode 字符集
Unicode 的中文名称为"统一码",理论上能容纳 100 多万个字符。它致力于将全球范围内的字符纳入统一的字符集之中,提供一种通用的字符集来处理和显示各种语言文字,减少因为编码标准不同而产生的乱码问题。在庞大的 Unicode 字符集中,常用的字符占用 2 字节,有些生僻的字符占用 3 字节甚至 4 字节。
当多种长度的 Unicode 码点同时出现在一个文本中时,系统如何解析字符?例如给定一个长度为 2 字节的编码,系统如何确认它是一个 2 字节的字符还是两个 1 字节的字符?对于以上问题,一种直接的解决方案是将所有字符存储为等长的编码。如下图所示,"Hello"中的每个字符占用 1 字节,"算法"中的每个字符占用 2 字节。我们可以通过==高位填 0 ==将"Hello 算法"中的所有字符都编码为 2 字节长度。这样系统就可以每隔 2 字节解析一个字符,恢复这个短语的内容了。
UTF-8 编码
UTF-8 已成为国际上使用最广泛的 Unicode 编码方法。它是一种可变长度的编码,使用 1 到 4 字节来表示一个字符,根据字符的复杂性而变。ASCII 字符只需 1 字节,拉丁字母和希腊字母需要 2 字节,常用的中文字符需要 3 字节,其他的一些生僻字符需要 4 字节。UTF-8 的编码规则并不复杂,分为以下两种情况。
- 对于长度为 1 字节的字符,将最高位设置为 0,其余 7 位设置为 Unicode 码点。值得注意的是,ASCII 字符在 Unicode 字符集中占据了前 128 个码点。也就是说,UTF-8 编码可以向下兼容 ASCII 码。
- 对于长度为 n(n>1)字节的字符,将首个字节的高n位都设置为 1,第 n+1位设置为0;从第二个字节开始,将每个字节的高 2 位都设置为10(校验符);其余所有位用于填充字符的 Unicode 码点。
除了 UTF-8 之外,常见的编码方式还包括以下两种。
- UTF-16 编码:使用 2 或 4 字节来表示一个字符。所有的 ASCII 字符和常用的非英文字符,都用 2 字节表示;少数字符需要用到 4 字节表示。对于 2 字节的字符,UTF-16 编码与 Unicode 码点相等。
- UTF-32 编码:每个字符都使用 4 字节。这意味着 UTF-32 比 UTF-8 和 UTF-16 更占用空间,特别是对于 ASCII 字符占比较高的文本。
从存储空间占用的角度看,使用 UTF-8 表示英文字符非常高效,因为它仅需 1 字节
;使用 UTF-16 编码某些非英文字符(例如中文)会更加高效,因为它仅需 2 字节
,而 UTF-8 可能需要 3 字节。
从兼容性的角度看,UTF-8 的通用性最佳,许多工具和库优先支持 UTF-8
。
换行
CRLF (Carriage Return Line Feed ):回车换行符,由CR字符后跟LF字符组成,即\r\n
,\r
是回车符,\n
是换行符。在Windows操作系统以及基于DOS的系统中使用CRLF作为行结束符。CRLF的作用是先执行回车操作(回到行首),再执行换行操作(移动到下一行),从而在文本数据流中创建一个新行。各个系统的换行标志:
- windows 用
\r\n
- linux/unix 用
\n
- Mac OS 用
\r
在不同操作系统下时,需注意这个行尾序列,也就是换行符的表示。
❗️❗️❗️从linux随便取一个有多行内容的文件到windows,用记事本打开,在linux下换行的内容会不换行,如果有N行,会变成一行显示,原因是linux取下来的文件只有\n
,但没有\r
。