关于char wchar_t 和 unicode utf8等混淆概念

本文深入解析了计算机中字符编码的基本原理,包括ASCII、Unicode与UTF-8的区别与联系,揭示了不同编码方式如何处理多语言文字,如中文字符,并详细解释了wchar_t与UTF-8的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下内容转载:

对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。

******************************

首先,内存中的数据是单纯的二进制数据,当然你要用十六进制来表示它也可以
不管你用什么指针指向这段内存,数据就是数据,不会有任何改变
你是用char*也好,用int*也罢,甚至用string*都一样,它们都只是指针,类型+地址而已,和它们指向的那段内存的数据没有任何关系——当然在使用中一般是有关系的,否则就是写代码的人有问题了

其次,中文是什么?英文是什么?日文是什么?
全部都是符号,全部都是概念,落在纸面上全部都是图形
和二进制有关系?一丁点的关系都没有

那么,什么是字符集?
规定二进制数据和某种语言内的文字之间的对应关系,这就叫该种语言的字符集
最基本的是ASCII,规定数值48对应字符'0',诸如此类,但由于这种对应关系的历史局限性(发明它的人当时没兴趣考虑非英文语言),同样的二进制数据,在不同的字符集内就对应不同的文字
而规定一套对应关系,使得二进制数据能够对应很多语言的文字,这就叫Unicode

unicode和utf8等等格式,本质上是不同的对应关系
char*可以用来指向各种数据的内存,不是因为它们都是char字符数据,而是因为char的大小是1个字节,方便指针控制(如果你要用void*指向各种内存,概念上是更加正确了,你试试看怎么偏移指针)
wchar_t其实就是typedef的2字节short,也就是对应unicode的编码范围为2字节数据,用的就是这种数据类型的字节数而已
所以char*和wchar_t*指向同一段内存,有什么错?一点错误都没有,它们都只指向这一段二进制数据而已,区别就在于你使用这两种类型的指针来操作数据的时候,按照相应的类型来操作这段内存,仅此而已

还有什么问题吗?


google半天,没有说char为啥能够支持中文。

——按你的说法,char可以“支持”任何类型的变量,因为它们都是以字节为基本单位的二进制数据
——不是char支持中文,而是char*可以指向一段存有二进制数据的内存,这段内存中的数据按照某种对应关系对应中文的文字集合,而你用来显示文字的显示模块也按照这种对应关系来转换二进制数据到文字相关属性(文字图形等)
——所以正确的说法是,你用来显示/处理文字的函数/模块,支持中文这个文字集合,以及你所选择的unicode这种对应关系

******************************

wchar_t unicode[1]=L'汉';//0x49 0x6c ;Little endian unicode 0x6c49
//UTF-8 编码字符理论上可以最多到 6个字节长,但目前全世界的所
//有文字和符号种类加起来也只要编到 4个字节长就够了。
//  UTF-8 是以 8位(即 1个字节)为单元对原始码进行编码(注意一
//点:这里所讲的原始码都是指Unicode码),并规定:多字节码(2个字
//节以上才称为多字节)以转换后第1个字节起头的连续“1”的数目(这
//些连续“1”称为标记位),表示转换成几个字节:“110”连续两个
//“1”,表示转换结果为2个字节,“1110”表示3个字节,而“11110”
//则表示4个字节……跟随在标记位之后的“0”,其作用是分隔标记位和
//字符码位。第2~第4个字节的起头两个位固定设置为“10”,也作为标
//记,剩下的6个位才做为字符码位使用。
//  这样,2字节UTF-8码剩下11个字符码位,可用以转换0080~07FF的
//原始字符码,3字节剩下16个字符码位,可用以转换0800~FFFF的原始字
//符码,由此类推。编码方式的模板如下:
//
//原始码(16进制) UTF-8编码(二进制)
//--------------------------------------------
//0000 - 007F       0xxxxxxx
//0080 - 07FF       110xxxxx 10xxxxxx
//0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx
//……
//--------------------------------------------
//
//  模板中的“x”表示字符码。
//  VB能识别的 Ascii码<007F,所以在VB中,Ascii码都只能编为1个
//字节的UTF-8码。汉字的 Unicode编码范围为0800-FFFF,所以被编为
//3个字节的UTF-8码。
//  例如“汉”字的Unicode编码是6C49,6C49在0800-FFFF之间,所以
//要用3个字节的模板:1110xxxx 10xxxxxx 10xxxxxx。
//1110xxxx 10xxxxxx 10xxxxxx
//11100110 10110001 10001001 0xE6,0xB1,0x89
//    0110   110001   001001
//0110110001001001 0x6c49
char utf8[3]={0xE6,0xB1,0x89};//utf8 汉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值