﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-luqingfei@C++-随笔分类-计算机基础知识</title><link>http://www.cppblog.com/luqingfei/category/14185.html</link><description>Be water, my friends!&lt;br/&gt;世界上只有一种失败，那就是半途而废。</description><language>zh-cn</language><lastBuildDate>Fri, 06 Aug 2010 10:12:07 GMT</lastBuildDate><pubDate>Fri, 06 Aug 2010 10:12:07 GMT</pubDate><ttl>60</ttl><item><title>[转]WindowsXP下运行命令中cmd和command的区别</title><link>http://www.cppblog.com/luqingfei/archive/2010/07/16/120519.html</link><dc:creator>路青飞</dc:creator><author>路青飞</author><pubDate>Fri, 16 Jul 2010 02:12:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/07/16/120519.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/120519.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/07/16/120519.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/120519.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/120519.html</trackback:ping><description><![CDATA[<p>cmd.exe和command.com</p>
<p><span style="BACKGROUND-COLOR: yellow">CMD.EXE是windows nt带的一个32位的命令行程序,那完全不是DOS. 它是Windows 窗口命令行接口，因此它可以通过窗口右上角的X来关闭，它不是一个dos窗口，如果运行cmd.exe则进程可以看到cmd.exe。</span>cmd是命令提示符（命令解释器），32位支持长文件名，中文 。cmd是进入控制台。</p>
<p>而<span style="BACKGROUND-COLOR: yellow">COMMAND.COM是用ntvdm虚拟出来的一个16位的dos环境</span>.同样也是基于命令行的. 是一个16位的DOS应用程序，它用于支持老的 dos应用程序，它必须通过命令行输入exit才可以退出，它一般运行于NTVDM中。如果用户运行 command.com，用户会在任务管理器中看到一个进程ntvdm.exe在运行。而且 command.exe还支持以前的16位的现在已经不用的命令。command是WindowsXP中的16位DOS，不支持长文件名，不支持中文。command是纯DOS系统,执行它后会建立一个全新的环境模式,(比如path=的设置就会有改变) 是运行在虚拟8086 模式的程序（可以看到进程中有个NTVDM出来了，这就是NT DOS 虚拟机），运行16位dos程序都会使用这个。16位程序都只支持8.3文件名（即文件名8个字符，扩展名3个字符），因此文件系统会保留两个文件名，一个长文件名，一个短文件名以供16位程序用，事实上他们都指向同一个文件。command也不能显示汉字，如果要显示汉字，可以更改代码页为936（简体中文），英文是437，用graftabl命令。用法 graftabl xxx 但是只能对应于图形模式下，在全屏幕状态是无效的。</p>
<p>但就用户来说，这两个命令有惊人的相似之处，他们同样都是运行环境,只是CMD更强大,虽然只能运行在NT内核的windows中,而command只是一个虚拟出来的dos运行环境罢了,不过他也能运行很多东东,总之都有用,尺有所短,寸有所长。比较旧的系统，如win95那些，就只有command而不存在cmd了。</p>
<p>另：debug程序可以用quit，或q命令退出。</p>
<p><span style="BACKGROUND-COLOR: yellow">另：用cmd和command分别调用debug，再用r命令查看各寄存器的值时发现段寄存器的初始值是不一样的，比如在cmd下DS,ES,SS,CS为1382，在command下他们的值为14B1。而其他寄存器的值是一样的。原因待查。</span></p>
<p>转自[http://oojakioo.blog.163.com/blog/static/1239368132009725102254654/]<br><br><em style="COLOR: #333399">哈哈，由我这个小菜来解释一下原因，CPU从何处执行执行指令，由代码段寄存器CS和指令指针寄存器IP里里的内容决定，它俩指向内存单元的物理地址。<br>你看到不一样，正说明了cmd.exe和command.com是两个独立的东东。<br>我目前还很菜，只能粗俗的解释一下。就到这里，我继续去看王爽大叔的《汇编语言》。真好看！<br><br></em></p>
<img src ="http://www.cppblog.com/luqingfei/aggbug/120519.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">路青飞</a> 2010-07-16 10:12 <a href="http://www.cppblog.com/luqingfei/archive/2010/07/16/120519.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>手工打造Win32汇编开发环境</title><link>http://www.cppblog.com/luqingfei/archive/2010/07/11/120080.html</link><dc:creator>路青飞</dc:creator><author>路青飞</author><pubDate>Sun, 11 Jul 2010 05:01:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/07/11/120080.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/120080.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/07/11/120080.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/120080.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/120080.html</trackback:ping><description><![CDATA[<p>开发工具基于MASM32 V8<br>编辑工具：EditPlus</p>
<p>直接解压缩到指定目录，比如D盘根目录：<br>d:\masm32\<br>d:\editplus\</p>
<p>可把批处理文件var.bat放置在masm32目录下。</p>
<p>批处理文件Var.bat用于设置临时环境变量，并且调用Makefile，运行编译后的可执行文件。</p>
<p>EditPlus已经配置了ASM代码高亮及模板。</p>
<p>在EditPlus的配置用户工具中，依照如下设置，即可以在Editplus中编译ASM代码文件，并运行编译后的可执行文件。<br>菜单文本：Run Asm<br>命令：d:\masm32\var.bat<br>参数：$(FileNameNoExt)<br>初始目录：$(FileDir)</p>
<p><br>开手你的第一个ASM练习:<br>step1: 打开EditPlus<br>step2: 点击菜单[文件]，[新建 ASM] ，然后EditPlus会自动加载一个hello world的ASM模板<br>step3:如果不想加点什么，可直接保存该代码文件。比如命名为HelloAsm<br>step4：在HelloAsm文件同目录下，建立makefile文件，内容如下：<br>&nbsp;NAME = HelloAsm<br>OBJS = $(NAME).obj</p>
<p>LINK_FLAG = /subsystem:windows<br>ML_FLAG = /c /coff</p>
<p>$(NAME).exe: $(OBJS)<br>&nbsp;Link $(LINK_FLAG) $(OBJS)<br>.asm.obj:<br>&nbsp;ml $(ML_FLAG) $&lt;</p>
<p>clean:<br>&nbsp;del *.obj<br>&nbsp;<br>&nbsp;<br>step5：执行EditPlus菜单[工具]下的RunAsm命令。</p>
<p>即可以编译HelloAsm文件，并且执行编译后的可执行文件。</p>
<p>这只是个简单的粗糙的ASM IDE开发环境。<br>主要用于新手入门。</p>
<p>感谢你的使用。<br></p>
<img src ="http://www.cppblog.com/luqingfei/aggbug/120080.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">路青飞</a> 2010-07-11 13:01 <a href="http://www.cppblog.com/luqingfei/archive/2010/07/11/120080.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]各种字符编码方式详解及由来(ANSI,GB2312,GBK,UNICODE,UTF-8)</title><link>http://www.cppblog.com/luqingfei/archive/2010/07/07/119538.html</link><dc:creator>路青飞</dc:creator><author>路青飞</author><pubDate>Wed, 07 Jul 2010 01:30:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/07/07/119538.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/119538.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/07/07/119538.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/119538.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/119538.html</trackback:ping><description><![CDATA[<p><em>最近在遇到一&#8220;乱码&#8221;问题，便对字符编码的产生兴趣，搜索到一篇好文章，转过来，慢慢咀嚼。<br>顺便改掉文章中的一些错别字</em></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一直对字符的各种编码方式懵懵懂懂，什么ANSI、GB2312、GBK、DBCS、UCSUNICODE、UTF-8&#8230;&#8230;是不是看的很晕，假如您细细的阅读本文你一定可以清晰的理解他们。Let's go!&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 很久很久以前，有一群人，他们决定用8个可以开合的晶体管来组合成不同的状态，以表示世界上的万物。他们看到8个开关状态是好的，于是他们把这称为"字节"。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 再后来，他们又做了一些可以处理这些字节的机器，机器开动了，可以用字节来组合出很多状态，状态开始变来变去。他们看到这样是好的，于是它们就这机器称为"计算机"。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 开始计算机只在美国用。八位的字节一共可以组合出256(2的8次方)种不同的状态。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 他们把其中的编号从第0至第31开始的32种状态分别规定了特殊的用途，一但终端、打印机遇上约定好的这些字节被传过来时，就要做一些约定的动作。遇上00x10, 终端就换行，遇上0x07, 终端就向人们嘟嘟叫，例如遇上0x1b, 打印机就打印反白的字，或者终端就用彩色显示字母。他们看到这样很好，于是就把这些0x20以下的字节状态称为"控制码"。<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 他们又把所有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示，一直编到了第127号，这样计算机就可以用不同字节来存储英语的文字了。大家看到这样，都感觉很好，于是大家都把这个方案叫做 <strong style="COLOR: #0000ff">ANSI</strong> 的"Ascii"编码（<strong style="COLOR: #0000ff">American Standard Code for Information Interchange，美国信息互换标准代码</strong>）。当时世界上所有的计算机都用同样的ASCII方案来保存英文文字。&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后来，就像建造巴比伦塔一样，世界各地的都开始使用计算机，但是很多国家用的不是英文，他们的字母里有许多是ASCII里没有的，为了可以在计算机保存他们的文字，他们决定采用127号之后的空位来表示这些新的字母、符号，还加入了很多画表格时需要用下到的横线、竖线、交叉等形状，一直把序号编到了最后一个状态255。从128到255这一页的字符集被称"<strong style="COLOR: #0000ff">扩展字符集</strong>"。从此之后，贪婪的人类再没有新的状态可以用了，美帝国主义可能没有想到还有第三世界国家的人们也希望可以用到计算机吧！&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 等中国人们得到计算机时，已经没有可以利用的字节状态来表示汉字，况且有6000多个常用汉字需要保存呢。但是这难不倒智慧的中国人民，我们不客气地把那些127号之后的奇异符号们直接取消掉,&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 规定：一个小于127的字符的意义与原来相同，但两个大于127的字节连在一起时，就表示一个汉字，前面的一个字节（他称之为<strong style="COLOR: #0000ff">高字节</strong>）从0xA1用到 0xF7，后面一个字节（<span style="COLOR: #0000ff"><strong>低字节</strong></span>）从0xA1到0xFE，这样我们就可以组合出大约7000多个简体汉字了。在这些编码里，我们还把数学符号、罗马希腊的字母、日文的假名们都编进去了，连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码，这就是常说的"<span style="COLOR: #0000ff"><strong>全角</strong></span>"字符，而原来在127号以下的那些就叫"<span style="COLOR: #0000ff"><strong>半角</strong></span>"字符了。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 中国人民看到这样很不错，于是就把这种汉字方案叫做 "<strong style="COLOR: #0000ff">GB2312</strong>"。GB2312 是对 ASCII 的中文扩展。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但是中国的汉字太多了，我们很快就就发现有许多人的人名没有办法在这里打出来，特别是某些很会麻烦别人的国家领导人。于是我们不得不继续把 GB2312 没有用到的码位找出来老实不客气地用上。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后来还是不够用，于是干脆不再要求低字节一定是127号之后的内码，只要第一个字节是大于127就固定表示这是一个汉字的开始，不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 <strong style="COLOR: #0000ff">GBK</strong> 标准，<span style="COLOR: #0000ff">GBK 包括了 GB2312 的所有内容，同时又增加了近20000个新的汉字（包括繁体字）和符号。</span><br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后来少数民族也要用电脑了，于是我们再扩展，又加了几千个新的少数民族的字，GBK 扩成了<strong style="COLOR: #0000ff">GB18030</strong>。从此之后，中华民族的文化就可以在计算机时代中传承了。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 中国的程序员们看到这一系列汉字编码的标准是好的，于是通称他们叫做 "<span style="COLOR: #0000ff"><strong>DBCS</strong></span>"（<strong style="COLOR: #0000ff">Double Byte Charecter Set 双字节字符集</strong>）。<u style="COLOR: #333399">在DBCS系列标准里，最大的特点是两字节长的汉字字符和一字节长的英文字符并存于同一套编码方案里，因此他们写的程序为了支持中文处理，必须要注意字串里的每一个字节的值，如果这个值是大于127的，那么就认为一个双字节字符集里的字符出现了。</u>那时候凡是受过加持（<span style="COLOR: #808080">这里不知道原作者是啥意思</span>），会编程的计算机僧侣们都要每天念下面这个咒语数百遍：&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "一个汉字算两个英文字符！一个汉字算两个英文字符&#8230;&#8230;"&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为当时各个国家都像中国这样搞出一套自己的编码标准，结果互相之间谁也不懂谁的编码，谁也不支持别人的编码，连大陆和台湾这样只相隔了150海里，使用着同一种语言的兄弟地区，也分别采用了不同的 DBCS 编码方案——当时的中国人想让电脑显示汉字，就必须装上一个"<strong style="COLOR: #0000ff">汉字系统</strong>"，专门用来处理汉字的显示、输入的问题，但是那个台湾的愚昧封建人士写的算命程序就必须加装另一套支持 <span style="COLOR: #0000ff"><strong>BIG5&nbsp; 编码</strong></span>的什么"倚天汉字系统"才可以用，装错了字符系统，显示就会乱了套！这怎么办？而且世界民族之林中还有那些一时用不上电脑的穷苦人民，他们的文字又怎么办？&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 真是计算机的巴比伦塔命题啊！&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 正在这时，大天使加百列及时出现了——一个叫 <span style="COLOR: #0000ff"><strong>ISO</strong></span>（<strong style="COLOR: #0000ff">国际标准化组织</strong>）的国际组织决定着手解决这个问题。他们采用的方法很简单：<span style="COLOR: #0000ff">废了所有的地区性编码方案，重新搞一个包括了地球上所有文化、所有字母和符号的编码！</span>他们打算叫它"<strong style="COLOR: #0000ff">Universal Multiple-Octet Coded Character Set</strong>"，简称 <strong style="COLOR: #0000ff">UCS</strong>, 俗称 "<strong style="COLOR: #0000ff">UNICODE</strong>"。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNICODE 开始制订时，计算机的存储器容量极大地发展了，空间再也不成为问题了。于是<span style="COLOR: #0000ff"> ISO 就直接规定必须用两个字节，也就是16位来统一表示所有的字符，对于ascii里的那些&#8220;半角&#8221;字符，UNICODE 包持其原编码不变，只是将其长度由原来的8位扩展为16位，而其他文化和语言的字符则全部重新统一编码。</span><span style="COLOR: #0000ff">由于"半角"英文符号只需要用到低8位，所以其高 8位永远是0，</span>因此这种大气的方案在保存英文文本时会多浪费一倍的空间。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="BACKGROUND-COLOR: yellow">&nbsp;这时候，从旧社会里走过来的程序员开始发现一个奇怪的现象：他们的strlen函数靠不住了，一个汉字不再是相当于两个字符了，而是一个！是的，从 UNICODE 开始，无论是半角的英文字母，还是全角的汉字，它们都是统一的"一个字符"！同时，也都是统一的"两个字节"，</span>请注意"字符"和"字节"两个术语的不同，&#8220;字节&#8221;是一个8位的物理存贮单元，而&#8220;字符&#8221;则是一个文化相关的符号。<span style="COLOR: #0000ff">在UNICODE 中，一个字符就是两个字节。一个汉字算两个英文字符的时代已经快过去了。</span>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;从前多种字符集存在时，那些做多语言软件的公司遇上过很大麻烦，他们为了在不同的国家销售同一套软件，就不得不在区域化软件时也加持那个双字节字符集咒语，不仅要处处小心不要搞错，还要把软件中的文字在不同的字符集中转来转去。UNICODE 对于他们来说是一个很好的一揽子解决方案，于是从 Windows NT 开始，MS 趁机把它们的操作系统改了一遍，把所有的核心代码都改成了用 UNICODE 方式工作的版本，从这时开始，WINDOWS 系统终于无需要加装各种本土语言系统，就可以显示全世界上所有文化的字符了。<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;但是，<span style="BACKGROUND-COLOR: yellow">UNICODE 在制订时没有考虑与任何一种现有的编码方案保持兼容，</span>这使得 GBK 与UNICODE 在汉字的内码编排上完全是不一样的，没有一种简单的算术方法可以把文本内容从UNICODE编码和另一种编码进行转换，这种转换<span style="COLOR: #0000ff">必须通过查表</span>来进行。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如前所述，<span style="COLOR: #0000ff">UNICODE 是用两个字节来表示为一个字符，他总共可以组合出65535不同的字符，这大概已经可以覆盖世界上所有文化的符号。</span>如果还不够也没有关系，ISO已经准备了<span style="COLOR: #0000ff"><strong>UCS-4方案</strong></span>，说简单了就是<span style="COLOR: #0000ff">四个字节来表示一个字符</span>，这样我们就可以组合出<span style="COLOR: #0000ff">21亿个不同的字符</span>出来（最高位有其他用途），这大概可以用到银河联邦成立那一天吧！&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #0000ff">UNICODE 来到时，一起到来的还有计算机网络的兴起，UNICODE 如何在网络上传输也是一个必须考虑的问题</span>，于是面向传输的众多 <span style="COLOR: #0000ff"><strong>UTF</strong></span>（<span style="COLOR: #0000ff"><strong>UCS Transfer Format</strong></span>）标准出现了，顾名思义，<strong style="COLOR: #0000ff">UTF8</strong>就是<span style="COLOR: #0000ff">每次8个位传输数据</span>，而<span style="COLOR: #0000ff">UTF16就是每次16个位</span>，<span style="COLOR: #0000ff">只不过为了传输时的可靠性，从UNICODE到 UTF时并不是直接的对应，而是要过一些算法和规则来转换。&nbsp;<br></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;受到过网络编程加持的计算机僧侣们都知道，<span style="BACKGROUND-COLOR: yellow">在网络里传递信息时有一个很重要的问题，就是对于数据高低位的解读方式</span>，一些计算机是采用低位先发送的方法，例如我们PC机采用的 INTEL 架构，而另一些是采用高位先发送的方式，<span style="BACKGROUND-COLOR: yellow">在网络中交换数据时，为了核对双方对于高低位的认识是否是一致的，采用了一种很简便的方法，就是在文本流的开始时向对方发送一个标志符</span>——<span style="COLOR: #0000ff">如果之后的文本是高位在位，那就发送"FEFF"，反之，则发送"FFFE"。</span>不信你可以用二进制方式打开一个UTF-X格式的文件，看看开头两个字节是不是这两个字节？&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 讲到这里，我们再顺便说说一个很著名的奇怪现象：当你在 windows 的记事本里新建一个文件，输入"联通"两个字之后，保存，关闭，然后再次打开，你会发现这两个字已经消失了，代之的是几个乱码！呵呵，有人说这就是联通之所以拼不过移动的原因。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其实这是因为GB2312编码与UTF8编码产生了编码冲撞的原因。&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从网上引来一段从UNICODE到UTF8的转换规则：&nbsp;<br>
<table style="WIDTH: 320px; BORDER-COLLAPSE: collapse" cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td><strong>Unicode</strong></td>
            <td><strong>UTF-8</strong></td>
        </tr>
        <tr>
            <td>0000 - 007F</td>
            <td>0xxxxxxx<br></td>
        </tr>
        <tr>
            <td>0080 - 07FF</td>
            <td>110xxxxx 10xxxxxx <br></td>
        </tr>
        <tr>
            <td>0800 - FFFF</td>
            <td>1110xxxx 10xxxxxx 10xxxxxx&nbsp;</td>
        </tr>
    </tbody>
</table>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如"汉"字的Unicode编码是6C49。6C49在0800-FFFF之间，所以要用3字节模板：1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是：0110 1100 0100 1001，将这个比特流按三字节模板的分段方法分为0110 110001 001001，依次代替模板中的x，得到：1110-0110 10-110001 10-001001，即E6 B1 89，这就是其UTF8的编码。&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而当你新建一个文本文件时，<span style="BACKGROUND-COLOR: yellow">记事本的编码默认是ANSI</span>,如果你在ANSI的编码输入汉字，那么他实际就是GB系列的编码方式，在这种编码下，"联通"的内码是： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c1 1100 0001 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aa 1010 1010 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cd 1100 1101 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a8 1010 1000&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意到了吗？第一二个字节、第三四个字节的起始部分的都是"110"和"10"，正好与UTF8规则里的两字节模板是一致的，于是再次打开记事本时，记事本就误认为这是一个UTF8编码的文件，让我们把第一个字节的110和第二个字节的10去掉，我们就得到了"00001 101010"，再把各位对齐，补上前导的0，就得到了"0000 0000 0110 1010"，不好意思，这是UNICODE的006A，也就是小写的字母"j"，而之后的两字节用UTF8解码之后是0368，这个字符什么也不是。这就是只有"联通"两个字的文件没有办法在记事本里正常显示的原因。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而如果你在"联通"之后多输入几个字，其他的字的编码不见得又恰好是110和10开始的字节，这样再次打开时，记事本就不会坚持这是一个utf8编码的文件，而会用ANSI的方式解读之，这时乱码又不出现了。&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 好了，终于可以回答NICO的问题了，<span style="BACKGROUND-COLOR: yellow">在数据库里，有n前缀的字串类型就是UNICODE类型，这种类型中，固定用两个字节来表示一个字符，无论这个字符是汉字还是英文字母，或是别的什么。&nbsp;<br></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="BACKGROUND-COLOR: yellow">如果你要测试"abc汉字"这个串的长度，在没有n前缀的数据类型里，这个字串是7个字符的长度，因为一个汉字相当于两个字符。而在有n前缀的数据类型里，同样的测试串长度的函数将会告诉你是5个字符，因为一个汉字就是一个字符。</span> <br><br>
<img src ="http://www.cppblog.com/luqingfei/aggbug/119538.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">路青飞</a> 2010-07-07 09:30 <a href="http://www.cppblog.com/luqingfei/archive/2010/07/07/119538.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>