惧留孙网

juliusun.com

惧留孙网 > 在线教程 > WIN32 SDK教程

UNICODE 和 ANSI 编码

  C语言,char为字符型,占用一个字节,在ASCII码表中即可查到其数字对应的字符。如65对应的字符是A。出现一个问题是,char类型只占用一个字节,1个字节有8位,每位只有0和1两种状态,那么一个字节,即8位,最多有2的8次方即256种结果。256种结果表示英文及数字足够了,但是表示汉语、韩语、日语等有几万个字符的语言,是不够的。解决这个问题,出现了两种解决方法。即UNICODE和ANSI。

  先说说ANSI的解决方法。ANSI解决这个问题是方法是,把一个字节的8位分成两部分,第一部分占1位,当作标志位;第二部分占7位,当作字符编码,我们简单他称它为编码位。也就是说只用一个字节中的7位表示字符,你查ASCII表会知道,ASCII表字符都在0-127范围内,即2的7次方。当表示英文及汉字的时候。标志位为0,编码位表示字符的ASCII码。当标志位为1的时候,系统会把这个字节,和后面的字节两个字节合起来,算作是一个字符。两个字节合起来,是16位,除了标志位,还有15位可以当作编码位。也就是有2的15次方即32768种结果,这样就能表示更多的字符了。因此ANSI编码里,英文字符(包括数字)占用一个字节,其它字符占用两个字节。

  再说说UNICODE的解决方法。UNICODE的解决办法是,用两个字节即16位表示一个字符,无论是英文、汉字还是其它语言字符。那么就有2的16次方即65536种表示结果。这表示各种语言字符,差不多够用了。

  关于ANSI和UNICODE,如果你理解不了以上内容,你可以简单的认为,ANSI编码中英文及数字占用一个字节,其它字符占用两个字节。UNICODE中,所有字符都占用两个字节。当然,为了表示更多字符,还有其它很多种表示方法,不过Visual C++(简称VC)只识别ANSI和UNICODE这两种编码。

  ANSI编码又称为 多字节编码、多字节字符集,英文名multibyte,UNICODE又称 宽字节编码、宽字节字符集,英文名widechar。不同资料称呼不同,注意多字节宽字节、或多字符宽字符这几个关键词即可。

  在以后的教程中Visual C++系列编译器简称VC。

  VC中,ANSI类型字符仍然用char来定义,UNICODE类型字符,用wchar_t来定义,VC通过typedef把wchar_t定义成了WCHAR类型,即typedef wchar_t WCHAR;,所以WCHAR就是wchar_t类型。为了区分ANSI和UNICODE编码,ANSI编码的字符仍然是单引号引起来的字符,如'a',而UNICODE字符则需要在引号前加大写的L,如UNICODE的写法为L'a'。同理,对于字符串。ANSI编码的字符串是char类型数组,UNICODE编码的字符串是wchar_t类型数组。UNICODE需要在字符串的双引号前加L。如"hello"是ANSI类型的字符串、L"hello"是UNICODE类型字符串。举例说明:

    wchar_t chw = L'a';  //chw 是UNICODE类型字符变量,占用2个字节
    char  ch = 'a';    //ch 是ANSI类型字符变量,占用1个字节

    wchar_t chw = L'中';  //chw是UNICODE编码字符,占用两个字节
    char ch = '中';    /*ch是ANSI编码字符,占一个字节,由于字符'中'编码是0xd6d0,而ch只占一个字节,所以取低8位,即0xd0,这样定义会损失高8位,好比把short类型转换成char一样*/

    wchar_t wcs[] = L"好a";  //wcs是UNICODE字符数组,三个元素L'好'、L'a'、L'\0',每个元素占用两个字节,共占用6个字节。
    char str[] = "好a";    //str是ANSI类型字符数组,三个元素中'好'占用两个字节,'a'和'\0'占用一个字节,共占用4个字节。

  字符串长度的计算。计算UNICODE字符串长度很好计算,两个字节是一个字符,如L"你好abc",有5个字符,2个汉字,3个英文字符,长度是5。ANSI字符长度在计算时,占用两个字符位置的字符,长度也算2。如strlen("你好abc")返回长度是7(strlen等处理ANSI编码的函数不能用来处理UNICODE字符,以后详细介绍),因为两个汉字占用了4个字符位置,3个英文占用三个字符位置,长度是7。

  UNICODE和ANSI编码的优缺点。UNICODE编码系统处理效率高,占用空间大,计算字符串占用空间算法简单。ANSI编码,系统处理效率低,占用空间小,计算字符串占用空间算法复杂。UNICODE优点是系统处理速度快,两个字节对应一个字符,缺点是,存储有英文字符时,占用空间较大。计算指定字符串占用空间大小容易,如L"好a"两个字符加上结尾L'0'三个字符占用6个字节。ANSI估缺点和UNICODE对应,由于有的字符占用一个字节,有的占用两个字节,系统需要区分,系统处理速度慢。优点是,存储英文字符时占用空间小。计算字符串占用空间时比UNICODE复杂,如"好a",要判断'好'是汉字,占用两个字节,加上'a'和'\0'英文字符共占用4个字节。

  在VC中,默认wchar_t是内置类型,如果在设置中关闭wchar_t为内置类型选项。VC是用unsigned short来处理wchar_t。VC6默认是ANSI编码,从Visual Studio 2010(包括Visual C++ 2010各版本在内)及以后的版本默认都是UNICODE编码。至于Visual Studio 2008及以前的版本,笔者由于长时间未用或从未使用过,不太了解默认用哪种编码,应该还是UNICODE的可能性较大。

  目前Windows主流系统(从Windows 2000开始)使用的内核是Win NT内核,以前的Windows版本如Windows 98、Windows 95等多用Win 9x内核(Win 9x名称可能就是因为采用这个内核的系统多是Windows 95、98等9开头的版本)。在系统内部Win NT内核使用的是UNICODE编码,Win 9x内核使用的是ANSI编码。

  Windows系统中,提供给开发者使用的的API(以函数形式),在涉及到字符时,都有ANSI和UNICODE两个版本。ANSI版本的API参数及返回值多为ANSI字符,UNICODE版本的API用的是UNICODE参数及返回值。开发者可以自行决定调用哪类API(当然,混用一点问题也没有,且Windows提供了ANSI和UNICODE两个字符或字符串相互转化的函数,可以随意转化)。

  用ANSI和UNICODE哪个好?目前我们进行开发,不必考虑Win 9x内核了。Windows 98系统及更早版本已经可以忽略了。我们只考虑Win NT内核。Win NT内核使用的是UNICODE。所以当我们调用UNICODE版本的函数时,是直接执行的。当我们调用ANSI版本的函数时,系统会在内部先把ANSI字符转化成UNICODE,再让内核执行,这会让程序效率降低。如果我们不考虑编译器默认编码,UNICODE字符特点是:效率高、占用空间大、字符串长度和占用空间关系容易换算;ANSI字符特点相反:效率低、占用空间小、字符串长度和占用空间关系换算复杂。综合衡量,UNICODE编码更好一点。不过初学者开发的程序对效率通常要求不高,如果你的编译器(如VC6)默认是ANSI编码,建议你同样采用ANSI编码,这样学习起来更简单。

  为什么Visual C++ 6.0默认编码是ANSI?因为VC6是针对Windows 98设计的,Windows 98内核是Win 9x内核,内核使用ANSI编码,所以VC6默认是ANSI编码。虽然编译器与Windows版本有对应关系,但是编译器兼容性很强,一般情况下,跨版本使用问题不大,考虑到多数人还在使用Windows XP等原因,目前很多公司开发仍在采用Visual C++ 2008。常用编译器及系统版本对应关系如下:

Visual C++ 6.0对应Windows 98
Visual Studio 2005(vs8.0)对应Windows XP
Visual Studio 2008(vs9.0)对应Windows Vista
Visual Studio 2010(vs10.0)对应Windows 7

  如果以上内容难以理解,可以只了解大概,会在以后的学习中,慢慢加强和深入。

视频教程

作者QQ:3304576112  交流QQ群:316930386 C语言窗口程序学习群 本教程内容由 juliusun.com 保留版权,请匆复制传播。

上一页  目录  下一页
抖音
©2015-2024 惧留孙网 juliusun.com

京ICP备15039193号-1

首页 教程 下载 文章 聊天 我的