﻿<?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/</link><description>&lt;font color='gray'&gt;为中华之崛起而崛起！&lt;/font&gt;&lt;br/&gt;
兼听则明，偏听则暗。
</description><language>zh-cn</language><lastBuildDate>Mon, 20 Apr 2026 02:04:53 GMT</lastBuildDate><pubDate>Mon, 20 Apr 2026 02:04:53 GMT</pubDate><ttl>60</ttl><item><title>使用lib.exe生成.lib文件</title><link>http://www.cppblog.com/luqingfei/archive/2013/07/15/201817.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Mon, 15 Jul 2013 07:34:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2013/07/15/201817.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/201817.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2013/07/15/201817.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/201817.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/201817.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">在程序使用Dll有两个加载方式，一种是动态方式，就是LoadLibrary载入Dll,然后用GetProcAddress来加载需要使用的Dll函数。另一种就是静态连接方式，将dll生成的lib，加入到工程中，然后就可以很方便的调用。</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">我们知道很多dll在发布时不提供lib，没有lib我们就不能静态的加载，所以得想办法来生成一个lib，在vs2005中有这样的一个命令</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">不过我们还需要一个def文件，怎样来获得一个def文件哪？</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">我们知道def是一个库导出文件 简单的格式是：EXPORTS&nbsp; 和 一些导出函数</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">我们可以用vc6自带的一个depends来查看dll中有哪些导出函数，来手动做一个.def文件</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">将xxx.dll和xxx.def，放到一个文件夹中，启动&#8220;Visual Studio 2005 命令提示&#8221;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">将工作目录切换到放有xxx.dll和xxx.def的文件夹中输入：</p><div style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">lib /def:xxx.def /MACHINE:x86</div><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">这样将会产生一个xxx.lib了，将此lib文件和dll文件拷到工程中，就可以进行静态链接了</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a href="http://blog.csdn.net/twtzw/article/details/2733783" style="font-family: verdana, 'courier new'; line-height: 21px;"></a></p><img src ="http://www.cppblog.com/luqingfei/aggbug/201817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2013-07-15 15:34 <a href="http://www.cppblog.com/luqingfei/archive/2013/07/15/201817.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何区分导入库和静态库</title><link>http://www.cppblog.com/luqingfei/archive/2013/07/15/201816.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Mon, 15 Jul 2013 07:32:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2013/07/15/201816.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/201816.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2013/07/15/201816.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/201816.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/201816.html</trackback:ping><description><![CDATA[<div>通过命令 &gt;lib /list Demo.lib</div><div></div><div>如果该 Demo.lib是静态库，输出如下：</div><div>&gt;lib /list Demo.lib</div><div>Microsoft (R) Library Manager Version 8.00.50727.42</div><div>Copyright (C) Microsoft Corporation. All rights reserved.</div><div></div><div>.\Debug\Demo.obj</div><div>.\Debug\Person.obj</div><div>.\Debug\stdafx.obj</div><div>.\Debug\Demo.res</div><div></div><div></div><div></div><div></div><div>如果该 Demo.lib是导入库，输出如下：</div><div>&gt;lib /list Demo.lib</div><div>Microsoft (R) Library Manager Version 8.00.50727.42</div><div>Copyright (C) Microsoft Corporation. &nbsp;All rights reserved.</div><div></div><div>Demo.dll</div><div>Demo.dll</div><div>Demo.dll</div><div>Demo.dll</div><div>Demo.dll</div><div>Demo.dll</div><div>Demo.dll<br /><br /><br />转：<a href="http://blog.sina.com.cn/s/blog_611b75a80100emow.html">http://blog.sina.com.cn/s/blog_611b75a80100emow.html</a></div><img src ="http://www.cppblog.com/luqingfei/aggbug/201816.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2013-07-15 15:32 <a href="http://www.cppblog.com/luqingfei/archive/2013/07/15/201816.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>lib文件</title><link>http://www.cppblog.com/luqingfei/archive/2013/07/15/201815.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Mon, 15 Jul 2013 07:25:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2013/07/15/201815.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/201815.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2013/07/15/201815.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/201815.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/201815.html</trackback:ping><description><![CDATA[<div>.lib是一种文件名后缀</div><div>该文件为Windows操作系统中的库文件，相当于Linux中的.a或.o、.so文件</div><div>lib有静态lib和动态lib之分。</div><div></div><div>lib文件通过编译才可以使用编译分静态与动态之分。</div><div></div><div>静态编译</div><div>静态lib将导出声明和实现都放在lib中。编译后所有代码都嵌入到宿主程序</div><div>动态编译</div><div>动态lib相当于一个h文件，是对实现部分（.dll文件）的导出部分的声明。编译后只是将导出声明部分编译到宿主程序中，运行时候需要相应的dll文件支持</div><div></div><div></div><div>一个lib文件是obj文件的集合。当然，其中还夹杂着其他一些辅助信息，目的是为了让编译器能够准确找到对应的obj文件。我们可以通过tlib.exe（在tc2.0下的根目录）来对lib文件进行操作，你可以把自己生成的obj文件通过tlib命令加入到一个lib文件中，也可以把lib文件内的obj文件进行删除操作，还可以把内部的obj文件给提取出来。明白了lib文件的大致结构以及对它的具体操作，在学习C语言的过程中，就会又多了一个切入点对C语言具体实现进行研究。</div><div></div><div></div><div>与dll区别</div><div>(1)lib是编译时需要的，dll是运行时需要的。</div><div>如果要完成源代码的编译，有lib就够了。</div><div>如果也使动态连接的程序运行起来，有dll就够了。</div><div>在开发和调试阶段，当然最好都有。</div><div></div><div></div><div>(2)一般的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的，而dll文件是运行期才会被调用的。如果有dll文件，那么对应的lib文件一般是一些索引信息，具体的实现在dll文件中。如果只有lib文件，那么这个lib文件是静态编译出来的，索引和实现都在其中。静态编译的lib文件有好处：给用户安装时就不需要再挂动态库了。但也有缺点，就是导致应用程序比较大，而且失去了动态库的灵活性，在版本升级时，同时要发布新的应用程序才行。</div><div></div><div>(3)在动态库的情况下，有两个文件，一个是引入库（.LIB）文件，一个是DLL文件，引入库文件包含被DLL导出的函数的名称和位置，DLL包含实际的函数和数据，应用程序使用LIB文件链接到所需要使用的DLL文件，库中的函数和数据并不复制到可执行文件中，因此在应用程序的可执行文件中，存放的不是被调用的函数代码，而是DLL中所要调用的函数的内存地址，这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来，从而节省了内存资源。从上面的说明可以看出，DLL文件必须随应用程序一起发行，否则应用程序将会产生错误。</div><div></div><img src ="http://www.cppblog.com/luqingfei/aggbug/201815.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2013-07-15 15:25 <a href="http://www.cppblog.com/luqingfei/archive/2013/07/15/201815.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]动态链接库、静态库、import库区别</title><link>http://www.cppblog.com/luqingfei/archive/2013/07/14/201792.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Sun, 14 Jul 2013 07:11:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2013/07/14/201792.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/201792.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2013/07/14/201792.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/201792.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/201792.html</trackback:ping><description><![CDATA[<div><strong style="font-size: 14pt;">动态链接库、静态库、import库区别</strong></div><div></div><div><strong>动态链接库(Dynamic Linked Library)：</strong></div><div>Windows为应用程序提供了丰富的函数调用，这些函数调用都包含在动态链接库中。其中有3个最重要的DLL，Kernel32.dll，它包含用于管理内存、进程和线程的各个函数；</div><div></div><div>User32.dll，它包含用于执行用户界面任务(如窗口的创建和消息的传送)的各个函数；GDI32.dll，它包含用于画图和显示文本的各个函数。</div><div></div><div><strong>静态库(Static Library)：</strong></div><div>函数和数据被编译进一个二进制文件(通常扩展名为.LIB)。在使用静态库的情况下，在编译链接可执行文件时，链接器从库中复制这些函数和数据并把它们和应用程序的其它模块</div><div></div><div>组合起来创建最终的可执行文件(.EXE文件)。</div><div></div><div><strong>导入库(Import Library)：</strong></div><div>在使用动态链接库的时候，往往提供两个文件：一个引入库和一个DLL。引入库包含被DLL导出的函数和变量的符号名，DLL包含实际的函数和数据。在编译链接可执行文件时，只需</div><div></div><div>要链接引入库，DLL中的函数代码和数据并不复制到可执行文件中，在运行的时候，再去加载DLL，访问DLL中导出的函数。</div><div></div><div>在运行Windows程序时，它通过一个被称作&#8220;动态链接&#8221;的进程与Windows相接。一个Windows的.EXE文件拥有它使用不同动态链接库的引用，所使用的函数即在那里。当Windows程</div><div></div><div>序被加载到内存中时，程序中的调用被指向DLL函数的入口，如果DLL不在内存中，系统就将其加载到内存中。</div><div></div><div>当链接Windows程序以产生一个可执行文件时，你必须链接由编程环境提供的专门的&#8220;导入库(import library)库&#8221;。这些导入库包含了动态链接库名称和所有Windows函数调用的</div><div></div><div>引用信息。链接程序使用该信息在.EXE文件中构造一个表，当加载程序时，Windows使用它将调用转换为Windows函数。<br /></div><div></div><div><strong>静态库与导入库的区别：</strong></div><div>导入库和静态库的区别很大，他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等，而对于导入库而言，其实际的执行代码位于动态库中，导入库只包含了</div><div></div><div>地址符号表等，确保程序找到对应函数的一些基本地址信息。<br /></div><div></div><div></div><div><strong>静态链接与动态链接：</strong></div><div></div><div>静态链接方法：#pragma comment(lib, "test.lib") ，静态链接的时候，载入代码就会把程序会用到的动态代码或动态代码的地址确定下来</div><div>静态库的链接可以使用静态链接，动态链接库也可以使用这种方法链接导入库</div><div></div><div>动态链接方法：LoadLibrary()/GetProcessAddress()和FreeLibrary()，使用这种方式的程序并不在一开始就完成动态链接，而是直到真正调用动态库代码时，载入程序才计算(被调用的那部分)动态代码的逻辑地址，然后等到某个时候，程序又需要调用另外某块动态代码时，载入程序又去计算这部分代码的逻辑地址，所以，这种方式使程序初始化时间较短，但运行期间的性能比不上静态链接的程序。</div><div></div><div>在软件开发的过程中，大家经常会或多或少的使用别人编写的或者系统提供的动态库或静态库，但是究竟是使用静态库还是动态库呢？他们的适用条件是什么呢？</div><div>&nbsp;</div><div>简单的说，静态库和应用程序编译在一起，在任何情况下都能运行，而动态库是动态链接，顾名思义就是在应用程序启动的时候才会链接，所以，当用户的系统上没有该动态库时，应用程序就会运行失败。再看它们的特点：</div><div>动态库：</div><div>1.共享：多个应用程序可以使用同一个动态库，启动多个应用程序的时候，只需要将动态库加载到内存一次即可；</div><div>2.开发模块好：要求设计者对功能划分的比较好。</div><div>&nbsp;</div><div>静态库：代码的装载速度快，执行速度也比较快，因为编译时它只会把你需要的那部分链接进去，应用程序相对比较大。但是如果多个应用程序使用的话，会被装载多次，浪费内存。</div><div>&nbsp;</div><div>总上，我个人认为，如果你的系统上有多个应用程序都使用该库的话，就把它编译成<strong>动态库</strong>，这样虽然刚启动的时候加载比较慢，但是多任务的时候会比较节省内存；如果你的系统上只有一到两个应用使用该库，并且使用的API比较少的话，就编译成静态库吧，一般的静态库还可以进行裁剪编译，这样应用程序可能会比较大，但是启动的速度会大大提高。</div><div>&nbsp;</div><div>呵呵，个人的一些心得，不足之处，欢迎指出！<br />转自：<a href="http://www.cnblogs.com/kex1n/archive/2011/09/06/2168435.html">http://www.cnblogs.com/kex1n/archive/2011/09/06/2168435.html<br /><br /></a></div><img src ="http://www.cppblog.com/luqingfei/aggbug/201792.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2013-07-14 15:11 <a href="http://www.cppblog.com/luqingfei/archive/2013/07/14/201792.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单的游戏服务器框架</title><link>http://www.cppblog.com/luqingfei/archive/2012/05/29/176587.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Tue, 29 May 2012 02:18:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2012/05/29/176587.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/176587.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2012/05/29/176587.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/176587.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/176587.html</trackback:ping><description><![CDATA[<a href="http://software.intel.com/zh-cn/blogs/2012/03/22/400010056/?cid=sw:prccsdn2203">http://software.intel.com/zh-cn/blogs/2012/03/22/400010056/?cid=sw:prccsdn2203</a><br />
<p>最近一段时间不是很忙，就写了一个自己的游戏服务器框架雏形，很多地方还不够完善，但是基本上也算是能够跑起来了。我先从上层结构说起，一直到实现细节吧，想起什么就写什么。</p>
<p>第一部分 服务器逻辑<br /><img alt="" src="http://images.csdn.net/20120322/1.jpg" /><br />服务器这边简单的分为三个部分，客户端的连接首先到达网关服务器，网关这里有个线程用来监听来自与客户端的连接，然后在将这些数据发送到游戏逻辑服务器上，这个逻辑游戏服务器上，数据的交互就是通过与数据服务器进行交互。RecordServer专门用来处理与数据库的连接，查询这些事情。当然为了游戏服务器能够最大程度的不卡，肯定就得规定好网关服务器上的连接数量，免得像我们号称流畅的铁道部订票网络一样做个卡B，想想玩一局dota被卡的悲剧吧。当我们要做一个大型网游时，这三个服务器显然不够。当然在自己写的小游戏的时候就无所谓了，几个服务器全部架设在自己的破笔记本上，不就是启动几个程序而已。</p>
<p>这个感觉写得就差不多了，到细节吧。</p>
<p>第二部分 实现细节</p>
<p>这个就比较乱了，零零散散的，随便写了。这里很多都是对各种工具的封装，以便于自己 在项目的使用</p>
<p>1.make</p>
<p>项目这么多目录，这么多子目录，肯定得用工具去编译了，使用aclocal,automake,autoconf,make,就把我们的程序编译好了，编写自己configure.in文件，定义编译选项、链接库等等一系列乱七八糟的东西，然后对每个需要编译的子项目编写Makefile.am,有的需要要编译成库的，比如base等基类这些，其他的都编译成可执行文件了，GatewayServer,LogicalServer,RecordServer。</p>
<p>2.套接字封装，epoll使用</p>
<p>linux里，我们使用socket来读写网络上的数据，这个很简单了，gateway上一个客户端连接过来，我们就为它分配一个socket 描述符了，在网关上，一个线程用来accept,一个线程用来做数据的处理，当accept一个连接请求后，放到数据处理的线程，接受到一个数据，然后直接转发到logical server上，我们使用epoll_wait，来处理套接上的读写处理。每n ms处理一次循环，每次循环中使用一次epoll_wait，一次把这些有事件的socket取出来。</p>
<p>3.数据加密解密，压缩解压</p>
<p>对网络上的数据，为了保证安全性，必须对它们进行加密解密处理，这个简单了，网上各种内容，这里就不说了（全部写完了，有时间再写）。对数据进行压缩，能减少带宽吞吐，就是简单的调用几个zlib函数的调用，不细说，在前面转发的《zlib使用》中有讲，发现自己太懒，实在是懒得打字了。</p>
<p>4.线程封装，互斥量，读写锁</p>
<p>这些都是简单的使用RAII或其他方式，对这些东西进行一次本地封装。（应该得写一个线程池去管理这些线程，todo）</p>
<p>5.数据库封装</p>
<p>使用mysql,使用mysql的C API函数，这个必须得封装一下，不是每次数据的处理，都得去做很多事情，实现一个本地的数据的Field(列),Record（记录）,Table（表）,DataBase（数据库）,RecordSet(查询结果集)。制作一个数据库连接句柄MysqlHandle，处理对数据库的连接，处理等，实现一个HandlerPool,，每次从Pool中取出一个句柄来对数据库进行查询，免得每次都去重新连接，什么的。</p>
<p>6.自己的内存池</p>
<p>在之前分享的文章中《内存池技术详解》《编写自己的内存分配器》，自己的《内存池应用》，已经很详细的说明了，内存池的制作，当然我在这里还是有一些改动的，但是大概思路就是这些了。</p>
<p>7.有一个状态机的实现</p>
<p>这个也在自己之前写的那个状态机相关的文章里，也做记录了。哈哈，实在是不想继续码字了，但是还是坚持下去。</p>
<p>8.lua与c++交互框架</p>
<p>这个暂时写了一半，等全部完成了，再来弄，反正就是像npc处理这些，脚本处理这些，使用tolua++。</p>
<p>9.tinyxml封装，正则表达式封装</p>
<p>tinyxml一个轻量级的xml解析器，很简单，反正是把这些现成的东西拿来自己用。正则表达式没有进入c++标准，但是还是很多现成的正则表达式的处理，直接用linux库下的regex.h,就是编译正则表达式，匹配结果这些，</p>
<p>10.log系统</p>
<p>一个项目怎么能没有自己的日志系统呢，反正就是打日志，往文件里面写东西，用std::fstream轻松搞定，定义好日志级别:error / debug / fatel / info这些</p>
<p>11.时间封装</p>
<p>这个必须有，否则自己还每次去调用get_clocktime,gmtime,time各种函数呀。</p>
<p>12.使用boost库里的，Noncopyable,Singleton这些设计方法，来写我们的代码</p>
<p>13.定义好各种信号句柄，信号发生时采用什么策略，如SIGPIPE，做忽略处理</p>
<p>待续。。。。。。。。（睡觉了）</p>
<p>游戏服务器技术应该算来已经很成熟了，相比客户端，它的技术更新速度很慢了。客户端这边，技术很多，各种游戏引擎比如3D的虚幻这些，什么粒子引擎，声音这些，页游的flash, html5,utility,，太多了，搞不过来呀。我先把服务器这边好好专专，其他的等以后再说吧。</p><img src ="http://www.cppblog.com/luqingfei/aggbug/176587.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2012-05-29 10:18 <a href="http://www.cppblog.com/luqingfei/archive/2012/05/29/176587.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]一个游戏程序员的学习资料</title><link>http://www.cppblog.com/luqingfei/archive/2012/05/29/176586.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Tue, 29 May 2012 02:17:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2012/05/29/176586.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/176586.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2012/05/29/176586.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/176586.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/176586.html</trackback:ping><description><![CDATA[<a href="http://software.intel.com/zh-cn/blogs/2012/03/20/400010004/?cid=sw:prccsdn2194">http://software.intel.com/zh-cn/blogs/2012/03/20/400010004/?cid=sw:prccsdn2194</a><br />
<p>想起写这篇文章是在看侯杰先生的《深入浅出MFC》时, 突然觉得自己在大学这几年关于游戏编程方面还算是有些心得，因此写出这篇小文,介绍我眼中的游戏程序 员的书单与源代码参考。一则是作为自己今后两年学习目标的备忘录,二来没准对别人也有点参考价值。我的原则是只写自己研究过或准备研究的资料，所以内容无 疑会带上强烈的个人喜好色彩, 比如对网络,数据库等重要方面完全没有涉及。因为自己主要对三维图形引擎, 人工智能算法, 脚本系统, 反外挂 (反反外挂? ^－^)等方面感兴趣。这学期电脑都没联网了,在岳麓山闭关修炼中(^－^),连这篇文章都得在学校图书馆电子阅览室（电影放映室？）上传,内容很多凭记忆写出, 如有误差敬请订正。程序员应该在理论学习与实践编程中反复迭代，所以学习资料是一回事，须知尽信书不如无书。</p>
<p>一、书籍：</p>
<p>算法与数据结构：</p>
<p>《数据结构（C语言版）》&#8212;&#8212;严蔚敏、吴伟民 清华出版社</p>
<p>我觉得其配套习题集甚至比原书更有价值，每个较难的题都值得做一下。</p>
<p>《Introduction to Algorithms》第二版 中文名《算法导论》</p>
<p>关 于算法的标准学习教材与工程参考手册，在去年CSDN网站上其翻译版竟然评为年度二十大技术畅销书，同时《程序员》杂志上开设了&#8220;算法擂台&#8221;栏目，这些溯 源固本的举动，不由得使人对中国现今浮躁不堪的所谓&#8220;IT&#8221;业又产生了一线希望。这本厚厚的书，幸亏打折我才买得起。虽然厚达千页，但其英文通俗晓畅，内 容深入浅出，可见经典之作往往比一般水准的书还耐读。还能找到MIT的视频教程，第一节课那个老教授嘻皮笑脸的，后面就是一长发助教上课了。</p>
<p>《C语言名题精选百则 技巧篇》&#8212;&#8212;冼镜光 机械工业出版社</p>
<p>作 者花费一年时间搜集了各种常见C程序段的极具技巧性的编程法，其内容都是大有来头的，而且给出了详细的参考资料。如一个普通的Fibonacci数就给出 了非递归解、快速算法、扩充算法等，步步深入，直至几无油水可榨。对于视速度如生命，连一个普通的浮点数转化为整数都另辟蹊径以减少CPU cycle的游戏程序员，怎可不看？</p>
<p>《计算机算法基础（第二版）》&#8212;&#8212; 佘祥宣等 华中科大出版社</p>
<p>我看到几个学校的研究生拿它作教材（研究生才开算法，太开玩笑了吧）。这本书薄是薄了点，用作者的话来说，倒也&#8220;精辟&#8221;。其实此书是《Fundamentals of Computer Algorithms》的缩写版，不过原书出版太久了，反正我是没找到。</p>
<p>《The Art of Computer Programming》Volume 1-3</p>
<p>作 者Donald E. Knuth是我心目中与冯.诺依曼、Dijkstra、Shannon并列的四位大师。这本书作者从读大学本科时开始写，一直写到博士时，十年磨一剑，足 见其下足了功夫。可作为计算机技术的核心&#8212;&#8212;算法与数据结构的终极参考手册。创新处也颇多，譬如常见的Shell排序他在书中提出可用(3i-1)/2的 间隔，这使其稍快于O(n1. 5)。当然这套书描述高度数学化，为此恐怕一般的人（我？）最好还得先看一本数学预备书《Concrete Mathematics》（直译为混凝土数学？^－^）再说。可惜的是这套书才出到第三卷，并没有覆盖全部常见的算法内容。不过好在对于游戏程序员来说， 越常见的算法用得越多，这也不算是什么要命的损失。</p>
<p>《STL源码剖析》&#8212;&#8212; 侯捷 华中科大出版社</p>
<p>侯 捷不用介绍了，华人技术作家中的旗舰，说其有世界级水准也不为过。这本书我以为是C++与数据结构的葵花宝典（欲练此功，必先自宫）。也就是说，不下几层 地狱很难看懂，因为它要求的预备知识太多了，如STL、数据结构、泛型编程、内存管理都要很扎实（为此是不是还要看看有内存管理设计模式之称的 《Small Memory Software》这本书呢？），但是一旦看懂，真会是所向披靡。</p>
<p>《Data Structures for Game Programmers》</p>
<p>每个数据结构的例程都是一个小游戏，还用SDL库实现了一个算法演示系统。虽然内容失之于浅，但起码让人了解了数据结构在游戏中的作用。</p>
<p>其 实游戏程序并不比其它程序特殊，甚至要求基本功更加扎实，所以花时间做一些看似与实际应用不甚相干的习题，对今后的工作是大有裨益的。而且有些应用很广的 算法，如常被人津津乐道的A*算法及其变种，牵涉到图的检索周游与分枝-限界法，恐怕还得读一些艰深的论文才能充分明白运用，如Donald E. Knuth的《An analysis of alpha-beta cutoffs》。其实还有不少此类的好书，如《Data Structures and Algorithms in C++》、《Programming Pearls》、《More Programming Pearls》（算法珠玑）等，我却以为要先看严谨一点的著作，再看内容随笔一点的书。</p>
<p>汇编：</p>
<p>《IBM-PC 汇编语言程序设计》第二版</p>
<p>国内经典教材。</p>
<p>《The Art of Assembly Language》</p>
<p>这本书足有1600页，噢！</p>
<p>C语言：</p>
<p>《The C Programming Language》第二版</p>
<p>虽然篇幅短小，但每个例程都很经典。（我们老师开始拿它作教材，后面换为谭小强的C语言书，理由为：例子尽是些文本处理。我就纳了闷了，难道现代的计算机程序不是将大量时间消耗在字符串与文本的处理上吗？）</p>
<p>C++：</p>
<p>学过C语言，再学C++，先看这本《C++ Primer》的缩写版：</p>
<p>《Essential C++》</p>
<p>对C++有个入门了解，再看</p>
<p>《C++ Common Knowledge: Essential Intermediate Programming》</p>
<p>就不会有什么重要的知识点完全不知所措了，接下来是</p>
<p>《The C++ Standard Library : A Tutorial and Reference》</p>
<p>标准库，当然主要是标准模板库的标准学习参考手册，然后最好平时边写程序边参悟。</p>
<p>《Effective C++》等</p>
<p>我是说书名以形容词 + C++的那些书，计有七八本，慢慢看吧，罗马不是一日建成的。</p>
<p>(《Essential C++》、《Effective C++》、《More Effective C++》、《Accelerated C++》、《Effective STL》、《Exceptional C++》、《More Exceptional C++》、《Imperfect C++》，虽然书名格式相似，但每一本都绝非马虎之作。)</p>
<p>谁说C++程序比C程序要慢？那就请看下面：</p>
<p>《The Design and Evolution of C++》</p>
<p>知其过去才能知其未来，才能应用。</p>
<p>《Inside the C++ Object Model》</p>
<p>揭露C++的编译器模型。</p>
<p>《Efficient C++ Performance Programming Techniques》</p>
<p>当算法优化已到极致，在运用汇编之前，最后还可看看此书，有时高级和低阶都能做成相同的事情。</p>
<p>还有两本特别的书：</p>
<p>《Modern C++ Design : Generic Programming and Design Patterns Applied》</p>
<p>作者想把设计模式和泛型编程结合起来，并写了个尝试提供一切的Loki库来实作,不过其观点并未得到C++社区的普遍响应。尽管如此，本书仍称得上思想前沿性与技术实用性结合的典范。</p>
<p>《C++ Template Metaprogramming》</p>
<p>把 编译器当作计算器？本书介绍了Boost库的MPL模板元编程库。当然提到Boost库，对于游戏程序员不能不提到其中的Graph库，有《The Boost Graph Library》一书可看。还有其中Python库，号称国内首款商业三维图形引擎的起点引擎就用了Boost－Python库。说实话我觉得起点引擎还 是蛮不错的，那个自制的三维编辑器虽然界面简陋，但功能还算蛮完善，给游戏学院用作教学内容也不错。另有一个号称中国首款自主研发的全套网游解决方案。我 看到它那个三维编辑器，心想这不就是国外一个叫freeworld3D的编辑器吗？虽然有点偏门，但我以前还较劲尝试破解过呢。还把英文界面汉化了，大概 用exescope这样的资源修改软件就能搞定吧。我又心想为什么要找freeworld3D这个功能并不太强大的编辑器呢？仅仅是因为它便宜到几十美 金？它唯一特别一点的地方就是支持导出OGRE图形引擎的场景格式，这样一想不由得使人对它图形引擎的&#8220;自主&#8221;性也产生怀疑了。这样的&#8220;自主&#8221;研发真让人 汗颜，只要中国还没封sourceforge这个网站（据说以前和freeBSD网站一起被封过？），国人就能&#8220;自主&#8221;研发。</p>
<p>有人还会推荐《C++ Primer》《Thinking in C++》《The C++ Programming Language》等书吧，诚然这些书也很好，但我总觉得它们太大部头了。还不如多花点时间看看国外好的源代码。</p>
<p>Windows编程</p>
<p>《Operating System Concepts》第五版</p>
<p>国内有些操作系统的教程其实就是它的缩写版。</p>
<p>《Windows 95 System Programming Secrets》</p>
<p>深入剖析了Windows操作系统的种种种种，有人爱看《Linux内核完全注释》，有人爱看《自己动手写操作系统》这样煽情的书，但我想作为商业的操作系统，把Windows内核剖析到这地步也高山仰止了。</p>
<p>《Programming Applications for Microsoft Windows》第四版</p>
<p>先进程线程，再虚存管理，再动态链接库，最多讲到消息机制。作者在序言中说：&#8220;我不讲什么ActiveX, COM等等，因为当你了解了这些基础后，那些东西很快就会明白！&#8221;可以作为《Programming Windows》的先修课。</p>
<p>计算机体系：</p>
<p>《Computer Systems : A Programmer&#8217;s Perspective》</p>
<p>和《The Art of Computer Programming》在我心中是计算机史上两本称得上伟大的书，计算机组成原理，操作系统，汇编，编译原理，计算机网络等等课程汇成这本千页的大书，因为计算机在作者眼中就是一个整体。</p>
<p>开源阅读：</p>
<p>《Code Reading : The Open Source Perspective》</p>
<p>张大千临摹了几百张明代石涛的山水，画出的画以假乱真，后来他去敦煌潜心临摹几年，回来画风大变，终成大家。程序员其实有4 0%的时间是在读别人的源代码，侯捷先生说：&#8220;源码面前，了无秘密&#8221;，又说&#8220;天下大事，必作于细&#8221;，可以与他的《上穷碧落下黄泉，源码追踪经验谈》参看。</p>
<p>MFC:</p>
<p>《深入浅出MFC》</p>
<p>我 实在以为没有看过侯捷先生的《深入浅出MFC》的人多半不会懂得MFC编程。其实我是打算用一年多的时间写一个给游戏美工用的三维编辑器，顺便作为毕业设 计。图形库就用MFC吧，反正也没得选择。如果要用wxWidgets无非是猎奇而已，还不是MFC的翻版，当然它跨平台了。就象阻击手对自己枪械的零件 了如指掌一样，要想用MFC写出非玩具程序的人一定要了解其内部构造。还有一本书叫《MFC深入浅出》，并不是同一本。</p>
<p>IDE:</p>
<p>《Microsoft Visual Studio 2005 Unleashed》</p>
<p>工欲善其事，必先利其器。当然我认为与其用形如Source Insight、Slick Edit、Code Visualizer之类的代码阅读器、图形化工具，还不如用自己的大脑。但如果你嫌打源代码慢的话，可以用Visual AssistX。如果嫌老是写重复相似的代码的话，可以用Code Smith。单元测试可以用CppUnit，Boost库中的测试框架也不错。有心情可以吧Visual Studio外接Intel的Compiler，内嵌STLport，但不是大工程，性能分析没必要动不动就用下VTune吧。</p>
<p>程序员之路：</p>
<p>《游戏之旅&#8212;&#8212;我的编程感悟》(#add不怎么样)</p>
<p>云 风大哥。在我心目中游戏程序员国外首推卡马克，国内首推云风。也许过两年我会到网易当云风大哥的助理程序员吧。It&#8217;s my dream.（^-^）他写这本书的时候本着只有透彻理解的东西才写出来，因此内容不会很酷新，但是相信我，每读一遍都有新的收获，主要还不是知识上的， 因为知识是学无止境的，授人以鱼不如授人以渔，精神上的启迪才是长久的。诚如经典游戏《 仙剑 奇侠传》的主力程序员兼美术指导姚壮宪（人称姚仙）在序言中所说的&#8220;云风得到的只是一些稿费，而整个中国民族游戏产业得到的将是一次知识的推动&#8221;，此言不虚矣。</p>
<p>《编程高手箴言》(#add差)</p>
<p>梁 肇新是豪杰超级解霸的作者，本来每个合格的程序员（Programmer , 而非Coder）都应该掌握的东西，现在变成了编程高手的独家箴言。不知是作者的幸运还是中国IT业的悲哀。知识点还是讲得蛮多的，不过对MFC的地位颇 有微词。我实在认为MFC的名声就是那些不懂得用它的人搞臭的。不过作者的牢骚也情有可原，每个具有创造力的程序员都应该不太喜欢framework。</p>
<p>《Masters of DOOM: How Two Guys Created an Empire and Transformed Pop Culture》中文名《DOOM启世录》</p>
<p>卡 马克，罗洛斯，这些游戏史上如雷贯耳的名字。（现在卡马克已专注于火箭制造上，罗洛斯则携妻回乡隐居）要不是没上过大学的卡马克和图形学大师亚伯拉罕的功 勋，可能到现在游戏中还不知三维为何物。勿庸置疑，在计算机界历史是英雄们所推动的。这本书真实的记录了这些尘世英雄的所为所思。</p>
<p>作为程序员的我对这几本策划与美工的书也产生了浓厚兴趣，以前搞过一两年的3DS MAX插件编程，觉得用maxscript还是好过MaxSDK，毕竟游戏开发中所多的是模型场景数据的导入导出，大可不必大动干戈。</p>
<p>策划：</p>
<p>《Creating Emotion in Games : The Craft and Art of Emotioneering》</p>
<p>在壮丽煊目的宏伟三维世界背后，在残酷的杀戮，动人心魄的情节背后，我们还需要什么来抓住玩家的心？答对了，就是emotion.真正打动人心的，才是深入骨髓的。</p>
<p>《Ultimate Game Design : Building Game Worlds》</p>
<p>从名字可以看出，写给关卡设计师的，特别是讲室外自然场景的构建颇有可取之处。</p>
<p>《Developing Online Games : An Insider&#8217;s Guide》</p>
<p>就象名为反模式的书讲软件团队运营一样，这本书讲商业运作多过技术。一个历经艰难，现在盛大的游戏程序员，翻译了这本书。<br />美工：</p>
<p>《Digital Cinematography &amp; Directing》</p>
<p>数字摄影导演术，每当你在3DS MAX或者Maya等三维创作软件中摆放摄影机，设计其运动轨迹时，你可曾想过你也站在导演的位置上了？</p>
<p>《The Animator&#8217;s Survival Kit》</p>
<p>看 着这本讲卡通角色运动规律的书，一边产生温习《猫和老鼠》的念头，一边继续对前不久新闻联播中关于中国产生了某计算机自动卡通动画生成软件报道的蔑视，这 条报道称此举可大大加快中国卡通动画的产量。我且不从技术上探讨其是否是在放卫星（其实我知道得很清楚，前文已表，本人搞过一两年的卡通动画辅助软件编 程），但计算机机械生成的动画怎可代替人类充满灵性的创作？</p>
<p>《The Dark Side of Game Texturing》</p>
<p>用Photoshop制作材质贴图，还真有些学问。</p>
<p>三维图形学：</p>
<p>搞三维图形学首先还是要扎扎实实的先看解析几何、线性代数、计算几何的教材，后面的习题一个都不能少。国内数学书还是蛮好的。苏步青大师的《计算几何》称得上具有世界级水准，可惜中国CAD的宏图被盗版给击垮了。现在是我们接过接力棒的时候了。It&#8217;s time!</p>
<p>《Computer Graphics Geometrical Tools》</p>
<p>《计算机图形学几何工具算法详解》算法很多，纰漏处也不少。</p>
<p>《3D Math Primer for Graphics and Game Development》</p>
<p>浅易，可作为三维数学的&#8220;速食&#8220;。</p>
<p>《Mathematics for 3D Game Programming &amp; Computer Graphics》第二版</p>
<p>比上面那本深入一些，证明推理的数学气也浓一些，可作为专业的数学书与编程实践一个过渡的桥梁吧。内容涉猎也广，射线追踪，光照计算，可视裁剪，碰撞检测，多边形技术，阴影算法，刚体物理，流体水波，数值方法，曲线曲面，还真够丰富。</p>
<p>《Vector Game Math Processors》</p>
<p>想学MMX,SSE吗，那就看它吧，不过从基础讲起的，要耐心哦。</p>
<p>DirectX:</p>
<p>《Introduction to 3D Game Programming with DirectX 9.0》</p>
<p>DirectX入门的龙书，作者自己写的简单示例框架，后面我干脆用State模式，把所有例子绑到一块儿去了。</p>
<p>《Beginning Direct3D Game Programming》</p>
<p>作 者取得律师学位后变成了游戏程序员，真是怪也哉。本书虽定位为入门级书，内容颇有独特可取之处。它用到的示例框架是DXSDK Sample Framework，而不是现在通行的DXUT。要想编译有两种办法吧，一是自己改写成用DXUT的。二是找旧的Sample Framework。我又懒得为了一个示例框架下载整个早期版本的DirectX，后面在Nvidia SDK 9.5中发现了。</p>
<p>《Advanced Animation with DirectX》</p>
<p>DirectX 高级动画技术。骨骼系统，渐变关键帧动画，偶人技术，表情变形，粒子系统，布料柔体，动态材质，不一而足。我常常在想，从三维创作软件导出的种种效果，变 成一堆text或binary，先加密压缩打包再解包解压解密，再用游戏程序重建一个Lite动画系统，游戏程序员也真是辛苦。</p>
<p>OpenGL:</p>
<p>《NeHe OpenGL Tutorials》</p>
<p>虽是网络教程，不比正式的书逊，本来学OpenGL就不过是看百来条C函数文档的工夫吧,如果图形学基础知识扎实的话。</p>
<p>《OpenGL Shading Language》</p>
<p>OpenGL支持最新显卡技术要靠修修补补的插件扩展，所以还要配合</p>
<p>《Nvidia OpenGL Extension Specifications》</p>
<p>来看为上。</p>
<p>《Focus on 3D Models》</p>
<p>《Focus on 3D Terrain Programming》</p>
<p>《Focus on Curves and Surfaces》</p>
<p>顾名思义，三本专论，虽然都很不深，但要对未知三维模型格式作反向工程前，研读Geomipmapping地形算法论文前，CAD前，还是要看看它们为上，如果没从别处得过到基础的话。</p>
<p>脚本：</p>
<p>先看</p>
<p>《Game Scripting Mastery》</p>
<p>等自己了解了虚拟机的构造，可以设计出简单的脚本解释执行系统了。</p>
<p>再去查Python , Lua ，Ruby的手册吧，会事半半功倍倍的。</p>
<p>《Programming Role Playing Games with DirectX 8.0》</p>
<p>一边教学一边用DirectX写出了一个GameCore库，初具引擎稚形。</p>
<p>《Isometric Game Programming with DirectX 7.0》</p>
<p>三维也是建立在二维的基础上，这就是这本书现在还值得看的原因。</p>
<p>《Visual C++网络游戏建模与实现》</p>
<p>联众的程序员写的，功力很扎实，讲棋牌类游戏编程，特别讲了UML建模和Rotional Rose。</p>
<p>《Object-Oriented Game Development》</p>
<p>套用某人的话：&#8220;I like this book.&#8221;</p>
<p>Shader:</p>
<p>要入门可先看</p>
<p>《Shaders for Game Programmers and Artists》</p>
<p>讲在RenderMonkey中用HLSL高级着色语言写Shader.</p>
<p>再看</p>
<p>《Direct3D ShaderX : Vertex and Pixel Shander Tips and Tricks》</p>
<p>用汇编着色语言，纯银赤金。</p>
<p>三大宝库：</p>
<p>《Game Programming Gems》</p>
<p>我只见到1-6本，据说第7、8本也出来了？附带的源代码常有bug，不过瑕不掩瑜，这套世界顶级游戏程序员每年一度的技术文集，涉及游戏开发的各个方面，我觉得富有开发经验的人更能在其中找到共鸣。</p>
<p>《Graphics Gems》全五本</p>
<p>图形学编程Bible，看了这套书你会明白计算机领域的科学家和工程师区别之所在。科学家总是说，这个东西在理论上可行。工程师会说，要使问题在logN的时限内解决我只能忍痛割爱，舍繁趋简。</p>
<p>《GPU Gems》出了二本</p>
<p>Nvidia公司召集图形学Gurus写的，等到看懂的那一天，我也有心情跑去Siggraph国际图形学大会上投文章碰运气。</p>
<p>游戏引擎编程：</p>
<p>《3D Game Engine Programming》</p>
<p>是ZFXEngine引擎的设计思路阐释，很平实，冇太多惊喜。</p>
<p>《3D Game Engine Design》</p>
<p>数学物理的理论知识讲解较多，本来这样就够了，还能期待更多吗？</p>
<p>人工智能：</p>
<p>《AI Techniques for Game Programming》</p>
<p>讲遗传算法，人工神经网络，主要用到位数组，图算法。书的原型是根据作者发表到GameDev.net论坛上的内容整理出来的，还比较切中实际。</p>
<p>《AI Game Programming Wisdom》</p>
<p>相当于AI编程的Gems。</p>
<p>《PC游戏编程(人机博弈)》</p>
<p>以 象棋程序为蓝本，介绍了很多种搜索算法，除了常见的极大极小值算法及其改进--负极大值算法，还有深度优先搜索以外。更提供了多种改进算法， 如：Alpha-Beta,Fail-soft alpha-beta,Aspiration Search, Minimal Window Search,Zobrist Hash,Iterative Deepening,History Heuristic,Killer Heuristic,SSS*,DUAL*,MFD and more.琳琅满目，实属难得。</p>
<p>反外挂：</p>
<p>《加密与解密(第二版)》 看雪论坛站长 段钢</p>
<p>破解序列号与反外挂有关系么？不过，世上哪两件事情之间又没有关系呢？</p>
<p>《UML Distilled》 Martin Fowler</p>
<p>很多人直到看了这本书才真正学懂UML。</p>
<p>Martin Fowler是真正的大师,从早期的分析模式,到这本UML精粹,革命性的重构都是他提出的,后来又写了企业模式一书。现在领导一个软件开发咨询公司，去年JavaOne中国大会他作为专家来华了吧。个人网站：MartinFowler.com</p>
<p>设计模式三剑客：</p>
<p>《Design Patterns Elements of Reusable Object-Oriented Software》</p>
<p>《Design Patterns Explained》</p>
<p>《Head First Design Patterns》</p>
<p>重构三板斧：</p>
<p>《Refactoring : Improving the Design of Existing Code》</p>
<p>《Refactoring to Patterns》</p>
<p>《Refactoring Workbook》</p>
<p>软件工程:</p>
<p>《Extreme Programming Explained : Embrace Change》第二版</p>
<p>其中Simplicity的Value真是振聋发聩，这就是我什么都喜欢轻量级的原因。</p>
<p>《Agile Software Development Principles,Patterns,and Practices》</p>
<p>敏捷真是炒得够火的，连企业都有敏捷一说，不过大师是不会这么advertising的。</p>
<p>《Code Complete》第二版</p>
<p>名著。</p>
<p>数学：</p>
<p>《数学，确定性的丧失》M.克莱因</p>
<p>原来数学也只不过是人类的发明与臆造，用不着供入神殿，想起历史上那么多不食人间烟火的科学家（多半是数学家），自以为发现了宇宙运作的奥秘，是时候走下神坛了。</p>
<p>物理：</p>
<p>《普通物理学》第一册 += 《Physics for Game Developers》</p>
<p>物理我想就到此为此吧，再复杂我可要用Newton Engine,ODE了，等待物理卡PPU普及的那天，就可充分发挥PhysX的功效了，看过最新的《细胞分裂》游戏Demo演示，成千上万个Box疯狂Collide，骨灰级玩家该一边摸钱包一边流口水了。</p>
<p>二、开源代码：</p>
<p>Irrlicht</p>
<p>著 名的鬼火引擎，从两年前第一眼看到它，这个轻量级的三维图形引擎，就喜欢上了它。源代码优雅，高效，且不故弄玄虚。值得每个C++程序员一读，并不限于图 形编程者。它的周边中也有不少轻量级的东西。如Lightfeather扩展引擎，ICE、IrrlichtRPG、IrrWizard.还有 IrrEdit、IrrKlang、IrrXML可用。（可能是为了效率原因，很多开源作者往往喜欢自己写XML解析库，如以上的IrrXML库,即使有现成的tinyXML库可用。这真会让tomcat里面塞Axis，Axis里面塞JUDDI，弄得像俄罗斯套娃玩具的Java Web Service Coder们汗颜。）</p>
<p>OGRE</p>
<p>排 名第一的开源图形引擎，当然规模是很大的，周边也很多。除了以C#写就的OgreStudio ，ofusion嵌入3DS MAX作为WYSWYG式的三维编辑器也是棒棒的，特别是其几个场景、地形插件值得研究。以至于《Pro OGRE 3D Programming》一书专论其用法。搜狐的《天龙八部》游戏就是以其作为图形引擎，当然还另外开发了引擎插块啦。我早知道OGRE开发组中有一个中 国人谢程序员，他以前做了很多年的传统软件编程。有一次天龙八部游戏的图形模块的出错信息中包含了一串某程序员的工作目录，有一个文件夹名即是谢程序员的 英文名，我据此推断谢程序员即是搜狐北京的主程。看来中国对开源事业还是有所贡献的嘛，王开源哥哥的努力看来不会白费！（^-^）不过我侦测的手法也有些 像网站数据库爆库了，非君子之所为作。</p>
<p>RakNet</p>
<p>基于UDI的网络库，竟还支持声音传输，以后和OpenVision结合起来做个视聊程序试试。</p>
<p>Blender</p>
<p>声誉最盛的开源三维动画软件，竟还带一个游戏引擎。虽然操作以快捷键驱动，也就是说要背上百来个快捷键才能熟练使用。但是作为从商业代码变为开源之作，威胁三维商业巨头的轻骑兵，历经十年锤炼，代码达百万行，此代码只应天上有，人间哪得几回看，怎可不作为长期的源码参考？</p>
<p>风魂</p>
<p>二维图形库。云风大哥的成名之作。虽然不代表其最高水平（最高水平作为商业代码保存在广州网易互动的SVN里呢），但是也可以一仰风采了。</p>
<p>圣剑英雄传</p>
<p>二 维RPG。几个作者已成为成都锦天的主力程序员。锦天的老总从一百万发家，三年时间身价过亿，也是一代枭雄了。这份代码作为几年前的学生作品也算可以了， 因为一个工程讲究的是四平八稳，并不一定要哪个模块多么出彩。反正我是没有时间写这么一个东东，连个美工都找不到，只能整天想着破解别人的资源（^- ^）。</p>
<p>Boost</p>
<p>C++准标准库，我想更多的时候可以参考学习其源代码。</p>
<p>Yake</p>
<p>我 遇到的最好的轻量级游戏框架了。在以前把一个工程中的图形引擎从Irrlicht换成OGRE的尝试中，遇到了它。OGRE的周边工程在我看来都很庸肿， 没有完善文档的情况下看起来和Linux内核差不多。不过这个Yake引擎倒是很喜欢。它以一个FSM有限状态机作为实时程序的调度核心，然后每个模块： 物理、图形、网络、脚本、GUI、输入等等都提供一个接口，接口之下再提供到每种具体开源引擎的接口，然后再接具体引擎。通过这样层层抽象，此时你是接 Newton Engine,ODE还是PysX都可以；是接OGRE,Crystal Space还是Irrlicht都可以；是接RakNet还是LibCurl都可以；是接Python，Lua还是Ruby都可以，是接CEGUI还是 others，是接OIS还是others（呵呵,记不起来others）都可以。所以Yake本质上不是OGRE的周边。虽然用Neoengine的人 都倒向了它，但是现在版本还很早。特别是我认为，学习研究时一定要有这种抽象之抽象，接口之接口的东西把思维从具体的绑定打开，而开发时抽象要有限度的， 就像蔡学镛在《Java夜未眠》中讲的，面向对象用得过滥也会得OOOO症(面向对象过敏强迫症)。</p>
<p>Quake Doom系列</p>
<p>据说很经典，卡马克这种开源的黑客精神就值得赞许。把商业源代码放出来，走自己的创新之路，让别人追去吧。不过Quake与Unreal引擎的三维编辑器是现在所有编辑器的鼻祖，看来要好好看看了。</p>
<p>Nvidia SDK 9.X</p>
<p>三 维图形编程的大宝库，这些Diret3D与OpenGL的示例程序都是用来展示其最新的显卡技术的。硬件厂商往往对软件产品不甚在意，源代码给你看,东西 给你用去吧，学完了还得买我的硬件。Intel的编译器，PhysX物理引擎大概也都是这样。Havok会把它的Havok物理引擎免费给别人用吗？别说 试用版，连个Demo都看不到。所以这套SDK的内容可比MS DirectX SDK里面那些入门级的示例酷多了，反正我是如获至宝，三月不知愁滋味。不过显卡要so-so哦。我的GeForce 6600有两三个跑不过去,差强人意。</p>
<p>三、网站：</p>
<p>www.CSDN.net</p>
<p>程序员大本营吧，软文与&#8220;新技术秀&#8221;讨厌了点，blog和社区是精华之所在。</p>
<p>www.GameRes.com</p>
<p>游戏程序员基地，文档库中还有点东西。投稿的接收者Seabug与圣剑英雄传的主程Seabug会是同一个人吗？一个在成都锦天担当技术重担的高手还有时间维护网站吗？我不得而知。</p>
<p>&#8220;何苦做游戏&#8221;网站</p>
<p>名字很个性，站长也是历尽几年前产业发展初期的艰难才出此名字。</p>
<p>www.66rpg.com</p>
<p>二维游戏图片资源很多，站长柳柳主推的RPGMaker 软件也可以玩一玩吧，但对于专业开发者来说不可当真。</p>
<p>www.GameDev.net</p>
<p>论坛中有不少热心的国外高手在活动。</p>
<p>www.SourceForge.net</p>
<p>不用说了，世界最大的开源代码库，入金山怎可空手而返？看到国外那些学生项目动不动就像模像样的。（DirectX的稚形就是英国的学生项目，在学校还被判为不合格。）</p>
<p>www.koders.com</p>
<p>源 代码搜索引擎,支持正则表达式,google Lab中也有。当你某种功能写不出来时,可以看一下开源代码怎么写的,当然不过是仅供参考,开源代码未必都有产品级的强度。说到google,可看 《Google Power Tools Bible》一书，你会发现，google的众多产品原来也有这么多使用门道。</p>
<p>这篇小文足足写了一天半的时间，不由得使我对侯捷一样的技术作家长期伏案辛勤劳作深深敬佩了。看来对于书籍或者软件，都应该尊重作者或者programmer的才智劳动。</p><img src ="http://www.cppblog.com/luqingfei/aggbug/176586.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2012-05-29 10:17 <a href="http://www.cppblog.com/luqingfei/archive/2012/05/29/176586.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]游戏行业进入&amp;生存指南（一）</title><link>http://www.cppblog.com/luqingfei/archive/2012/05/13/174726.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Sun, 13 May 2012 00:27:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2012/05/13/174726.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/174726.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2012/05/13/174726.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/174726.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/174726.html</trackback:ping><description><![CDATA[<p>游戏行业进入&amp;生存指南（一）<br /><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><br />07年发表自电脑商情报，后来被各处转载，居然很多游戏学校还拿来当教材，迟早写一篇游戏学校篇。</p>
<p><wbr></p>
<p><wbr></p>
<p><wbr><wbr><wbr>上个世纪末的时候，我还是一名游戏制作爱好者，历经摸索、努力，进入了中国的游戏行业。众所周知，在历经了几近绝望的失败之后，网络游戏的曙光来临，中国游戏业获得了生存并发展下去的可能，越来越多的爱好者也有了闯荡这一行业的机会。<br /><wbr><wbr><wbr>自我接触游戏业之初，就听到有许许多多的人在外面嚷嚷，说是多么的想进入游戏业，说进入游戏业是多么的艰难，还质问这个行业为什么总是不给新人以机会。当时我也有差不多的想法和情绪，但在若干年后的今天，当我和团队一起从事游戏研发，并且负责不断为团队补充新鲜血液之际，却发现彼时的声音依然存在，而且更加响亮。<br /><wbr><wbr><wbr>我要说的事实是，所有的游戏公司都缺人，不管新兴的小工作室还是名声久远的大公司都需要人手。需要什么样的人呢？传说中的&#8220;千万年薪&#8221;的顶级策划？对今天我所讲内容感兴趣的你，显然不是他们要找的对象，或者说，你真的想做游戏吗？<br /><wbr><wbr><wbr>在这里，我只是想告诉那些有志于做游戏的人如何进入这一行业，以及在入业初期应该注意的各个方面。而在具体职能划分上，我主要谈及的是游戏策划的入行和进阶。毕竟，游戏策划这份工作我们可以视之为游戏行业催生的新职业&#8212;&#8212;一个门槛极低却异常难以入职，入职者绝大多数又都陷于平庸，或离开或湮灭的职业。<br /><wbr><wbr><wbr>叙事必先立论，我今天的观点是：</p>
<p><wbr><wbr><wbr>如果你想进入一个行业，那就努力的进去。<br /><wbr><wbr><wbr>&#8212;&#8212;&#8220;<span style="background-color: yellow">你呼唤山，山不向你走来，你便向山走去</span>。&#8221;<br /><wbr><wbr><wbr><br /><wbr><wbr><wbr>不要思前想后，犹犹豫豫，婆婆妈妈。<br /><wbr><wbr><wbr>&#8212;&#8212;&#8220;<span style="background-color: yellow">你不知道远方有没有你的梦，但你首先要走到远方</span>。&#8221;<br /><wbr><wbr><wbr><br /><wbr><wbr><wbr>如果你在一个行业过得不爽不开心，请走，不要在那里抱怨。抱怨改变不了环境，只能让你变得更加令人讨厌。<br /><wbr><wbr><wbr>&#8212;&#8212;&#8220;<span style="background-color: yellow">君子合则留，不合则走，绝交不出恶语</span>。&#8221;</p>
<p><wbr><wbr><wbr>我不想讨论任何严肃的话题，譬如教育、政治、法律等；也不想讨论企业管理、员工福利、相关法规；更不想激起愤青、P孩们乐于反抗的态度和声音。如果依靠年青激烈的言辞就能改变周围，改变环境，改变世界，那么我求求你们，把精力花在更崇高的地方。<br /><wbr><wbr><wbr>如果你对我的说法感到愤怒了，不满了，那么，请翻过此页。</p>
<p><wbr><wbr><wbr>今天我们要谈的是：在你做对之前，不要犯错误。</p>
<p>你因为如下原因进入游戏业&#8212;&#8212;<br /><wbr><wbr><wbr><br />A：玩了很多游戏想做；<br />B：认为自己是天才，充满创造力，想找个地方用；<br />C：这行能赚钱，试图名利双收；<br />D：感到现在的游戏都是**作品，想改变现状；<br />E：高薪就业与兴趣相结合；<br />F：当作一份工作。<br /><wbr><wbr><wbr><br /><wbr><wbr><wbr>于是，你想成为一名游戏策划，你开始设想怎样才能成为一名游戏策划、游戏企划，乃至游戏设计师之类的事情。最简单的方法是写一份简历投递出去。随便打开&#8220;前程无忧&#8221;、&#8220;智联招聘&#8221;、&#8220;中华英才网&#8221;什么的网站，上面的游戏公司还是很多的。&#8212;&#8212;可是，为什么你发出去的信息就都石沉大海了呢？<br /><wbr><wbr><wbr>在你准备花钱进某某游戏培训机构增加个人能力之前，或者在你准备到各大游戏论坛大骂：&#8220;为什么不给新人以机会？&#8221;之前，又或者在你意志消沉，准备于若干年后回忆&#8220;做游戏的梦&#8221;之前&#8212;&#8212;请你先看看下面这篇游戏公司投递应聘材料须知，我想这对你应该有所帮助。说不定，这还会让你感到宽慰呢，因为你不是一个人在犯错，比你差得多的人遍地都是......<br /><wbr><wbr><wbr>换言之，如果你的简历比以下的更出色，你的希望已经非常大了。</p>
<p>投递应聘材料须知：<br /><wbr><wbr><wbr>符合以下条件的邮件会被直接删除，你有异议吗？看看写在后面的拒绝理由。</p>
<p>1、别人帮忙发的简历（别人帮你，会被视为中介，一律免谈。你托别人发，对自己没有信心嘛。当然，熟人推荐的例外）；</p>
<p>2、给别家公司发的简历，抄送一份过来（这是一个最起码的礼貌问题，好比你要拿三份礼物送给三家，你只能拿一份跑一家，我很奇怪，分开发很麻烦吗？）；</p>
<p>3、利用一些招聘网站的模版发过来的，或者是一些招聘网站自动发过来的（既然是一份愿意从事的职业，请认真对待，而不是发传单。你轻率，我也轻率）；</p>
<p>4、邮件的内容只有一句话：&#8220;我是你们想找的人，请和我联系，留下qq或者手机号码&#8221;（公司招聘上有公司信息，你的邮件中没有你的信息，对话必须建立在双方对等的情况下）；</p>
<p>5、邮件内部附一个网址链接，说&#8220;这个链接有我的介绍和作品&#8221;（对不起，陌生人给的链接从来不点，怕中毒，邮件附件为可执行文件的同样处理）。</p>
<p><wbr><wbr><wbr>此外，如果求职邮件有以下情况的，同样立即否决：</p>
<p>1、邮件里称自己为天纵英才，睿智博学，能力超群将是中国游戏业救世主的（第一，咱池小水浅，怕无法让您这条大龙翱翔；第二，在黑客帝国里，先知没说尼奥是救世主，谁也不会找到尼奥当他是，我们这行也没有先知说您是救世主；第三，尊驾这样德才兼备的人士，衷心希望您去从事更高尚、更伟大的职业）；</p>
<p>2、邮件里称自己有天才想法、非凡设计、无以伦比的构思，期待共同成功的（委婉的说，有这种气魄和精神是好的，但是未经验证谁也不能保证成功，我不是说完全没有成功的可能，只是咱不能拿十数人到数十人好几年的劳作，几百上千万的资金投入来验证您的豪言壮语不是？坦白点讲，阁下何德何能，有何资历，如何服众啊？凭什么要众人受您驱策，以成就您的青天白日大头梦呢？）；</p>
<p>3、邮件的简历与游戏业，游戏制作业毫无关系（这种简历经常发自刚毕业的大学生，上书姓名、性别、出生年月日，以及教育经历、获奖情况、个人爱好等。除此之外，既不谈对游戏的爱好，也不谈对游戏业的认识。所以，我只能诚恳的告诉你，这种简历发到任何游戏公司都是直接回收站），补充一点，似乎所有人都当过学生干部？也统统获得过奖学金？</p>
<p>4、邮件内容语无伦次，瞻前顾后，扭扭捏捏。<br /><wbr><wbr><wbr>例句a：我叫XX，学生，我喜欢游戏。那个XX游戏很不错，我觉得应该改进一下，让XX的攻击力更强一点。我玩过很多游戏，有一次玩XX的时候......（自我介绍都不会的人，大概也不会和人相处）；<br /><wbr><wbr><wbr>例句b：游戏设计师这个职业是干什么的，不知道适不适合我......（你都不知道，我怎么知道？）；<br /><wbr><wbr><wbr>例句c：你们公司怎么样啊？我想来工作，又怕（待遇不高、没有发展前途、家庭反对），所以我很犹豫（您慢慢犹豫吧）；</p>
<p>5、简历中错字连篇、重大常识性错误、信口胡说的。<br />（诸如在个人能力介绍中，不厌其烦的说有&#8220;教强&#8221;的XX能力，&#8220;教深&#8221;的XX修养，在个人薪金期望上写错位数达到年薪4亿的，写游戏名字中英文拼写都错误的，某某平台的游戏张冠李戴到另一个平台上的......）；</p>
<p>6、简历制作及内容不合格的。譬如&#8212;&#8212;<br /><wbr><wbr>A：基本文档*作不过关，表格不整齐，内容不清晰，结构不美观，文字不对齐，字体不整洁（这样的简历中往往自称office软件使用熟练？让人怎么信！）；<br /><wbr><wbr>B：拷贝别人的简历修改而成（拷贝简历模板不是你的错，但把原模板上的超链接以及其他讯息都拷贝过来我就无话可说了，莫非当年抄卷子时也顺便抄了别人的名字？）；<br /><wbr><wbr>C：简历的附件作品名称为&#8220;新建文档&#8221;、&#8220;新建rar&#8221;的（对自己所附的作品尚且不够注意的人，不可能对所做的游戏负责任）；<br /><wbr><wbr>D：拿应聘其它公司的考题答卷作为自己作品的（保护考题的机密性，是笔试应该也必须遵循的规范，游戏研发是需要保密的行业）；<br /><wbr><wbr>E：有强烈的主观和敏感内容的简历（任意臧否其它公司的游戏，运营方式的。或者希望把游戏作为寄托自己政治成见，思想理念的载体）。</p>
<p>7、可能有潜在性麻烦的邮件。<br /><wbr><wbr>A：说自己的创意非常独特，阅<a><u><font color="#b5b57d">读者</font></u></a>要遵守相关协议，不然阅读者所属公司未来开发的某款游戏可能成为起诉的对象......（不知道写这句话的人懂不懂这个基本道理：不能执行的创意就是狗屁！好比你预测出股票的涨跌，而你没钱买一样。你跟在一起股民说&#8220;假如明天谁按照我的预测买了股票赚钱，谁就是剽窃我的分析&#8221;试试看？）；<br /><wbr><wbr>B：说如果贵公司不招收他就是重大错误，会后悔一辈子，难逃破产倒闭命运的（武侠小说中看过这样的情节，某某少年才俊投靠名门大派而不得入，若干年后终成一方霸主，然后耀武扬威的前来兴师问罪。像这样以复仇还愿为目标的&#8220;潜在成功者&#8221;，还是不要为好）；<br /><wbr><wbr>C：讲自己的个人经历苦大仇深的，讲自己的目标生死不渝的，讲自己为了做游戏百折不挠的（人生在世，目标专一固然好，如果把希望只寄托在一件事情上，很危险）；<br /><wbr><wbr>D：说自己的家境非常优越，生活无比幸福，前途一片光明，即使不做游戏也会吃香喝辣，快活一生的。或说做游戏<a><u><font color="#b5b57d">纯粹</font></u></a>是爱好，今天不做了，明天就可以去更舒服、更有钱的地方享受生活的（其实我知道你是想表达一种强烈的愿望，可是你不觉得这种表达方式意味着你随时可能离开，从而导致团队的不稳定吗？）。</p>
<p>8、简历中有不切实际的要求的。<br /><wbr><wbr>A：面对全职职位提出要兼职的（一般来说，游戏研发中没有兼职职位。对于部分音乐、美术、文案工作可以外包完成，这主要是考虑到研发进度的协调管理。）；<br /><wbr><wbr>B：要求按照自己的作息制度安排工作时间的（就算是一家可以根据实际情况需要执行整体或者局部弹性工作时间的公司，也绝不会允许个别人的不定时工作）；<br /><wbr><wbr>C：要求按照自己的生活需要提供薪水的（上海房价最高13万1平方米，通铺最便宜130一个月，你有什么样的能耐就吃什么样的饭，睡什么床是你的事情，无论哪家单位，都不会是你擦亮的阿拉丁神灯）；<br /><wbr><wbr>D：要求按照自己的理念组织公司结构和管理规章的（尚方宝剑、金牌令箭、总裁手令、皇上圣旨、锦衣卫都统腰牌、血滴子主管执照......您拿出一件来证明一下您的身份罢）；<br /><wbr><wbr>E：要求按照自己居住的地区成立分公司的（伊丽莎白泰勒当年拍片就要求过在另一个地方搭棚拍摄，你比她大牌吗？）；<br /><wbr><wbr>F：要求特定人，或指定级别的领导来才能面试的（经常在某些俗滥电视剧中看到某人气宇轩昂的走到某门口，大声说：&#8220;叫XXX、县令、总经理来见我！&#8221;现在我终于在简历中看到了......）；<br /><wbr><wbr>G：要求飞机往返面试并提供补贴的（摩根斯坦利的首席分析师离职后，有上百家金融公司找他做事，估计他是飞机往返面试的，google也进行这样的面试，不过呢，你有多大斤两，得飞机托运？）；<br /><wbr><wbr>H：没有提要求就咒骂的。有痛骂其它公司没有伯乐的，有痛骂游戏界黑暗的，有痛骂游戏开发运营商**的。总之必然是要灭亡的（虽说不是明着骂我们，可毕竟兔死狐悲，物伤其类呀！）；<br /><wbr><wbr>I：要求通过免费或者最低生活费来工作的（一家正规公司是不可能接受的，经常看到有爱好者说：&#8220;试试不行吗？不合适我就走？&#8221;但是你有没有想过，你不合适可以走，但公司对你的培养呢？团队的稳定呢？）。</p>
<p>9、接受过来自XX游戏培训机构的简历（这个部分将在下期予以说明）。</p>
<p>10、附有几十页乃至数百页不等的策划案（策划书）。<br /><wbr><wbr><wbr>（这本来是一个加分选项，然而，几乎百分之百的所谓策划书都毫无新意，绝大多数是基于其他网上流传的策划书模板改写而来，经常是除了种族名、角色名，技能名不同之外，格式、玩法完全一样。特别是从一些游戏培训机构投递来的简历，与其说是作品，不如说是作业&#8212;&#8212;拿了一份模板改出来的作业！我知道很多人写得很认真，而且在许多细节上用足了脑筋，煞费了苦心，然而这是毫无意义的。因为这份策划书除了你看，没有别人看！与其这样，不如试用1-2页讲述你设计的游戏的卖点和玩点，牢记&#8212;&#8212;不要抄别人的话，不要说想当然的话！）。</p>
<p><wbr><wbr><wbr>以上，就是我今天所要讲的内容，不知你是否有所收获？是否你投递的简历也有着同样的问题？你可能会有很多的怨言，很多的不满，然而那是毫无益处的，在下一期里，我将会告诉你怎样去写一份应聘策划的简历。<br /><wbr><wbr><wbr>结尾之际，请大家读读下面这篇&#8220;策划之野望&#8221;，如果你的思想和下面的内容有所吻合，那么你就要有所警醒咯！</p>
<p>策划之野望&#8212;&#8212;</p>
<p><wbr><wbr><wbr>游戏策划这门职业，睡觉睡到自然醒，开着火红的法拉利前往工作室，路人，嗯...还有许多<a><u><font color="#b5b57d">美女</font></u></a>用艳羡的目光望着你行注目礼，看着你驶进所有玩家都尊称为神殿的公司大门。公司门廊上镶满了白金级作品的徽标。你踏入宽敞奢华，彷佛科幻电影一般的办公室，看到了游戏开发团队&#8212;&#8212;他们都是各类技术方面的天才，随便在什么专业论坛露面都会被顶礼膜拜，而他们看你却像看着教皇一般。于是你发话&#8212;&#8212;说出字字千金般的几句话，团队中人顿时感到醍醐灌顶，茅塞顿开，然后诚惶诚恐的按照你的设计去展开工作，一个个鞠躬尽瘁，竭尽全力，通宵达旦......<br /><wbr><wbr><wbr>不久后，游戏上市，销量超人，横扫欧美日台韩各地游戏销售榜，各大游戏媒体毫不吝啬的把头版和彩图献给你和你的游戏。各大发行商也毫不犹豫的把分成的巨额收入打到你的帐上，争先恐后要以对外保密的高价签定下一个游戏的发行权，而你只是随便更换了一部跑车，非常谦虚的说：&#8220;游戏的成功，属于我们整个团队......&#8221;<br /></p><img src ="http://www.cppblog.com/luqingfei/aggbug/174726.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2012-05-13 08:27 <a href="http://www.cppblog.com/luqingfei/archive/2012/05/13/174726.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数学的魅力：取余运算还可以这样</title><link>http://www.cppblog.com/luqingfei/archive/2011/02/21/140369.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Mon, 21 Feb 2011 06:08:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2011/02/21/140369.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/140369.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2011/02/21/140369.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/140369.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/140369.html</trackback:ping><description><![CDATA[5%2 = =0<br>上面这个取余操作，想必很多人都用到过。<br>5%2的结果只有两种：0和1。<br><br>今天遇到下面这样的需求：<br>实现"四舍六入五单双"的函数或方法<br>有没有一种方法实现,"四舍六入五单双",即,如舍去位数为5时,要看它前面的数是双数还是单数,是双数时舍去,是单数时进位.<br>如:5.38舍入后为5.4<br>5.34舍入后为5.3<br>5.35舍入后为 5.4, 而5.45舍入后为 5.4<br><br>最后用下面的Excel函数公式解决：<br>=ROUND(A3,2)-IF(INT(MOD(A3*1000,20))=5,0.01,0)<br><br>发现下面这样一个小技巧：<br>只有10位上的数字是偶数时，且个位上是5时，这个数字除以20，他的余数才可能是5<br><br><br>感叹，以前取余基本都是对2取，现在思路一下被打开了。<br>这就是数学之美！:-)<br>
<img src ="http://www.cppblog.com/luqingfei/aggbug/140369.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2011-02-21 14:08 <a href="http://www.cppblog.com/luqingfei/archive/2011/02/21/140369.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>智能指针auto_ptr运用实例：常数型智能指针的特性</title><link>http://www.cppblog.com/luqingfei/archive/2011/01/04/137954.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Tue, 04 Jan 2011 07:29:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2011/01/04/137954.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/137954.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2011/01/04/137954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/137954.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/137954.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">展示const&nbsp;auto_ptr的特性</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">memory</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><br></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">&nbsp;define&nbsp;output&nbsp;operator&nbsp;for&nbsp;auto_ptr<br>*&nbsp;&nbsp;print&nbsp;object&nbsp;value&nbsp;or&nbsp;NULL<br></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>ostream</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;(ostream</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;strm,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;auto_ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000">&nbsp;p)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;does&nbsp;p&nbsp;own&nbsp;an&nbsp;object&nbsp;?&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(p.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">()&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strm&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">NULL</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;NO:&nbsp;print&nbsp;NULL</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strm&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;YES:&nbsp;print&nbsp;the&nbsp;object</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;strm;<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;auto_ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;p(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">42</span><span style="COLOR: #000000">));<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;auto_ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;q(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">));<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;auto_ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;r;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">after&nbsp;initialization:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;p:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;p&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;q:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;q&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;r:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;r&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">q&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">*r&nbsp;=&nbsp;*p;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;ERROR:&nbsp;undefined&nbsp;behavior&nbsp;对于一个&#8220;未指向任何对象&#8221;的auto_ptr进行提领（dereference）操作，C++标准规格，<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">这会导致未定义行为，比较如说导致程序的崩溃。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">77</span><span style="COLOR: #000000">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">after&nbsp;assigning&nbsp;values:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;p:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;p&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;q:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;q&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;r:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;r&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">q&nbsp;=&nbsp;p;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;ERROR&nbsp;at&nbsp;compile&nbsp;time<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">r&nbsp;=&nbsp;p;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;ERROR&nbsp;at&nbsp;compile&nbsp;time</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">}</span></div>
<br>输出结果：<br>after initialization:<br>&nbsp;p: 42<br>&nbsp;q: 0<br>&nbsp;r: NULL<br>after assigning values:<br>&nbsp;p: -77<br>&nbsp;q: 42<br>&nbsp;r: NULL<br>请按任意键继续. . .<br>
<img src ="http://www.cppblog.com/luqingfei/aggbug/137954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2011-01-04 15:29 <a href="http://www.cppblog.com/luqingfei/archive/2011/01/04/137954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>智能指针auto_ptr运用实例：移转拥有权的行为</title><link>http://www.cppblog.com/luqingfei/archive/2011/01/04/137951.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Tue, 04 Jan 2011 06:29:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2011/01/04/137951.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/137951.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2011/01/04/137951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/137951.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/137951.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">memory</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><br></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">&nbsp;define&nbsp;output&nbsp;operator&nbsp;for&nbsp;auto_ptr<br>*&nbsp;&nbsp;print&nbsp;object&nbsp;value&nbsp;or&nbsp;NULL<br></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br><br>template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>ostream</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;(ostream</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;strm,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;auto_ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000">&nbsp;p)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;does&nbsp;p&nbsp;own&nbsp;an&nbsp;object&nbsp;?</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(p.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">()&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strm&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">NULL</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;NO:print&nbsp;NULL</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strm&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;YES:print&nbsp;the&nbsp;object</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;strm;<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;auto_ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;p(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">42</span><span style="COLOR: #000000">));<br>&nbsp;&nbsp;&nbsp;&nbsp;auto_ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;q;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">after&nbsp;initialization:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;p:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;p&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;q:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;q&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;q&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;p;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">after&nbsp;assigning&nbsp;auto&nbsp;pointers:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;p:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;p&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;q:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;q&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">q&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;change&nbsp;value&nbsp;of&nbsp;the&nbsp;object&nbsp;q&nbsp;owns</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;q;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">after&nbsp;change&nbsp;and&nbsp;reassingnment:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;p:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;p&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;q:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;q&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>}<br><br></span></div>
<p><br>输出结果：<br>after initialization:<br>&nbsp;p: 42<br>&nbsp;q: NULL<br>after assigning auto pointers:<br>&nbsp;p: NULL<br>&nbsp;q: 42<br>after change and reassingnment:<br>&nbsp;p: 55<br>&nbsp;q: NULL<br>请按任意键继续. . .</p>
<p><br><br><br>&nbsp;</p>
<img src ="http://www.cppblog.com/luqingfei/aggbug/137951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2011-01-04 14:29 <a href="http://www.cppblog.com/luqingfei/archive/2011/01/04/137951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++实现插入排序（升序+降序）</title><link>http://www.cppblog.com/luqingfei/archive/2010/11/24/134527.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Wed, 24 Nov 2010 08:58:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/11/24/134527.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/134527.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/11/24/134527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/134527.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/134527.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;arr[]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">};<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;len&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">&nbsp;arr</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">&nbsp;arr[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">];<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">原序列：</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">len;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;arr[i]&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">--插入排序（升序）----------------</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">len;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;key&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;arr[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(j&nbsp;</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;key&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;arr[j])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;arr[j];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;key;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">---------------------------------</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">升序：</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">len;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;arr[i]&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">--插入排序（降序）----------------</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">len;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;key&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;arr[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(j&nbsp;</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;key&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;arr[j])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;arr[j];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;key;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">---------------------------------</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">降序：</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">len;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;arr[i]&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>}</span></div>
运行结果：<br>原序列：5, 2, 4, 6, 1, 3,<br>升序：1, 2, 3, 4, 5, 6,<br>降序：6, 5, 4, 3, 2, 1,
<img src ="http://www.cppblog.com/luqingfei/aggbug/134527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-11-24 16:58 <a href="http://www.cppblog.com/luqingfei/archive/2010/11/24/134527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>javascript实现的插入排序算法</title><link>http://www.cppblog.com/luqingfei/archive/2010/11/24/134517.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Wed, 24 Nov 2010 07:26:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/11/24/134517.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/134517.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/11/24/134517.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/134517.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/134517.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">script&nbsp;type</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">text/javascript</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">格式化时间</span><span style="COLOR: #008000"><br>/*</span><span style="COLOR: #008000">*<br>&nbsp;*&nbsp;格式化时间&lt;br&nbsp;/&gt;<br>&nbsp;*&nbsp;eg:&nbsp;new&nbsp;Date().format('yyyy-MM-dd&nbsp;HH:mm:ss')//2009-10-19&nbsp;16:21:30<br>&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>Date.prototype.format&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">(format)&nbsp;{<br>&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;o&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{<br>&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">M+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.getMonth()&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;month</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">d+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.getDate(),&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;day</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">H+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.getHours(),&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;hour</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">m+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.getMinutes(),&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;minute</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">s+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.getSeconds(),&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;second</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">q+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:Math.floor((</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.getMonth()&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">),&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;quarter</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">S</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.getMilliseconds()<br>&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;millisecond</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;}<br>&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">(y</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">.test(format))<br>&nbsp;&nbsp;format&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;format.replace(RegExp.$</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.getFullYear()&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;.substr(</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;RegExp.$</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">.length));<br>&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;k&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;o)<br>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;RegExp(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;k&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).test(format))<br>&nbsp;&nbsp;&nbsp;format&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;format.replace(RegExp.$</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;RegExp.$</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">.length&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">&nbsp;o[k]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">00</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;o[k]).substr((</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;o[k]).length));<br>&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;format;<br>}<br><br><br></span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;arr&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Array(</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">);<br>document.write(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">插入排序法：</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>document.write(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;br&nbsp;/&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Date().format('yyyy</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">MM</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">dd&nbsp;HH:mm:ss.S'));<br>document.write(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;br&nbsp;/&gt;排序前：</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;arr.join(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">));<br>document.write(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;br&nbsp;/&gt;排序后：</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;InsertionSort(arr));<br>document.write(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;br&nbsp;/&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Date().format('yyyy</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">MM</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">dd&nbsp;HH:mm:ss.S'));<br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">插入排序法</span><span style="COLOR: #008000"><br></span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;InsertionSort(arr)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">******核心部分开始************************************</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">arr.length;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;key&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;arr[i];</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">关键字，从序列的第2个元素开始。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">关键字元素的前一个元素索引值。从零开始。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">遍历关键字前的序列，从后向前逐个与关键字比较，如果大于关键字，就向后移一位。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(j&nbsp;</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;key&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;arr[j])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;arr[j];</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把比关键字大的元素，</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">从后向前遍历，所以减减。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">经过上一个循环比较后，j当前指的元素是小于关键字的。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">所以关键字应放置在j+1位置。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;key;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">******核心部分结束************************************</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;arr.join(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">返回字符串值，其中包含了连接到一起的数组的所有元素，元素由指定的分隔符分隔开来。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">}<br><br></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">script</span><span style="COLOR: #000000">&gt;</span></div>
<img src ="http://www.cppblog.com/luqingfei/aggbug/134517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-11-24 15:26 <a href="http://www.cppblog.com/luqingfei/archive/2010/11/24/134517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]ACM国际大学生程序设计</title><link>http://www.cppblog.com/luqingfei/archive/2010/11/23/134423.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Tue, 23 Nov 2010 12:57:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/11/23/134423.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/134423.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/11/23/134423.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/134423.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/134423.html</trackback:ping><description><![CDATA[<p>入门三本：<br>《数据结构与算法》（傅清祥，王晓东编著，我所见过的最好的算法教材）<br>程序设计导引及在线实践 作者: 李文新<br>ACM程序设计培训教程 吴昊</p>
<p>基础提高：<br>算法艺术与信息学竞赛 第二版 刘汝佳<br>算法设计与分析 王晓东<br>算法设计与试验题解 王晓东<br>科曼：《算法导论》<br>组合数学 第三版 冯舜玺 译<br>计算几何－算法设计与分析 周培德<br>国际信息学奥林匹克竞赛指导— — 实用算法的分析与程序设计　 吴文虎 王建德</p>
<p>网络算法与复杂性理论 谢政 李建平<br>《Concrete Mathematics --- A Foundation For Computer Science》 Ronald L. Graham ， Donald E. Knuth ， Oren Patashnik《具体数学》（能买到中文版最好）<br>《计算机程序设计艺术》三卷 Knuth <br>组合数学的算法与程序设计<br>《程序设计中的组合数学》 吴文虎<br>图论的算法与程序设计<br>图、网络与算法</p>
<p>国际大学生程序设计竞赛辅导教程 郭嵩山 崔昊</p>
<p>《ACM国际大学生程序设计竞赛试题与解析》全部册（吴文虎著，清华大学出版社）<br>C算法．第1卷，基础、数据结构、排序和搜索（第三版）<br>C算法(第2卷图算法第3版中文版)译者:周良忠 (美国)塞奇威克著 <br>国际大学生程序设计竞赛例题解 四本 郭嵩山</p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 请所有的新队员认真完成以下各题。如果做题遇到困难，如题意难以理解、不知如何着手或不知错在哪里，不要气馁，可以请教别的队员，也可请教教练。我们会尽力帮助你完成这几组中每一道题。但不要复制别人的程序，即便参考了别人的程序，也要亲自再完成一遍。而且不建议过多参考别人程序，这样会消弱训练的效果，也减少了思考的乐趣。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 有些队员可能觉得某些题太简单，但我们还是建议将它们都做掉。因为题目虽然简单，但是再简单的题目都不能保证一次做对，而做错题的各种原因如题意理解错误，格式错误等你都会碰到。了解这些原因对减少错误率很有好处。</p>
<p><br>&nbsp;</p>
<img src ="http://www.cppblog.com/luqingfei/aggbug/134423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-11-23 20:57 <a href="http://www.cppblog.com/luqingfei/archive/2010/11/23/134423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]算法方面的好书</title><link>http://www.cppblog.com/luqingfei/archive/2010/11/23/134422.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Tue, 23 Nov 2010 12:55:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/11/23/134422.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/134422.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/11/23/134422.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/134422.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/134422.html</trackback:ping><description><![CDATA[<p>1.The Art of Computer Programming<br>作者：Donald E. Knuth<br>2.Introduction to Algorithms<br>作者：Thomas H. Cormen，Charles E. Leiserson，Ronald L. Rivest<br>3.算法与数据结构<br>作者：傅清祥 王晓东<br>出版社：电子工业出版社<br>4.国际信息学奥林匹克竞赛指导--实用算法的分析与程序设计<br>作者：吴文虎 王建德<br>出版社：电子工业出版社<br>5.Computer Algorithms: Introduction to Design and Analysis<br>作者：Sara Baase ，Allen Van Gelder<br>出版社：影印版由高等教育出版社出版<br>6.数据结构与算法--面向对象的C++设计模式<br>英文版书名：<br>Data Structures and Algorithms with Object-Oriented Design Patterns in C++<br>作者：Bruno R. Preiss<br>出版社：影印版和中文版由电子工业出版社出版<br>7.数据结构、算法与应用--C++语言描述<br>英文版书名：<br>Data Structure, Algorithms, and Application in C++<br>作者：Sartaj Sahni<br>出版社：影印版和中文版由机械工业出版社出版 </p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/luqingfei/aggbug/134422.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-11-23 20:55 <a href="http://www.cppblog.com/luqingfei/archive/2010/11/23/134422.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]备战ACM/ICPC资料</title><link>http://www.cppblog.com/luqingfei/archive/2010/11/23/134421.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Tue, 23 Nov 2010 12:51:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/11/23/134421.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/134421.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/11/23/134421.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/134421.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/134421.html</trackback:ping><description><![CDATA[<p>一：知识点<br>&nbsp;&nbsp;&nbsp; 数据结构：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1，单，双链表及循环链表<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2，树的表示与存储，二叉树（概念，遍历）二叉树的&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 应用（二叉排序树，判定树，博弈树，解答树等）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3，文件操作（从文本文件中读入数据并输出到文本文&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 件中）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4，图（基本概念，存储结构，图的运算）<br>&nbsp;&nbsp; 数学知识<br>&nbsp;&nbsp;&nbsp;&nbsp; 1，离散数学知识的应用（如排列组合、简单的图论，数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 理逻辑）<br>&nbsp;&nbsp;&nbsp;&nbsp; 2，数论知识<br>&nbsp;&nbsp;&nbsp;&nbsp; 3，线性代数<br>&nbsp;&nbsp;&nbsp;&nbsp; 4，组合代数<br>&nbsp;&nbsp;&nbsp;&nbsp; 5，计算几何<br>二 算法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1，排序算法（冒抛法，插入排序，合并排序，快速排&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 序，堆排序）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2，查找（顺序查找，二分发）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3，回溯算法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4，递归算法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5，分治算法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6，模拟法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7，贪心法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8，简单搜索算法（深度优先，广度优先），搜索中的<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 剪枝，A*算法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9，动态规划的思想及基本算法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10，高精度运算&nbsp;&nbsp;&nbsp; <br>三、ACM竞赛的题型分析<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 竞赛的程序设计一般只有16种类型，它们分别是：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dynamic Programming （动态规划） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Greedy （贪心算法） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Complete Search （穷举搜索） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Flood Fill （不知该如何翻译） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Shortest Path （最短路径） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Recursive Search Techniques （回溯搜索技术） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Minimum Spanning Tree （最小生成树） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Knapsack （背包问题） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Computational Geometry (计算几何学) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Network Flow （网络流） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Eulerian Path （欧拉回路） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Two-Dimensional Convex Hull （不知如何翻译） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BigNums （大数问题） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Heuristic Search （启发式搜索） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Approximate Search （近似搜索） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ad Hoc Problems （杂题） </p>
<p>四&nbsp; ACM竞赛参考书 <br>&nbsp;<br>&nbsp; 《实用算法的分析与程序设计》&nbsp; （吴文虎，王建德著，电子工业出版社，竞赛类的黑宝书）<br>&nbsp; 《青少年国际和全国信息学（计算机）奥林匹克竞赛指导）――组合数学的算法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 和程序设计》&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （吴文虎，王建德著，清华大学出版社，参加竞赛组合数学必学）<br>&nbsp; 《计算机算法设计与分析》&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （王晓东编著，最好的数据结构教材）<br>&nbsp; 《数据结构与算法》&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （傅清祥，王晓东编著，我所见过的最好的算法教材）<br>&nbsp; 《信息学奥林匹克竞赛指导――1997-1998竞赛试题解析》（吴文虎，王建德著，清华大学出版社，&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 内容极佳）<br>&nbsp; 《计算机程序设计技巧》&nbsp;&nbsp;&nbsp; D.E.Kruth著，算法书中最著名的《葵花宝典》，大师的作品，难度大）<br>&nbsp; 《计算几何》&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （周陪德著，全面介绍了计算几何）<br>&nbsp; 《ACM国际大学生程序设计竞赛试题与解析（一）》&nbsp; （吴文虎著，清华大学出版社）<br>&nbsp;&nbsp; &lt;&lt;数学建模竞赛培训教材&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 共三本 叶其孝主编<br>&nbsp;&nbsp; &lt;&lt;数学模型&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第二版 姜启源<br>&nbsp;&nbsp; &lt;&lt;随机规划&gt;&gt; <br>&nbsp;&nbsp; &lt;&lt;模糊数学&gt;&gt; <br>&nbsp;&nbsp; &lt;&lt;数据结构&gt;&gt;<br>&nbsp;&nbsp; &lt;&lt;数学建模入门&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 徐全智<br>&nbsp;&nbsp; &lt;&lt;计算机算法设计与分析&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 国防科大&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>五 常见的几个网上题库<br>&nbsp;&nbsp; 常用网站：<br>&nbsp;&nbsp;&nbsp; 1）信息学初学者之家：<a href="http://oibh.ioiforum.org/">http://oibh.ioiforum.org/</a><br>&nbsp;&nbsp; （2）大榕树编程世界：<a href="http://www.fjsdfz.org/~drs/program/default.asp">http://www.fjsdfz.org/~drs/program/default.asp</a><br>&nbsp;&nbsp; （3）中国教育曙光网：<a href="http://www.chinaschool.org/aosai/">http://www.chinaschool.org/aosai/</a><br>&nbsp;&nbsp; （4）福建信息学奥林匹克：<a href="http://www.cfcs.com.cn/fjas/index.htm">http://www.cfcs.com.cn/fjas/index.htm</a><br>&nbsp;&nbsp; （5）第20届全国青少年信息学奥林匹克竞赛：<a href="http://www.noi2003.org/">http://www.noi2003.org/</a><br>&nbsp;&nbsp; （6）第15届国际青少年信息学奥林匹克竞赛：<a href="http://www.ioi2003.org/">http://www.ioi2003.org/</a><br>&nbsp;&nbsp; （7）全美计算机奥林匹克竞赛：<a href="http://ace.delos.com/usacogate">http://ace.delos.com/usacogate</a><br>&nbsp;&nbsp; （8）美国信息学奥林匹克竞赛官方网站：<a href="http://www.usaco.org/">http://www.usaco.org/</a><br>&nbsp;&nbsp; （9）俄罗斯Ural州立大学：<a href="http://acm.timus.ru/">http://acm.timus.ru/</a><br>&nbsp;&nbsp; （10）西班牙Valladolid大学：<a href="http://acm.uva.es/problemset">http://acm.uva.es/problemset</a><br>&nbsp;&nbsp; （11）ACM-ICPC：<a href="http://icpc.baylor.edu/icpc/">http://icpc.baylor.edu/icpc/</a><br>&nbsp;&nbsp; （12）北京大学：<a href="http://acm.pku.edu.cn/JudgeOnline/index.acm">http://acm.pku.edu.cn/JudgeOnline/index.acm</a><br>&nbsp;&nbsp; （13）浙江大学：<a href="http://acm.zju.edu.cn/">http://acm.zju.edu.cn/</a><br>&nbsp;&nbsp; （14）IOI：<a href="http://olympiads.win.tue.nl/ioi/">http://olympiads.win.tue.nl/ioi/</a><br>&nbsp;&nbsp; （15）2003年江苏省信息学奥林匹克竞赛夏令营：<a href="http://jsoi.czyz.com.cn/">http://jsoi.czyz.com.cn</a><br>&nbsp;&nbsp; （16）<a href="http://acm.zju.edu.cn/">http://acm.zju.edu.cn</a><br>&nbsp;&nbsp; （17）<a href="http://acm.zsu.edu.cn/">http://acm.zsu.edu.cn</a><br>&nbsp;&nbsp; （18）<a href="http://www.shumo.com/">www.shumo.com</a><br>&nbsp;&nbsp; （19）<a href="http://www.bepark.com/downldmanag/index.asp">http://www.bepark.com/downldmanag/index.asp</a><br>&nbsp;&nbsp; （20）<a href="http://www.yh01.com/">http://www.yh01.com</a>&nbsp;&nbsp;&nbsp; colin_fox/colin_fox </p>
<p>五 如何备战ACM/ICPC<br>&nbsp;&nbsp;&nbsp; 1，个人准备（算法书，习题集，网上做题和讨论）<br>&nbsp;&nbsp;&nbsp; 2，1000题=亚洲冠军=世界决赛<br>&nbsp;&nbsp;&nbsp; 3，做好资料收集和整理工作； </p>
<p><br>&nbsp;</p>
<img src ="http://www.cppblog.com/luqingfei/aggbug/134421.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-11-23 20:51 <a href="http://www.cppblog.com/luqingfei/archive/2010/11/23/134421.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]ACM大量习题题库及建议培养计划</title><link>http://www.cppblog.com/luqingfei/archive/2010/11/23/134396.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Tue, 23 Nov 2010 07:44:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/11/23/134396.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/134396.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/11/23/134396.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/134396.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/134396.html</trackback:ping><description><![CDATA[<p>ACM大量习题题库 <br>现在网上有许多题库，大多是可以在线评测，所以叫做Online Judge。除了USACO是为IOI准备外，其余几乎全部是大学的ACM竞赛题库。</p>
<p>USACO<br><a href="http://ace.delos.com/usacogate">http://ace.delos.com/usacogate</a><br>美国著名在线题库，专门为信息学竞赛选手准备</p>
<p><br>TJU<br><a href="http://acm.tongji.edu.cn/">http://acm.tongji.edu.cn/</a><br>同济大学在线题库，唯一的中文题库，适合NOIP选手</p>
<p><br>ZJU<br><a href="http://acm.zju.edu.cn/">http://acm.zju.edu.cn/</a><br>浙江大学在线题库</p>
<p><br>JLU<br><a href="http://acm.jlu.edu.cn/">http://acm.jlu.edu.cn/</a><br>吉林大学在线题库（一直上不去）</p>
<p><br>PKU<br><a href="http://acm.pku.edu.cn/">http://acm.pku.edu.cn</a><br>北京大学在线题库</p>
<p><br>URAL<br><a href="http://acm.timus.ru/">http://acm.timus.ru</a><br>俄罗斯乌拉尔大学在线题库</p>
<p><br>SGU<br><a href="http://acm.sgu.ru/">http://acm.sgu.ru/</a><br>俄罗斯圣萨拉托夫州大学在线题库</p>
<p><br>ELJ<br><a href="http://acm.mipt.ru/judge/bin/problems.pl?lang=en">http://acm.mipt.ru/judge/bin/problems.pl?lang=en</a><br>俄罗斯莫斯科物理技术学院</p>
<p><br>SPOJ<br><a href="https://spoj.sphere.pl/">https://spoj.sphere.pl/</a><br>波兰格但斯克理工大学</p>
<p><br>UVA<br><a href="http://acm.uva.es/">http://acm.uva.es/</a><br>西班牙的Universidad de Valladolid在线题</p>
<p><br>ACM联系建议</p>
<p>一位高手对我的建议：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 一般要做到50行以内的程序不用调试、100行以内的二分钟内调试成功.acm主要是考算法的<br>，主要时间是花在思考算法上，不是花在写程序与debug上。 <br>下面给个计划你练练：</p>
<p>第一阶段：<br>&nbsp;&nbsp;&nbsp; 练经典常用算法，下面的每个算法给我打上十到二十遍，同时自己精简代码，<br>因为太常用，所以要练到写时不用想，10-15分钟内打完，甚至关掉显示器都可以把程序打<br>出来. <br>1.最短路(Floyd、Dijstra,BellmanFord) <br>2.最小生成树(先写个prim,kruscal要用并查集，不好写) <br>3.大数（高精度）加减乘除 <br>4.二分查找. (代码可在五行以内) <br>5.叉乘、判线段相交、然后写个凸包. <br>6.BFS、DFS,同时熟练hash表(要熟，要灵活,代码要简) <br>7.数学上的有：辗转相除（两行内），线段交点、多角形面积公式. <br>8. 调用系统的qsort, 技巧很多，慢慢掌握. <br>9. 任意进制间的转换</p>
<p><br>第二阶段：<br>&nbsp;&nbsp;&nbsp; 练习复杂一点，但也较常用的算法。 <br>如： <br>1. 二分图匹配（匈牙利），最小路径覆盖 <br>2. 网络流，最小费用流。 <br>3. 线段树. <br>4. 并查集。 <br>5. 熟悉动态规划的各个典型：LCS、最长递增子串、三角剖分、记忆化dp <br>6.博弈类算法。博弈树，二进制法等。 <br>7.最大团，最大独立集。 <br>8.判断点在多边形内。 <br>9. 差分约束系统. <br>10. 双向广度搜索、A*算法，最小耗散优先.</p>
<p><br>第三阶段：<br>&nbsp;&nbsp;&nbsp; 前两个阶段是打基础，第三阶段是锻炼在比赛中可以快速建立模型、想新算法<br>。这就要平时多做做综合的题型了。 <br>1. 把oibh上的论文看看（大概几百篇的，我只看了一点点，呵呵）。 <br>2. 平时扫扫zoj上的难题啦，别老做那些不用想的题.(中大acm的版主经常说我挑简单的来<br>做:-P ) <br>3. 多参加网上的比赛，感受一下比赛的气氛，评估自己的实力. <br>4. 一道题不要过了就算，问一下人，有更好的算法也打一下。 <br>5. 做过的题要记好 :-)&nbsp; </p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/luqingfei/aggbug/134396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-11-23 15:44 <a href="http://www.cppblog.com/luqingfei/archive/2010/11/23/134396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>40岁以后的程序员还能做什么? </title><link>http://www.cppblog.com/luqingfei/archive/2010/11/05/132557.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Fri, 05 Nov 2010 06:47:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/11/05/132557.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/132557.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/11/05/132557.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/132557.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/132557.html</trackback:ping><description><![CDATA[<div class=postbody>
<p>如果不到30岁，看到40岁标题这几个字就跳过去，那么你的人生很有可能失去提早准备的机会。要回答『程序员40岁以后还可以做点什么』的这个问题，首先要<span style="BACKGROUND-COLOR: yellow">看一看那些已经超过40岁的程序员现在都在干什么，然后相互比较，从中得到启发，思考如何选择一条最适合自己模仿的路。</span></p>
<p><span style="BACKGROUND-COLOR: yellow">衡量一个人成功的标准有很多，有些人把财富或权力视为成功，还有些人则把内心的安宁和身体健康视为成功，甚至不同国家地区、文化背景下也有其特色。</span>当然，还有一个我们容易忽略的重点，就是这些前辈在他们二十多岁选择的技术和方向，过了二十年后，究竟哪些投资报酬率最高？我们在时代变迁下，从这些选择中领悟到什么？这些选择具有什么样的特质？又有哪些可以作为现在选择的参考？</p>
<p>信息化时代的特征是快速变化和创新，所以如果你不够快或不够创新，显然这不是一个适合养老的行当。姑且不谈每年新生人口有多少，就是每年国内大学毕业生的人数，就差不多相当于目前香港人口的总数，这些职场新力军可以比前辈更卖力学习，有些甚至要求更低工资，在选择机会时更没有后顾之忧，并且能放手大干一场。</p>
<p>所以，<span style="BACKGROUND-COLOR: yellow">如果你二十几岁，但目前正在做的事没有任何积累，只是不断在淘汰与被淘汰间轮回，沉迷一些短暂的技术噱头，忽略人际关系的成长，那么很显然，时间对你是不利的。因为等到面临40岁这道关卡时，你会发现自己和和十年前差异并不大，并且开始怀疑自己的价值和竞争力，更别提什么不可替换性了。</span></p>
<p><span style="BACKGROUND-COLOR: yellow">聪明和智慧是有区别的，聪明是一时的反应和敏捷，而智慧则需要经验和时间的积累。</span>新生代固然在聪明上占有先天的优势，但年长的一代是否具有智慧并不是绝对，这需要看他们在年轻时，是否建立了一套积累智慧的完备体系，否则最终可能落得既不聪明也没有智慧的空白，甚至望着大把青春渐逝，徒呼负负。</p>
<p>我现在已经年过40了，只是当年正巧赶上台湾90年代信息发展的初期。在我之前很多出色的前辈，有些技术写手，后来成立了规模大大小小的出版工作室或公司；有的则是成立了软件公司，在攫取几桶金后，投资其他行业或公司；还有的回到学校重新执教，过着平淡又充实的日子；更多的则是不知其所踪(<span style="BACKGROUND-COLOR: yellow">下落不明?连搜索引擎都找不到了</span>...)。</p>
<p>我还在写代码吗？当然，编程和英文一样是我不会放弃的兴趣，只不过前者是和机器沟通的语言。VBA一直都是我喜爱的工具 - 在任何时间、任何地点进行创意设计。当然，我也使用Visual Studio 2010，但只是作为技术管理，指导团队如何在项目中协作和系统化思考。</p>
<p>我真正的收入来源是金融和传媒，但这两者都不是我在学习编程后才涉猎的领域。不论你在编程的某个领域多么出色或者靠着这项能力获取了多少收入，永远记得：『<span style="BACKGROUND-COLOR: yellow">在当今信息化的时代，你要具备编程与自动化的能力，但不能只靠编程过活</span>。』，<span style="BACKGROUND-COLOR: yellow">所以及早为自己做准备，这样不论过了多少岁，永远都可以当一个快乐而非忧虑的程序员。</span></p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/oiio/archive/2010/11/03/5983765.aspx"><u><font color=#800080>http://blog.csdn.net/oiio/archive/2010/11/03/5983765.aspx</font></u></a></p>
</div>
<img src ="http://www.cppblog.com/luqingfei/aggbug/132557.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-11-05 14:47 <a href="http://www.cppblog.com/luqingfei/archive/2010/11/05/132557.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++入门经典：(一)基本概念</title><link>http://www.cppblog.com/luqingfei/archive/2010/10/18/130226.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Mon, 18 Oct 2010 01:32:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/10/18/130226.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/130226.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/10/18/130226.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/130226.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/130226.html</trackback:ping><description><![CDATA[<p>基本概念</p>
<p>编程语言</p>
<p>除了C++之外，还有Java、BASIC、COBOL、FORTRAN、PASCAL和C（只是因为它是B语言的后续语言）等编程语言。<br>所有这些称为高级语言，因为它们可以比较容易地表达出要计算机完成的工作，而且不针对某台计算机。<br>高级语言中的每个源语句一般映射为几个内部机器指令。<br>低级语言比较接近内部机器指令，通常称为汇编语言，一个汇编语言专门用于一种硬件设计，一般一个汇编指令映射为一个内部机器指令。</p>
<p>编程语言简史<br>FORTRAN是第一种开发出来的高级语言，第一个FORTRAN编译器是在19世纪50年代后期开发出来的。<br>已有40多年的历史了，目前仍广泛应用于科学和工程计算中，但C++和其他语言也逐渐进入这些领域。</p>
<p>COBOL语言专门用于商务数据处理应用程序，它的历史几乎与FORTRAN语言一样长，目前几乎不用COBOL编写代码。</p>
<p>BASIC在19世纪70年代诞生，那时已经有了个人计算机的概念。有趣的是，Microsoft销售的第一个产品是一个BASIC解释程序。<br>这种语言所固有的易用性使之很快普及，直到今天仍非常流行。</p>
<p>Java是在19世纪90年代开发的，它最初开发为Oak语言，用于给小型电子设备编程。<br>1995年，Oak演变为Java语言，可以在Web页面中内嵌代码，从那时起直到现在，这已经成为Java的主要用途。<br>Java成功的主要原因是它的可移植性。Java程序可以在任何支持它的硬件平台上运行，而且不需要任何修改。<br>Java语言的语法有许多特性，使它看起来很像C++，但有很大的区别。Java在可移植性方面比C++好，但执行性能比不上C++。</p>
<p>C在上个世纪70年代被开发为一种高级语言，用于低级编程，例如实现操作系统。大多数Unix操作系统就是用C编写的。</p>
<p><br>C++是19世纪80年代早期开发的，是一种基于C的面向对象语言。<br>顾名思义，C++表示C的累加。<br>由于C++基于C，所以这两种语言有许多共同的语法和功能，C中所有低级编程的功能都在C++中保留下来。<br>但是，C++比其前身丰富得多，用途也广泛得多。<br>C++对内存管理功能进行了非常大的改进，C++还具有面向对象的功能，所以C在功能上只是C++的一个很小的子集。<br>C++在适用范围、性能和功能上也是无可匹敌的。<br>因此，目前大多数高性能的应用程序和系统仍使用C++编写。</p>
<p><br>解释性程序和编译性程序的执行过程<br>无论使用哪种编程语言，编写出来的程序都是由各个指令或源语句构成的，它们描述了希望计算机执行的动作。<br>这些指令或源语句统称为源代码，存储在磁盘的源文件中。<br>任何规模的C++程序都是由若干个源文件组成的。</p>
<p>编程语言的目的是，与计算机可以执行的程序相比，能够更简单地描述希望计算机执行的动作。<br>计算机只能执行包含机器指令（也称为机器代码）的程序，不能直接执行我们编写的程序。</p>
<p>用前面提到的语言编写的程序基本上有两种执行方式，在大多数情况下，一种语言会选择其中一种执行方式。<br>例如，用BASIC语言编写的程序通常是解释性的，<br>也就是说，另一个称为解释器的程序会检查BASIC源代码，确定该程序要做什么，再让计算机完成这些动作。</p>
<p>而C++是一种编译语言。在执行C++程序之前，必须用另一个程序（即编译器）把它转换为机器语言。<br>编译器会检查并分析C++程序，并生成机器指令，以执行源代码指定的动作。<br>当然，解释和编译都不像这里描述的那样简单，但其工作原理就是这样。</p>
<p>使用解释性语言，执行过程是间接的，也就是说，每次执行程序时，都需要确定源代码的意图。<br>因此，这种语言比编译语言的对应程序的执行速度慢得多，有时要慢100倍。<br>其优点是在运行之前，不必等待程序的编译。<br>使用解释性语言，一旦输入代码，就可以立刻执行程序。</p>
<p>任何一种语言要么是解释性，要么是编译性的，这通常是由该语言的设计和用途来决定。<br>前面说过BASIC是一种解释性语言，但这不是绝对的，目前有许多BASIC语言的编译器。</p>
<p>没有所谓&#8220;最好&#8221;的语言，因为这取决于环境。<br>看具体环境在意的是开发速度，还是运行速度，又或是移植能力等等。</p>
<p><br>库<br>每次编写程序时，如果总是要从头开始编写，就相当繁琐。<br>为了解决这个问题，编程语言通常提供了大量预先编写好的代码，以执行标准的操作，这样就不必重新编写这些代码了。<br>可用于任意程序的标准代码都保存在一个库中。<br>编程语言附带的库跟语言本身一样重要，因为库的质量和使用范围对完成某一编程任务所需的时间有非常大的影响。</p>
<p>C++是一种功能强大的语言</p>
<p>C++的ANSI/ISO标准</p>
<p><br>名称<br>C++程序中的许多元素都有用来表示它们的名称，也称为标识符。<br>在C++程序中，可以命名的5种元素是：<br>函数、变量、类型、标签、命名空间</p>
<p><br>关键字<br>C++中有一些保留字，称为关键字，它们在C++语言中有特殊的含义。</p>
<p><br>C++语句和语句块<br>语句是指定程序做什么和程序所处理的数据元素的基本单元。</p>
<p>把名称引入源文件的语句称为声明。<br>声明只是引入名称，指定该名称表示什么，它与定义不同。</p>
<p>定义是分配一些内存，来包含名称所指代的内容。<br>大多数声明也是定义??????????(这句如何理解？？)</p>
<p><br>变量是内存中一个可以存储数据项的空间。<br>下面的语句示例声明了一个变量名，定义并初始化了一个变量：<br>double result = 0.0;<br>这个语句把名称result声明为一个double类型的变量（声明），<br>把内存分配给该变量（定义），<br>并设置其初始值为0.0（初始化）。</p>
<p>可以把几个语句放在一对花括号中，此时这些语句就称为语句块。<br>函数体就是一个语句块。<br>语句块也称为复合语句，因为在许多情况下，语句块可以看做是一个语句。</p>
<p>在C++中，在可以放置一个语句的任何地方，都可以放置一个包含在花括号对中的语句块。</p>
<p>语句块可以放在其他语句块内部，这个概念称为嵌套。语句块可以嵌套任意级。</p>
<p>语句块对用于存储数据项的变量有重要的作用。（变量作用域?）</p>
<p>代码的显示样式<br>注意使用制表符、空格缩进程序语句，显示出这些语句的逻辑；再以一致的方式使用定义程序块的匹配花括号，使块之间的关系更清晰。</p>
<p>程序结构<br>每个C++程序都由一个或多个文件组成。<br>根据约定，用于存储源代码的文件有两类：头文件和源文件。<br>头文件可以包含描述程序所需的数据类型的代码，以及其他类型的声明。<br>头文件通常用文件扩展名.h来区分，但这不是强制的。<br>源文件的扩展名是.cpp，它包含了函数声明，即程序的可执行代码。这些代码通常引用在自己的头文件中定义的数据类型的声明或定义。</p>
<p>编译器在编译代码时，需要知道这些声明或定义，因此应在文件的开头通过#include指令指定.cpp文件中需要的.h文件。<br>#include指令是编译器的一个指令，它可以把指定头文件的内容插入代码，还需要为代码需要的标准库头文件添加#include指令。</p>
<p>编译器提供了大量的标准头文件，其中包含使用标准库功能所需要的声明。<br>实际上，C++的标准头文件名都没有扩展名，这就把它们与其他头文件区分开来。</p>
<p>程序的函数和执行<br>C++程序至少包含一个函数main()，但程序一般还包含许多其他函数，一些是自己编写的，另一些是标准库函数。<br>执行一个函数称为调用函数。在调用函数时，可以给它传送数据项。<br>在函数执行完后，执行控制返回到调用函数的地方。<br>函数在执行完毕时，还可以把一个值返回到调用的位置上。<br>返回值可以存储起来，以备以后使用，也可以参与某种类型的计算，例如算术表达式的计算。</p>
<p><br>从源文件中创建可执行文件<br>从C++源代码中创建可以执行的程序模块需要两步：<br>第一步是编译器把每个.cpp文件转换为对象文件，其中包含了与源文件内容对应的机器码。<br>第二步是链接程序把编译器生成的对象文件合并到包含完整可执行程序的文件中。</p>
<p>编译器把每个源文件看作一个独立的实体，为每个.cpp文件生成一个对象文件。<br>然后在链接步骤中，把程序的对象文件和必要的库函数组合到一个可执行文件中。</p>
<p>实际上，编译是一个迭代的过程，编写源码，编译，发现错误，修改源码，再编译，发现错误，再修改，再编译，&#8230;&#8230;</p>
<p><br>编译<br>源文件的编译过程包含两个主要阶段，而它们之间的转换是自动的。<br>第一个阶段是预处理阶段，在正式的编译阶段之前进行。<br>预处理阶段将根据已放置在文件中的预处理指令来修改源文件的内容。<br>#include指令就是一个预处理指令，它把头文件的内容添加到.cpp文件中。还有其他许多预处理指令。</p>
<p>这个在编译之前修改源文件的方式提供了很大的灵活性，以适应不同的计算机和操作系统环境。<br>一个环境需要的代码跟另一个环境所需的代码可能有所不同，因为可用的硬件或操作系统是不同的。<br>在许多情况下，可以把用于不同环境的代码放在同一个文件中，再在预处理阶段修改代码，使之适应当前的环境。</p>
<p>预处理器一般不能独立于编译器来执行，调用编译器会自动执行预处理过程，之后才编译代码。</p>
<p><br>链接<br>编译器为给定源文件输出的是机器码，执行这个过程需要较长时间。<br>在对象文件之间并没有建立任何连接。<br>对应于某个源文件的对象文件包含在其他源文件中的定义的函数引用或其他指定项的引用，而这些函数或项仍没有被解析。<br>同样，也没有建立同库函数的链接。<br>实际上，这些函数的代码并不是文件的一部分。<br>这些工作是由链接程序完成的。</p>
<p><br>链接程序把所有对象文件中的机器码组合在一起，<br>并解析它们之间的交叉引用。<br>它还集成了对象模块所使用的库函数的代码。<br>这是链接程序的一种简化表示，因为这里假定在可执行模块中，模块之间的所有链接都是静态建立的。<br>实际上有些链接是动态的，即这些链接是在程序执行时建立的。</p>
<p>链接程序静态地建立函数之间的链接，即在程序执行之前建立组成程序的源文件中所包含的函数链接。<br>动态建立的函数之间的链接（在程序执行过程中建立的链接）将函数编译并链接起来，创建另一种可执行模块——动态链接库或共享库。<br>动态链接库中的函数链接是程序调用函数时才建立的，在程序调用之前，该链接是不存在的。</p>
<p><br>动态链接库优点：<br>动态链接库中的函数可以在几个并行执行的程序之间共享，在执行的多个函数需要动态链接库中的函数所提供的服务时，这将节省同一个函数占用的内存空间。<br>动态链接库在调用其中的函数之前是不会加载到内存中的，也就是说，如果不使用给定动态链接库中的函数，该动态链接库就不会占用内存空间。</p>
<p>动态链接库是与操作系统紧密相关的一个系统功能。</p>
<p>C++源字符<br>编写C++语句要使用基本源字符集，这些是在C++源文件中可以显式使用的字符集。<br>包括：大小写字母，数字，控制字符，一些特殊字符。</p>
<p>在C++中使用的字符定义并没有说明字符的编码方式。编译器将决定用于编写C++源代码的字符在计算机上如何表示。</p>
<p><br>通用字符集（Universal Character Set, UCS）。<br>由UCS标准定义的字符编码与Unicode定义的编码相同。</p>
<p><br>三字符序列<br>就是用于表示另一个字符的三个字符序列。以前为了表示键盘上没有的字符，这是必不可少的一种方法。<br>编译器会用对应的字符替代它们，再对源代码进行其他处理。</p>
<p><br>转义序列<br>通过转义序列可以把控制字符输入字符常量。转义序列是指定字符的一种间接方式，通常以一个反斜杠\开头。</p>
<p>由于反斜框表示转义序列的开始，因此把反斜杠字符输入一个字符常量的唯一方式是使用两个连续的反斜杠。</p>
<p>转义序列还提供了用键盘不支持的语言来表示字符的一种通用方式，因为可以使用十六进制（基数是16）或八进制（基数是8）数字前置一个反斜杠来指定字符的编码。</p>
<p>由于使用了数字编码，可以用这种方式指定任何字符。</p>
<p>在C++中，十六进制数据以x或X开头。</p>
<p>还可以使用至多3个八进制数字前置一个反斜杠来表示字符。例如\165。没有x或X，就表示该编码应解释为一个八进制数字。</p>
<p>cout &lt;&lt; "\n\" Least said\n\t\tsoonest mended.\ "\n\a";<br>双引号之间的字符串称为字符串字面量。<br>双引号字符表示该字符串字面量的开始和结束，它们不是字符串的一部分。</p>
<p>字符串内部的双引号不会解释为字符串字面量的结束，这是因为每个双引号的前面都有一个反斜杠，表示这是一个转义序列。</p>
<p><br>语句中的空白<br>除了在语句的元素之间或引号中的字符串内用作分隔符之外，编译器会忽略空白。<br>因此可以在代码中包含任意多个空白，使程序的可读性更高。</p>
<p>在一些编程语言中，语句的结尾是代码行的末尾，但在C++中，语句的结尾用分号表示。<br>因此，可以把一个语句分散放在好几行代码行上。</p>
<p><br>程序的注释<br>C++中注释有两种形式：单行和多行。<br>单行注释以双斜杠开头（//）。<br>编译器会忽略双斜杠后面的所有内容。</p>
<p>多行注释以/*开头，以*/结尾。在/*和*/之间的所有内容都被忽略。<br>注意多行注释不能嵌套，否则会使编译器发出错误消息。</p>
<p><br>标准库<br>标准库包含了大量的函数和其他支持实体，增加和扩展了C++的基本语言功能。<br>标准库的内容是C++的一部分，在语言的语法和语义方面跟C++相同。<br>C++的标准定义了这两者，所以每个符合该标准的编译器都提供了完整的标准库。</p>
<p>标准库的范围是很特殊的。<br>使用该标准库将获得非常多的功能，包括基本元素如基本语言支持、<br>输入输出函数和异常处理（异常是在程序执行中发生的偶然事件，常常是某种错误）、<br>实用函数，数学例程和各种预先编写好并测试通过的功能。<br>在程序执行过程中可借助这些功能来存储和管理数据。</p>
<p><br>使用标准库所需要的定义和声明位于标准头文件中。<br>C++标准库中的几乎所有内容都是在命名空间std中定义的。</p>
<p><br>用C++编程</p>
<p>过程化编程方法和面向对象编程方法</p>
<p><br>小结<br>C++程序至少包含一个main()函数。<br>函数的可执行部分由包含在一对花括号中的语句组成。<br>一对花括号定义了一个语句块。<br>在C++中，语句用分号结束。<br>关键字是C++中有特殊含义的一组保留字。程序中的实体不能与C++语言中的任何关键字同名。<br>C++程序包含在一个或多个文件中。<br>定义函数的代码通常存储在扩展名为.cpp的文件中。<br>定义数据类型的代码通常存储在扩展名为.h的头文件中。<br>C++标准库提供了支持和扩展C++语言的大量功能。<br>C++中的输入和输出是利用流来执行的，并且需要使用插入和撮运算符，即&lt;&lt;和&gt;&gt;。<br>面向对象的编程方式需要定义专门用于某程序的新数据类型。一旦定义好需要的数据类型，就可以根据这些新数据类型来编写程序。</p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/luqingfei/aggbug/130226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-10-18 09:32 <a href="http://www.cppblog.com/luqingfei/archive/2010/10/18/130226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++标准程序库—自修教程与参考手册 </title><link>http://www.cppblog.com/luqingfei/archive/2010/10/11/129443.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Mon, 11 Oct 2010 08:12:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/10/11/129443.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/129443.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/10/11/129443.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/129443.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/129443.html</trackback:ping><description><![CDATA[<p>&nbsp;<a title=C++标准程序库 href="http://img3.douban.com/lpic/s1092079.jpg" target=_blank jQuery1286784576148="36" border="0"><img title=点击看大图 alt=C++标准程序库 src="http://img3.douban.com/mpic/s1092079.jpg"></a><br>译者: 侯捷 / 孟岩<br>作者: [德] Nicolai M. Josuttis</p>
<p>副标题: 自修教程与参考手册<br>ISBN: 9787560927824 <br>页数: 800<br>出版社: 华中科技大学出版社<br>定价: 108.00元<br>装帧: 平装16开<br>出版年: 2002-9<br></p>
<h2>简介 &#183; &#183; &#183; &#183; &#183; &#183; </h2>
<div class=indent>　　这本包含最新资料的完整书籍，反映出被ANSI/ISO C++语言标准规格书纳入的C++标准程序库的最新组成。更明确地说，这本书将焦点放在标准模板库身上，检验其中的容器、迭代器、仿函数和算法。读者还可以找到特殊容、字串、数值类别、国际化议题、IOStream。每一个元素都有深刻的呈现，包括其介绍、设计、运用实例、细部解说、陷阱、意想不到的危险，以及相关类别和函数的精确樯记式和定义式。<br></div>
<h2>目录 &#183;&#183;&#183;&#183;&#183;&#183; </h2>
<div class=indent id=dir_1110941_short style="DISPLAY: none" jQuery1286784576148="159">巨细靡遗&#183;井然有序（侯捷译序）<br>孟岩译序<br>目录<br>前言<br>致谢<br>1．关于本书<br>&#183; &#183; &#183; &#183; &#183; &#183; (<a href="javascript:$('#dir_1110941_short').hide();$('#dir_1110941_full').show();$.get('/j/subject/j_dir_count',{id:1110941});void(0);" jQuery1286784576148="49"><font color=#666699>更多</font></a>) </div>
<div class=indent id=dir_1110941_full>巨细靡遗&#183;井然有序（侯捷译序）<br>孟岩译序<br>目录<br>前言<br>致谢<br>1．关于本书<br>2．C++及其标准程序库简介<br>3．一般概念<br>4．通用工具<br>5．Standard Template Library（STL，标准模板库）<br>6．STL容器（STL Container）<br>7．STL 迭代器（STL Iterators）<br>8．STL 仿函数（functors）(又名函数对象，function objects)<br>9．STL算法（STL Algorithms）<br>10．特殊容器（Special Containers）<br>11．Strings（字符串）<br>12．数值（Numerics）<br>13．以Stream Classes<br>14．国际化（Internationalization,i18n）<br>15．空间配置器（Allocator）<br>网络上的资源<br>参考书目<br>索引<br></div>
<img src ="http://www.cppblog.com/luqingfei/aggbug/129443.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-10-11 16:12 <a href="http://www.cppblog.com/luqingfei/archive/2010/10/11/129443.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Win32汇编--图形操作--GDI原理</title><link>http://www.cppblog.com/luqingfei/archive/2010/09/24/127502.html</link><dc:creator>luqingfei</dc:creator><author>luqingfei</author><pubDate>Fri, 24 Sep 2010 05:51:00 GMT</pubDate><guid>http://www.cppblog.com/luqingfei/archive/2010/09/24/127502.html</guid><wfw:comment>http://www.cppblog.com/luqingfei/comments/127502.html</wfw:comment><comments>http://www.cppblog.com/luqingfei/archive/2010/09/24/127502.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/luqingfei/comments/commentRss/127502.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luqingfei/services/trackbacks/127502.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>Win32</span><span>汇编</span><span>--</span><span>图形操作</span><span>--GDI</span><span>原理</span></p>
<p>&nbsp;</p>
<p><span>Windows</span><span>是基于图形界面的，所以在</span><span>Win32</span><span>编程中，图形操作是最常用的操作。</span><span>GDI</span><span>的意义在于将程序对图形界面的操作和硬件设备隔绝开来，在程序中可以将所有的图形设备都看成是虚拟设备，包括视频显示器和打印机等，然后通过</span><span>GDI</span><span>函数用同样的方法去操作它们，由</span><span>Windows</span><span>负责将函数调用转化成针对具体硬件的操作。只要一个设备提供了和</span><span>Windows</span><span>兼容的驱动程序，它就可以被看做是一个标准的设备。以前在</span><span>DOS</span><span>系统下写应用程序的时候，如果要进行图形操作，那么就要考虑到市场上每种显示卡的不同，否则在装配某种显卡的计算机上就可能无法正常运行，对汇编程序员来说，这真是一个恶梦。在</span><span>Win32</span><span>编程中，正是</span><span>GDI</span><span>函数让这个恶梦成为历史。</span></p>
<p>&nbsp;</p>
<p><span>GDI</span><span>函数全部包括在</span><span>GDI32.DLL</span><span>中，在编程的时候，注意要在源程序的开头加上相应的包含语句：</span></p>
<p><span>include <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>gdi32.inc</span></p>
<p><span>includelib <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>gdi32.lib</span></p>
<p>&nbsp;</p>
<p><span>和</span><span>GDI</span><span>相关的内容真是太庞大了，只要查看一下</span><span>gdi32.inc</span><span>文件就可以发现，函数的总数达到了</span><span>300</span><span>多个，和</span><span>GDI</span><span>相关的数据结构也非常多，为了能了解</span><span>GDI</span><span>的原理和基本的使用方法：</span></p>
<p><span>归纳起来，</span><span>GDI</span><span>操作可以从</span><span>3</span><span>个方面去了解——</span><span>When, Where</span><span>和</span><span>How</span><span>：</span></p>
<p><span>When</span><span>——指的是进行图形操作的时机，究竟什么时刻最适合程序进行图形操作呢？——&#8220;</span><span>GDI</span><span>程序的结构&#8221;</span></p>
<p><span>Where</span><span>——指的是图形该往哪里画，既然</span><span>Windows</span><span>隔离了硬件图形设备，那么该把什么地方当做&#8220;下笔&#8221;的地方呢？——&#8220;设备环境&#8221;</span></p>
<p><span>How</span><span>——了解了上面两个问题后，最后还要知道&#8220;如何画&#8221;，这就涉及如何使用大部分</span><span>GDI</span><span>函数的问题了。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>一、</span><span>GDI</span><span>程序的结构</span></p>
<p><span>1</span><span>、客户区的刷新</span></p>
<p><span>正如上面所说的，这里讨论的是&#8220;</span><span>When</span><span>&#8221;的问题，读者可能会问：为什么会有这个问题，如果要向窗口输出图形，程序想在什么时候输出那就是什么时候，难道这个时刻还有规定不成？</span></p>
<p>&nbsp;</p>
<p><span>在</span><span>DOS</span><span>操作系统中编程的时候，程序把文字或图形输出到屏幕，在输出新的内容之前，这些内容总是保留在屏幕原处，这些内容会被意外覆盖的唯一情况是激活一个</span><span>TSR</span><span>程序，但</span><span>TSR</span><span>程序在退出之前有义务恢复原来的屏幕，如果它无法恢复屏幕的内容，那么这是它的责任，我们不会在自己的程序中去考虑屏幕内容会无缘无故消失这种情况，所以可以把屏幕看成是应用程序私有的。</span></p>
<p>&nbsp;</p>
<p><span>如果程序输出的内容过多，如用</span><span>dir</span><span>显示一个含有很多文件的目录，用户根本无法看清快速上翻的屏幕，这时程序可以设计一个参数来暂停一下，如</span><span>dir/p</span><span>。这已经是</span><span>DOS</span><span>程序最&#8220;体贴&#8221;的做法了，如果用户想回过头去看已经滚出屏幕的内容，那可对不起，只能再执行一遍了！</span></p>
<p>&nbsp;</p>
<p><span>所以对</span><span>DOS</span><span>程序来说，程序想在什么时候输出信息那就是什么时候，根本不存在</span><span>When</span><span>这个问题。</span></p>
<p>&nbsp;</p>
<p><span>但在</span><span>Windows</span><span>操作系统中，屏幕是多个程序&#8220;公用&#8221;的，用户程序不要指望输出到窗口中的内容经过一段时间后还会保留在那里，它们可能被别的东西覆盖，如其他窗口、鼠标箭头或下拉的菜单等。在</span><span>Windows</span><span>中，恢复被覆盖内容的责任大部分属于用户程序自己，理由很简单：</span><span>Windows</span><span>是个多任务的操作系统，假如程序</span><span>B</span><span>覆盖了程序</span><span>A</span><span>的窗口内容，覆盖掉的内容由程序</span><span>B</span><span>负责恢复的话，它就必须保存它覆盖掉的内容，但是在它将保存的内容恢复之前，程序</span><span>A</span><span>也在运行，并可能在程序</span><span>B</span><span>恢复以前已经向它自己的窗口输出新的内容，结果当程序</span><span>B</span><span>恢复它保存的窗口内容时，保存的内容可能是过时的（而</span><span>DOS</span><span>的情况就不同，</span><span>TSR</span><span>程序激活的时候，用户程序是被挂起的），所以最好的办法就是让程序</span><span>A</span><span>自己来决定如何恢复。</span></p>
<p>&nbsp;</p>
<p><span>Windows</span><span>系统采用的方法是：当</span><span>Windows</span><span>检测到窗口被覆盖的地方需要恢复的时候，它会向用户程序发送一个</span><span>WM_PAINT</span><span>消息，消息中包括了需要恢复的区域，然后由用户程序来决定如何恢复被覆盖的内容。</span></p>
<p>&nbsp;</p>
<p><span>如果程序因为忙于处理其他事务以至于无法及时响应</span><span>WM_PAINT</span><span>消息，那么窗口客户区原先被覆盖的地方可能会被</span><span>Windows</span><span>暂时画成一块白色（或者背景色）的矩形，或者根本就是保留被覆盖时的情形，直到程序有时间去响应</span><span>WM_PAINT</span><span>消息为止。我们常常可以看到这种情况发生在死锁程序的客户区内，这就是因为死锁的程序无法响应</span><span>WM_PAINT</span><span>消息来恢复客户区造成的。</span></p>
<p>&nbsp;</p>
<p><span>所以对于&#8220;</span><span>When</span><span>&#8221;这个问题，答案是：程序应该在</span><span>Windows</span><span>要求的时候绘画客户区，也就是在收到</span><span>WM_PAINT</span><span>消息的时候。如果程序需要主动刷新客户区，那么可以通过调用</span><span>InvalidateRect</span><span>等函数引发一条</span><span>WM_PAINT</span><span>消息，因为在</span><span>WM_PAINT</span><span>消息中刷新客户区的代码是必须存在的，所以用这种看似&#8220;舍近求远&#8221;的办法实际上可以节省一份重复的代码。即使是在游戏程序这种&#8220;主动刷新&#8221;远远多于&#8220;被动刷新&#8221;的程序中，只要窗口有被其他东西覆盖的可能，那么这个原则就是适用的。</span></p>
<p>&nbsp;</p>
<p><span>2</span><span>、</span><span>GDI</span><span>程序的结构</span></p>
<p><span>对于</span><span>Win32</span><span>程序来说，</span><span>WM_PAINT</span><span>消息随时可能发生，这就意味着，程序再也不能像在</span><span>DOS</span><span>下一样输出结果后就不管了，反过来，程序在任何时刻都应该知道如何恢复整个或局部客户区中以前输出的内容。</span></p>
<p>&nbsp;</p>
<p><span>如果程序的功能比较简单，可以将计算及刷新整个客户区的代码全部安排在</span><span>WM_PAINT</span><span>消息中完成，这样，每次当客户区的全部或部分需要被更新的时候，程序重新执行整个生成客户区屏幕数据的功能模块并刷新客户区。这种结构适用于功能模块很短小且执行速度很快的情况，整个过程的时间最好不超过几百</span><span>ms</span><span>，否则，用户会在一个明显的等待时间后才看到程序把客户区中的&#8220;空洞&#8221;补上。</span></p>
<p>&nbsp;</p>
<p><span>当生成屏幕数据的功能模块有些复杂的时候，就应该考虑采用如下结构，即功能模块和客户区刷新模块分别在不同的子程序中实现，功能模块单独用一个子程序完成，这个子程序可以由用户通过选择菜单项在</span><span>WM_COMMAND</span><span>消息中执行，也可以新建另外一个线和来完成，总之，它最后把计算结果放到一个缓冲区中，而每当客户区需要刷新时，程序在</span><span>WM_PAINT</span><span>消息中调用客户区刷新子程序，这个子程序从计算好的缓冲区中取出数据并输出到客户区中，由于单纯的屏幕刷新过程是很快的，所以用户根本来不及看到客户区中的空洞。</span></p>
<p>&nbsp;</p>
<p><span>3</span><span>、探讨</span><span>WM_PAINT</span><span>消息</span></p>
<p><span>当客户区被覆盖并重新显示的时候，</span><span>Windows</span><span>并不是在所有的的下都发送</span><span>WM_PAINT</span><span>消息，下面是几种不同的情况：</span></p>
<p><span><span>l<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>当鼠标光标移过窗口客户区以及图标拖过客户区这两种情况，</span><span>Windows</span><span>总是自己保存被覆盖的区域并恢复它，并不需要发送</span><span>WM_PAINT</span><span>消息通知用户程序。</span></p>
<p><span><span>l<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>当窗口客户区被自己的下拉式菜单覆盖，或者被自己弹出的对话框覆盖后，</span><span>Windows</span><span>会尝试保存被覆盖的区域并在以后恢复它，如果因为某种原因无法保存并恢复的话，</span><span>Windows</span><span>会发送一个</span><span>WM_PAINT</span><span>消息通知程序。</span></p>
<p><span><span>l<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>别的情况造成窗口的一部分从不可见变到可见，如程序从最小化的状态恢复，其他的窗口覆盖客户区后移开，用户改变了窗口的大小不一和用户按动滚动条等，在这些情况下，</span><span>Windows</span><span>会向窗口发送</span><span>WM_PAINT</span><span>消息。</span></p>
<p><span><span>l<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>一些函数会引发</span><span>WM_PAINT</span><span>消息，如</span><span>UpdateWindow</span><span>，</span><span>InvalidateRect</span><span>以及</span><span>InvalidateRgn</span><span>函数等。</span></p>
<p>&nbsp;</p>
<p><span>窗口过程收到</span><span>WM_PAINT</span><span>消息后，并不代表整个客户区都需要被刷新，有可能客户区被覆盖的区域只有一小块，这个区域就叫做&#8220;无效区域&#8221;，程序只需要更新这个区域。</span></p>
<p>&nbsp;</p>
<p><span>和</span><span>WM_TIMER</span><span>消息类似，</span><span>WM_PAINT</span><span>消息也是一个低级别的消息，虽然它不会像</span><span>WM_TIMER</span><span>消息一样被丢弃，但</span><span>Windows</span><span>总是在消息循环空的时候才把</span><span>WM_PAINT</span><span>放入其中，实际上，</span><span>Windows</span><span>为每个窗口维护一个&#8220;绘图信息结构&#8221;，无效区域的坐标就在其中，每当消息循环空的时候，如果</span><span>Windows</span><span>发现存在一个无效区域，就会放入一个</span><span>WM_PAINT</span><span>消息。</span></p>
<p>&nbsp;</p>
<p><span>无效区域的坐标并不附带在</span><span>WM_PAINT</span><span>消息的参数中，在程序中有其他方法可以获取，</span><span>WM_PAINT</span><span>消息只是通知程序有个区域需要更新而已，所以</span><span>Windows</span><span>也不会同时将两条</span><span>WM_PAINT</span><span>消息放入消息循环，当</span><span>Windows</span><span>要放入一条</span><span>WM_PAINT</span><span>消息的时候，如果发现已存在一个无效区域了，那么它只需要把新旧两个无效区域合并计算出一个新的无效区域就可以了，消息循环中还是只需要一条</span><span>WM_PAINT</span><span>消息。</span></p>
<p>&nbsp;</p>
<p><span>由于存在&#8220;无效区域&#8221;这样一个东西，所以程序在</span><span>WM_PAINT</span><span>消息中对客户区刷新完毕后工作并没有结束，如果不使无效区域变得有效，</span><span>Windows</span><span>会在下一轮消息循环中继续放入一个</span><span>WM_PAINT</span><span>消息。当</span><span>Windows</span><span>检查&#8220;绘图信息结构&#8221;的时候发现没有了无效区域，也就不会继续发送</span><span>WM_PAINT</span><span>消息了。</span></p>
<p>&nbsp;</p>
<p><span>WM_PAINT</span><span>消息的处理流程一般是：</span></p>
<p><span>.if<span>&nbsp;&nbsp;&nbsp; </span>eax == WM_PAINT<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;eax</span><span>为</span><span>uMsg</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke BeginPaint, hWnd, addr stPS</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;</span><span>刷新客户区的代码</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke EndPaint, hWnd, addr stPS</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>xor&nbsp;eax, eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret</span></p>
<p>&nbsp;</p>
<p><span>读者可以发现中间并没有调用</span><span>ValidateRect</span><span>来使无效区域变得有效，这是因为</span><span>BeginPaint</span><span>函数和</span><span>EndPaint</span><span>函数隐含有这个功能，如果不是以</span><span>BeginPaint/EndPaint</span><span>当做消息处理代码的头尾的话，那么在</span><span>WM_PAINT</span><span>消息返回的时候就必须调用</span><span>ValidateRect</span><span>函数。</span></p>
<p>&nbsp;</p>
<p><span>BeginPaint</span><span>函数的第二个参数是一个绘图信息结构的缓冲区地址，</span><span>Windows</span><span>会在这里返回绘图信息结构，结构中包含了无效区域的位置和大小，绘图信息结构的定义如下：</span></p>
<p><span>PAINTSTRUCT STRUCT</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hdc<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>?</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>fErase<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>?</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>rcPaint<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>RECT<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;&gt;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>fRestore<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>?</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>fIncUpdate<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>?</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>rgbReserved<span>&nbsp;&nbsp; </span>BYTE 32 dup(?)</span></p>
<p><span>PAINTSTRUCT ENDS</span></p>
<p>&nbsp;</p>
<p><span>其中</span><span>hdc</span><span>字段是窗口的设备环境句柄，</span><span>rcPaint</span><span>字段是一个</span><span>RECT</span><span>结构，它指定了无效区域矩形的对角顶点，</span><span>fErase</span><span>字段如果为非零值，表示</span><span>Windows</span><span>在发送</span><span>WM_PAINT</span><span>消息前已经用背景色擦除了无效区域，后面</span><span>3</span><span>个字段是</span><span>Windows</span><span>内部使用的，应用程序不必去理会它们。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>二、设备环境</span></p>
<p><span>解决了&#8220;</span><span>When</span><span>&#8221;的总是后，再考虑一下&#8220;</span><span>Where</span><span>&#8221;的问题。</span></p>
<p><span>在</span><span>DOS</span><span>操作系统中，向屏幕输出数据实际上是把输出内容拷贝到视频缓冲区中，如果在文本模式下显示信息，只需要把内容拷贝到</span><span>B8000h</span><span>处的内存中；显示图形信息，可以把图形数据拷贝到</span><span>A0000h</span><span>处的内存中。</span></p>
<p>&nbsp;</p>
<p><span>在</span><span>Windows</span><span>中，</span><span>GDI</span><span>接口把程序和硬件分隔出来，在</span><span>Win32</span><span>编程中，再也不能通过直接向视频缓冲区拷贝数据的办法来显示信息了，那么，究竟该往哪里输出图形呢——这就是&#8220;</span><span>Where</span><span>&#8221;的问题。答案是：通过&#8220;设备环境&#8221;来输出图形。</span></p>
<p><span>1</span><span>、什么是设备环境</span></p>
<p><span>在</span><span>Windows</span><span>中，所有与图形相关的操作都是用统一的方法来完成的（不然就不能称为&#8220;图形设备接口&#8221;了）。不管是绘画屏幕上的一个窗口，还是把图形输出到打印机，或者对一幅位图进行绘画，使用的绘图函数都是相同的，为了实现方法上的统一，必须将所有的图形对象看成是一个虚拟的设备，这些设备可能有不同的属性，如黑白打印机和彩色屏幕的颜色深度是不同的，不同打印机的尺寸和分辨率可能是不同的，绘图仪只支持矢量而不支持位图等。不同设备的不同属性就构成了一个绘图的&#8220;环境&#8221;，就像</span><span>DOS</span><span>操作系统中把视频缓冲区当做图形操作的对象一样，这个绘图的&#8220;环境&#8221;就是</span><span>Win32</span><span>编程中图形操作的对象，把它叫做&#8220;设备环境&#8221;。设备环境实际上是一个数据结构，结构中保存的就是设备的属性，当对设备环境进行图形操作的时候，</span><span>Windows</span><span>可以根据这些属性找到对应的设备进行相关的操作。</span></p>
<p>&nbsp;</p>
<p><span>在实际使用中，通过&#8220;设备环境&#8221;可以操作的对象很广泛，除了可以是打印机或绘图仪等硬件设备外，也可以是窗口的客户区，包括大大小小的所有可以被称为窗口的按钮与控件等的客户区，也可以是一个位图。总之，任何需要用到图形操作的东西都可以通过&#8220;设备环境&#8221;进行绘图。</span></p>
<p>&nbsp;</p>
<p><span>为了更好地理解&#8220;设备环境&#8221;是什么，先来看一个例子：</span></p>
<p><span>//DcCopy.asm</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.386</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.model flat, stdcall</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>option casemap:none</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>; Include </span><span>文件定义</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>include<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>windows.inc</span></p>
<p><span>include<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>gdi32.inc</span></p>
<p><span>includelib<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>gdi32.lib</span></p>
<p><span>include<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>user32.inc</span></p>
<p><span>includelib<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>user32.lib</span></p>
<p><span>include<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>kernel32.inc</span></p>
<p><span>includelib<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>kernel32.lib</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>ID_TIMER<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>equ<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>1</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>; </span><span>数据段</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.data?</span></p>
<p><span>hInstance<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>dd<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>?</span></p>
<p><span>hWin1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>dd<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>?</span></p>
<p><span>hWin2<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>dd<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>?</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.const</span></p>
<p><span>szClass1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>db<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>'SourceWindow',0</span></p>
<p><span>szClass2<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>db&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>'DestWindow',0</span></p>
<p><span>szCaption1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>db<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>'</span><span>请尝试用别的窗口覆盖本窗口</span><span>!',0</span></p>
<p><span>szCaption2<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>db<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>'</span><span>本窗口图像拷贝自另一窗口</span><span>',0</span></p>
<p><span>szText<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>db<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>'Win32 Assembly, Simple and powerful!',0</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.code</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>; </span><span>定时器过程</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>_ProcTimer<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>proc<span>&nbsp;&nbsp;&nbsp; </span>_hWnd, uMsg, _idEvent, _dwTime</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>local<span>&nbsp;&nbsp; </span>@hDc1, @hDc2</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>local<span>&nbsp;&nbsp; </span>@stRect:RECT</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;GetDC, hWin1</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>@hDc1, eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;GetDC, hWin2</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>@hDc2,eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;GetClientRect, hWin1, addr @stRect</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;BitBlt, @hDc2, 0, 0, @stRect.right, @stRect.bottom, @hDc1, 0, 0, SRCCOPY</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;ReleaseDC, hWin1, @hDc1</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;ReleaseDC, hWin2, @hDc2</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span>_ProcTimer<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>endp</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>; </span><span>窗口过程</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>_ProcWinMain<span>&nbsp;&nbsp;&nbsp; </span>proc<span>&nbsp;&nbsp;&nbsp; </span>uses ebx edi esi, hWnd, uMsg, wParam, lParam</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>local<span>&nbsp;&nbsp; </span>@stPs:PAINTSTRUCT</span></p>
<p><span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>local<span>&nbsp;&nbsp; </span>@stRect:RECT</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>local<span>&nbsp;&nbsp; </span>@hDc</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>eax, uMsg</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>ecx, hWnd</span></p>
<p><span>;****************************************************************</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.if<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>eax == WM_PAINT &amp;&amp; ecx == hWin1</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke BeginPaint, hWnd, addr @stPs</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>@hDc, eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;GetClientRect, hWnd, addr @stRect</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;DrawText, @hDc, addr szText, -1, addr @stRect, DT_SINGLELINE or DT_CENTER or DT_VCENTER</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;EndPaint, hWnd, addr @stPs</span></p>
<p><span>;****************************************************************</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.elseif eax == WM_CLOSE</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;PostQuitMessage, NULL</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;DestroyWindow, hWin1</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;DestroyWindow, hWin2</span></p>
<p><span>;****************************************************************</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.else</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;DefWindowProc, hWnd, uMsg, wParam, lParam</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.endif</span></p>
<p><span>;****************************************************************</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>xor eax, eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret</span></p>
<p><span>_ProcWinMain<span>&nbsp;&nbsp;&nbsp; </span>endp</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>_WinMain proc</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>local<span>&nbsp;&nbsp; </span>@stWndClass:WNDCLASSEX</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>local<span>&nbsp;&nbsp; </span>@stMsg:MSG</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>local<span>&nbsp;&nbsp; </span>@hTimer</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;GetModuleHandle, NULL</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>hInstance, eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;RtlZeroMemory, addr @stWndClass, sizeof @stWndClass</span></p>
<p><span>;****************************************************************</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke<span>&nbsp;&nbsp; </span>LoadCursor, 0, IDC_ARROW</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>@stWndClass.hCursor, eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>hInstance</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pop<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>@stWndClass.hInstance</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>@stWndClass.cbSize, sizeof WNDCLASSEX</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>@stWndClass.style, CS_HREDRAW or CS_VREDRAW</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>@stWndClass.lpfnWndProc, offset _ProcWinMain</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>@stWndClass.hbrBackground, COLOR_WINDOW + 1</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>@stWndClass.lpszClassName, offset szClass1</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke<span>&nbsp;&nbsp; </span>RegisterClassEx, addr @stWndClass</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke<span>&nbsp;&nbsp; </span>CreateWindowEx, WS_EX_CLIENTEDGE, offset szClass1, offset szCaption1, WS_OVERLAPPEDWINDOW, 450, 100, 300, 300, NULL, NULL, hInstance, NULL</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hWin1, eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;</span>invoke<span>&nbsp;&nbsp; </span>ShowWindow, hWin1, SW_SHOWNORMAL</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke<span>&nbsp;&nbsp; </span>UpdateWindow, hWin1</span></p>
<p><span>;****************************************************************</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>@stWndClass.lpszClassName, offset szClass2</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;RegisterClassEx, addr @stWndClass</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;CreateWindowEx, WS_EX_CLIENTEDGE, offset szClass2, offset szCaption2, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>hWin2, eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;ShowWindow, hWin2, SW_SHOWNORMAL</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;UpdateWindow, hWin2</span></p>
<p><span>;****************************************************************</span></p>
<p><span>; </span><span>设置定时器</span></p>
<p><span>;****************************************************************</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;SetTimer, NULL, NULL, 100, addr _ProcTimer</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>@hTimer, eax</span></p>
<p><span>;****************************************************************</span></p>
<p><span>; </span><span>消息循环</span></p>
<p><span>;****************************************************************</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.while TRUE</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;GetMessage, addr @stMsg, NULL, 0, 0</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.break&nbsp;.if eax == 0</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;invoke&nbsp;TranslateMessage, addr @stMsg</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;DispatchMessage, addr @stMsg</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.endw</span></p>
<p><span>;****************************************************************</span></p>
<p><span>; </span><span>清除定时器</span></p>
<p><span>;****************************************************************</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;KillTimer, NULL, @hTimer</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret</span></p>
<p><span>_WinMain endp</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>start:</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>call<span>&nbsp;&nbsp;&nbsp; </span>_WinMain</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke&nbsp;ExitProcess, NULL</span></p>
<p><span>;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span></p>
<p><span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>end start</span></p>
<p><span>这个程序的代码用到的大部分知识都是前面已经讲到的，在</span><span>_WinMain</span><span>中，用一个同样的窗口类建立了两个窗口，两个窗口属于同一个窗口类，所以它们的窗口过程都是</span><span>_ProcWinMain</span><span>，为了关闭任何一个窗口都可以结束程序，</span><span>WM_CLOSE</span><span>消息中用</span><span>DestroyWindow</span><span>函数摧毁了两个窗口。程序设置了一个周期为</span><span>100ms</span><span>的定时器，</span><span>Windows</span><span>会每隔</span><span>100ms</span><span>调用</span><span>_ProcTimer</span><span>子程序。在</span><span>_ProcTimer</span><span>中，将其中一个窗口的客户区拷贝到另一个窗口的客户区中，方法是通过</span><span>GetDC</span><span>获取窗口的</span><span>DC</span><span>句柄，并用</span><span>BitBlt</span><span>函数完成拷贝工作，所以在右边的窗口显示了一句&#8220;</span><span>Win32 Assembly, Simple and powerful!</span><span>&#8221;，左边的窗口中也会出现这句话。</span></p>
<p>&nbsp;</p>
<p><span>程序每</span><span>100ms</span><span>将右边窗口的客户区拷贝到左边的窗口客户区中，通过左边窗口的客户区就可以了解右边客户区的</span><span>DC</span><span>对应的究竟是什么内容。</span></p>
<p>&nbsp;</p>
<p><span>通过左边窗口的变化可以惊奇地发现：右边窗口客户区的内容并不是程序自己输出到客户区的那句文本，而是以客户区为矩形区域的屏幕上我们真正看到的东西，它竟然包括其他窗口覆盖在上面的东西。这就意味着，扫雷游戏和纸牌游戏通过自己客户区对应的设备环境画图形，图形数据竟然画到了</span><span>DcCopy</span><span>窗口客户区对应的设备环境中。</span></p>
<p>&nbsp;</p>
<p><span>这个例子验证了<strong>&#8220;设备环境&#8221;只是&#8220;环境&#8221;而不是&#8220;设备&#8221;，它并不存储发给它的图形数据，图形数据透过它写到了它所描述的&#8220;设备&#8221;上，每个窗口客户区的&#8220;设备环境&#8221;对应的设备都是屏幕，但它们在位置上可能重叠，所以向一个窗口的客户区写数据相当于同时写了下层窗口的客户区。</strong></span></p>
<p>&nbsp;</p>
<p><span>为了让当前激活的窗口在视觉上保持在最上面，下层窗口向自己客户区写的内容首先要经过</span><span>Windows</span><span>的&#8220;过滤&#8221;，只有没有被其他窗口覆盖掉的部分才真正被写到了屏幕上。</span></p>
<p>&nbsp;</p>
<p><span>读者应该时刻提醒自己——&#8220;设备环境&#8221;只是一个环境，是设备属性的一组定义，程序输出的图形数据透过&#8220;设备环境&#8221;被定向到了具体的设备上，&#8220;设备环境&#8221;本身并不存储这些数据。</span></p>
<p>&nbsp;</p>
<p><span>Device Context</span><span>中</span><span>Context</span><span>的含义：设备环境的上面是应用程序，下面是具体设备，而它是用来&#8220;联系上下关系&#8221;用的。</span></p>
<p>&nbsp;</p>
<p><span>有人可能认为：屏幕上的窗口就像放在桌面上的一张张纸，虽然一张纸可能暂时被另一张遮住，但纸上写的东西还是存在的，移开另一张纸就可以再次露出来。但实际情况是：桌面更像一个用粉笔写的公告黑板，一个窗口相当于划了一块空间写告示，写另一个告示的时候要把老告示的内容擦去一部分以便写新的内容，擦去的东西也就不存在了，如果要恢复老告示，那么必须把擦去的部分重新写上去。</span></p>
<p>&nbsp;</p>
<p><span>2</span><span>、获取设备环境句柄</span></p>
<p><span>要想对任何设备绘图，首先必须获取设备的&#8220;设备环境句柄&#8221;（</span><span>hDC</span><span>），几乎所有的</span><span>GDI</span><span>函数的操作目标都是</span><span>hDC</span><span>，在程序中得到一个</span><span>hDC</span><span>有几种方法。</span></p>
<p>&nbsp;</p>
<p><span>最常用的方法是在</span><span>WM_PAINT</span><span>消息中用</span><span>BeginPaint</span><span>函数得到</span><span>hDC</span><span>，</span><span>WM_PAINT</span><span>消息的代码结构一般是：</span></p>
<p><span>.if<span>&nbsp;&nbsp;&nbsp; </span>eax == WM_PAINT<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;eax</span><span>为</span><span>uMsg</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke BeginPaint, hWnd, addr stPS</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;</span><span>刷新客户区的代码</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke EndPaint, hWnd, addr stPS</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>xor eax, eax</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret</span></p>
<p>&nbsp;</p>
<p><span>BeginPaint</span><span>函数的返回值就是需要刷新区域的</span><span>hDC</span><span>。要注意的是：</span><span>BeginPaint</span><span>返回的</span><span>hDC</span><span>对应的尺寸仅是无效区域，无法用它绘画到这个区域以外的地方去。由于窗口过程每次接收</span><span>WM_PAINT</span><span>消息时的无效区域可能是不同的，所以这个</span><span>hDC</span><span>的值仅在</span><span>WM_PAINT</span><span>消息中有效，程序不应该保存它并把它用在</span><span>WM_PAINT</span><span>消息以外的代码中。基于同样的道理，</span><span>BeginPaint</span><span>和</span><span>EndPaint</span><span>函数只能用在</span><span>WM_PAINT</span><span>消息中，因为只有这时候才存在无效区域。</span></p>
<p>&nbsp;</p>
<p><span>程序中常常有这种需求，就是在非</span><span>WM_PAINT</span><span>消息中主动绘画客户区，由于</span><span>BeginPaint</span><span>和</span><span>EndPaint</span><span>函数必须在</span><span>WM_PAINT</span><span>消息中使用，所以这时必须用另外的方法获取</span><span>hDC</span><span>，可以使用以下的方法：</span></p>
<p><span>invoke GetDC, hWnd<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;</span><span>获取</span><span>hDC</span></p>
<p><span>;</span><span>返回值是</span><span>hDC</span></p>
<p><span>;</span><span>绘图代码</span></p>
<p><span>invoke ReleaseDC, hWnd<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;</span><span>释放</span><span>hDC</span></p>
<p>&nbsp;</p>
<p><span>GetDC</span><span>函数返回的</span><span>hDC</span><span>对应窗口的整个客户区，当使用完毕的时候，</span><span>hDC</span><span>必须用</span><span>ReleaseDC</span><span>函数释放。对于用</span><span>GetDC</span><span>获取的</span><span>hDC</span><span>，</span><span>Windows</span><span>建议使用的范围限于单条消息内，当程序在处理某条消息的时候需要绘画客户区时，可以用</span><span>GetDC</span><span>获取</span><span>hDC</span><span>，但在消息返回前，必须用</span><span>ReleaseDC</span><span>将它释放掉，如果在下一条消息中需要继续使用到</span><span>hDC</span><span>，那么必须重新用</span><span>GetDC</span><span>函数获取。</span></p>
<p>&nbsp;</p>
<p><span>上面的两种方法获取的</span><span>hDC</span><span>都是窗口的</span><span>hDC</span><span>，如果要操作的是其他的东西，如打印机、位图等，就不能使用</span><span>BeginPaint</span><span>或</span><span>GetDC</span><span>函数了。当绘图的对象是一个设备的时候，可以用</span><span>CreateDC</span><span>函数来建立一个</span><span>DC</span><span>：</span></p>
<p><span>invoke CreateDC, lpszDriver, lpszDevice, lpszOutput, lpInitData</span></p>
<p><span>lpszDriver</span><span>指向设备名称，如显示设备的设备名是</span><span>DISPLAY</span><span>，打印机的设备名一般为</span><span>WINSPOOL</span><span>，下面这几句代码建立的</span><span>DC</span><span>对应整个屏幕：</span></p>
<p><span>szDriver<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>db<span>&nbsp;&nbsp;&nbsp; </span>&#8220;DISPLAY&#8221;,0</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoke CreateDC, addr szDriver, NULL, NULL, NULL</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov hDC, eax</span></p>
<p>&nbsp;</p>
<p><span>当绘图对象是位图的时候，同样需要一个和位图句柄相联系的</span><span>DC</span><span>，这时可以用函数</span><span>CreateCompatibleDC</span><span>来创建一个显示表面仅存在于内存中的</span><span>DC</span><span>：</span></p>
<p><span>invoke CreateCompatibleDC, hDC</span></p>
<p><span>参数中的</span><span>hDC</span><span>是用来参考的</span><span>DC</span><span>句柄，如果指定的参数是</span><span>NULL</span><span>，那么建立的</span><span>DC</span><span>将和当前屏幕的设置兼容，为了用</span><span>CreateCompatibleDC</span><span>建立的</span><span>DC</span><span>绘画一个位图，还需要用</span><span>SelectObject</span><span>函数将</span><span>hDC</span><span>和位图句柄联系起来。</span></p>
<p>&nbsp;</p>
<p><span>用</span><span>CreateDC</span><span>和</span><span>CreateCompatibleDC</span><span>函数建立的</span><span>hDC</span><span>在使用结束以后，必须用</span><span>DeleteDC</span><span>函数删除，注意这里不能用</span><span>ReleaseDC</span><span>，这个函数是和</span><span>GetDC</span><span>配合用的。</span></p>
<p>&nbsp;</p>
<p><span>用</span><span>BeginPaint/EndPaint</span><span>以及</span><span>GetDC</span><span>获取的</span><span>hDC</span><span>的使用时间不能超出本条消息，与此相比，用</span><span>CreateDC</span><span>以及</span><span>CreateCompatibleDC</span><span>建立的</span><span>hDC</span><span>就没有这个限制，可以在任何时刻建立它并且一直使用到不再需要为止。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>三、色彩和坐标</span></p>
<p><span>1</span><span>、</span><span>Windows</span><span>中的色彩</span></p>
<p><span>可以表示的颜色总数由颜色深度决定，也就是存储每个像素所用的位数，各种显示设备可以显示的颜色总数可能大不相同，如果设备支持的颜色深度太浅，就会影响到图像的质量，会让人看起来觉得很粗糙和不自然。</span></p>
<p>&nbsp;</p>
<p><span>一种颜色可以分解成红、绿、蓝三原色，所以可以用红、绿、蓝</span><span>3</span><span>个分量的组合来表示各种颜色。</span></p>
<p>&nbsp;</p>
<p><span>当设备支持的颜色深度少于等于</span><span>8</span><span>位时（如</span><span>8</span><span>位（</span><span>256</span><span>色）、</span><span>4</span><span>位（</span><span>16</span><span>色）、</span><span>2</span><span>位（</span><span>4</span><span>色）或</span><span>1</span><span>位（</span><span>2</span><span>色）），总体位数太少，不足以用来表达</span><span>3</span><span>个颜色分量，这时系统建立一个色彩表，像素数据用来做索引在色彩表中获取颜色值，所以低于</span><span>8</span><span>位的颜色称为索引色。</span></p>
<p>&nbsp;</p>
<p><span>只有当颜色深度大于</span><span>8</span><span>位的时候，像素数据中才直接包含红、绿、蓝</span><span>3</span><span>个分量。当颜色深度为</span><span>16</span><span>位的时候，红、绿、蓝各用</span><span>5</span><span>位表示，剩下的</span><span>1</span><span>位用做属性位，实际可以表示的颜色数目为</span><span>2^15=32 768</span><span>种，</span><span>16</span><span>位深度的彩色又称为</span><span>16</span><span>位色、高彩色或增强色。当颜色深度为</span><span>24</span><span>位的时候，</span><span>3</span><span>个分量各用</span><span>8</span><span>位表示，实际可以表示的颜色数目为</span><span>2^24=16777216</span><span>种，</span><span>24</span><span>位深度的彩色又称为</span><span>24</span><span>位色、</span><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="16" UnitName="m"><span>16M</span></st1:chmetcnv><span>色或真彩色。对于人的眼睛来说，超过</span><span>16</span><span>位的颜色就已经很难分辨了。</span></p>
<p>&nbsp;</p>
<p><span>在</span><span>Win32</span><span>的编程中，统一使用</span><span>32</span><span>位的整数表示一个深度为</span><span>24</span><span>位的颜色，在这</span><span>32</span><span>位中只使用低</span><span>24</span><span>位，每一种原色分量占用</span><span>8</span><span>位，其中</span><span>0~7</span><span>位为红色，</span><span>8~15</span><span>位为绿色，</span><span>16~23</span><span>位为蓝色。在程序中用到一种颜色常数的时候，可以如下使用：</span></p>
<p><span>move ax, </span><span>红色</span><span> + </span><span>绿色</span><span>*100h + </span><span>蓝色</span><span>*10000h&nbsp;;</span><span>将颜色放入</span><span>eax</span><span>中</span></p>
<p>&nbsp;</p>
<p><span>当显示设备无法表示</span><span>24</span><span>位色的时候，</span><span>Windows</span><span>会自动用设备可以显示的最接近的颜色来代替它，当显示设备的颜色深度比较低的时候，可以通过函数</span><span>GetNearestColor</span><span>来得知一种颜色（颜色）会被系统替换成哪种颜色：</span></p>
<p><span>invoke GetNearestColor, hDC, dwColor<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;</span><span>返回真正使用的颜色值</span></p>
<p>&nbsp;</p>
<p><span>但是当显示设备颜色深度太低的时候，经过</span><span>Windows</span><span>自动转换的图像可能会让人觉得很不自然，所以在有些时候，程序员可能希望预先得知设备的颜色深度，然后根据具体情况显示不同的图形。</span></p>
<p>&nbsp;</p>
<p><span>显示设备的颜色深度可以用以下函数获取：</span></p>
<p><span>invoke GetDeviceCaps, hDC, PLANES</span></p>
<p><span>mov ebx, dwPlanes</span></p>
<p><span>invoke GetDeviceCaps, hDC, BITSPIXEL</span></p>
<p><span>mul ebx</span></p>
<p><span>mov dwColorDepth, eax</span></p>
<p>&nbsp;</p>
<p><span>第一个函数调用返回</span><span>DC</span><span>的色彩平面数，第二个函数调用返回每个像素的色彩位数，颜色深度最后可以通过</span><span>dwPlanes</span><span>乘以</span><span>dwBitsPixel</span><span>得到。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>2</span><span>、</span><span>Windows</span><span>中的坐标系</span></p>
<p><span>要用</span><span>GDI</span><span>函数绘图，就必须首先了解这些函数使用的坐标系，在默认的状态下，</span><span>Windows</span><span>坐标系以左上角做坐标原点，以右方当做</span><span>X</span><span>坐标的正方向，以下方当做</span><span>Y</span><span>坐标的正方向。坐标的数值要用一个有符号的</span><span>16</span><span>位数来表示，范围从</span><span>-32 768~32767</span><span>，坐标的单位为像素。这种坐标系定义方法的好处是：窗口中每一点的坐标不会因为窗口的大小改变而改变，试想一下，如以数学中通常的表示方法，以左下角做坐标原点，那么当窗口高度被用户调整的时候，客户区中每一点的</span><span>Y</span><span>坐标都会变化，在具体使用中就会有诸多不便。</span></p>
<p>&nbsp;</p>
<p><span>但是</span><span>Windows</span><span>也提供了其他的一些坐标映射方法供程序员使用，可以用</span><span>SetMapMode</span><span>函数来为一个</span><span>DC</span><span>设置新的坐标映射方法：</span></p>
<p><span>invoke SetMapMode, hDC, iMapMode</span></p>
<p><span>可以设置的参数包括坐标原点、坐标和逻辑单位和坐标的正方向等，参数中的</span><span>iMapMode</span><span>为新的映射方式，其可以选择的取值如下表所示，</span><span>Windows</span><span>默认使用的映射方式为</span><span>MM_TEXT</span><span>。</span></p>
<p><span>Windows</span><span>中可用的坐标映射方式</span></p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=139>
            <p><strong><span>映射方式</span></strong></p>
            </td>
            <td vAlign=top width=107>
            <p><strong><span>原点</span></strong></p>
            </td>
            <td vAlign=top width=107>
            <p><strong><span>逻辑单位</span></strong></p>
            </td>
            <td vAlign=top width=107>
            <p><strong><span>X</span></strong><strong><span>正方向</span></strong></p>
            </td>
            <td vAlign=top width=107>
            <p><strong><span>Y</span></strong><strong><span>正方向</span></strong></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=139>
            <p><span>MM_TEXT(</span><span>默认方式</span><span>)</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>左上</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>像素</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>右</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>下</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=139>
            <p><span>MM_HIENGLISH</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>左上</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>0.001</span><span>英寸</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>右</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>上</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=139>
            <p><span>MM_LOENGLISH</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>左上</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>0.01</span><span>英寸</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>右</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>上</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=139>
            <p><span>MM_HIMETRIC</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>左上</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>0.01</span><span>毫米</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>右</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>上</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=139>
            <p><span>MM_LOMETRIC</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>左上</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>0.1</span><span>毫米</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>右</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>上</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=139>
            <p><span>MM_TWIPS</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>左上</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>1/1440</span><span>英寸</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>右</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>上</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=139>
            <p><span>MM_ISOTROPIC</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>可变</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>可变（</span><span>x=y</span><span>）</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>可变</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>可变</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=139>
            <p><span>MM_ANISOTROPIC</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>可变</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>可变（</span><span>x!=y</span><span>）</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>可变</span></p>
            </td>
            <td vAlign=top width=107>
            <p><span>可变</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>可以看到，除了默认的</span><span>MM_TEXT</span><span>方式外，下面</span><span>5</span><span>种映射方式：</span><span>MM_HIENGLISH</span><span>，</span><span>MM_LOENGLISH</span><span>，</span><span>MM_HIMETRIC</span><span>，</span><span>MM_LOMETRIC</span><span>和</span><span>MM_TWIPS</span><span>采用的都是原点位于左上角、</span><span>X</span><span>正方向向上的映射方式，另外，它们的坐标逻辑单位是不同的。</span></p>
<p>&nbsp;</p>
<p><span>最后的两种映射方式</span><span>MM_ISOTROPIC</span><span>和</span><span>MM_ANISOTROPIC</span><span>提供了更灵活的选择，设置为这两种映射方式后，程序可以继续调用</span><span>SetViewportOrgEx</span><span>，</span><span>SetViewportExtEx</span><span>和</span><span>SetWindowExtEx</span><span>函数来自由设置坐标系的原点、逻辑单位和坐标的正方向等所有参数。在其他映射方式下的时候，不能使用这</span><span>3</span><span>个设置函数，这时任何对它们的调用都会被忽略。</span></p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/luqingfei/aggbug/127502.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luqingfei/" target="_blank">luqingfei</a> 2010-09-24 13:51 <a href="http://www.cppblog.com/luqingfei/archive/2010/09/24/127502.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>