汉字到底占几个字节丨C

这里写图片描述


首先需要注意

汉字所占字节数,与所使用语言自身没有关系,是与其使用的字符集的编码方案有关


验证方法

1.把下面代码保存到一个文本文体中

#include <stdio.h>
#include <string.h>
int main(){
        char *a = "我";
        printf("%d",strlen(a));
        return 0;
}

2.在终端中用vim打开保存上面代码的文件。

    \>vim char.c       ( >表示终端中输入)

3.在vim中输入如下 :set fileencoding 会显示当前编码格式。(冒号不能省略)


4.把文件编码改为utf-8 在打开的文件中输入 :set fileencoding=utf-8 冒号不能省,保存文件。


5.编译执行

   >gcc char.c
   >./a.out

6.重复3-5步,把第四步utf-8改为gb2312
:set fileencoding=gb2312


7.两次打印一个3,一个2


结论

到底C语言中的汉字占用几个字节,只跟其采用的字符集的编码方案有关

gb2312中占用2个字节,utf-8中占用3个字节


额外介绍字符集与编码方式

一、中文可能碰到的编码

ANSI:最早的时候计算机ASCII码只能表示256个符号(含控制符号),这个字符集表示英文字母足够,其中,我们键盘上可见的符号的编码范围是从32到126(大小写英文字母、数字、英文符号等)。但表示汉字、日语、韩语就不太够用了,汉字常用字有3000多个。

不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码

但是中国人也要用电脑打字,于是,中国人就研究出来了最早的中文字符集GB2312(GBK就是后来的扩展),GB2312的做法是,把ASC码取值范围的128~255这个区间挪用了一下,用两个ASC码表示一个汉字,这样可用的编码范围用十六进制表示就是0x8080到0xFFFF,这大概能表示一万多个符号,足够了。[注:实际没用那么多,GBK的范围是8140-FEFE]

那个时候,计算机技术还不发达,各个国家搞自己的,比如台湾,也另搞了一套,叫BIG5(俗称:大五码),跟大陆的也不太一样,但方法是类似的,都是用0x80到0xFF这个区间。然后日语(有编码JIS)、韩语等等也各搞一套。

这些国家的编码区间都是重叠的,但同一个汉字(比如有一些汉字同时存在于简体、繁体、日语汉字中)有不同的编码,很混乱是不是?但也凑合用了。编码不同导致了很多麻烦,比如一个网页,如果你不知道它是什么编码的,那么你可能很难确定它显示的是什么,一个字符可能是大陆简体/台湾繁体/日本汉字,但又是不同的几个字。所以如果用一些很老的软件,可能会听说有中文版/日文版之类的,对应的版本只能在对应的系统上运行。

后来,这个对操作系统的开发实在是太困难了,因为这意味着不同语言的版本,都要重新编码。于是发明了Unicode。

Unicode这个东西,就是要把地球上所有的语言的符号,都用统一的字符集来表示,一个编码真正做到了唯一。

Unicode里有几种编码方案:

UTF-8:UTF-8则是网页比较流行的一种格式:用一个字节表示英文字符,用3个字节表示汉字,准确的说,UTF-8是用二进制编码的前缀,如果某个UTF-8的编码的第一个字节的最高二进制位是0,则这个编码占1字节,如果是110,则占2字节,如果是1110,则占3字节……

UTF-16BE/LE:UTF-16就是Windows模式的编码模式(Windows里说的Unicode一般都是指这种编码),用2个字节表示任意字符,注意:英文字符也占2个字节(变态不?),这种编码可以表示65536个字符,至于LE和BE,就是一个数值在内存/磁盘上的保存方式,比如一个编码0x8182,在磁盘上应该是0x81 0x82呢?还是0x82 0x81呢?就是高位是最先保存还是最后保存的问题,前者为BE,后者为LE。

UTF-32:UTF-32对每个字符都使用4字节,用得很少,太费空间

二、字符集与编码格式

对于 ASCII、GB 2312、Big5、GBK、GB 18030 之类的遗留方案来说,基本上一个字符集方案只使用一种编码方案。
比如 ASCII 这部标准本身就直接规定了字符和字符编码的方式,所以既是字符集又是编码方案;而 GB 2312 只是一个区位码形式的字符集标准,不过实际上基本都用 EUC-CN 来编码,所以提及「GB 2312」时也说的是一个字符集和编码连锁的方案;GBK 和 GB 18030 等向后兼容于 GB 2312 的方案也类似。

于是,很多人受这些遗留方案的影响而无法理解字符集和编码的关系。

对于 Unicode,字符集和编码是明确区分的。Unicode/UCS 标准首先是个统一的字符集标准。而 Unicode/UCS 标准同时也定义了几种可选的编码方案,在标准文档中称作「encoding form」,主要包括 UTF-8、UTF-16 和 UTF-32。
所以,对 Unicode 方案来说,同样的基于 Unicode 字符集的文本可以用多种编码来存储、传输。
所以,用「Unicode」来称呼一个编码方案不合适,并且误导

<think>好的,用户现在问的是“汉字几个字”。之前他们问过关于C语言存储打印中文的问题,当时我详细解释了不同编码方式下的存储方法,包括UTF-8宽字符。现在这个问题可能也是他们在处理字符编码时遇到的疑惑,尤其是在不同的编码标准下,汉字字节数可能不同。 首先,我需要确定用户的具体需求。他们可能是在编程中遇到了中文字符处理的问题,比如字符串长度计算、内存分配或者文件存储时需要考虑字符的字节数。了解这一点后,我应该详细说明不同编码标准下的差异,比如UTF-8、GBK、Unicode等,以及在不同环境下(如不同操作系统或编程语言)的情况。 接下来,我要回顾之前的回答。在之前的C语言存储中文部分,我提到了UTF-8中每个汉字3字节,而宽字符在Windows是UTF-16(2或4字节),Linux是UTF-32(4字节)。这里需要进一步扩展,说明不同编码标准的具体情况,比如GBK是2字节,Unicode的不同编码形式等。 同时,用户可能对为什么会有不同的字节数感到困惑,需要解释编码的基本原理,比如ASCII兼容性、变长编码等。此外,可能还需要提到实际应用中的注意事项,比如在编程时如何正确处理多字节字符,避免常见的乱码问题。 另外,考虑到用户之前的问题涉及C语言,可能需要补充在不同编程语言中处理汉字字节数的差异,但用户这次的问题比较通用,所以重点应放在编码标准本身,而不是特定语言。 还要注意用户可能的误区,比如认为所有汉字都固定占用2或3字节,需要强调编码方式的不同导致的变化,以及如何判断当前使用的编码方法。此外,示例部分可以举一些常见编码的例子,帮助用户理解。 最后,总结关键点,确保用户能够根据实际需求选择合适的编码方式,并注意编码一致性,避免乱码。需要提醒用户在处理汉字时,始终明确编码方式,并进行必要的测试验证。</think>在计算机中,**汉字字节占用取决于具体的字符编码标准**,以下是常见编码方案的说明: --- ### 1. **ASCII 编码** - **无法存储汉字**,仅支持英文字符(1字节)。 --- ### 2. **GBK/GB2312 编码** - **每个汉字 2 字节** - 例:"`汉`" → `0xBABA`(2字节十六进制) - **适用范围**:早期中文Windows系统默认编码。 --- ### 3. **UTF-8 编码** - **每个汉字 3 字节** - 例:"`汉`" → `0xE6B189`(3字节十六进制) - **特殊规则**: - 部分生僻汉字或扩展字符可能 4 字节- **适用范围**:现代跨平台应用的主流编码(推荐使用)。 --- ### 4. **UTF-16 编码** - **基本汉字 2 字节** - 例:"`汉`" → `0x6C49`(2字节十六进制) - **特殊规则**: - 部分扩展字符(如Emoji)需用 **4 字节(代理对)**。 - **适用范围**:Java、Windows API 内部常用。 --- ### 5. **UTF-32 编码** - **所有字符固定 4 字节** - 直接存储Unicode码点,无兼容性优化。 - **适用范围**:内存处理场景(如文本分析)。 --- ### 6. **实际应用注意事项** 1. **编码一致性**: - 文件保存、程序读取、终端显示的编码需统一(推荐UTF-8)。 2. **编程中的陷阱**: ```c // C语言中,strlen("汉")返回字节数(UTF-8时为3) printf("%zu", strlen("汉")); // 输出 3 ``` 3. **判断编码方式**: - 通过文本编辑器查看(如VSCode右下角显示编码类型)。 - 使用工具检测(如Linux `file -i filename`)。 --- ### 7. **不同场景示例** | 编码类型 | 汉字 "中" 的字节表示 | 总字节数 | |----------|-----------------------------|----------| | GBK | `0xD6D0` | 2 | | UTF-8 | `0xE4B8AD` | 3 | | UTF-16 | `0x4E2D`(小端序为`0x2D4E`)| 2 | | UTF-32 | `0x00004E2D` | 4 | --- ### 总结 - **常规使用**:优先选择UTF-8(兼容性强,跨平台)。 - **旧系统兼容**:GBK(需注意2字节限制)。 - **明确需求**:根据文件
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值