当前位置:C++技术网 > 资讯 > 程序员不得不知道的内码ANSI

程序员不得不知道的内码ANSI

更新时间:2015-06-27 00:04:10浏览次数:1+次

    看了网上一些文章对内码的解释,实在是没有说清楚内码的最简单的理解。总是游走在外面。虽然很多人能够大概明白是怎么一回事,但是自己再说也说不出个所以然,而对于初学者,更是看得似懂非懂。那就让我来打通它吧。
    其实计算机的各种技术,如果你能够真正理解透了,就可以对于很多技术都能够快速理解。因为很多技术不仅仅是原理很像,根本上就是一回事,只是应用的场合不一样,所以叫法不一样罢了。写作本文的目的,就是将这个内码ANSI的本质含义分析出来。
    写过Windows程序的朋友一定知道一个常识,Windows API函数是有两种版本的,一种是Unicode版本,一种是ANSI版本,Unicode版本通常叫做宽字符版本,而ANSI版本叫做窄字符版本。Unicode是一种全球统一编码,处理起来更加方便。而ANSI编码则是内码。函数的这两种版本,指的是对函数中要处理的字符的解释的版本。如果是Unicode版本,则将参数传入的字符按照Unicode编码来解释,而如果是ANSI版本,则需要根据代码页和代码页对应的字符集的字符集编码来解释。从这里可以看出,处理Unicode版本的字符是非常方便的,而处理ANSI字符则较为麻烦。因此,微软的API都提供了标准版本为Unicode版本,ANSI版本函数会将ANSI编码的字符在函数内部会转换成Unicode版本字符,然后再调用对应的Unicode版本的函数进行处理。还有些API函数,压根就只有Unicode版本的。相信在以后,可能会只用Unicode版本的API函数吧。从这里也可以看出,使用Unicode版本的函数效率更高,处理起来也更加方便。
    在Windows内部,都是以Unicode编码来运作的,所以,底层是很方便处理的。为了兼容以前的版本,才不得不保留了ANSI版本。在文章《 轻松彻底理解符号、字符和字符集(ASCII、Unicode)  》和《字符集与字符编码的关系详细分析 》详细解释了字符集和字符集编码相关的问题。从中提到了Unicode是全球统一的字符编码。为了将全球的文字编码到一个字符集编码中,为了方便的处理,自然会对各种类型各个国家的字符放在不同的区段中。微软将每一个区段叫做代码页。比如ACSII编码就对应与Unicode的最低的128个位置,从0到127的128个编号就是ASCII编码的范围。我们可以理解为这是第一个代码页。之后128号到某一个号段,是另外一种字符集的编码。而一个代码页中的字符集的编码,则是对应的字符集的编码,比如ASCII。Unicode只是将所有的字符集编码整合到了一起而已。代码页就是某一个字符集在Unicode的一个区段的编号,一个字符集就是一个区段。当然这只是大概的理解。然而Unicode的编码,实际上并不是真的只是简单的将各个国家的编码简单的整合成一个,而是根据全世界字符的类型,分门别类,然后再将一个国家的放在一块,这样,相同的字符都在一个代码段中,在一个代码段中,可能有几个国家的字符,比如中文和日文在一组,而中文都在一起,这样就可以将中文所在的位置的起始编号和结束的编号就作为中文字符在Unicode的范围。所以Unicode编码中还有不是字符的图形符号等。
    而内码则是微软定义的在Windows中使用的一种逻辑编码。这个内码叫做ANSI。ANSI并不对应一个实际的字符集的字符。它只是逻辑的一段编号。从0到一个数字。使用时根据系统设置的区域语言,来将ANSI字符转换成对应的区域语言的字符集编码。而读取解释字符的时候,也会根据系统设置的区域语言来获取对应的字符集编码来解释字符。也就是说,如果你在中文的系统用文本编辑器以ANSI编码存储到文件中,那么系统会将ANSI编码根据当前系统的区域语言获取对应的代码段,从而得到对应的字符集编码,将字符按照实际的编码存储。读取文件时,也会根据当前系统的区域语言获取对应的字符集编码来解释存储的字符,如果当期是中文的,那么就能够正确的读取出字符。如果先将系统的区域语言设置为英文,那么重启系统后,再读取此文件,则会按照ASCII编码来解释中文,自然也就出现了乱码。只要存入时系统的区域语言和读取时的区域语言不一样,就会出问题。这个问题实际山就是不同编码的错乱,一种编码存储就只能用另一种编码读取解释。

    更改系统区域设置步骤如下:
    系统区域设置可确定用于在不使用 Unicode 的程序中输入和显示信息的默认字符集(字母、符号和数字)和字体。这可让非 Unicode 程序在使用指定语言的计算机上运行。在计算机上安装其他显示语言时,可能需要更改默认系统区域设置。为系统区域设置选择不同的语言并不会影响 Windows 或其他使用 Unicode 的程序的菜单和对话框中的语言。

1.打开控制面板,单击打开“区域和语言”。
2.单击“管理”选项卡,然后在“非 Unicode 程序的语言”下单击“更改系统区域设置”。  如果系统提示您输入管理员密码或进行确认,请键入该密码或提供确认。
3.选择语言,然后单击“确定”。若要重新启动计算机,请单击“立即重新启动”。

    以上内容,最好是亲自试验一下,这样体会和理解会更加深刻。区域语言选项给你选择,是让系统清楚的判断你所要选择的编码在Unicode的哪一段,然后系统就可以判断出代码页,然后做对应的转换。内码ANSI就是要这样转来转去的。
    而是用Unicode字符集的编码UTF-8、UTF-16,UTF-32等字符集编码存储的字符,只要操作系统支持Unicode编码,到哪里都是一样的。不会因为缺少字符集等显示乱码。而ANSI这个转换机制会让编码变得复杂,从而更容易出错。程序中界面显示的都是用Unicode字符,那么不管你换什么区域语言,都不会有任何影响,而如果使用ANSI编码显示的字符,如果更换区域语言,则最后会受到很大影响。
    现在ANSI一般使用一个字节或多个字节来表示(MBCS,Multi-Byte Character System)。这只是ANSI的一个逻辑表示,最终会对应到实际的编码中。比如ANSI存储英文单词时,用一个字节表示,对应到Unicode的ASCII编码区段,而用两个字节存储中文字符,最后会对应到Unicode的中文区段。