字符编码问题
之前关于字符编码问题在网上看了不少文章
还有关于Java采用Unicode编码这句话到底应该怎么理解?
以及Java面试题:Java中,char型变量中能不能存储一个中文汉字,为什么?
等等这些一连串的问题。
刚开始确实被误导了不少概念,不过现在总算是理清了。在此做一下记录。
字符编码简单分析一下
- 世界万物在计算机上是用0和1来表示的,所以全球的字符、符号都是可以用0和1来表示
- Unicode是计算机业界标准,给世界上所有的字符都规定了唯一的编号
- GB2312、GBK等,GB开头的 主要是针对中文常见字符,规定了另一套编号
- ASCII是美国为了表示 美国所需要的128个字符规定了一套编号标准
- 当然除此之外还有其他,比如ISO 8859-1
计算机存储单位 几个概念
1bit:也叫1位、1比特;
8位: 即 2 8 2^{8} 28 用二进制来表示是10000000 可以表示256个字符;
1B: 即1字节;
1B(byte,字节)= 8 bit 所以1B可以表示256个字符;也是计算机的最小存储单位
1KB(Kilobyte,千字节)=1024B= 2^10 B;
1MB(Megabyte,兆字节,百万字节,简称“兆”)=1024KB= 2^20 B;
1GB(Gigabyte,吉字节,十亿字节,又称“千兆”)=1024MB= 2^30 B;
ASCII(American Standard Code for Information Interchange)
- 用1B(1字节)的大小来表示英文的128个字符,最高位设置为0
- 所以如果是按照ASCII来的话,每一个英文字母占用的大小都是1B
GB2312
- 字体名称:仿宋
- 固定使用2B(2字节)来表示一个汉字,不过还是不够表示所有汉字,但可以表示绝大部分常见的汉字
- 表示英文字符:如果两个字节最高位都是0,就表示ASCII字符
- 表示汉字:如果两个字节最高位都是1,就表示汉字
GBK(Chinese Internal Code Specification)
- GBK全称《汉字内码扩展规范》GBK即“国标”、“扩展”汉语拼音的第一个字母
- 固定使用2B(2字节)来表示一个汉字,表示的范围比GB2312大一些,包括了罕用字符和繁体字
Unicode(Universal Code)
Unicode为全世界所有的字符都进行了编码 大概有一百多万,那这一百多万个字符该用多少个字节来表示呢?对于这个问题有以下几种解决方案:
- UTF-32(UCS Transfromation Formate 32bit)
- 全部用4个字节的二进制表示,也就是32位,编号不够的二进制位补零
- 任何一个字符都是32位,无论字母还是汉字
- UTF-16(UCS Transfromation Formate 16bit)
- 采用变长字节表示
- 一部分用4个字节表示,一部分用2个字节表示
- 因为2个字节可以表示绝大部分字符,因此比较节省空间
- UTF-8(UCS Transfromation Formate 8bit)
- 采用变长字节表示
- 用1个字节、2个字节、3个字节、4个字节表示的都有
- UTF-8兼容ASCII,所以,用一个字节表示的英文字符就和ASCII一样了
- 对于大部分汉字来讲,需要用三个字节来表示,可能是为了兼容ASCII做出的牺牲吧!
关于Java中,char型变量中能不能存储一个中文汉字,为什么?
- 首先答案是当然可以
- 为什么?
- char 数据类型 本身占用2个字节大小
- Java采用Unicode编码,意思是按照Unicode上的编号来解析二进制数
- 汉字有的占2个字节,有的占4个字节(比如一些生僻字"𫝈、𫝉、𫝊、𫝋",属于汉字 Unicode 编码扩展部分的)
- 两个字节的肯定可以表示
- 4个字节的就不可以表示了
补充:ANSI
- ANSI标准:一种标准,美国国家标准学会(AMERICAN NATIONAL STANDARDS INSTITUTE: ANSI)
- ANSI:一种字符代码,即表示字符的代码。如:在简体中文Windows系统中的ANSI编码是GBK编码,而在日文Windows系统中的ANSI编码则是另一种编码方式