关于宽字符和窄字符之间的区别,以及为什么当我们采用Printf和char*的时候可以输出一个中文字符,大概是因为默认情况下的编码方式是UTF-8的编码方式。
具体的可以参考这两篇博客:关于宽字符和窄字符 和 关于宽字符
Unicode或者宽字符都没有改变char数据型态在C中的含义。char继续表示1个字节的储存空间,sizeof (char)继续返回1。理论上,C中1个字节可比8位长,但对我们大多数人来说,1个字节(也就是1个char)是8位宽。
C中的宽字符基于wchar_t数据型态,它在几个表头文件包括WCHAR.H中都有定义,像这样:
typedef unsigned short wchar_t ;
因此,wchar_t数据型态与无符号短整数型态相同,都是16位宽。
宽窄字符与UTF16,UTF8不是对应的关系。宽窄字符是与一个字符所占的字节数有关,如果 一个字符只占一个字节,那么那么它就是窄字符,一个宽字符通常占2个字节。在c/c++/objective c 中,如果你想把一个窄字符(例如ASCII 字符)表示为宽字符通常的做法是使用wchar来取代char,例如 wchar t = 'A'; wchar_t * p = L"Hello!" ; 这里每一个字符都占了2个字节,并且采用了UTF16编码。 |
2. UTF8和UTF16是unicode的两种编码方法,他们都是采用了可变的字节长度来表示一个字符,例如UTF8是
使用1个字节到4个字节来表示世界上各种语言的不同字符。而UTF16则是2个字节到6个(?记不清了)字节来表示不同
字符。他们的最主要区别在于字符的最小字节数(UTF8是1,UTF16是2)。
这也就造成了UTF8可以和ASCII编码相兼容(那7位的ASCII字符在ASCII与UTF-8下的编码是相同的),
但是UTF16却不可以,以至于对于UTF16的字符串我们必须使用类似于wprintf专门的函数来处理宽字符。
另外对于mac os objective c下普通c string采用的是UTF8编码,所以
在英文系统下你通过printf依然可以正确的输出中文等字符,例如:
const char* str = "你好";
printf("%s", str);
这里printf支持utf8,并不会出现乱码。
但是如果使用
const char* str = "你好";
NSLog(@"%s", str);
输出的却是乱码,很奇怪,NSLog竟然不支持utf8。