简单地说,这是两种字符编码方式。通常Unicode使用两个字节表示每个字符,即每个字符为16位二进制长度。而ANSI编码使用一个字节表示每个字符,即8个二进制位。
ANSI本来是美国的国家标准,后来渐渐通行于世。标准的ANSI字符一共有128个,后来扩充到255个,而ANSI使用8位(1个字节)标识每个字符,最多也只能表示这些字符。C语言中的char类型就是用来储存ANSI编码的字符的。Char类型有signed char 和unsigned char两种char,默认的char是有符号的signed char ,可以表示的字符编码范围是-128~127,无符号的unsigned char 可以表示0~255.
继续刚才的话题,ANSI只能表示最多256个字符,对于英文,的确足够,可是对于亚洲地区的复杂语言,这是远远不够的。因此,为了统一一个全世界都可以使用的字符编码,Unicode产生了。UNICODE可以表示65,536(2的16次方) 个字符,足够全世界的文字使用。
下面简单说一下目前Windows的编码。
从WinNT开始(包括使用NT技术的Win2000、XP、Vista等),系统核心内建支持和使用UNICODE编码方案。
为了保持兼容性,中文Windows的默认编码为ANSI方式。那么ANSI如何处理中文呢?
我们知道,标准的ANSI字符有128个,编码从0~127,这些编码包括了最常用的字母、数字和常用标点和排版控制符。而中文和其他一些字符,则被编码为负数开始以区别于标准ANSI。
如果学过计算机数制的知识,那么就能够知道,标准的ANSI字符由于是正数,二进制开头的符号位为0,而表示中文和其他字符的编码规定是负数,所以首位是1,因此,中文Windows在处理字符编码的时候,遇到0,则认为后面的8个位是一个标准ANSI字符,遇到1,则认为后面的16个二进制位表示的是一个非标准ANSI字符,Windows会把这16个位(2个字节)的内容和系统的中文字符编码表(映射表)对比,以确认代表的是什么字符。
所以,普通的中文文件如果在没有对中文提供支持的英文系统上打开(大多数Windows版本是能够正确处理的),则会导致乱码。
还有另外一种形式的因为ANSI的这种字符处理机制产生的乱码,我们可以自己验证一下:
打开记事本,在其中输入“联通”二字,保存,再打开,就会发现其中的文字变成了乱码,这是因为由于ANSI的识别出现问题。
具体的编码方案十分繁杂,关于上面的联通问题,就可以参考
http://blog.csdn.net/GunRosez/archive/2004/11/02/164164.aspx
(GunRosez的专栏)
而UNICODE不会有这方面的问题,它不用更多的转换,每个汉字和每个字母都是一样的两个字节编码表示,不会产生歧义。
总的来说,UNICODE虽然占用的空间肯能稍微多些,在通用性上面是一个更好的选择。
上一篇文章提到了API,实际上,在Windows的API函数中,每一个涉及到了字符串传递的函数,如最基本的MessageBox(用来显示一个消息框),都有两个版本,MessageBoxA和MessageBoxW,前者是ANSI版本,后者是宽字符版本,通常就是UNICODE。
C++中的char是对应ANSI字符的,C++中还有一个基本类型wchar_t就是对应UNICODE字符的。
编程的时候应该首先决定使用更加通用的宽字符UNICODE,还是占用空间较少的ANSI,个人认为应用软件可以使用UNICODE好一些。
除了UNICODE和ANSI,还有和UNICODE关系比较近的几种编码,比如UTF-8等,不过桌面软件应用不是很广泛,而网络上用的稍微多一些,侧重网络开发的.Net框架对各种编码都有很好的支持,VB.net(包括2002、2003、2005)和C#等都默认使用UNICODE编码文本文件和字符串。顺便提一句,VC6、7默认使用ANSI编码,VC2005及以上版本默认使用UNICODE。