UTF-8 类型为可变长类型,但是UTF-8和unicode转换无需查表,他们的有用信息部分是完全一致的,转换规则如下:
UTF-8
0000 – 007F
0xxxxxxx
0080 – 07FF
110xxxxx 10xxxxxx
0800 – FFFF
1110xxxx 10xxxxxx 10xxxxxx
可见它是根据数值的大小来做长度区分的:
1.小于7F(127)的数,7bit即可存储,一字节的最高bit为0,来和2字节3字节长度做区分,同时也完全兼容ascii;
2.80到7FF最大数占11bit,所以一个字节肯定不够了,需要两个字节来存储,多余的5bit填充110和10,110的含义是接下来两字节一体;
3.0800到FFFF用3字节表示,由于最大数长度达到16bit,还要填充指示长度的信息,所以要使用3字节,剩余填充的8bit中1110的含义为接下来3字节一体。
GBK或GB2313与Unicode之间的转换只能通过查表来实现,姑且算是可变长度的,但它的边长和utf-8不同,GBK中所有汉字都是2字节长度,只有原ascii中的字符是1字节,所以此字符集中只有两种长度的字符,ascii:1字节,非ascii:2字节,并且高位字节的高bit位为1,以示区分。
重要:
linux中,使用vim时默认编码为utf-8,如果.c文件存英文字符,则ascii和utf-8完全一致,所以你可以说编码方式是ascii也可以说是utf-8,甚至可以说是gbk,因为此时它们没有任何区别,但是包含ascii字符以外的字符时,就是utf-8。一般gcc和cl.exe(window平台 vs编译器)在不指定的情况下,选择执行编码方式时,gcc会选择,和源码编码方式一致的执行编码方式, 而cl.exe则 选择gbk编码方式,即使源码编码方式为utf-8,cl.exe也会将utf-8类型的字符串先转化成gbk,在存放在exe可执行文件中,除非我们认为指定cl.exe必须使用utf-8为执行编码方式,cl.exe才会放弃gbk编码,详细见下表。
#include <stdio.h>
int main(int argc, char * argv[])
{
printf("sizeof(\"你好\") = %d\n", sizeof("你好"));
return 0;
}
运行结果为7,可见编码方式为utf-8。
此外,也可以手动设置预编译指令,指定执行编码方式,详细见下表
以下表格个字段含义解释:
源码字符集:使用WinHex查看源码中字符串常量字节流,使用Microsoft Visual Studio 2010菜单“文件 > 高级保存选项”来转换源码字符集。
执行字符集:使用WinHex查看可执行文件中字符串常量的字节流。
是否设置windows预编译选项:#pragma execution_character_set(“utf-8”)
是否设置Linux编译选项:-finput-charset和-fexec-charse
红色显示的就是“汉”的编码:“汉”的GBK编码为BA BA,UTF-8编码为E6 B1 89
Microsoft Visual Studio 2010编译器测试数据:

GCC(版本gcc version 4.4.5)测试数据:
