﻿<?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>IT博客-weitom1982-随笔分类-计算机基础知识</title><link>http://www.cnitblog.com/weitom1982/category/1320.html</link><description>向各位技术前辈学习,学习再学习.</description><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 16:23:20 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 16:23:20 GMT</pubDate><ttl>60</ttl><item><title>WinCVS操作手册</title><link>http://www.cnitblog.com/weitom1982/archive/2007/09/27/34090.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Thu, 27 Sep 2007 06:11:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2007/09/27/34090.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/34090.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2007/09/27/34090.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/34090.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/34090.html</trackback:ping><description><![CDATA[<div align=center><strong><font size=6>WinCVS操作手册</font></strong></div>
<div>&nbsp;</div>
<div style="MARGIN-RIGHT: 1.25pt"><strong><span style="FONT-SIZE: 12pt">撰稿：paladin.lin<span>&nbsp;&nbsp;&nbsp;&nbsp; 2003</span>年11月5日</span></strong></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 25.55pt; TEXT-INDENT: -25.55pt"><strong><font size=5><span style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%">第一章：&nbsp;</span>概述</font></strong></div>
<div style="TEXT-INDENT: 21pt">CVS是目前比较流行与优秀的版本管理与控制工具，是用来管理其它日常文档（如word工作文档之类）的一个强有力的工具。</div>
<div style="TEXT-INDENT: 21pt">WinCVS是CVS的一个客户端软件，它运行在Windows上，采用图形化方式登陆CVS服务器和CVS相关的操作与管理，不要学习复杂的cvs命令。企业内部都采用Linux/Unix做服务器，用Windows做客户端，所以WinCVS与CVS服务器是目前应用最广泛的版本控制与管理的组合。</div>
<div style="TEXT-INDENT: 21pt">本文主要介绍WinCVS的日常操作， CVS服务器的配置将在另外的文章中介绍，本文所有操作是基于CVS服务配置正确、数据仓库已初始化的基础上，</div>
<div style="MARGIN-LEFT: 25.55pt; TEXT-INDENT: -25.55pt"><strong><font size=5><span style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%">第二章：&nbsp;</span>术语</font></strong></div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -33pt; TEXT-ALIGN: left" align=left><strong><span>1、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Repository</strong>-------仓库<span>:</span> CVS服务器的根目录。模块（<span>Module）的集合</span> </div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -33pt; TEXT-ALIGN: left" align=left><strong><span>2、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Module</strong>------------模块<span>:，CVS服务器根目录下的</span>第一级子目录。通常用于存放一个项目的所有文件</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -33pt; TEXT-ALIGN: left" align=left><strong><span>3、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Checkout</strong>----------检出<span>:</span> 通常指将仓库中的一整个模块首次导出到本地。</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -33pt; TEXT-ALIGN: left" align=left><strong><span>4、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Import</strong>------------导入<span>:</span>通常指通过提交整个目录结构并创建一个新的模块。</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -33pt; TEXT-ALIGN: left" align=left><strong><span>5、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Release</strong>-------发行版本<span>:</span>整个产品的版本</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -33pt; TEXT-ALIGN: left" align=left><strong><span>6、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Revision</strong>--------修订版<span>:</span>单个文件的版本</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -33pt; TEXT-ALIGN: left" align=left><strong><span>7、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Tag</strong>---------------标签<span>:</span>在一个开发的特定期对一个文件集给定的符号名</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -33pt; TEXT-ALIGN: left" align=left><strong><span>8、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Update</strong>------------更新<span>:</span>从模块中下载其他人的修改过的文件。更新本地的拷贝。</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -33pt; TEXT-ALIGN: left" align=left><strong><span>9、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Commit</strong>------------提交<span>:</span>将自己修改过的文件提交到模块中。</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 25.55pt; TEXT-INDENT: -25.55pt"><strong><font size=5><span style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%">第三章：&nbsp;</span>WinCVS初始化配置</font></strong></div>
<div style="MARGIN-LEFT: 2cm; TEXT-INDENT: -43.1pt"><strong><span style="FONT-SIZE: 12pt">第一步：<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">安装</span><span style="FONT-SIZE: 14pt">Wincvs</span></div>
<div style="MARGIN-LEFT: 63pt">执行setup.exe安装,然后在一步步的确认就ok了.安装完毕后运行wincvs:</div>
<div style="MARGIN-LEFT: 9pt" align=center><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/e4c85d1f58984de7b2e47eb041b296de.jpg"></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 2cm; TEXT-INDENT: -43.1pt"><strong><span style="FONT-SIZE: 12pt">第二步：<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">配置</span><span style="FONT-SIZE: 14pt">WinCVS</span><span style="FONT-SIZE: 14pt">参数</span></div>
<div style="MARGIN-LEFT: 9pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/df82d77543ad4a26899a7de7871941c4.png"></div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#216;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>Preferences -&gt; General :</strong><strong>普通参数设置</strong></div>
<div style="MARGIN-LEFT: 9pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/dc41654e211f4249b45e6a48f5ef98a0.png"></div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>1.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>Authentication :<span>&nbsp;&nbsp;&nbsp; </span></strong>验证方式,CVS默认采用<strong>pserver</strong>。</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>2.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>Path:<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong>CVS服务器的路径,就是<strong>Repository(</strong>仓库<strong>)</strong><strong>。</strong></div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>3.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>Host address:</strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CVS</span>服务器的IP地址或者域名。</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>4.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>User name:<span>&nbsp;&nbsp;&nbsp; </span></strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>用户名。</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>5.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>CVSROOT:</strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CVSROOT,</span>由上面4项生成的字符串，用于连接服务器</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>6.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>&nbsp;</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#216;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>Preferences -&gt; Globals :</strong><strong>全局参数设置</strong></div>
<div style="MARGIN-LEFT: 21pt"><strong>&nbsp;</strong></div>
<div style="MARGIN-LEFT: 21pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/07b60a3a0253427eb153994177330e78.png"></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><strong><span>1.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>checkout read-only</strong><strong>： &nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><strong>检出只读，wincvs</strong><strong>默认导出文件为只读状态。去掉该选项。</strong></div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><strong><span>2.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><strong>Prune</strong><strong>（remove</strong><strong>）empty directories&nbsp;</strong><strong>剪除（删除）空目录，去掉该选项。</strong></div>
<div><strong>&nbsp;</strong></div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#216;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>Preferences -&gt; WinCVS : WinCVS</strong><strong>参数设置</strong></div>
<div style="MARGIN-LEFT: 33pt"><strong><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/5e9a2ecb24c2408f9ba87799f7df7020.png"></strong></div>
<div><strong>&nbsp;</strong></div>
<div style="MARGIN-LEFT: 2cm; TEXT-INDENT: -43.1pt"><strong><span style="FONT-SIZE: 12pt">第三步：<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">登陆</span></div>
<div style="MARGIN-LEFT: 13.6pt">&nbsp;</div>
<div style="MARGIN-LEFT: 42pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/c352e89afc4d488c93395f04aaf8cde2.png"></div>
<div style="MARGIN-LEFT: 42pt">&nbsp;</div>
<div style="MARGIN-LEFT: 42pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/2490c59c0a54495ca13b407650211c0f.png"></div>
<div style="MARGIN-LEFT: 42pt">&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/69317db4d1e443d3a4f7e8dfe34a8a71.png"></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 2cm; TEXT-INDENT: -43.1pt"><strong><span style="FONT-SIZE: 12pt">第四步：<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">导入模块</span></div>
<div style="MARGIN-LEFT: 13.6pt">&nbsp;</div>
<div style="MARGIN-LEFT: 13.6pt">&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/fc3fa8f36f7344d4944c4f85bdf80043.png"></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#216;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>选择需要导入的目录</strong></div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/35ce43e45a7e4055ac5b5c646cd4317d.png"></div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#216;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>整理导入的文件类型（Entry State</strong><strong>是OK</strong><strong>标记就无需修改）</strong></div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/f710105370a047c0ba8d0ae8b5e21d3f.png"></div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#216;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>修改选中的文件类型</strong></div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/b319edda0450410d9c88cf899b0cfe28.png"></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#216;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>导入设置</strong></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/efb7881c5f9242c7811de5ac11e468bb.png"></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/5e0adf2028434bebac277067aff31e90.png"></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 2cm; TEXT-INDENT: -43.1pt"><strong><span style="FONT-SIZE: 12pt">第五步：<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">导出模块</span></div>
<div>cmd：</div>
<div>1 cvs checkout -P Documents/sipsir</div>
<div>该命令会在本地创建Documents</div>
<div>cvs client tool：</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/6a8cd34755be41bebcb6522903026425.png"></div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#216;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>导出设置</strong></div>
<div style="MARGIN-LEFT: 33pt">&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/5f7570b8918b4e3593ea6201c9559627.png"></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#216;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>模块成功导出</strong></div>
<div style="MARGIN-LEFT: 33pt">&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/baf8ee8cc483423a88dfd1bbf11f1bb4.png"></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 25.55pt; TEXT-INDENT: -25.55pt"><strong><font size=5><span style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%">第四章：&nbsp;</span>WinCVS日常操作</font></strong></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 22.7pt; TEXT-INDENT: -8.5pt"><strong><span style="FONT-SIZE: 14pt">一、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">修改文件，并上传到服务器</span></div>
<div style="MARGIN-LEFT: 84pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#178;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>准备修改文件</strong></div>
<div style="MARGIN-LEFT: 9pt" align=center><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/4062b79eddf34eeea754efb194319de7.png"></div>
<div style="MARGIN-LEFT: 9pt" align=center>&nbsp;</div>
<div style="MARGIN-LEFT: 84pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#178;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>修改文件</strong></div>
<div style="MARGIN-LEFT: 63pt"><strong>&nbsp;</strong></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/920d8c52e3b3427e9c7060df1e9be949.png"></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 84pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#178;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>上传的修改文件</strong></div>
<div style="MARGIN-LEFT: 33pt"><strong><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/fdc465d8f9fa41128433a5f07c465327.png"></strong></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/c5ac4df381e84969a651e4b223f5451e.png"></div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/8e854dddc4df408982725e96adaa887a.png"></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 22.7pt; TEXT-INDENT: -8.5pt"><strong><span style="FONT-SIZE: 14pt">二、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">下载服务器的文件，替换本地文件</span></div>
<div>假设服务器上&#8220;测试wincvs.doc&#8221;的word文件已经是1.2本,下载到本地来</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/2179beec8c5c432991fefd18e2222a8a.png"></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/23529a57eeaf47b0a4ab478f712b032c.png"></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/9c2239894589438ebeb1097df829a753.png"></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 22.7pt; TEXT-INDENT: -8.5pt"><strong><span style="FONT-SIZE: 14pt">三、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">修改了一个文件</span><span style="FONT-SIZE: 14pt">,</span><span style="FONT-SIZE: 14pt">结果发现修改错了，需要重新下载服务器的文件。</span></div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/0ea39633e4604261930cf583968ace67.png"></div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/709218c1978940c4934b2b5a27c0745c.png"></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 22.7pt; TEXT-INDENT: -8.5pt"><strong><span style="FONT-SIZE: 14pt">四、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">添加一个文件或一个目录。</span></div>
<div>cmd:</div>
<div>添加一个文件或目录</div>
<div>1 添加：<span style="FONT-SIZE: 10pt">cvs add test.txt</span></div>
<div><span style="FONT-SIZE: 10pt">2 </span><span style="FONT-SIZE: 10pt">提交：</span><span style="FONT-SIZE: 10pt">cvs commit -m "no message" test.txt</span></div>
<div><span style="FONT-SIZE: 10pt">添加目录及目录下所有文件</span><span style="FONT-SIZE: 10pt">,</span><span style="FONT-SIZE: 10pt">如</span><span style="FONT-SIZE: 10pt">D:/cvs/sipsir</span></div>
<div><span style="FONT-SIZE: 10pt">1 cd D:/cvs</span></div>
<div><span style="FONT-SIZE: 10pt">2 cvs add sipsir</span></div>
<div><span style="FONT-SIZE: 10pt">3 cd sipsir</span></div>
<div><span style="FONT-SIZE: 10pt">4 cvs add *&nbsp;&nbsp; (</span><span style="FONT-SIZE: 10pt">会把目录下所有文件和目录都添加了</span><span style="FONT-SIZE: 10pt">)</span></div>
<div><span style="FONT-SIZE: 10pt">5 cvs commit &#8211;m &#8220;&#8221;</span></div>
<div><span style="FONT-SIZE: 10pt">cvs client tool</span></div>
<div style="MARGIN-LEFT: 63pt; TEXT-INDENT: -36pt"><span style="FONT-SIZE: 14pt">&#178;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>打开需要放置文件的目录</strong></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/f979b08fd5ba494996343ce6738d5845.png"></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 54pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#178;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>新建立一个文件或目录</strong></div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/132e183dd78f40ee84f7baf7a23bb27e.png"></div>
<div style="MARGIN-LEFT: 105pt">&nbsp;</div>
<div style="MARGIN-LEFT: 105pt">&nbsp;</div>
<div style="MARGIN-LEFT: 27pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#178;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>上传目录（如果文件中有子目录或文件，没有递归上传，需要在操作一遍）</strong></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/6fdf9b5e8c2c4e8192471f5ef77d09af.png"></div>
<div style="MARGIN-LEFT: 27pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#178;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>上传文件</strong></div>
<div><strong><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/9d5ff183c8d34aefa9f98b7df2f2564c.png"></strong></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 84pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 14pt">&#178;<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt">文件只是标记添加成功，还需要执行上传操作（具体操作查看</span><strong>&#8220;上传的修改文件&#8221;</strong><span style="FONT-SIZE: 12pt">）</span></div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/405bc48092314433abe0d69aaa3194c1.png"></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 22.7pt; TEXT-INDENT: -8.5pt"><strong><span style="FONT-SIZE: 14pt">五、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">如何取回以前的某个版本</span></div>
<div><span style="FONT-SIZE: 14pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/c7d4b542ace44a73abeba8159cb1e2a0.png"></span></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/6c0d6a7b464a4e33823462f03db4e6b6.png"></div>
<div>&nbsp;</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/c363293b2a6749339cc7b1ed90b0b4d4.png"></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 22.7pt; TEXT-INDENT: -8.5pt"><strong><span style="FONT-SIZE: 14pt">六、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">删除分支</span><span style="FONT-SIZE: 14pt">/</span><span style="FONT-SIZE: 14pt">标签，取得最新的版本</span></div>
<div><span style="FONT-SIZE: 14pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/977628e215334a14b7dc6109a85c742b.png"></span></div>
<div>&nbsp;</div>
<div><span style="FONT-SIZE: 14pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/b73a587ee21842129cca57fc820b6584.png"></span></div>
<div>&nbsp;</div>
<div><span style="FONT-SIZE: 14pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/2ebbcf34c02b4a779c6630006a584db5.png"></span></div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 22.7pt; TEXT-INDENT: -8.5pt"><strong><span style="FONT-SIZE: 14pt">七、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">固定版本：经过一段时间修改，各个文件的版本不一致，而且文档管理到了一个阶段，需要固定版本。</span></div>
<div><span style="FONT-SIZE: 14pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/ccaa5d157dfc41e68b2f01f77af15328.png"></span></div>
<div>&nbsp;</div>
<div><span style="FONT-SIZE: 14pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/2eccac5205dc4b1590e9076887ee23ba.png"></span></div>
<div>&nbsp;</div>
<div><span style="FONT-SIZE: 14pt"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/0fbfce3d42bf4adfb39fa767c951edfa.png"></span></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 22.7pt; TEXT-INDENT: -8.5pt"><strong><span style="FONT-SIZE: 14pt">八、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">删除</span><span style="FONT-SIZE: 14pt">cvs</span><span style="FONT-SIZE: 14pt">服务器上的一个文件。</span></div>
<div><span style="FONT-SIZE: 10pt">cmd</span><span style="FONT-SIZE: 10pt">：</span></div>
<div><span style="FONT-SIZE: 10pt">1 &nbsp;cvs remove -f test.txt</span></div>
<div>2 &nbsp;<span style="FONT-SIZE: 10pt">cvs commit -m "no message"</span></div>
<div><span style="FONT-SIZE: 10pt">cvs client tool:</span></div>
<div><span style="FONT-SIZE: 10pt">1 </span><span style="FONT-SIZE: 10pt">选中</span><span style="FONT-SIZE: 10pt">test.txt</span><span style="FONT-SIZE: 10pt">文件</span></div>
<div><span style="FONT-SIZE: 10pt">&nbsp; <img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/f86b902082264bfcb712bd9d0df7ece2.png"></span></div>
<div><span style="FONT-SIZE: 10pt">2 </span><span style="FONT-SIZE: 10pt">删除文件</span></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/e51ae48025fe4a3eb7187abadcbf8f66.png"></div>
<div>3 提交</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/sipsir/7e9573f3826a4401bf6e15fb5e9133b8.png"></div>
<div style="MARGIN-LEFT: 22.7pt; TEXT-INDENT: -8.5pt"><strong><span style="FONT-SIZE: 14pt">九、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 14pt">删除</span><span style="FONT-SIZE: 14pt">cvs</span><span style="FONT-SIZE: 14pt">服务器上的一个目录。</span></div>
<div><span style="FONT-SIZE: 10pt">假设要删除</span><span style="FONT-SIZE: 10pt"> %cvs_home%\sipsir</span><span style="FONT-SIZE: 10pt">目录</span><span style="FONT-SIZE: 10pt">,</span> 需要先删除目录中的所以文件，使该目录成为一个空目录，然后运行cvs update -P让CVS从仓库中清除空目录。</div>
<div><span style="FONT-SIZE: 10pt">cmd</span><span style="FONT-SIZE: 10pt">：</span></div>
<div><span style="FONT-SIZE: 10pt">1 cd %cvs_home%</span></div>
<div><span style="FONT-SIZE: 10pt">2 </span>cvs update &#8211;P</div>
<div>3 cvs update</div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/34090.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2007-09-27 14:11 <a href="http://www.cnitblog.com/weitom1982/archive/2007/09/27/34090.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WinCVS与CVSNT简明使用手则 </title><link>http://www.cnitblog.com/weitom1982/archive/2007/09/27/34089.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Thu, 27 Sep 2007 05:50:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2007/09/27/34089.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/34089.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2007/09/27/34089.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/34089.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/34089.html</trackback:ping><description><![CDATA[<div class=posttitle><a class=singleposttitle id=viewpost.ascx_TitleUrl href="http://blog.sunmast.com/sunmast/articles/563.aspx">WinCVS与CVSNT简明使用手则</a> </div>
<p><span class=14><strong>1、前言：</strong></span><br><br>CVS是版本控制的利器，目前在Linux和Windows下都有不同版本；但是国内大多数应用介绍都是基于Linux等开放源代码的开放性软件组织，而且讲解的也不系统，让人摸不着头脑；Windows下的CVS使用介绍更是了了无几。 <br>本文是针对Windows的LAN环境下使用CVS的经验介绍，一步一步的向您介绍如何配置和使用CVS的服务器端和客户端。同时，本文只使用到了CVS当中最基本的东西，还有很多更为高级的东西，本文暂不涉及。下面是本文的另一个连接映射，欢迎大家讨论使用，共同进步。 <br>文章连接http://www.kuihua.net/book/list.asp?id=66 <br>论坛连接http://www.kuihua.net/bbs/dispbbs.asp?boardID=1&amp;;RootID=670&amp;ID=670 </p>
<p><strong><span class=14>2、安装版本：</span></strong><br><br><span class=14>2.1、服务器端(CVSNT)</span> </p>
<p>1. 本文使用的是CVSNT-2.0.4，这是一个比较稳定的版本，不要使用最新的CVSNT-2.1.1，本人在使用中发现有比较严重的Bug。 <br>2. 下载连接http://www.cvsnt.org 目前，它提供2.0.6和2.1.1版本的下载。 <br>3. 上面连接还提供源代码，有兴趣的朋友还可以下载下来仔细研究：）。 <br>4. 有心的朋友，仔细观察就会发现http://www.cvsnt.org 并没有提供任何客户端的下载，那是因为CVS.exe既可以用于服务器端又可以用于客户端，WinCVS是为了客户端使用的方便而定制的外壳。（关于这一点，本人未得到任何证实，只是本人在使用过程中的一种体会，欢迎大家讨论。） </p>
<p class=14>2.2、客户端(WinCVS) </p>
<p>1. 本文使用的是WinCVS-1.3b13，这应该是一个最新版本：），本人在使用过程中并没有发现有任何严重的Bug。 <br>2. 下载连接http://sourceforge.net/projects/cvsgui/ <br>3. 此网站还提供丰富的CVS文档和相关源代码，以及多个OS下面的相关文档和代码；有收藏癖的朋友有福了：）。 <br>4. WinCVS-1.3b13 使用的CVSNT的版本是CVSNT-2.0.2，在与服务器端的CVSNT-2.0.4 版本配合使用时，未发现任何不兼容或冲突现象。 <br>5. 在本人的系统中用cvs version命令显示的结果如下： <br>Client: Concurrent Versions System (CVSNT) 2.0.2 (client/server) <br>Server: Concurrent Versions System (CVSNT) 2.0.4 (client/server) </p>
<p class=14><strong>3、服务器端(CVSNT)的安装与配置：</strong> </p>
<p class=14>3.1、服务器端机器和环境配置： </p>
<p>1. 操作系统：Windows 2000 Professional SP2中文版 <br>2. 机器名称：Server <br>3. 机器地址：192.168.0.6 (内部IP) <br>4. 网络环境：100兆交换局域网 <br>5. 硬盘分区格式：FAT32与NTFS都可以。 <br>6. 准备2个CVSNT的工作目录： <br>F:\KHRoot (存放自己源代码的根目录) <br>F:\KHTemp (存放CVS出错信息的目录) <br>7. 本机上存在有的用户列表：（由NT或本机的使用者创建） <br>Administrator (系统管理员) <br>Jackey (普通用户) <br>Goury (普通用户) <br>Riolee (普通用户) </p>
<p class=14>3.2、安装CVSNT： </p>
<p>1. 下载CVSNT-2.0.4；使用administrator登陆到Server机器上。 <br>2. 双击自解压的exe文件，选择Full Install，其它按照默认方式安装；安装完毕后可以在服务控制器中发现多了2个服务：cvsnt与cvslocking <br>3. 发送Service Control Panel到桌面，形成快捷方式。 <br>4. 安装程序会自动将CVS安装路径，设置到系统的Path环境变量当中，因此使用者可以在控制台(cmd)中任意位置执行cvs.exe，这一点对下面的配置很重要！！ </p>
<p class=14>3.3、配置CVSNT服务器： </p>
<p>1. 双击Service Control Panel快捷方式，在Service Status页面，确认2个服务正常和稳定运行。 <br>2. 选择Repository页面，点按Add按钮，选择已经准备好的F:\KHRoot这个目录，确认，OK，Yes，这时会在F:\KHRoot下面建立CVSRoot目录，这是CVS默认的管理目录（默认模块）。如果报错，那是系统Path路径未设置正确。 <br>3. 选择Advanced页面，勾上Use local users for pserver ...，（Why? I don&#8217;t know!J）,在Temporary栏选择已经准备好的F:\KHTemp，确认，OK。 <br>4. 点按【应用】按钮，确认，退出，OK，搞定！！ </p>
<p><span class=14>3.4、小结：</span><br><br>1. 至此，CVSNT服务器端基本配置完毕，下面进行WinCVS的使用和管理。 <br>2. 由于CVS支持远程管理，也就是客户端与服务器集成的特性，因此，我们将添加用户、权限控制、模块维护等所有的管理工作都放到远端(WinCVS)进行管理，服务器端这时可以Ctrl+Atl+Del进入锁定状态了，下面的所有工作都交给远端的WinCVS来进行管理。 </p>
<p><span class=14><strong>4 客户端(WinCVS)的安装与配置： </strong></span></p>
<p><span class=14>4.1 客户端机器和环境配置：</span><br><br>1. 操作系统：Windows 2000 Professional SP2中文版 <br>2. 机器名称：YCW2000 <br>3. 机器地址：192.168.0.2 (内部IP) <br>4. 网络环境：100兆交换局域网，可以直接访问到Server <br>5. 硬盘分区格式：FAT32与NTFS都可以。 </p>
<p class=14>4.2 安装WinCVS： </p>
<p>1. 下载WinCVS 1.3b13，全部按照默认安装就可以了。 <br>2. 启动WinCVS，开始使用。特别注意：以下的所有操作都是在YCW2000(192.168.0.2)这台机器上远程完成的，此时的Server(192.168.0.6)主机已经进入了锁定状态。 </p>
<p class=14><strong>5 管理员使用WinCVS进行远程管理： </strong></p>
<p class=14>5.1 配置WinCVS成管理员状态： </p>
<p>1. 准备管理员工作目录：(在YCW2000机器上) <br>E:\CVSClient\Admin (管理员工作目录) <br>E:\CVSTemp (WinCVS临时目录) <br>2. 第一次启动WinCVS时会自动弹出Preferences配置页面，也可以通过Admin=&gt;Preference菜单进入；第一次使用时需要配置如下的3个页面： <br>General页面设置： <br>注：按照图示方式输入即可，需要注意的是Path部分的格式是Unix路径格式，它指的是CVSNT端设置的工作根目录。 <br>CVS页面设置： 注：Home路径是设置密码等文件的存放位置，必须指定，否则在登陆时，WinCVS也要弹出设置框。这个Home路径需要Python.exe这个外挂程序才有效。这里选择已经准备好的路径：E\CVSTemp <br>WinCVS页面设置： <br>注：此页面设置WinCVS的外挂编辑程序，通常使用UltraEdit比较方便。 <br>3. 设置管理员的工作路径：可以点按图标 ，或View=&gt;Browse Location=&gt;Change&#8230;菜单进行设置，选择已经准备好的路径：E:\CVSClient\Admin，确认，OK，这时此目录将出现在WinCVS的左边导航栏【Workspace】内。 <br>4. 至此，WinCVS就被配置成了远程的管理员使用状态，下面进行一般管理员需要的基本操作演练。演练的内容为：Administrator需要管理Jackey，Goury，Riolee三个用户，分别为这3个用户建立工作目录，每个人只能访问自己的工作目录。同时，只有Administrator能够进行权限分配，其它人没有任何管理权限。 </p>
<p class=14>5.2 管理员进行管理演练： </p>
<p>1. 登陆远程CVSNT： <br>　　◇ 选择Admin=&gt;Login菜单，默认设置，OK。 <br>　　◇ 弹出密码输入框，确认，OK。注意观察输出框【OutPut】的返回结果。 <br>2. Checkout默认模块：（CVSRoot管理模块） <br>　　◇ 在左边导航栏【Workspace】内，选择【Admin】点按右键，选择【Checkout <br>　　modules&#8230;】，在【Checkout settings】中输入CVSRoot，确定，OK。如下图： <br>　　◇ 如果成功的话，会在【Admin】栏下增加一个【CVSRoot】目录。表示您已经将【<br>　 CVSRoot】这个管理模块下载到本地了。 </p>
<p><span class=14>3. CVS中目录权限介绍：</span><br><br>◇ 系统支持的目录权限列表： <br>r (读取权限) <br>w (写入权限) <br>c (创建和删除权限) <br>n (没有任何权限) <br>◇ 默认情况下，任何用户都拥有任何目录的所有权限。 <br>◇ 任何情况下只有目录的拥有者和Administrator才有权力更改目录的使用权限。下面将会介绍如何修改目录权限和目录的拥有者。 </p>
<p class=14>4. 修改CVSRoot的权限：只让Administrator拥有rcw三种全部权限。 </p>
<p>◇ 选中刚刚下载的【CVSRoot】模块，【Ctrl+L】或Admin=&gt;Command Line&#8230;，弹出Command Line Settings对话框，直接执行CVS命令。 <br>◇ 取消所有用户的默认权限：cvs chacl default:n 回车，OK，完成。 <br>◇ 设置Administrator拥有所有权限：cvs chacl administrator:rcw 回车，OK，完成。 <br>◇ 更改【CVSRoot】的拥有者：cvs chown administrator 回车，OK，完成。 <br>◇ 查看【CVSRoot】的权限状态：cvs lsacl 回车，OK，在【Output】中显示： <br>Owner: administrator <br>default:n <br>administrator:rwc <br>◇【CVSRoot】的权限配置完毕。 </p>
<p class=14>5. 编写代码库中的模块文件，便于多用户下载方便。 </p>
<p>l 需要自己编写的模块文件格式如下：(实现基本功能) <br>【模块一的描述】【n个空格或参数】【相对目录路径一(DirA)】 <br>【模块二的描述】【n个空格或参数】【相对目录路径二(DirB)】 <br>&#8230;&#8230; <br>【模块X的描述】【n个空格或参数】【相对目录路径X(DirX)】 <br>◇【描述信息】与【相对路径】在字面上不一致时，需要使用-a参数。 <br>◇ 【相对路径】指的是CVS会自动带上根路径，这里是F:\KHRoot，所以上面例子的完整路径为：F:\KHRoot\DirA <br>◇ 了解了模块文件结构，现在来实际操作一把：双击【CVSRoot】模块下的modules文件，用UltraEdit打开进行编辑。 <br>◇ 为Jackey，Goury，Riolee三个用户分配工作目录和完成其它模块描述。 <br>CVSRoot CVSRoot <br>Jackey工作目录 -a Jackey <br>Goury工作目录 -a Goury <br>Riolee工作目录 -a Riolee <br>◇ 编辑完毕，存盘。回到WinCVS，选中modules这个文件【Ctlr+M】或右键选择【Commit selection&#8230;】，默认设置，【确认】，OK，完成上传。 </p>
<p class=14>6 . 为三个用户分别上传工作目录： </p>
<p>◇ 在YCW2000机器上的E:\CVSClient\Admin分别建立三个目录分别名为：Jackey，Goury，Riolee，作为临时交换目录。 <br>◇ 在新创建的每个目录中用UltraEdit或拷贝一个Readme.txt作为引子文件！！：） <br>◇ 然后，回到WinCVS，在【Workspace】栏的【Admin】目录下形成如下的目录结构： <br>◇ 分别选中Goury，Jackey，Riolee，右键，点按【Import Module】，选择【Continue】，其它全部使用默认值，【确定】，OK，完成上传工作。 <br>◇ 仔细观察【Output】窗口，确认都成功上传了。 <br>◇ 转移到系统的Explore程序中，删除E:\CVSClient\Admin目录下的Jackey，Goury，Riolee三个目录。然后回到WinCVS当中。(一定要删除！！！：) <br>◇ 至此，就完成了工作目录的上传工作。 </p>
<p class=14>7. 【Checkout】下载3个用户的工作目录到【Admin】目录下： </p>
<p>◇ 在【Workspace】栏选择【Admin】目录，右键，点按【Checkout Module&#8230;】,如下图： <br>◇ 选择【&#8230;】，得到CVSNT上最新的模块配置情况，弹出如下的信息框： <br>◇ 这个结构图就是刚才在modules当中编写的模块文件格式信息。选择【Jackey工作目录】，下载到YCW2000机器的E:\CVSClient\Admin目录下。 <br>◇ 按照以上操作，依次分别下载【Goury工作目录】和【Riolee工作目录】。形成如下状态： </p>
<p><br><span class=14>8. 为三个用户分别设置各自目录的访问权限。（只有自己才能访问自己的工作目录）</span> </p>
<p>◇ 选中【Goury】目录，【Ctrl+L】或Admin=&gt;Command Line&#8230;，弹出Command Line Settings对话框，直接执行CVS命令。 <br>◇ 取消所有用户的默认权限：cvs chacl default:n 回车，OK，完成。 <br>◇ 设置Goury拥有所有权限：cvs chacl goury:rcw 回车，OK，完成。 <br>◇ 查看【CVSRoot】的权限状态：cvs lsacl 回车，OK，在【Output】中显示： <br>Owner: administrator <br>default:n <br>goury:rwc <br>◇ 按照以上的方法依次分别设置【Jackey】与【Riolee】的工作目录访问权限。 <br>◇ 至此，完成了3个用户的目录权限分配。注意，虽然Administrator也没有权力再次【Checkout】那3个用户的工作目录，但是它是这些目录的拥有者又是Administrator，因此，只有它才有权力更改这些目录的访问权限。 </p>
<p><span class=15>9. CVSNT系统中的用户管理原则：</span><br><br>◇ CVSNT的用户与本机(这里是Server机器)上的NT用户是相关联的，即CVSNT用的全是本机上存在的已有用户，因此在默认情况下可以不用设置任何用户名，只要使用本机上已经存在的用户名就可以用WinCVS进行登陆。 <br>◇ 只有用Administrator身份登陆到CVSNT系统中，才有权力进行新用户的创建和删除。 <br>◇ 使用CVS创建的新用户，必须与服务器端机器上的NT用户相绑定，才能生效；因此，这个新用户实际上是绑定它的NT用户的一个替身，在CVS系统中称为&#8220;别名&#8221;。 <br>◇ 一个NT用户可以有多个&#8216;替身&#8217;或&#8216;别名&#8217;，充当多个CVS用户。 </p>
<p class=14>10. 用WinCVS进行新用户的添加和删除。(确保使用Administrator登陆) </p>
<p>◇ 【Ctrl+L】或Admin=&gt;Command Line&#8230;，弹出Command Line Settings对话框，直接执行CVS命令。 <br>◇ 添加新用户【Killer】：cvs passwd -a Killer 回车，设置密码，OK，完成。 <br>◇ 绑定【Killer】到【Jackey】：cvs passwd -r Jackey Killer 回车，设置密码，OK，完成。 <br>◇ 两次输入的密码可以不同，但以第二次输入的密码为最终密码。 <br>◇ 删除用户【Killer】：cvs passwd -X Killer 回车，OK，完成。<br>◇ 其它特殊的功能查看passwd命令的帮助。 <br><br><span class=14>11.使用完毕后，一定要【Logout】，因为WinCVS退出时并不会自动注销自己在远端的会话；这样做是为了防止其它人接着打开WinCVS，不用登陆就可以完成你能进行的所有操作了。</span></p>
<span class=14>
<p class=14><strong>6 WinCVS中常见的特殊操作： </strong></p>
<p class=14>6.1 如何删除下载的文件或目录： </p>
<p>1. 选中下载的某个或多个文件，执行【Remove】命令。 <br>2. 再次选中这些文件，执行【Commit】命令就完成了删除文件的操作。 <br>3. 本质上CVS是不会删除任何文件和目录的，即使是执行了以上操作，删除了某些文件，远端CVS实际执行的是将提交删除的文件放到了一个叫【Attic】的目录下，因此，这些被删除的文件是可以通过一定的方法恢复的。 </p>
<p class=14>6.2 如何恢复已经删除的文件或目录： </p>
<p>1. 在执行了【Remove】命令之后恢复文件。 <br>◇ 【Ctrl+L】直接输入命令cvs add xxxxx，或执行【Add Selection】界面操作。 <br>◇ 这样就可以直接恢复还未提交的删除文件。 <br>2. 在执行了【Commit】命令之后恢复文件。 <br>◇ 只能用【Ctrl+L】直接输入命令cvs add xxxxx，这时会得到一个空的文件。 <br>◇ 选中这个空文件，执行【Update】操作，得到这个文件的实体。 <br>◇ 再次选中这个文件，执行【Commit】操作，得到这个文件最新版本。 <br>3. 由于CVS系统中本质上不会删除任何目录，因此，谈不上对目录的恢复，但是CVS系统默认情况下是要在用户本机上（如：YCW2000）要删除空目录，因此，可以用如下方法得到已被删除的空目录：cvs checkout -p xxx，也可以在Admin=&gt;Preference的【Globals】页面进行设置。 <br>4. 可见，CVS系统能够保证：只要上传到服务器的文件，无论你怎么在远程进行如何的操作，正常的或非正常的操作，都可以用Administrator登陆上去，通过以上的方法找到丢失的文件。除非用户进入到远端服务器，将文件手动删除，那就没办法了：） </p>
<p><span class=14>6.3 如何得到以前版本的文件：</span><br><br>1. 有时我们需要得到以前版本的文件，而WinCVS默认方式只传递最新的版本。 <br>2. 选中某个文件，【Ctrl+G】或右键，点按【Graph selection&#8230;】，使用默认设置，就可以得到该文件所以版本的图形结构描述。 <br>3. 选中一个版本，右键，点按【Retrieve revision】，就可以得到相应的老版本文件。当然也可以得到最新版本的文件：） </p>
<p><span class=14>6.4 有时WinCVS会变得异常缓慢，怎么办？</span><br><br>1. 确认安装了WinCVS的机器上没有安装CVSNT服务器端，因为它们使用的版本有可能不一致。 <br>2. 只安装了WinCVS，但以前安装过其它版本的WinCVS，怎么办？ <br>3. 先卸载所有的WinCVS系统，删除安装目录下的残留文件。 <br>4. 打开注册表编辑器，全程查找cvs关键字，找到一个删除一个，一直到找不到为止！！：） <br>5. 重新安装WinCVS，这个问题基本上就可以解决了，我就是这样解决，不晓得你那里如何？：） </p>
<p><span class=14><strong>7 其它说明：</strong></span><br><br>1. 本文的重点在介绍如何让使用者搭建CVSNT+WinCVS这个系统，因此重点介绍了管理员的常用操作，至于一般用户使用到的操作，相对比较简单和单一，使用WinCVS的次数多了，很快就会熟悉它了。 <br>2. 这篇文档只是窥探了CVS的一点皮毛而已，CVS当中还有很多高级的用法，以及上百个命令，还有很多新鲜的管理源代码的方法，比如：tag，branch等模式；因此，热烈欢迎大家积极探索，不断共享，不断进步。。。。。。。。 <br>3. 另外，cvs.html这个帮助，里面的信息也很丰富，但是，很多地方写得不够清楚，需要不断猜测和实践才能知道怎么回事，本文的很多经验都是看这个帮助，如此这般，采用这个笨办法得到的。。。。。。 <br>4. 最后，祝愿看到此文的人，得到的帮助、提高等好处大于或等于浪费的时间、反而退步等坏处！！</p>
</span>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/34089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2007-09-27 13:50 <a href="http://www.cnitblog.com/weitom1982/archive/2007/09/27/34089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>中病毒后不能/无法显示隐藏文件怎么办</title><link>http://www.cnitblog.com/weitom1982/archive/2007/06/18/28672.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 18 Jun 2007 06:58:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2007/06/18/28672.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/28672.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2007/06/18/28672.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/28672.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/28672.html</trackback:ping><description><![CDATA[<p>有多种病毒会把一些重要文件隐藏起来,下面看看如何解决中病毒后<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">不能</strong>/无法<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>的问题,象落雪病毒就会引起这种现象，<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">不能</strong>/无法<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>是因为病毒修改了注册表的某些键值,这时我们可以采取下面的方法来<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>：</p>
<p>第一种解决<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">不能</strong>/无法<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>的方法： 把下面内容复制到记事本，保存为 1.reg文件于任何地方，然后双击就搞定了。<br>&nbsp;<br>REGEDIT4</p>
<p>[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden]<br>"Text"="隐藏文件"<br>"Type"="group"<br>"Bitmap"="C:\\WINDOWS\\SYSTEM\\SHDOC401.DLL,4"<br>"HelpID"="update.hlp#51131"</p>
<p>[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\SHOWALL]<br>"RegPath"="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"<br>"Text"="显示所有文件"<br>"Type"="radio"<br>"CheckedValue"=dword:00000000<br>"ValueName"="Hidden"<br>"DefaultValue"=dword:00000000<br>"HKeyRoot"=dword:80000001<br>"HelpID"="update.hlp#51105"</p>
<p>[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\NOHIDDEN]<br>"RegPath"="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"<br>"Text"="不<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>"<br>"Type"="radio"<br>"CheckedValue"=dword:00000000<br>"ValueName"="Hidden"<br>"DefaultValue"=dword:00000000<br>"HKeyRoot"=dword:80000001<br>"HelpID"="update.hlp#51104"</p>
<p>[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\NOHIDORSYS]<br>"RegPath"="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"<br>"Text"="不<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>或系统文件"<br>"Type"="radio"<br>"CheckedValue"=dword:00000000<br>"ValueName"="Hidden"<br>"DefaultValue"=dword:00000000<br>"HKeyRoot"=dword:80000001<br>"HelpID"="update.hlp#51103"<br>[/code]<br><strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>:<br>[code]<br>REGEDIT4</p>
<p>[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden]<br>"Text"="隐藏文件"<br>"Type"="group"<br>"Bitmap"="C:\\WINDOWS\\SYSTEM\\SHDOC401.DLL,4"<br>"HelpID"="update.hlp#51131"</p>
<p>[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\SHOWALL]<br>"RegPath"="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"<br>"Text"="显示所有文件"<br>"Type"="radio"<br>"CheckedValue"=dword:00000001<br>"ValueName"="Hidden"<br>"DefaultValue"=dword:00000000<br>"HKeyRoot"=dword:80000001<br>"HelpID"="update.hlp#51105"</p>
<p>[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\NOHIDDEN]<br>"RegPath"="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"<br>"Text"="不<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>"<br>"Type"="radio"<br>"CheckedValue"=dword:00000002<br>"ValueName"="Hidden"<br>"DefaultValue"=dword:00000000<br>"HKeyRoot"=dword:80000001<br>"HelpID"="update.hlp#51104"</p>
<p>[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\NOHIDORSYS]<br>"RegPath"="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"<br>"Text"="不<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>或系统文件"<br>"Type"="radio"<br>"CheckedValue"=dword:00000000<br>"ValueName"="Hidden"<br>"DefaultValue"=dword:00000000<br>"HKeyRoot"=dword:80000001<br>"HelpID"="update.hlp#51103"</p>
<p><br><br>我们还可以用下面的方法解决<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">不能</strong>/无法<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong>的问题,具体如下:<br>第二种方法：<br>&nbsp;有时候系统中病毒以后(例如sxs.exe和lsass(落雪病毒)),杀毒软件无法杀毒,或</p>
<p>者没有杀毒软件.这时就需要手动杀毒.这时往往需要删除病毒文件,病毒文件为了</p>
<p>保护自己,总是把自己隐藏起来.把文件属性设置成隐藏,一般的病毒我们通过修改</p>
<p>菜单:工具--文件夹选项--查看--<strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">显示隐藏文件</strong> 即可.但是很多病毒通过修改注册</p>
<p>表使我们这步操作失效,还是无法看到隐藏文件,下面的操作就是教我们如何通过</p>
<p>修改注册表让隐藏的文件原形毕露。</p>
<p>首先要显示出被隐藏的系统文件</p>
<p>运行——regedit</p>
<p>HKEY_LOCAL_MACHINE\Software\Microsoft\windows\CurrentVersion\explorer\A</p>
<p>dvanced\Folder\Hidden\SHOWALL，将CheckedValue键值修改为1</p>
<p>但可能依然没有用，隐藏文件还是没有显示，这是因为病毒在修改注册表达到隐</p>
<p>藏文件目的之后，把本来有效的DWORD值CheckedValue删除掉，新建了一个无效的</p>
<p>字符串值CheckedValue，并且把键值改为0！</p>
<p>方法：删除此CheckedValue键值，单击右键 新建——Dword值——命名为</p>
<p>CheckedValue，然后修改它的键值为1，这样就可以选择&#8220;显示所有隐藏文件&#8221;和</p>
<p>&#8220;显示系统文件&#8221;。&nbsp;</p>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/28672.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2007-06-18 14:58 <a href="http://www.cnitblog.com/weitom1982/archive/2007/06/18/28672.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows xp 进程查询</title><link>http://www.cnitblog.com/weitom1982/archive/2007/06/18/28669.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 18 Jun 2007 06:17:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2007/06/18/28669.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/28669.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2007/06/18/28669.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/28669.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/28669.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 什么是系统进程？它能做什么？                        　　进程是程序在计算机上的一次执行活动。当你运行一个程序，你就启动了一个进程。显然，程序是死的(静态的)，进程是活的(动态的)。进程可以分为系统进程和用户进程。凡是用于完成操作系统的各种功能的进程就是系统进程，它们就是处于运行状态下的操作系统本身；用户进程就是所有由你启动的进程。进程是操作系统进行资源分配的单位。　...&nbsp;&nbsp;<a href='http://www.cnitblog.com/weitom1982/archive/2007/06/18/28669.html'>阅读全文</a><img src ="http://www.cnitblog.com/weitom1982/aggbug/28669.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2007-06-18 14:17 <a href="http://www.cnitblog.com/weitom1982/archive/2007/06/18/28669.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编译原理学习导论 </title><link>http://www.cnitblog.com/weitom1982/archive/2007/01/23/22238.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Tue, 23 Jan 2007 05:08:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2007/01/23/22238.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/22238.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2007/01/23/22238.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/22238.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/22238.html</trackback:ping><description><![CDATA[
		<h2> </h2>
		<p>大学课程为什么要开设编译原理呢？这门课程关注的是编译器方面的产生原理和技术问题，似乎和计算机的基础领域不沾边，可是编译原理却一直作为大学本科的必修课程，同时也成为了研究生入学考试的必考内容。编译原理及技术从本质上来讲就是一个算法问题而已，当然由于这个问题十分复杂，其解决算法也相对复杂。我们学的数据结构与算法分析也是讲算法的，不过讲的基础算法，换句话说讲的是算法导论，而编译原理这门课程讲的就是比较专注解决一种的算法了。在20世纪50年代，编译器的编写一直被认为是十分困难的事情，第一Fortran的编译器据说花了18年的时间才完成。在人们尝试编写编译器的同时，诞生了许多跟编译相关的理论和技术，而这些理论和技术比一个实际的编译器本身价值更大。就犹如数学家们在解决著名的哥德巴赫猜想一样，虽然没有最终解决问题，但是其间诞生不少名著的相关数论。</p>
		<p>推荐参考书</p>
		<p>虽然编译理论发展到今天，已经有了比较成熟的部分，但是作为一个大学生来说，要自己写出一个像Turboc C,Java那样的编译器来说还是太难了。不仅写编译器困难，学习编译原理这门课程也比较困难。</p>
		<p>正是因为编译原理学习相对困难，那么就要求有好的教师和好的教材。教师方面不是我们能自己更改的，而在教材方面我们却可以按自己的意愿来阅读。我下面推荐几本好的编译原理的教材。我推荐的书籍都是国外的经典教材，因为在国内的教材中，确实还没发现什么让人满意的。</p>
		<p>第一本书的原名叫《Compilers Principles,Techniques,and Tools》,另外一个响亮的名字就是龙书。原因是这本书的封面上有条红色的龙，也因为獗臼樵诒嘁朐?砘?×煊蛉肥堤?忻???所以很多国外的学者都直接取名为龙书。最近机械工业出版社已经出版了此书的中文版，名字就叫《编译原理》。该书出的比较早，大概是在85或86年编写完成的，作者之一还是著名的贝尔实验室的科学家。里面讲解的核心编译原理至今都没有变过，所以一直到今天，它的价值都非凡。这本书最大的特点就是一开始就通过一个实际的小例子，把编译原理的大致内容罗列出来，让很多编译原理的初学者很快心里有了个底,也知道为什么会有这些理论，怎么运用这些理论。而这一点是我感觉国内的教材缺乏的东西，所以国内的教材都不是写给愿意自学的读者，总之让人看了半天，却不知道里面的东西有什么用。</p>
		<p>第二本书的原名叫《Modern Compiler Design》,中文名字叫做《现代编译程序设计》。该书由人民邮电出版社所出。此书比较关注的是编译原理的实践，书中给出了不少的实际程序代码，还有很多实际的编译技术问题等等。此书另外一个特点就是其“现代”而字。在传统的编译原理教材中，你是不可能看到如同Java中的“垃圾回收”等算法的。因为Java这样的解释执行语言是在近几年才流行起来的东西。如果你想深入学习编译原理的理论知识，那么你肯定得看前面那本龙书，如果你想自己动手做一个先进的编译器，那么你得看这本《现代编译程序设计》。</p>
		<p>第三本书就是很多国内的编译原理学者都推荐的那本《编译原理及实践》。或许是这本书引入国内比较早吧，我记得我是在高中就买了这本书，不过也是在前段时间才把整本书看完。此书作为入门教程也的确是个不错的选择。书中给出的编译原理讲解也相当细致，虽然不如前面的龙书那么深入，但是很多地方都是点到为止，作为大学本科教学已经是十分深入了。该书的特点就是注重实践，不过感觉还不如前面那本《现代编译程序设计》的实践味道更重。此书的重点还是在原理上的实践，而非前面那本那样的技术实践。《编译原理及实践》在讲解编译原理的各个部分的同时，也在逐步实践一个现代的编译器Tiny C.等你把整本书看完，差不多自己也可以写一个Tiny C了。作者还对Lex和Yacc这两个常用的编译相关的工具进行了很详细的说明，这一点也是很难在国内的教材中看到的。</p>
		<p>推荐了这三本教材，都有英文版和中文版的。很多英文好的同学只喜欢看原版的书，不我的感觉是这三本书的翻译都很不错，没有必要特别去买英文版的。理解理论的实质比理解表面的文字更为重要。</p>
		<p>编译原理的实质</p>
		<p>前面已经说过，学习编译原理其实也就是学习算法而已，没什么特别的。只不过这些算法的产生已经形成了一套理论。下面我来看看编译原理里面到底有什么高深的理论吧。</p>
		<p>几乎每本编译原理的教材都是分成词法分析，语法分析（LL算法，递归下降算法，LR算法），语义分析，运行时环境，中间代码，代码生成，代码优化这些部分。其实现在很多编译原理的教材都是按照85,86出版的那本龙书来安排教学内容的，所以那本龙书的内容格式几乎成了现在编译原理教材的定式，包括国内的教材也是如此。一般来说，大学里面的本科教学是不可能把上面的所有部分都认真讲完的，而是比较偏重于前面几个部分。像代码优化那部分东西，就像个无底洞一样，如果要认真讲，就是单独开一个学期的课也不可能讲得清楚。所以，一般对于本科生，对词法分析和语法分析掌握要求就相对要高一点了。</p>
		<p>词法分析相对来说比较简单。可能是词法分析程序本身实现起来很简单吧，很多没有学过编译原理的人也同样可以写出各种各样的词法分析程序。不过编译原理在讲解词法分析的时候，重点把正则表达式和自动机原理加了进来，然后以一种十分标准的方式来讲解词法分析程序的产生。这样的做法道理很明显，就是要让词法分析从程序上升到理论的地步。</p>
		<p>语法分析部分就比较麻烦一点了。现在一般有两种语法分析算法，LL自顶向下算法和LR自底向上算法。LL算法还好说，到了LR算法的时候，困难就来了。很多自学编译原理的都是遇到LR算法的理解成问题后就放弃了自学。其实这些东西都是只要大家理解就可以了，又不是像词法分析那样非得自己写出来才算真正的会。像LR算法的语法分析器，一般都是用工具Yacc来生成，实践中完全没有比较自己来实现。对于LL算法中特殊的递归下降算法，因为其实践十分简单，那么就应该要求每个学生都能自己写。当然，现在也有不少好的LL算法的语法分析器，不过要是换在非C平台，比如Java,Delphi,你不能运用YACC工具了，那么你就只有自己来写语法分析器。</p>
		<p>等学到词法分析和语法分析时候，你可能会出现这样的疑问：“词法分析和语法分析到底有什么？”就从编译器的角度来讲，编译器需要把程序员写的源程序转换成一种方便处理的数据结构（抽象语法树或语法树）,那么这个转换的过程就是通过词法分析和语法分析的。其实词法分析并非一开始就被列入编译器的必备部分，只是我们为了简化语法分析的过程，就把词法分析这种繁琐的工作单独提取出来，就成了现在的词法分析部分。除了编译器部分，在其它地方，词法分析和语法分析也是有用的。比如我们在DOS,Unix,Linux下输入命令的时候，程序如何分析你输入的命令形式，这也是简单的应用。总之，这两部分的工作就是把不“规则”的文本信息转换成一种比较好分析好处理的数据结构。那么为什么编译原理的教程都最终把要分析的源分析转换成“树”这种数据结构呢？数据结构中有Stack, Line,List…这么多数据结构，各自都有各自的特点。但是Tree这种结构有很强的递归性，也就是说我们可以把Tree的任何结点Node提取出来后，它依旧是一颗完整的Tree。这一点符合我们现在编译原理分析的形式语言，比如我们在函数里面使用函树，循环中使用循环，条件中使用条件等等，那么就可以很直观地表示在Tree这种数据结构上。同样，我们在执行形式语言的程序的时候也是如此的递归性。在编译原理后面的代码生成的部分，就会介绍一种堆栈式的中间代码，我们可以根据分析出来的抽象语法树，很容易，很机械地运用递归遍历抽象语法树就可以生成这种指令代码。而这种代码其实也被广泛运用在其它的解释型语言中。像现在流行的Java,.NET，其底层的字节码bytecode,可以说就是这中基于堆栈的指令代码的。</p>
		<p>关于语义分析，语法制导翻译，类型检查等等部分，其实都是一种完善前面得到的抽象语法树的过程。比如说，我们写C语言程序的时候，都知道，如果把一个浮点数直接赋值给一个整数，就会出现类型不匹配，那么C语言的编译器是怎么知道的呢？就是通过这一步的类型检查。像C++语言这中支持多态函数的语言，这部分要处理的问题就更多更复杂了。大部编译原理的教材在这部分都是讲解一些比较好的处理策略而已。因为新的问题总是在发生，旧的办法不见得足够解决。</p>
		<p>本来说，作为一个编译器，起作用的部分就是用户输入的源程序到最终的代码生成。但是在讲解最终代码生成的时候，又不得不讲解机器运行环境等内容。因为如果你不知道机器是怎么执行最终代码的，那么你当然无法知道如何生成合适的最终代码。这部分内容我自我感觉其意义甚至超过了编译原理本身。因为它会把一个计算机的程序的运行过程都通通排在你面前，你将来可能不会从事编译器的开发工作，但是只要是和计算机软件开发相关的领域,都会涉及到程序的执行过程。运行时环境的讲解会让你更清楚一个计算机程序是怎么存储，怎么装载，怎么执行的。关于部分的内容，我强烈建议大家看看龙书上的讲解，作者从最基本的存储组织，存储分配策略，非局部名字的访问，参数传递，符号表到动态存储分配(malloc,new)都作了十分详细的说明。这些东西都是我们编写平常程序的时候经常要做的事情，但是我们却少去探求其内部是如何完成。</p>
		<p>关于中间代码生成，代码生成,代码优化部分的内容就实在不好说了。国内很多教材到了这部分都会很简单地走马观花讲过去，学生听了也只是作为了解，不知道如何运用。不过这部分内容的东西如果要认真讲，单独开一学期的课程都讲不完。在《编译原理及实践》的书上，对于这部分的讲解就恰到好处。作者主要讲解的还是一种以堆栈为基础的指令代码，十分通俗易懂，让人看了后，很容易模仿，自己下来后就可以写自己的代码生成。当然，对于其它代码生成技术，代码优化技术的讲解就十分简单了。如果要仔细研究代码生成技术，其实另外还有本叫做《Advance Compiler Desgin and Implement》,那本书现在由机械工业出版社引进的，十分厚重，而且是英文原版。不过这本书我没有把它列为推荐书给大家，毕竟能把龙书的内容搞清楚，在中国已经就算很不错的高手了，到那个时候再看这本《Advance Compiler Desgin and Implement》也不迟。代码优化部分在大学本科教学中还是一个不太重要的部分，就是算是实践过程中，相信大家也不太运用得到。毕竟，自己做的编译器能正确生成执行代码已经很不错了，还谈什么优化呢？</p>
		<p>关于实践</p>
		<p>编译原理的课程毕竟还只是讲解原理的课程，不是专门的编译技术课程。这两门课程是有很大的区别的。编译技术更关注实际的编写编译器过程中运用到的技术，而原理的课关注讲解其基本理论。但是计算机科学本身就是一门实践性很强的课程，如果能够学以致用，那才叫真正的学会。李阳在讲解疯狂英语的时候就说到，只要当你会实际中运用一个单词一个词组的时候你才能叫学会了这个单词或者词组，而不是只是知道了它的拼写和意思。其实任何学习都是一样的，如果缺少了实践的结合，你不能算学会。</p>
		<p>编译原理的课程主要就是讲解编译器产生的理论和原理，那么很简单，自己写个编译器就是最好的实践过程了。不过你得小心，编译系统可能是所有软件系统中最复杂的系统之一,不然为什么大学里面还会把编译器的编写开成一门叫做编译原理的课程来讲？我很佩服那些学了操作系统原理就开始自己写操作系统，学了编译原理就开始自己写编译器的人们，确实，在中国，敢这么做的学生太少了。且不管你这样做能不能做成功，至少有了这个尝试，会让你的程序设计，系统规划安排的功底增进不少。我下面给出一些关于实践过程中可能会遇到的困难，希望能够在你陷入困境的前帮你一把。</p>
		<p>1. Lex和Yacc. 这两工具是作为词法分析很语法分析的工具。如果你自己写一个编译器，我十分不建议你连词法分析这种事情都亲手来写。Lex和Yacc应该是作为每本编译原理的教材的必备内容，可是在国内的教材中缺很少看到。这两个工具是Unix系统下的小东西，如果你要在Windows中运用，那么你最好去下在cygwin这个软件。它是个在Windows下模拟Unix的东东，里面就包含了flex.exe和bison.exe(yacc)这两个工具.这两个工具使用起来还挺麻烦的(其实unix 下的很多十分有用的工具都是这样), 不过在《编译原理与实践》这本书上对于这两个工具的讲解十分详细,还列举了不少实际的例子。</p>
		<p>2. 做解释型语言比做生成机器代码的编译器简单。虽然说，做解释型的编译器，像Java那样的，你还得自己去写解释器，不过这样你就不必去查找机器代码的资料了。如果你做生成的最终机器代码编译器可能会遇到问题还有就是寄存器为基础的代码生成方法。前面说过，如果你生成的是以堆栈为基础的代码，那么其代码生成过程十分简单，需要考虑的东西也不多，如果你考虑最终的机器代码生成的话，你必须考虑机器的寄存器如何分配等麻烦的问题。</p>
		<p>3. 考虑用别人已经生成的语法文件，尽量不要自己动手写词法文件和语法文件.以前一个朋友曾经说过,写出一个好的程序语言的语法定义,就几乎完成了一个编译器的一半.确实是这样,语法文件的编写是个很难的事情.现在网上到处都可以找到比如C语言,C++,Java, Tiny C,Minus C等语言的词法文件和语法文件,你完全可以自己下下来来用.</p>
		<p>在《编译原理及实践》的书中，作者给出了一个Tiny C的全部代码.我自我感觉作者的这个编译器做得很不错,相对于其它php,perl等语言的源代码来说,简单得多,容易看懂,而且很清晰地展现了一个完成的编译系统的实现过程.其源代码可以在作者的网站上下载</p>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/22238.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2007-01-23 13:08 <a href="http://www.cnitblog.com/weitom1982/archive/2007/01/23/22238.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>how to write a os </title><link>http://www.cnitblog.com/weitom1982/archive/2007/01/23/22237.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Tue, 23 Jan 2007 05:07:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2007/01/23/22237.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/22237.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2007/01/23/22237.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/22237.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/22237.html</trackback:ping><description><![CDATA[
		<h2>QUOTE<br />作者：伊梅 本文选自：开放系统世界——赛迪网 2002年10月10日</h2>
		<p>
				<br />自由软件社区是一个充满自由和梦想的地方，在10余年的时间里它创造了一个又一个奇迹。然而，这些奇迹的创造者不只是Stallman，也不只是Linus Torvalds，而是活跃在世界各地的不计其数的开发人员。 </p>
		<p>在使用各种功能强大的自由软件时，我总会对其开发者充满崇敬之情，期盼有朝一日自己也能成为他们中的一员。很多对自由社区充满向往之情的人，虽然也想努力融身于其中，但又不知该怎么做。那么，就请与我们一起从编写一个简单的操作系统开始吧！ </p>
		<p>
				<br />我们要做的事情</p>
		<p>
				<br />有人可能担心自己既没有学过计算机原理，也没有学过操作系统原理，更不懂汇编语言，对C语言也一知半解，能写操作系统吗？答案是没问题。我将带大家一步一步完成自己的操作系统。当然如果学一学上述内容再好不过。 </p>
		<p>首先要明确处理器(也就是CPU)控制着计算机。对PC而言，启动的时候，CPU都处在实模式状态，相当于只是一个Intel 8086处理器。也就是说，即使你现在拥有一个奔腾处理器，它的功能也只能是8086级别。从这一点上来讲，可以使用一些软件把处理器转换到著名的保护模式。只有这样，我们才可以充分利用处理器的强大功能。 </p>
		<p>编写操作系统开始是对BIOS控制，取出存储在ROM里的程序。BIOS是用来执行POST(Power On Self Test，自检)的。自检是检查计算机的完整性(比如外设是否工作正常、键盘是否连接等)。这一切完成以后，你就会听到PC喇叭发出一声清脆的响声。如果一切正常，BIOS就会选择一个启动设备，并且读取该设备的第一扇区(即启动扇区)，然后控制过程就会转移到指定位置。启动设备可能是一个软盘、光盘、硬盘，或者其它所选择的设备。在此我们把软盘作为启动设备。如果我们已经在软盘的启动扇区里写了一些代码，这时它就被执行。因此，我们的目的很明确，就是往软盘的启动扇区写一些程序。 </p>
		<p>首先使用8086汇编来写一个小程序，然后将其拷贝至软盘的启动扇区。为了实现拷贝，要写一个C程序。最后，使用软盘启动计算机。 </p>
		<p>
				<br />需要的工具</p>
		<p>
				<br />● as86：这是一个汇编程序，它负责把写的代码转换成目标文件。 </p>
		<p>● ld86：这是一个连接器，as86产生的目标代码由它来转换成真正的机器语言。机器语言是8086能够解读的形式。 </p>
		<p>● GCC：著名的C编程器。因为我们需要写一个C程序将自己的OS转移到软盘中。 </p>
		<p>● 一张空软盘：它用于存储编写的操作系统，也是启动设备。 </p>
		<p>● 一台装有Linux的计算机：这台机器可以很旧，386、486都可以。 </p>
		<p>在大部分标准Linux发行版中都会带有as86和ld86。在我使用的Red Hat 7.3中就包含有这两个工具，并且在默认的情况下，它已经安装在机器里。如果使用的Linux没有这两个工具，可以从网上下载(<a href="http://www.cix.co.uk/~mayday/">http://www.cix.co.uk/~mayday/</a>)，这两个工具都包含在一个名为bin86的软件包中。此外，有关的文档也可以在网上获得(<a href="http://www.linux.org/docs/ldp/howto/Assembly-HOWTO/as86.html">www.linux.org/docs/ldp/howto/Assembly-HOWTO/as86.html</a>)。 </p>
		<p>
				<br />开始工作</p>
		<p>
				<br />使用一个你喜欢的编辑器输入以下内容： </p>
		<p>entry start<br />start:<br />      mov ax,#0xb800<br />      mov es,ax<br />      seg es<br />      mov [0],#0x41<br />      seg es<br />      mov [1],#0x1f<br />loop1: jmp loop1</p>
		<p> </p>
		<p>这是as86可以读懂的一段汇编程序。第一个句子指明了程序的入口点，声明整个过程从start处开始。第二行指明了start的位置，说明整个程序要从start处开始执行。0xb800是显存的开始地址。#表明其后是一个立即数。执行语句： </p>
		<p>mov ax,#oxb800</p>
		<p> </p>
		<p>ax寄存器的值就变为0xb800，这就是显存的地址。下面再将这个值移至es寄存器，es是附加段寄存器。请记住8086有一个分段的体系结构。它的各段寄存器为代码段、数据段、堆栈段和附加段，对应的寄存器名称分别为cs、ds、ss和es。事实上，我们把显存地址送入了附加段，因此，任何送入附加段的东西都会被送到显存中。 </p>
		<p>要在屏幕上显示字符，就需要向显存中写两个字节。前一个是所要显示字符的ASCⅡ值，第二个字节表示该字符的属性。属性包括字符的前景色、背景色及是否闪烁等等。seg es指明下一个将要执行的指令是指向es段的。所以，我们把值0x41(在ASCⅡ中表示的字符是A)送到显存的第一个字节中。接下来要把字符的属性送到下一个字节当中。在此输入的是0x1f，该属性指的是在蓝色背景下显示白色的字符。因此，如果执行这个程序，就可以在屏幕上得到显示在蓝底上的一个白色的A。接着是一个循环。因为在执行完显示字符的任务后，要么让程序结束，要么使用一个循环使其永远运行下去。把该文件命名为boot.s，然后存盘。 </p>
		<p>此处显存的概念说得不是很清楚，有必要进一步解释一下。假设屏幕由80列×25行组成，那么第一行就需要160字节，其中一个字节用于表示字符，另外一个字节用于表示字符的属性。如果要在第三行显示某一字符的话，就要跳过显存的第0和1字节(它们是用于显示第1列的)，第2和3字节(它们是用于显示第2列的)，然后把需要显示字符的ASCⅡ码值入第4字节，把字符的属性写入第5字节。 </p>
		<p>
				<br />把程序写至启动扇区</p>
		<p>
				<br />下面写一个C程序，把我的操作系统写入软盘第一扇区。程序内容如下： </p>
		<p>#include  /* unistd.h 需要这个文件 */<br />#include     /* 包含有read和write函数 */<br />#include <br />int main()<br />{<br />  char boot_buf[512];<br />   int floppy_desc, file_desc;<br />  file_desc = open("./boot", O_RDONLY);<br />  read(file_desc, boot_buf, 510);<br />  close(file_desc);<br />  boot_buf[510] = 0x55;<br />  boot_buf[511] = 0xaa;<br />  floppy_desc = open("/dev/fd0", O_RDWR);<br />  lseek(floppy_desc, 0, SEEK_CUR);<br />  write(floppy_desc, boot_buf, 512);<br />  close(floppy_desc);<br />}</p>
		<p> </p>
		<p>首先，以只读模式打开boot文件，然后在打开文件时把文件描述符复制到file_desc变量中。从文件中读取510个字符，或者读取直到文件结束。在本例中由于文件很小，所以是读取至文件结束。然后关闭文件。 </p>
		<p>最后4行代码打开软盘驱动设备(一般来说是/dev/fd0)。使用lseek找到文件开始处，然后从缓冲中向软盘写512个字节。 </p>
		<p>在read、write、open和lseek的帮助页中，可以看到与函数所有有关的参数及其使用方法。程序中有两行比较难懂： </p>
		<p>boot_buf[510] = 0x55;<br />boot_buf[511] = 0xaa;</p>
		<p> </p>
		<p>该信息是用于BIOS的，如果它识别出该设备是一个可启动的设备，那么在第510和511的位置，该值就应该是0x55和0xaa。程序会把文件boot读至名为boot_buf的缓冲中。它要求改变第510和第511字节，然后把boot_buf写至软盘之上。如果执行代码，软盘上的前512字节就包含了启动代码。最后，把文件存为write.c。 </p>
		<p>
				<br />编译运行</p>
		<p>
				<br />使用下面的命令把文件变为可执行文件： </p>
		<p>as86 boot.s -o boot.o<br />ld86 -d boot.o -o boot<br />cc write.c -o write</p>
		<p> </p>
		<p>首先将boot.s文件编译成目标文件boot.o，然后将该文件连接成最终的boot文件。最后C程序编译成可执行的write文件。 </p>
		<p>插入一个空白软盘，运行以下程序： </p>
		<p>./write</p>
		<p> </p>
		<p>重新启动电脑，进行BIOS的界面设置，并且把软盘设为第一个启动的设备。然后插入软盘，电脑从软盘上启动。 </p>
		<p>启动完成后，在屏幕上可以看到一个字母A(蓝底白字)，启动速度很快，几乎是在瞬间完成。这就意味着系统已经从我们制作的软盘上启动了，并且执行了刚才写入启动扇区的程序。现在，它正处在一个无限循环的状态。所以，如果想进入Linux，必需拿掉软盘，并且重启机器。 </p>
		<p>至此，这个操作系统就算完成了，虽然它没有实现什么功能，但是它已经可以启动机器了<br />上一期，我讲述了如何在软盘的启动扇区写一些代码，然后再从软盘启动的过程。制作好一个启动扇区，在切换到保护模式之前，我们还应该知道如何使用BIOS中断。BIOS中断是一些由BIOS提供的、为了使操作系统的创建更容易的低级程序。在本文中，我们将学习处理BIOS的中断。 </p>
		<p>
				<br />为什么要用BIOS</p>
		<p>
				<br />BIOS会把启动扇区拷贝至RAM中，并且执行这些代码。除此之外，BIOS还要做很多其它的事情。当一个操作系统刚开始启动时，系统中并没有显卡驱动、软盘驱动等任何驱动程序。因此，启动扇区中不可能包含任何一个驱动程序，我们要采取其它的途径。这个时候，BIOS就可以帮助我们了。BIOS中包含有各种可以使用的程序，包括检测安装的设备、控制打印机、计算内存大小等用于各种目的的程序。这些程序就是所说的BIOS中断。 </p>
		<p>
				<br />如何调用BIOS中断</p>
		<p>
				<br />在一般的程序设计语言中，函数的调用是一件非常容易的事情。比如在C语言中，如果有一个名为display的程序，它带有两个参数，其中参数noofchar表示显示的字符数，参数attr表示显示字符的属性。那么要调用它，只需给出程序的名称即可。对于中断的调用，我们使用的是汇编语言中的int指令。 </p>
		<p>比如，在C语言中要显示一些东西时，使用的指令如下所示： </p>
		<p>display(nofchar，attr)；</p>
		<p>
				<br />而使用BIOS时，要实现相同功能使用的指令如下： </p>
		<p>int 0x10</p>
		<p>
				<br />如何传递参数</p>
		<p>
				<br />在调用BIOS中断之前，我们需要先往寄存器中送一些特定的值。假设要使用BIOS的中断13h，该中断的功能是把数据从软盘传送至内存之中。在调用该中断之前，要先指定拷贝数据的段地址，指定驱动器号、磁道号、扇区号，以及要传送的扇区数等等。然后，就要往相应的寄存器送入相应的值。在进行下面的步骤前，读者有必要对这一点有比较明确地认识。 </p>
		<p>此外，一个比较重要的事实是同一个中断往往可以实现各种不同的功能。中断所实现的确切功能取决于所选择的功能号，功能号一般都存在ah寄存器之中。比如中断13h可以用于读磁盘、写磁盘等功能，如果把3送入ah寄存器中，那么中断选择的功能就是写磁盘；如果把2送入ah寄存器中，选择的功能则是读磁盘等。 </p>
		<p>
				<br />我们要做的事情</p>
		<p>
				<br />这次我们的源代码由两个汇编语言程序和一个C程序组成。第一个汇编文件是引导扇区的代码。在引导扇区中，我们写的代码是要把软盘中第二扇区拷贝至内存段的0x500处(地址是0x5000，即偏移地址为0)。这时我们需要使用BIOS的中断13h。这时启动扇区的代码就会把控制权转移至0x500处。在第二个汇编文件中，代码会使用BIOS中断10h在屏幕上显示一个信息。C程序实现的功能则是把可执行的文件1拷贝至启动扇区，把可执行的文件2拷贝至软盘的第二扇区。 </p>
		<p>
				<br />启动扇区代码</p>
		<p>
				<br />使用中断13h，启动扇区把软盘第二扇区里的内容加载至内存的0x5000处(段地址为0x500)。下面的代码是用于实现这一目的的代码，将其保存至文件sbect.s中。 </p>
		<p>LOC1=0x500<br />entry start<br />start:<br />mov ax,#LOC1<br />mov es,ax<br />mov bx,#0 <br />mov dl,#0 <br />mov dh,#0 <br />mov ch,#0 <br />mov cl,#2 <br />mov al,#1 <br />mov ah,#2 <br />int 0x13<br />jmpi 0,#LOC1</p>
		<p>
				<br />上面代码第一行类似于一个宏。接下去的两行则是把值0x500加载至es寄存器中，这是软盘上第二扇区代码将拷贝到的地方(第一扇区是启动扇区)。这时，把段内的偏移设为0。 </p>
		<p>接下来把驱动器号送入dl寄存器中，其中磁头号送入dl寄存器中，磁道号送入ch寄存器中，扇区号送入cl寄存器中，扇区数送入al寄存器之中。我们想要实现的功能是把扇区2、磁道号为0、驱动器号为0的内容送至段地址0x500处。所有这些参数都和1.44MB的软盘相对应。 </p>
		<p>把2送入ah寄存器中，是选择了由中断13h提供的相应功能，即实现从软驱转移数据的功能。 </p>
		<p>最后调用中断13h，并且转至偏移为0的段地址0x500处。 </p>
		<p>
				<br />第二个扇区的代码</p>
		<p>
				<br />第二个扇区中的代码如下所示(把这些代码保存至文件sbect2.s之中)： </p>
		<p>entry start<br />start:<br />mov ah,#0x03 <br />xor bh,bh<br />int 0x10</p>
		<p>mov cx,#26 <br />mov bx,#0x0007 <br />mov bp,#mymsg<br />mov ax,#0x1301 <br />int 0x10</p>
		<p>loop1: jmp loop1<br />mymsg:<br />.byte 13,10<br />.ascii “Operating System is Loading......”</p>
		<p>
				<br />上面代码将被加载至段地址为0x500处，并且被执行。在这段代码中，使用了中断10h来获取目前的光标位置，然后显示信息。 </p>
		<p>从第3行到第5行用于得到目前光标的位置，在此中断10h选用的是功能3。然后，清除了bh寄存器的内容，并把字符串送至ch寄存器中。在bx中，我们送入了页码及显示的属性。此处，我们想要在黑背景上显示白色的字符。然后，把要显示字符的地址送到bp之中，信息由两个字节组成，其值分别为13的10，它们分别对应回车和LF(换行)的ASCⅡ值。接下来是一个由29个字符组成的串；在下面实现的功能是输出字符串然后移动光标；最后是调用中断，然后进入循环。 </p>
		<p>
				<br />C程序代码</p>
		<p>
				<br />C程序的源代码如下所示，将其存储为write.c文件。 </p>
		<p>#include &lt;sys/types.h&gt; /* unistd.h needs this */<br />#include &lt;unistd.h&gt; /* contains read/write */<br />#include &lt;fcntl.h&gt;<br />int main()<br />{<br />char boot_buf[512];<br />int floppy_desc, file_desc;<br />file_desc = open(“./bsect”, O_RDONLY);<br />read(file_desc, boot_buf, 510);<br />close(file_desc);<br />boot_buf[510] = 0x55;<br />boot_buf[511] = 0xaa;<br />floppy_desc = open(“/dev/fd0”, O_RDWR);<br />lseek(floppy_desc, 0, SEEK_SET);<br />write(floppy_desc, boot_buf, 512);<br />file_desc = open(“./sect2”, O_RDONLY);<br />read(file_desc, boot_buf, 512);<br />close(file_desc);<br />lseek(floppy_desc, 512, SEEK_SET);<br />write(floppy_desc, boot_buf, 512);<br />close(floppy_desc);<br />}</p>
		<p>
				<br />在上一期中，我曾经介绍过如何操作能启动的软盘。现在这一个过程稍微有点不同，首先把由bsect.s编译出来的可执行文件bsect拷贝至软盘的启动扇区。然后再把由sect2.s产生的可执行文件sect2拷贝至软盘的第二个扇区。 </p>
		<p>把上述文件置于同一目录之下，然后分别对其进行编译，方法如下所示： </p>
		<p>as86 bsect.s -o bsect.o<br />ld86 -d bsect.o -o bsect</p>
		<p>
				<br />对sect2.s文件重复以上的操作，得出可执行文件sect2。编译write.c，插入软盘后执行write文件，命令如下所示： </p>
		<p>cc write.c -o write<br />./write</p>
		<p>
				<br />下一步我们要做的事情</p>
		<p>
				<br />从软盘启动以后，可以看到显示出来的字符串。这是使用了BIOS中断来完成的。下一期要做的事情是在这个操作系统中实现实模式向保护模式的转换。</p>
		<p> </p>
		<p>
				<br />--------------------------------------------------------------------------------<br />htldm 回复于：2002-12-17 15:22:55 <br />现在，这个操作系统已经越来越接近当年Linus Torvalds的那个具有“历史意义”的Linux内核了。因此，要马上把这个系统切换到保护模式之下。 </p>
		<p>什么是保护模式</p>
		<p>自从1969年推出第一个微处理器以来，Intel处理器就在不断地更新换代，从8086、8088、80286，到80386、80486、奔腾、奔腾Ⅱ、奔腾4等，其体系结构也在不断变化。80386以后，提供了一些新的功能，弥补了8086的一些缺陷。这其中包括内存保护、多任务及使用640KB以上的内存等，并仍然保持和8086家族的兼容性。也就是说80386仍然具备了8086和80286的所有功能，但是在功能上有了很大的增强。早期的处理器是工作在实模式之下的，80286以后引入了保护模式，而在80386以后保护模式又进行了很大的改进。在80386中，保护模式为程序员提供了更好的保护，提供了更多的内存。事实上，保护模式的目的不是为了保护程序，而是要保护程序以外的所有程序（包括操作系统）。 </p>
		<p>简言之，保护模式是处理器的一种最自然的模式。在这种模式下，处理器的所有指令及体系结构的所有特色都是可用的，并且能够达到最高的性能。 </p>
		<p>保护模式和实模式</p>
		<p>从表面上看，保护模式和实模式并没有太大的区别，二者都使用了内存段、中断和设备驱动来处理硬件，但二者有很多不同之处。我们知道，在实模式中内存被划分成段，每个段的大小为64KB，而这样的段地址可以用16位来表示。内存段的处理是通过和段寄存器相关联的内部机制来处理的，这些段寄存器（CS、DS、SS和ES）的内容形成了物理地址的一部分。具体来说，最终的物理地址是由16位的段地址和16位的段内偏移地址组成的。用公式表示为： </p>
		<p>物理地址=左移4位的段地址+偏移地址。 </p>
		<p>在保护模式下，段是通过一系列被称之为“描述符表”的表所定义的。段寄存器存储的是指向这些表的指针。用于定义内存段的表有两种：全局描述符表(GDT)和局部描述符表(LDT)。GDT是一个段描述符数组，其中包含所有应用程序都可以使用的基本描述符。在实模式中，段长是固定的(为64KB)，而在保护模式中，段长是可变的，其最大可达4GB。LDT也是段描述符的一个数组。与GDT不同，LDT是一个段，其中存放的是局部的、不需要全局共享的段描述符。每一个操作系统都必须定义一个GDT，而每一个正在运行的任务都会有一个相应的LDT。每一个描述符的长度是8个字节，格式如图3所示。当段寄存器被加载的时候，段基地址就会从相应的表入口获得。描述符的内容会被存储在一个程序员不可见的影像寄存器(shadow register)之中，以便下一次同一个段可以使用该信息而不用每次都到表中提取。物理地址由16位或者32位的偏移加上影像寄存器中的基址组成。实模式和保护模式的不同可以从图1和图2中很清楚地看出来。</p>
		<p>
				<br />图1 实模式的寻址</p>
		<p>
				<br />图2 保护模式下的寻址</p>
		<p>
				<br />图3 段描述俯的格式</p>
		<p>此外，还有一个中断描述符表(IDT)。这些中断描述符会告诉处理器到那里可以找到中断处理程序。和实模式一样，每一个中断都有一个入口，但是这些入口的格式却完全不同。因为在切换到保护模式的过程中没有使用到IDT，所以在此就不多做介绍了。 </p>
		<p>进入保护模式</p>
		<p>80386有4个32位控制寄存器，名字分别为CR0、CR1、CR2和CR3。CR1是保留在未来处理器中使用的，在80386中没有定义。CR0包含系统的控制标志，用于控制处理器的操作模式和状态。CR2和CR3是用于控制分页机制的。在此，我们关注的是CR0寄存器的PE位控制，它负责实模式和保护模式之间的切换。当PE=1时，说明处理器运行于保护模式之下，其采用的段机制和前面所述的相应内容对应。如果PE=0，那么处理器就工作在实模式之下。 </p>
		<p>切换到保护模式，实际就是把PE位置为1。为了把系统切换到保护模式，还要做一些其它的事情。程序必须要对系统的段寄存器和控制寄存器进行初始化。把PE位置1后，还要执行跳转指令。过程简述如下： </p>
		<p>1.创建GDT表; </p>
		<p>2.通过置PE位为1进入保护模式; </p>
		<p>3.执行跳转以清除在实模式下读取的任何指令。 </p>
		<p>下面使用代码来实现这个切换过程。 </p>
		<p>需要的东西</p>
		<p>◆ 一张空白软盘 </p>
		<p>◆ NASM编译器 </p>
		<p>下面是整个程序的源代码： </p>
		<p>org 0x07c00; 起始地址是0000:7c00 <br />jmp short begin_boot ; 跳过其它的数据，跳转到引导程序的开始处<br />bootmesg db "Our OS boot sector loading ......"<br />pm_mesg db "Switching to protected mode ...."<br />dw 512 ; 每一扇区的字节数<br />db 1 ; 每一簇的扇区数<br />dw 1 ; 保留的扇区号<br />db 2<br />dw 0x00e0 <br />dw 0x0b40 <br />db 0x0f0 <br />dw 9 <br />dw 18 <br />dw 2 ; 读写扇区号<br />dw 0 ; 隐藏扇区号<br />print_mesg :<br />mov ah,0x13 ; 使用中断10h的功能13，在屏幕上写一个字符串<br />mov al,0x00 ; 决定调用函数后光标所处的位置<br />mov bx,0x0007 ; 设置显示属性<br />mov cx,0x20 ; 在此字符串长度为32 <br />mov dx,0x0000 ; 光标的起始行和列<br />int 0x10 ; 调用BIOS的中断10h<br />ret ; 返回调用程序<br />get_key :<br />mov ah,0x00 <br />int 0x16 ; Get_key使用中断16h的功能0，读取下一个字符<br />ret<br />clrscr :<br />mov ax,0x0600 ; 使用中断10h的功能6，实现卷屏，如果al=0则清屏<br />mov cx,0x0000 ; 清屏<br />mov dx,0x174f ; 卷屏至23，79<br />mov bh,0 ; 使用颜色0来填充<br />int 0x10 ; 调用10h中断<br />ret<br />begin_boot :<br />call clrscr ; 先清屏<br />mov bp,bootmesg ; 提供串地址<br />call print_mesg ; 输出信息<br />call get_key ; 等待用户按下任一键<br />bits 16<br />call clrscr ; 清屏<br />mov ax,0xb800 ; 使gs指向显示内存<br />mov gs,ax ; 在实模式下显示一个棕色的A<br />mov word [gs:0],0x641 ; 显示<br />call get_key ; 调用Get_key等待用户按下任一键<br />mov bp,pm_mesg ; 设置串指针<br />call print_mesg ; 调用print_mesg子程序<br />call get_key ; 等待按键<br />call clrscr ; 清屏<br />cli ; 关中断<br />lgdt[gdtr] ; 加载GDT <br />mov eax,cr0 <br />or al,0x01 ; 设置保护模式位<br />mov cr0,eax ; 将更改后的字送至控制寄存器中<br />jmp codesel:go_pm<br />bits 32<br />go_pm : <br />mov ax,datasel <br />mov ds,ax ; 初始化ds和es，使其指向数据段<br />mov es,ax <br />mov ax,videosel ; 初始化gs，使其指向显示内存<br />mov gs,ax <br />mov word [gs:0],0x741 ; 在保护模式下显示一个白色的字符A<br />spin : jmp spin ; 循环<br />bits 16<br />gdtr :<br />dw gdt_end-gdt-1 ; gdt的长度<br />dd gdt ; gdt的物理地址<br />gdt<br />nullsel equ $-gdt ; $指向当前位置，所以nullsel = 0h<br />gdt0 ; 空描述符<br />dd 0 <br />dd 0 ; 所有的段描述符都是64位的<br />codesel equ $-gdt ; 这是8h也就是gdt的第二个描述符<br />code_gdt <br />dw 0x0ffff ; 段描述符的界限是4Gb<br />dw 0x0000 <br />db 0x00 <br />db 0x09a <br />db 0x0cf <br />db 0x00 <br />datasel equ $-gdt <br />data_gdt <br />dw 0x0ffff <br />dw 0x0000 <br />db 0x00 <br />db 0x092<br />db 0x0cf<br />db 0x00<br />videosel equ $-gdt <br />dw 3999 <br />dw 0x8000 ; 基址是0xb8000<br />db 0x0b<br />db 0x92 <br />db 0x00 <br />db 0x00<br />gdt_end<br />times 510-($-$$) db 0 <br />dw 0x0aa55</p>
		<p>
				<br />把上面的代码存在一个名为abc.asm的文件之中，使用命令nasm abc.asm，将得出一个名为abc的文件。然后插入软盘，输入命令：dd if=abc of=/dev/fd0。该命令将把文件abc写入到软盘的第一扇区之中。然后重新启动系统，就会看到如下的信息： </p>
		<p>*Our os booting................ <br />* A (棕色) <br />* Switching to protected mode.... <br />* A (白色)</p>
		<p>
				<br />对代码的解释</p>
		<p>上面给出了所有的代码，下面我对上述代码做一些解释。 </p>
		<p>◆ 使用的函数 </p>
		<p>下面是代码中一些函数的说明： </p>
		<p>print_mesg 该子程序使用了BIOS中断10h的功能13h，即向屏幕写一字符串。属性控制是通过向一些寄存器中送入不同的值来实现的。中断10h是用于各种字符串操作，我们把子功能号13h送到ah中，用于指明要打印一个字符串。al寄存器中的0说明了光标返回的起始位置，0表示调用函数后光标返回到下一行的行首。如果al为1则表示光标位于最后一个字符处。 </p>
		<p>显存被分成了几页，在同一时刻只能显示其中的一页。bh指明的是页号；bl则指明要显示字符的颜色；cx指明要显示字符串的长度；dx指明光标的位置(即起始的行和列)。所有相关寄存器初始化完成以后，就可以调用BIOS中断10h了。 </p>
		<p>get_key 使用中断16h的子功能00h，从屏幕得到下一个字符。 </p>
		<p>clrscr 该函数使用了中断10h的另外一个子功能06h，用于输出开始前清屏。初始化时给al中送入0。寄存器cx和dx指明要清屏的屏幕范围，在本例中是整个屏幕。寄存器bh指明屏幕填充的颜色，在本例中是黑色。 </p>
		<p>◆ 其它内容 </p>
		<p>程序一开始是一条短跳转指令，跳到begin_boot处。在实模式下，在此打印一个棕色的“A”，并且设置一个GDT。切换到保护模式，并且打印一个白色的“A”。这两种模式使用的都是自己的寻址方法。 </p>
		<p>在实模式下，使用段寄存器gs指示显存位置，我们使用的是CGA显卡(默认基址是0xb8000)。在代码中是不是漏了一个0呢？没有，因为实模式下会提供一个附加的0。这种方式也被80386继承下来了。A的ASCⅡ是0x41，0x06指明了需要一个棕色的字符。该显示会一直持续直至按下任意键。下面要在屏幕上显示一句话，告诉使用者下面马上要进入保护模式了。 </p>
		<p>启动到保护模式，在进行切换时不希望此时有中断的影响，故要关闭所有的中断(使用cli来实现)。然后对GDT初始化。在整个切换过程中，对4个描述符进行了初始化。这些描述符对代码段(code_gdt)、数据和堆栈段(data_gdt)，以及为了访问显存而对显示段进行初始化。此外，还会对一个空描述符进行初始化。 </p>
		<p>GDT的基址要加载至GDTR系统寄存器之中。gdtr段的第一个字加载的是GDT的大小，在下一个双字中则加载的是基址。然后，lgdt指令把把gdt段加载至GDTR寄存器中。现在已经做好了切换到保护模式前的所有准备。最后一件事情就是把CR0寄存器的PE位置1。不过，即使这样还没有处于保护模式状态之下。 </p>
		<p>设置了PE位以后，还需要通过执行JMP指令来清除处理器指令预取队列。在80386中，使用指令前总是先将其从内存中取出，并且进行解码和寻址。然而，当进入保护模式以后，预取指令信息(它还处于实地址模式)就无效了。使用JMP指令的目的就是强迫处理器放弃无效的信息。 </p>
		<p>现在，已经在保护模式下了。那么，如何检测是在保护模式状态之下呢？让我们来看一看屏幕上这个白色的字母A。在这里，使用了数据段选择符(datase1)对数据段和附加段进行了初始化，使用显示段选择符(videose1)对gs进行了初始化。告示的字符“A”其ASCⅡ值和属性位于[gs:0000]处，也就是b8000:0000处。循环语句使得该字符一直在屏幕上显示，直至重新启动系统。 </p>
		<p>下一步要做的事</p>
		<p>现在，这个操作系统已经工作在保护模式下了，但是实际上它并不实现什么具体的功能。你可以在这个基础上为它增加各种操作系统所具有的功能。我们自己动手写操作系统到此也就告一段落。 <br /></p>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/22237.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2007-01-23 13:07 <a href="http://www.cnitblog.com/weitom1982/archive/2007/01/23/22237.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>嵌入式测试的文字</title><link>http://www.cnitblog.com/weitom1982/archive/2006/07/24/14102.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 24 Jul 2006 03:34:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/07/24/14102.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/14102.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/07/24/14102.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/14102.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/14102.html</trackback:ping><description><![CDATA[嵌入式软件测试的困难之一就是如何获取测试产生的数据, 大多数的软件测试工具在测试软件的时候都要提供测试脚本,如果进行覆盖率分析就要对代码插装, 测试可执行程序在目标环境下运行时就会有数据产生,这些数据就是产生测试报告的重要输入条件, 所以要顺利实现嵌入式软件测试, 首先需要解决的就是如何把测试数据上载会主机.<br />经过我们实际摸索发现, 大概我们可以把数据的上载分为3 种方式:<br />1. 实际的物理通道<br />2. 开发工具IDE的虚拟IO功能<br />3. 读取内存区数据<br />下面我们对这几种方式做一些简单的介绍:<br />实际的物理通道<br />这种方式就是目标机和主机之间具备物理的通信方式, 比如以太网, 串口,并口, USB等, 这几种方式, 在测试的时候我们可以直接使用这种通信程序, 和主机通信, 实现测试数据上载, 一般情况下,测试工具的库中IO函数使用fprintf(), 那么在这种方式下,就需要修改测试工具的库, 假设以太网的发数据的函数是Netsend(), 那么我们需要定制fprintf, 使它调用Netsend(), 这样就可以实现数据上传了. 这种方式最方便但是要求系统必须已经具备这种通信方式和通信软件, 一般适用于系统级的测试.<br />开发工具虚拟IO<br />开发嵌入式软件一般需要支持交叉开发方式的开发工具, 大多数这种开发工具具备编译,下载,调试的功能, 测试时也可以借助开发工具来下载测试程序, 需要注意的是, 有些高级的开发工具IDE, 具备虚拟IO功能, 给测试带来了很大的方便, 比如说: Tornado, TI CCS,<br />在Tornado的shell中运行测试程序时, 可以把printf的内容打印到消息窗口中, CCS可以支持fprintf,直接在主机上生成测试数据文件, 用户在使用这些工具的时候, 就像在主机上测试一样, 完全可以理由开发工具赋予的模拟IO功能.<br />读取内存数据<br />假设目标系统既没有物理通信方式, 开发工具也没有虚拟IO功能, 我们还可以采用读取内存数据的方式, 我们可以开辟一块足够大的缓存, 修改测试工具的库, 把输出的数据写入buffer中, 在测试过程中或者测试执行后, 使用开发工具读取内存的功能把缓存中的数据读取出来,在主机上保存成文件,这种方式需要系统有足够的内存资源, 但是适用性很广,因为几乎所有的开发调试工具都具备这样的功能. <br />总之嵌入式软件测试很复杂, 需要根据实际情况采取不同的策略. 本文只是单独就数据读取的问题做了一些讨论. <br /><img src ="http://www.cnitblog.com/weitom1982/aggbug/14102.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-07-24 11:34 <a href="http://www.cnitblog.com/weitom1982/archive/2006/07/24/14102.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>相对最完整的软件测试工具手册 </title><link>http://www.cnitblog.com/weitom1982/archive/2006/07/24/14100.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 24 Jul 2006 03:21:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/07/24/14100.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/14100.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/07/24/14100.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/14100.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/14100.html</trackback:ping><description><![CDATA[
		<div class="posthead">
				<h2>
						<span id="_ctl3_lblPermalink">
								<span>
										<font size="2">1、 从测试功能上分<br />（1） 单元测试<br />针对不同语言，如JUNIT<br />（2） 功级测试<br />E—Test：功能强大，由于不是采用POST URL的方式回放脚本，所以可以支持多内码的测试数据（当然要程序支持），基本上可以应付大部分的WEB SITE。<br />MI公司的WINRUNNER<br />COMPUWARE的QARUN<br />RATIONAL的SQA ROBOT<br />（3） 压力测试<br />MI公司的WINLOAD<br />COMPUWARE的QALOAD<br />RATIONAL的SQA LOAD<br />（4） 负载测试<br />LOADRUNNER<br />RATIONAL VISUAL QUANTIFY<br />（5） WEB<a href="http://www.testage.net/AutoTest/">测试工具</a><br />MI公司的ASTRA系列<br />RSW公司的E—TEST SUITE等<br />（6） WEB系统<a href="http://www.testage.net/AutoTest/">测试工具</a><br />WORKBENCH<br />WEB APPLICATION STRESS TOOL（WAS）<br />（7） 数据库<a href="http://www.testage.net/AutoTest/">测试工具</a><br />TESTBYTES<br />（8） 回归<a href="http://www.testage.net/AutoTest/">测试工具</a><br />RATIONAL TEAM TEST<br />WINRUNNER<br />（9） 嵌入式<a href="http://www.testage.net/AutoTest/">测试工具</a><br />ATTOLTESTWARE。是ATTOLTESTWARE公司的自动生成测试代码的<a href="http://www.testage.net/">软件测试</a>工具，特别适用于嵌入式实时应用软件单元和通信系统测试。<br />CODETEST是AppliedMicrosystemsCorp.公司的产品,是广泛应用的嵌入式软件在线<a href="http://www.testage.net/AutoTest/">测试工具</a>。<br />GammaRay。GammaRay系列产品主要包括软件逻辑分析仪GammaProfiler、可靠性评测工具GammaRET等。<br />LogiScope是TeleLogic公司的工具套件，用于代码分析、<a href="http://www.testage.net/">软件测试</a>、覆盖测试。<br />LynxInsure++是LynxREAL-TIMESYSTEMS公司的产品，基于LynxOS的应用代码检测与分析<a href="http://www.testage.net/AutoTest/">测试工具</a>。<br />MessageMaster是ElviorLtd.公司的产品，测试嵌入式软件系统工具，向环境提供基于消息的接口。<br />VectorCast是VectorSoftware.Inc公司的产品。由6个集成的部件组成，自动生成测试代码，为主机和嵌入式环境构造可执行的测试架构。<br />（10） 系统性能<a href="http://www.testage.net/AutoTest/">测试工具</a><br />Rational Performance<br />（11） 页面链接测试<br />Link Sleuth<br />（12） 测试流程管理工具<br />Test Plan Control<br />（13） 测试管理工具<br />TestDirector<br />Rational公司的Test Manager<br />Compuware公司的QADirector<br />TestExpert：是Silicon Valley Networks公司产品的测试管理工具，能管理整个测试过程，从测试计划、测试例程、测试执行到测试报告。<br />（14） 缺陷跟踪工具<br />TrackRecord等<br />（15） 其他<a href="http://www.testage.net/AutoTest/">测试工具</a>包<br />TestVectorGenerationSystem是T—VECTechnologies公司的产品。提供自动模型分析、测试生成、测试覆盖分析和测试执行的完整工具包，具有方便的用户接口和完备的文档支持。<br />TestQuestPro是TestQuest公司的非插入码式的自动操纵<a href="http://www.testage.net/AutoTest/">测试工具</a>，提供一种高效的自动检测目标系统，获取其输出性能的测试方法。<br />TestWorks是SoftwareResearch.Inc公司的一整套<a href="http://www.testage.net/">软件测试</a>工具，既可单独使用，也可捆绑销售使用。<br />2、 从测试的方法上分：<br />（1） 白盒<a href="http://www.testage.net/AutoTest/">测试工具</a><br />白盒测试工主要有：Numega、PuRe、软件纠错工具（Rational Purify）。<br />内存资源泄漏检查：<br />Numega中的BounceChecher<br />Rational的 Purify等<br />代码覆盖率检查：<br />Numega的TrueCoverage<br />Rational的PureCoverage<br />TeleLogic公司的LogiScope<br />Macabe公司的Macabe<br />代码性能检查：<br />Numega的TrueTime<br />Rational的Quantify等<br />代码静态度量分析度量检查工具：LogiScope和Macabe等<br />黑盒<a href="http://www.testage.net/AutoTest/">测试工具</a>主要有：QACenter、SQATeamTest、Rational Visual Visual Test。<br />QACenter：QACenter帮助所有测试人员创建一个快速、可重用的测试过程。这些<a href="http://www.testage.net/AutoTest/">测试工具</a>自动帮助管理测试过程、快速分析和调试程序，包括针对回归、强度、单元、并发、集成、移植，容量和负载建立测试用例，自动执行测试和产生文档结果。QACenter主要包括以下几个模块：<br />QARun：应用的功能<a href="http://www.testage.net/AutoTest/">测试工具</a>。<br />QALoad：强负载下应用的性能<a href="http://www.testage.net/AutoTest/">测试工具</a>。<br />QADirector：测试的组织设计和创建以及管理工具。<br />TrackRecord：集成的缺陷跟踪管理工具。<br />EcoTools：高层次的性能监测工具。<br /><br /><br />3、部分具体<a href="http://www.testage.net/AutoTest/">测试工具</a>的介绍<br />（1）、性能优化工具EcoScope<br />EcoScope 是一套定位于应用（即服务提供者本身）及其所依赖的所有网络计算资源的解决方案。EcoScope可以提供应用视图，并标出应用是如何与基础架构相关联的。这种视图是其他网络管理工具所不能提供的。EcoScope能解决在大型企业复杂环境下分析与测量应用性能的难题。通过提供应用的性能级别及其支撑架构的信息，EcoScope能帮助IT部门就如何提高应用性能提出多方面的决策方案。<br />EcoScope的应用主要表现在以下几个方面：<br />确保成功部署新应用<br />维护性能的服务水平<br />加速问题检测与纠正的高级功能<br />定制视图有助于高效地分析数据<br />（2）、数据库测试数据自动生成工具——TestBytes<br />在数据库开发的过程中，为了测试应用程序对数据库的访问，应当在数据库中生成测试用例数据，我们可能会发现当数据库中只有少量数据时，程序可能没有问题，但是当真正投入到运用中产生了大量数据时就出现问题了，这往往是因为程序的编写没有达到，所以一定及早地通过在数据库中生成大量数据来帮助开发人员完善这部分功能和性能。<br />TestBytes是一个用于自动生成测试数据的强大易用的工具，通过简单的点击式操作，就可以确定需要生成的数据类型（包括特殊字符的定制），并通过与数据库的连接来自动生成数百万行正确的测试数据，可以极大地提高数据库开发人员、QA测试人员、数据仓库开发人员、应用开发人员的工作效率。<br />（3）、PC—LINT<br />PC—LINT 主要进行更严格的语法检查功能，还完成相当程度的语义检查功能。可以这样认为：PC—LINT是一个更加智能、更加严格的编译器。PC—LINT在实现语法和某些语义规则检查时，是通过参数配置完成的，它的选项就有数百个之多，因此，在使用PC—LINT过程中，了解选项的含义也很重要。<br />（4）、TCL<br />TCL是Tool Command Language的缩写，它是一种很流行的脚本解释器，尤其在测试领域，它的最大特点是可移植性好，接口简单，方便，可以很容易地嵌入到软件中，作为自己的解释器使用。<br />TCL提供两种接口：编程接口和用户接口。编程接口是通过LIB或DLL形式提供的，提供了一些函数（命令）供调用，包括：分配一个解释器指针（对象）；初始化解释器（指针）；注册扩展函数等。用户接口很简单，即编写的脚本，脚本里面包含对扩展命令的调用。<br />（5）VB<a href="http://www.testage.net/AutoTest/">测试工具</a>：VB Watch<br />（6）Java 程序的<a href="http://www.testage.net/AutoTest/">测试工具</a><br />1）Bean—Test<br />2）EJBQuickTest<br />3）JStyle<br />4）JTest<br />5）HttpUnit<br />6）JUnit<br />（7）、覆盖测试<br />C—Cover<br />C—Cover是一个<a href="http://www.testage.net/AutoTest/">测试工具</a>软件，用来找出没有被测到的代码，并报告测试的覆盖率。C—Cover<br />只支持C/C++的代码覆盖率分析，其它语言不支持。但不受OS的限制。<br /></font>
										<font size="3">===============================================<br /><font size="2">单元测试方面：（对开发人员比较有用） J-Unit工具。<br />  功能测试方面：E-test是个不错的选择，功能很强大，由于不是采用Post URL的方式回放脚本，所以可以支持多内码的测试数据（当然要程序支持）。基本上可以应付大部分的Web Site。<br />  如果只是利用脚本回放代替手工劳动，或者做对页面响应数的性能测试，Microsoft Web Application Stress Tool是个不错的选择。<br />   另外，在性能测试方面，PureLoad也是一个不错的工具，完全用Java写成，可以测试各种C/S程序，如SMTP Server等。这两个工具都是使用Post URL的方法测试Web Application的。对大量使用JavaScript的页面不太适合。当然，如果程序在Unix，linux下面运行的话，可以直接编写Shell 脚本程序，更加方便。<br />  另外，还有很多专门的工具，比如说Linkbot是专门作页面链接测试的。<br />  另外，测试流程管理工具也有不少，个人用过也一直在用的是Test Plan Control，短小精悍，不错。   至于WinRunner和LoadRunner之类，因为没有License，所以都没怎么用过，惭愧。不过我看过一篇英国人评价英国测试市场上最流行的五个软件的文章。WinRunner得分最高。<br />  <a href="http://www.testage.net/AutoTest/">测试工具</a>从测试的方法上可以分为两种：白盒测试和黑盒测试   白盒<a href="http://www.testage.net/AutoTest/">测试工具</a>主要有：<br />  内存资源泄漏检查：Numega中的bouncechecker,Rational的Purify等<br />   代码覆盖率检查：Numega中的truecoverage,Rational的Purecoverage，Telelogic公司的 logiscope, Macabe公司的Macabe等   代码性能检查：Numega中的truetime,Rational的Quantify等<br />  代码静态度量分析质量检查工具：logiscope和Macabe等<br />  黑盒<a href="http://www.testage.net/AutoTest/">测试工具</a>主要有：   客户端功能测试：MI公司的winrunner,compuware的qarun,Rational的SQA robot等等<br />  服务器端压力性能测试： MI公司的winload,compuware的qaload,Rational的SQA load等等<br />  Web<a href="http://www.testage.net/AutoTest/">测试工具</a>：MI公司的Astra系列，rsw公司的e-test suite等等<br />  测试管理工具：rational的test manager,compuware的qadirector等等，此外还有缺陷跟踪工具 trackrecord等。<br />  数据库<a href="http://www.testage.net/AutoTest/">测试工具</a>:TestBytes<br />  黑盒<a href="http://www.testage.net/AutoTest/">测试工具</a>：QACenter、SQATeamTest，Rational Viaual Test。<br />  回归<a href="http://www.testage.net/AutoTest/">测试工具</a>：Rational TeamTest，WinRunner（MI公司）<br />  WEB系统<a href="http://www.testage.net/AutoTest/">测试工具</a>：TEST，Workberch，Web Appication Stress Tool（WAS）<br />  白盒<a href="http://www.testage.net/AutoTest/">测试工具</a>：Numega 、PuRe、软件纠错工具（Rational Purity）。<br />  嵌入式<a href="http://www.testage.net/AutoTest/">测试工具</a>：Logiscope（静态<a href="http://www.testage.net/AutoTest/">测试工具</a>）、CodeTest。<br />  系统负荷<a href="http://www.testage.net/AutoTest/">测试工具</a>：RationalPerformance<br />  涵盖<a href="http://www.testage.net/AutoTest/">测试工具</a>范围评估工具<br />  软件性能<a href="http://www.testage.net/AutoTest/">测试工具</a>：LoadRunner（MI产品）、Rational Visual Qantify<br />  测试管理工具：TestDirector（MI产品支持整个生命周期中测试流程管理）</font></font>
								</span>
						</span>
				</h2>
		</div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/14100.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-07-24 11:21 <a href="http://www.cnitblog.com/weitom1982/archive/2006/07/24/14100.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>注册表被破坏的现象 </title><link>http://www.cnitblog.com/weitom1982/archive/2006/05/08/10215.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 08 May 2006 09:15:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/05/08/10215.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/10215.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/05/08/10215.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/10215.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/10215.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="585" border="0">
				<tbody>
						<tr>
								<th class="f24">
										<h1> </h1>
								</th>
						</tr>
						<tr>
								<td>
										<hr size="1" bgcolor="#d9d9d9" />
								</td>
						</tr>
						<tr>
								<td align="middle" height="20">
								</td>
						</tr>
						<tr>
								<td height="15">
										<p align="center">
										</p>
								</td>
						</tr>
						<tr>
								<td class="l17" align="right">
								</td>
						</tr>
						<tr>
								<td class="f14" id="zoom">一、注册表遭到破坏后，可能会出现以下现象：<br />·无法启动系统<br />·无法运行或正常运行合法的应用程序<br />·找不到启动系统或运行应用程序所需的文件<br />·没有访问应用程序的权限<br />·不能正确安装或调入驱动程序<br />·不能进行网络连接<br />·注册表条目有误<br />二、注册 
<table cellspacing="0" cellpadding="0" align="left"><tbody><tr><td></td></tr></tbody></table>表被破坏的原因<br />通常注册表被破坏的原因可以归纳为以下四类。<br />1、应用程序错误<br />通常用户需要经常在Windows操作系统中添加或删除各种应用程序。而在实际使用过程中，很少有完全没有错误的应用程序，那些看似很微小的错误，可能会导致非常严重的后果。同时，当计算机中安装了大量软件后，有可能出现彼此间的冲突。此外，一些做Beta测试的软件，自身也没有定型，还存在许多错误，可能会对注册表造成影响。这些应用程序在注册表中添加了错误的内容。错误的数据文件和应用程序间的关联，是破坏注册表的一个潜在原因。<br />2、驱动程序不兼容<br />由于PC机的体系结构是一个开放性的体系结构，当驱动程序和其他程序协同工作的时候，就会发生不兼容的现象。又或者某些驱动程序是16位的，在安装到32位的Windows 9x操作系统后，也会出现不兼容的现象。<br />3、硬件问题<br />除了非正常断电外，比如硬盘、内存或其他硬件的质量不过关，都会造成数据读写错误或因过度超频等状况使机器的稳定性下降，以及病毒等对BIOS程序或CMOS存储器造成破坏等，都可能导致注册表的破坏。<br />4、误操作<br />注册表中的数据众多、内容复杂，不太熟悉注册表的用户在手工修改注册表时，很可能会破坏注册表中的内容。用户可能在无意间将某个重要的键值删除或双击了某个注册表文件将其导入了注册表，这些操作都极易破坏整个系统。<br />这个问题，用户可以尝试将系统对双击注册表文件的响应，由默认的“合并”该为“编辑”，以避免用户的误操作，提供系统安全性。具体的操作步骤如下。<br />步骤<br />(1)打开任意一个浏览器窗口，选择【查看】菜单下的【文件夹选项】选项，打开“文件夹选项”对话框，再打开“文件类型”选项卡。<br />(2)选中“注册表项目”，单击【编辑】按钮，随即系统将弹出“编辑文件类型”对话框，选中“编辑”并单击【设为默认值】按钮。<br />(3)单击【关闭】按钮即可。<br />这样，再单击.reg的注册表文件时，它的默认行就会变成编辑状态，与Windows界面的其他部分保持了一致。<br />三、注册表的还原及恢复<br />如果在注册表被破坏前进行了备份，则修改注册表就会比较方便，否则就要借助于一些专用工具了。通常，要恢复注册表，应从最简单的方法做起。这里，将从易到难逐一给大家介绍。 <br />1、重新启动系统<br />这是最简单的处理方法。由于Windows注册表中的许多信息都保存在内存中，并且每次启动系统时，注册表都会把硬盘中的信息调入内存，所以用户可以通过重新将硬盘中的数据调入内存的方式来修正各种错误。在启动Windows时出现错误信息时，单击【确定】按钮，则Windows将首先恢复注册表，然后进入启动过程，若注册表的错误较轻，可能机器启动后系统就会恢复如初了。<br />虽然并不是所有情况下都适用这种方法，但在做复杂的处理之前可以试一试。<br />2、使用安全模式启动<br />若在启动Windows系统时遇到注册表错误，可以尝试在安全模式下启动。具体做法是在启动时，单击【F5】键，此时系统会自动修复注册表问题。若在安全模式下启动成功，就可以在正常模式下启动Windows系统了。<br />3、简单拷贝法还原<br />对Windows95来讲，可以利用自身提供的备份文件，进行简单的拷贝，覆盖现有的注册表文件。具体的操作步骤与备份的过程类似。这里就不再做过多的解释了。<br />4、Windows98自动备份的还原<br />若可以进入Windows，哪怕只是在安全模式下，只要Win Zip等支持CAB压缩格式的软件选择最近的或前几天的备份压缩包文件，将其中的4个文件解压出来，重新启动计算机到DOS下，利用这些文件覆盖相应的文件即可。 <br />若无法进入Windows，可以尝试在DOS下利用Windows自带的Extract.exe文件打开该压缩文件，恢复替换原注册表文件即可，命令为“extract/Y Sysbackup\rb00?.cab”（其中？为0～4）。<br />5、Windows2000备份的还原<br />用户可以在启动Windows2000时使用备份的注册表来恢复，具体的操作步骤如下。<br />步骤<br />(1)在任务栏上单击【开始】按钮，然后单击【关闭系统】选项。<br />(2)单击【重新启动】之后，单击【确定】按钮。<br />(3)当屏幕出现“正在启动Windows2000”提示后，单击【F8】键。<br />(4)使用箭头键，选中“最后一次正确配置”，然后按回车键确认，系统将启动Windows2000。<br />操作执行完毕，注册表被还原到上一次成功启动计算机时的状态。<br />6、利用导入法完全还原<br />可以在Windows或DOS下，利用导出的注册表文件还原系统。通常，为了保险起见，用户最好在安全模式下或直接在DOS下操作。<br />在Windows下恢复注册表时，在注册表编辑器中，单击【注册表】菜单中的【引入注册表文件】选项，在出现的对话框中选中所需恢复的备份文件，再单击【打开】按钮即可将注册表备份还原到Windows系统中了。<br />7、利用导入法部分还原<br />部分还原是指利用以前备份的注册表文件或其他注册表文件来覆盖现有的主键，也就是“还原项”。具体的操作步骤如下。<br />步骤<br />(1)在Regedit32注册表编辑器中，将光标移至要还原的主键上。<br />(2)选择【注册表】菜单下的【还原】命令，并在“还原项”对话框中选择要还原的注册表文件。<br />(3)单击【打开】按钮，确认覆盖现有的主键后，即可还原该项到当前选定的项上。<br />8、利用加载配置单元还原<br />“加载配置单元”和“卸载配置单元”这两个命令仅在HKEY_USERS或HKEY_LOCAL_MACHINE预定义项窗口中才有效。将配置单元加载到注册表中后，配置单元将成为其中一个项的子项。具体的操作步骤如下。<br />步骤<br />(1)在Regedit32注册表编辑器中，任选一个预定义项中的主键。 <br />(2)选择【注册表】菜单下的【加载配置单元】命令，在随即弹出的“加载配置单元”对话框中，选择要加载的注册表文件。<br />(3)单击【打开】按钮后出现“加载配置单元”对话框，在对话框的“项名称”文本框内输入新主键的名称，再单击【确定】按钮。<br />这里，“加载配置单元”引入的是注册表内原来没有的内容。<br />9、用Eru.exe恢复Windows 9x注册表<br />在Windows 9x光盘的Other\Misc\ERU目录中，提供了备份注册表的程序Eru.exe。在装有Eru和备份文件的软盘上运行Eru.exe命令对注册表进行恢复，具体的操作步骤如下。 <br />步骤<br />(1)把可执行文件Eru.exe复制到C：\Windows目录下。<br />(2)重新启动计算机到MS-DOS模式下。<br />(3)运行Eru.exe，并根据提示操作即可。<br />备份信息可以保存在驱动器A中的引导盘中，也可以指定存放在包括网络驱动器的任何位置上。<br />10、使用System.lst恢复注册表<br />如果Windows 9x不能正常启动，并且没有对系统注册表进行备份，这时可以尝试利用System.lst对系统注册表进行恢复。<br />当Windows 9x成功安装以后，系统会自动将第一次正常运行时的系统信息保存在C盘根目录下的System.lst文件中，这个文件也是系统、只读、隐含文件，它不会随着Windows的系统配置改变而改变，利用它，有可能将系统恢复到最初安装时的状态。具体操作步骤如下。<br />步骤<br />(1)在DOS环境下，依次执行如下命令：<br />Attrib –h –r –r C:\System.lst<br />Attrib –h –r –s C:\Windows\System.dat<br />Copy C:\System.lst C:\Windows\System.dat<br />Attrib +h +r +s C:\System.lst<br />Attrib +h +r +s C:\Windows\System.dat<br />(2)重新启动计算机。<br />由于System.lst中保存的是Windows第一次正常运行时的系统信息，后面更改Windows的软硬件配置信息都没有被更新到这个文件中，所以在成功启动后，还需对系统进行许多调整才能恢复到被破坏前的状态。 <br />在实际应用中，当Windows98的注册表遭到较重破坏后，即使能够修复，效果可能也并不太好，此时重新安装系统也许是更好的选择。<br />最后再一次重申，如果对注册表不熟悉，不要随意用注册表编辑器对其进行修改，因为注册表的一点小问题会导致系统不正常工作。在修改注册表之前，一定要记得备份注册表。<br />恶意网页更改注册表<br />在浏览网页注册表被修改，使得IE默认连接首页、标题栏及IE右键菜单被改为浏览网页时的地址（多为广告信息），更有甚者使浏览者的电脑在启动时出现一个提示窗口显示自己的广告，遇到这种情况我们该怎样办呢？<br />　　其实，该恶意网页是含有有害代码的ActiveX网页文件，这些广告信息的出现是因为浏览者的注册表被恶意更改的结果。<br />　　1、IE默认连接首页被修改<br />　　IE浏览器上方的标题栏被改成“欢迎访问……网站”的样式，这是最常见的篡改手段，受害者众多。<br />　　受到更改的注册表项目为：<br />HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\Start Page<br />HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\Start Page<br />　　通过修改“Start Page”的键值，来达到修改浏览者IE默认连接首页的目的， <br />　　解决办法：<br />　　①在Windows启动后，点击“开始”→“运行”菜单项，在“打开”栏中键入regedit，然后按“确定”键；<br />　　②展开注册表到<br />HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main下，在右半部分窗口中找到串值“Start Page”双击 ，将Start Page的键值改为“about:blank”即可； <br />　　③同理，展开注册表到<br />HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main<br />　　在右半部分窗口中找到串值“Start Page”，然后按②中所述方法处理。<br />　　④退出注册表编辑器，重新启动计算机，一切OK了！<br />　　特殊例子：当IE的起始页变成了某些网址后，就算你通过选项设置修改好了，重启以后又会变成他们的网址啦，十分的难缠。其实他们是在你机器里加了一个自运行程序，它会在系统启动时将你的IE起始页设成他们的网站。<br />　　解决办法：运行注册表编辑器regedit.exe，然后依次展开<br />HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Current Version\Run<br />　　主键，然后将其下的registry.exe子键删除，然后删除自运行程序c:\Program Files\registry.exe，最后从IE选项中重新设置起始页就好了。<br />2、篡改IE的默认页<br />　　有些IE被改了起始页后，即使设置了“使用默认页”仍然无效，这是因为IE起始页的默认页也被篡改啦。具体说来就是以下注册表项被修改： <br />HKEY_LOCAL_MACHINE\Software\Microsoft\InternetExplorer\Main\Default_Page_URL　“Default_Page_URL”这个子键的键值即起始页的默认页。<br />　　解决办法：<br />　　运行注册表编辑器，然后展开上述子键，将“Default_Page_UR”子键的键值中的那些篡改网站的网址改掉就好了，或者设置为IE的默认值。<br />　　3、修改IE浏览器缺省主页，并且锁定设置项，禁止用户更改回来。<br />　　主要是修改了注册表中IE设置的下面这些键值(DWORD值为1时为不可选)：<br />[HKEY_CURRENT_USER\Software\Policies\Microsoft\InternetExplorer\Control Panel]"Settings"=dword:1<br />[HKEY_CURRENT_USER\Software\Policies\Microsoft\InternetExplorer\Control Panel]"Links"=dword:1<br />[HKEY_CURRENT_USER\Software\Policies\Microsoft\InternetExplorer\Control Panel]"SecAddSites"=dword:1<br />　　解决办法：<br />　　将上面这些DWORD值改为“0”即可恢复功能。<br />4、IE的默认首页灰色按扭不可选这是由于注册表 HKEY_USERS\.DEFAULT\Software\Policies\Microsoft\InternetExplorer\Control Panel<br />下的DWORD值“homepage”的键值被修改的缘故。原来的键值为“0”，被修改为“1”（即为灰色不可选状态）。<br />　　解决办法：将“homepage”的键值改为“0”即可。<br />5、IE标题栏被修改<br />　　在系统默认状态下，是由应用程序本身来提供标题栏的信息，但也允许用户自行在上述注册表项目中填加信息，而一些恶意的网站正是利用了这一点来得逞的：它们将串值Window Title下的键值改为其网站名或更多的广告信息，从而达到改变浏览者IE标题栏的目的。<br />　　受到更改的注册表项目为：<br />HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\Window Title<br />HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\Window Title<br />　　解决办法：<br />　　①在Windows启动后，点击“开始”→“运行”菜单项，在“打开”栏中键入regedit，然后按“确定”键；<br />　　②展开注册表到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InternetExplorer\Main下，在右半部分窗口中找到串值“Window Title” ，将该串值删除即可，或将WindowTitle的键值改为“IE浏览器”等你喜欢的名字； <br />　　③同理，展开注册表到<br />HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main然后按②中所述方法处理。<br />　　④退出注册表编辑器，重新启动计算机，运行IE，你会发现困扰你的问题解决了！<br />　　6、IE右键菜单被修改<br />　　受到修改的注册表项目为：<br />HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt下被新建了网页的广告信息，并由此在IE右键菜单中出现！<br />　　解决办法：<br />　　打开注册标编辑器，找到<br />HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt<br />　　删除相关的广告条文即可，注意不要把下载软件FlashGet和Netants也删除掉啊，这两个可是“正常”的呀，除非你不想在IE的右键菜单中见到它们。<br />7、IE默认搜索引擎被修改<br />　　在IE浏览器的工具栏中有一个搜索引擎的工具按钮，可以实现网络搜索，被篡改后只要点击那个搜索工具按钮就会链接到那个篡改网站。出现这种现象的原因是以下注册表被修改： <br />HKEY_LOCAL_MACHINE\Software\Microsoft\InternetExplorer\Search\CustomizeSearch<br />HKEY_LOCAL_MACHINE\Software\Microsoft\InternetExplorer\Search\SearchAssistant<br />　　解决办法：<br />　　运行注册表编辑器，依次展开上述子键，将“CustomizeSearch”和“SearchAssistant”的键值改为某个搜索引擎的网址即可。<br />　　8、系统启动时弹出对话框<br />　　受到更改的注册表项目为：<br />HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Winlogon<br />　　在其下被建立了字符串“LegalNoticeCaption”和“LegalNoticeText”，其中“LegalNoticeCaption”是提示框的标题，“LegalNoticeText”是提示框的文本内容。由于它们的存在，就使得我们每次登陆到Windwos桌面前都出现一个提示窗口，显示那些网页的广告信息！<br />　　解决办法：<br />　　打开注册表编辑器，找到<br />HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Winlogon<br />　　这一个主键，然后在右边窗口中找到“LegalNoticeCaption”和“LegalNoticeText”这两个字符串，删除这两个字符串就可以解决在登陆时出现提示框的现象了。<br />　　9、浏览网页注册表被禁用 <br />　　这是由于注册表<br />HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System下的DWORD值“DisableRegistryTools”被修改为“1”的缘故，将其键值恢复为“0”即可恢复注册表的使用。<br />　　10、浏览网页开始菜单被修改<br />　　这是最“狠”的一种，让浏览者有生不如死的感觉。浏览后不仅有类似上面所说的那些症状，还会有以下更悲惨的遭遇：<br />　　1)禁止“关闭系统” <br />　　2)禁止“运行” <br />　　3)禁止“注销” <br />　　4)隐藏C盘——你的C盘找不到了！<br />　　5)禁止使用注册表编辑器regedit <br />　　6)禁止使用DOS程序<br />　　7)使系统无法进入“实模式” <br />　　8)禁止运行任何程序<br />　　具体的原因和解决办法请看天极网e企业之安全之路栏目的这篇文章：《浏览网页注册表被修改之迷及解决办法》。<br />　　11、IE中鼠标右键失效<br />　　浏览网页后在IE中鼠标右键失效，点击右键没有任何反应！<br />　　要特别注意的是，在你编制的注册表文件unlock.reg中，“REGEDIT4”一定要大写，并且它的后面一定要空一行，还有，“REGEDIT4”中的“4”和“T”之间一定不能有空格，否则将前功尽弃！许多朋友写注册表文件之所以不成功，就是因为没有注意到上面所说的内容，这回该注意点喽。 <br />注：1.3721网站上网助手中有一个安全与修复，可以修复以下ie被改的症状<br />修复浏览器标题、首页、默认地址等 <br />修复非法写入浏览器链接栏、文件创建日期、 <br />系统时间显示等其他地方的网址 <br />修复浏览器的Internet选项为可用 <br />修复浏览器查看源文件功能 <br />修复注册表编辑器为可用 <br />取消对"控制面板"的非法限制 <br />修复注册表文件导入功能 <br />取消"网上邻居"的非法限制 <br />修复重新开机后自动弹出浏览器窗口的问题 <br />修复重新开机后重复感染浏览器的问题 <br />修复开机后弹出对话框的问题 <br />恢复浏览器默认的搜索引擎 <br />在地址栏中键入www.3721.com ,然后选择其它产品—上网助手—安全与修复—在线安装3721上网助手，然后在页面的右侧有一个“一健修复”，点击后关掉所有浏览器窗口，然后重新启动浏览器，即可修复大部分的浏览器被更改的故障。<br /></td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/10215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-05-08 17:15 <a href="http://www.cnitblog.com/weitom1982/archive/2006/05/08/10215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单位转换探讨</title><link>http://www.cnitblog.com/weitom1982/archive/2006/04/19/9361.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Wed, 19 Apr 2006 02:52:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/04/19/9361.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/9361.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/04/19/9361.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/9361.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/9361.html</trackback:ping><description><![CDATA[
		<font color="#ffffff">的</font>单位转换探讨
<p><a href="http://suncilang.21ic.org/">自由人笔记</a><br />1 基础知识<br />1.1 用于构成十进制倍数和分数单位的词头(词冠)<br />词头中文名    词头英文名    符号    所表示的因数    词头中文名    词头英文名    符号    所表示的因数<br />分    deci    ｄ    10-1    皮    pico    ｐ    10-12<br />厘    centi    ｃ    10-2    千    kilo    Ｋ    103<br />毫    milli    ｍ    10-3    兆    mega    Ｍ    106<br />微    micro    μ    10-6    吉    giga    Ｇ    109<br />纳    nano    ｎ    10-9    太    tera    T    1012<br />　　为不失一般性，下面的一些公式中将以希腊字母Θ代表无词头和十进制分数单位的词头（ｍ、μ、ｎ、ｐ）。但一定要注意Θ本身并不是一种词头，仅是本文为避免列出大量雷同的公式而约定的一个符号而已。所以，当您看到Θ时，一定要想到它就是ｍ、μ、ｎ、ｐ或者是没词头；在您需要含无词头单位参数的公式时，就请把Θ去掉；而在您需要含某种词头单位参数的公式时，就就请把Θ换成所需的词头。<br />1.2 分贝<br />在电子学中，分贝是表示传输增益或传输损耗以及相对功率比等的标准单位，其代号为ｄＢ（英文decibel的缩写）。其形式上表示倍数，实质上既能表示经作常用对数压缩处理后的倍数（以分贝表示的传输增益和传输损耗等，特点是本质无量纲），又能表示约定基准值的参数值（电压电平、功率电平，以分贝表示的电场强度、功率通量密度，杂散辐射功率和邻道功率相对于载波功率的电平等，特点是本质有量纲）。采用的根本原因在于对数运算能够压缩数据长度和简化运算（将乘、除、指数运算分别转化为加、减、乘运算），特别适合表达指数变化规律。我们这里约定，以符号ｌｇ表示以１０为底的对数。经作对数变换后的本质有量纲单位常称作电平单位（与其基准值相等的参数值称零电平。电平的单位还有贝尔和奈培两种，但由于文献[1]规定“统一使用分贝为电信传输单位”，这里不采用。以下所称电平均以分贝为词头），而原来的单位可称作线性单位。<br />分贝与线性值的比较见下表：<br />分贝值（ｄＢ）    电压、电流比线性值    功率比线性值    分贝值（ｄＢ）    电压、电流比线性值    功率比线性值    分贝值（ｄＢ）    电压、电流比线性值    功率比线性值<br />0.0    1.000    1.000    1    1.122    1.259    11    3.548    12.59<br />0.1    1.012    1.023    2    1.259    1.585    12    3.981    15.85<br />0.2    1.023    1.047    3    1.413    1.995    13    4.467    19.95<br />0.3    1.035    1.072    4    1.585    2.512    14    5.012    25.12<br />0.4    1.047    1.096    5    1.778    3.162    15    5.623    31.62<br />0.5    1.059    1.122    6    1.995    3.981    16    6.310    39.81<br />0.6    1.072    1.148    7    2.239    5.012    17    7.079    50.12<br />0.7    1.084    1.175    8    5.012    6.310    18    7.943    63.10<br />0.8    1.096    1.202    9    2.818    7.943    19    8.913    79.43<br />0.9    1.109    1.230    10    3.162    10.00    20    10.00    100.0<br />　　分贝的定义分以下三种情况：<br />1.2.1 对电压和与电压呈线性关系的参数的表达<br />　　电压和与电压呈线性关系的参数，这里权且简称为电压型参数，以Ａ表示，以ｘ表示其<br />单位。以１ｘ为基准值，则Ａ的电平单位为称分贝ｘ，代号为ｄＢｘ，计算公式为<br />　　　　　　　　　　　 　Ａ（ｘ）<br />　　Ａ（ｄＢｘ）＝２０lg ————　　　　　　　　　　　　　　　　　　      （１）　<br />　　　　　　　　　　　　　１ｘ　　<br />　　　　　　　　　　Ａ（ｄＢｘ）<br />　　　　　　　　　　——————<br />　　　　　　　　　　　　２０<br />　　Ａ（ｘ）＝１０　　　　　　　　　　　　　　　　　　　　　     　　 　　（２）<br />　　Ａ可以是电压（电动势、端电压）、电场强度和天线系数，ｘ可以是Ｖ、ｍＶ、μＶ，Ｖ/m、ｍＶ/m、μＶ/m和m-1 等，对应的电平单位分别为ｄＢＶ、ｄＢｍＶ、ｄＢμＶ，　ｄＢＶ/m、ｄＢｍＶ/m、ｄＢμＶ/m(常记为ｄＢμ)和ｄＢm-1等。<br />　　同类电压型电平单位（天线系数除外）词头之间的转换公式为<br />　　ｄＢｘ＝ｄＢｍｘ＋６０＝ｄＢμｘ＋１２０　　　　　　  　 　　　　　 　（３）<br />　　ｄＢｍｘ＝ｄＢμｘ＋６０　　　　　　　　　　　　　　　　     　　　　 （４）<br />1.2.2 对功率和与功率呈线性关系的参数的表达<br />　　功率和与功率呈线性关系的参数，这里权且简称为功率型参数，以Ｂ表示，以ｘ表示其单位。以１ｙ为基准值，则Ｂ的电平单位称分贝ｙ，代号为ｄＢｙ，计算公式为<br />　　　　　　　　　　　 　Ｂ（ｙ）<br />　　Ｂ（ｄＢｙ）＝１０lg ————　　　　　　　　　　　　　　　　　     　（５）<br />　　　　　　　　　　　　　１ｙ　　　<br />　　　　　　　　  　Ｂ（ｄＢｙ）<br />　　　　　　　　　　——————<br />　　　　　　　　　　　　１０<br />　　Ｂ（ｙ）＝１０　　　　　　　　　　　　   　　　　　　　　   　　　　　（６）<br />　　Ｂ可以是功率或功率密度，ｙ 可以是 Ｗ、ｍＷ、μＷ，Ｗ/m2、ｍＷ/cm2、μＷ/cm2 、ｐＷ/m2等, 对应的电平单位分别为ｄＢW、ｄＢｍW(常记为ｄＢｍ)、ｄＢμW, ｄＢＷ/m2、ｄＢｍＷ/cm2、ｄＢμＷ/cm2、ｄＢｐＷ/m2等。<br />　　同类功率型电平单位词头之间的转换公式为<br />　　ｄＢｙ＝ｄＢｍｙ＋３０＝ｄＢμｙ＋６０　　　　　　　　　　　    　　　（７）<br />ｄＢｍｙ＝ｄＢμｙ＋３０　　　　　　　　　　　　　　　　　　　      　（８）<br />1.2.3对功率倍数的表达<br />　　以Ｐ１表示输入功率、辐射功率、载波功率(对应的电压有效值为U１,电流有效值为I１)，Ｐ２表示输出功率、接收功率、杂散辐射／邻道功率（对应的电压有效值为U2，电流有效值为I2），仍以ｙ表示Ｐ１、Ｐ２的单位，则传输增益Ｇ或传输损耗Ｌ的分贝表达式为：<br />　　　　　　　　　　　　　　　Ｐ２（ｙ）　　  　　U２（I２）<br />　　Ｇ（或Ｌ）（ｄＢ）＝１０lg ————  ＝２０lg ————  　　　　　    　（９）<br />　　　　　　　　　　　　　　　Ｐ１（ｙ）　　  　　U１（I１）<br />　　这里的ｙ可以是Ｗ、ｍＷ、μＷ、ＫＷ、ＭＷ等，Ｐ１(U１、I１)与Ｐ２(U２、I２)的单位应一致，Ｇ和Ｌ的单位为ｄＢ  。<br />　　杂散辐射相对于载波功率的电平Ｐ杂散辐射和邻道功率相对于载波功率的电平Ｐ邻道功率，其值为负数，单位一般记为ｄＢC（英文carrier有“载波”之意），表达式为：<br />　　　　　　　　　　　　 　        　　Ｐ２（ｙ）<br />　　Ｐ杂散辐射（或Ｐ邻道功率）（ｄＢC）＝１０lg ————         　　　　　　　　（１０）<br />　　　　　　　　　　　　           　　Ｐ１（ｙ）　<br />　　特别地，当U１表示接收机的可用灵敏度,U2分别表示接收机输入比可用灵敏度高３ｄＢ的有用信号而使输出信纳比降回到１２ｄＢ的相邻波道上无用信号电压和落入有用信号工作频率的二信号三阶互调的组合频率的电压（两条频率的电压应相等）时，两电压倍数的分贝值分别表示接收机的邻道选择性Ｐ邻道选择和互调抗扰性Ｐ互调抗扰，其值为正数，单位一般记为ｄＢｒ（英文relative有“相对的” 之意），表达式为：<br />　　　　　　　　　　　　           　 　U２（ｙ）<br />　　Ｐ邻道选择（或Ｐ互调抗扰）（ｄＢｒ）＝２０lg ————  　　  　        　　　（１１）<br />　　　　　　　　　　　　           　   U１（ｙ）　<br />另外，天线增益和噪声系数也可归入此类，详见第6节。<br /><br />2 射频电压<br />　　射频电压一般指电台、仪器射频级和天线系统中所研究频率上信号的电压幅度，按检波方式，可分为平均值(AV)电压、均方根值(RMS)电压、峰值(PEAK)电压等，以下简称为电压。习惯上，信号发生器和接收天线输出端的开路电压称为电动势，以ｅin表示；而当其接上负载（如通信接收机、场强仪、测试接收机、频谱分析仪、综合测试仪的收信端等，下面统称为接收设备,以及假负载）后,其输出端和所接负载输入端的电压称为端电压，以Ｖin表示。电压的线性单位通常有Ｖ、ｍＶ、μＶ，对应的电平单位分别为ｄＢＶ、ｄＢｍＶ、ｄＢμＶ。不同词头的电压单位间的换算可利用（３）、（４）两式。为区别电动势与端电压，通常在电动势单位后加(e.m.f.)或（EMF），而在端电压单位后加（c.c.）或不加注明。<br />　　当信号发生器或接收天线输出端的阻抗与负载阻抗匹配时，电动势为端电压的２倍，即<br />　　ｅin（ΘＶ）＝２Ｖin（ΘＶ）　　　　　　　　　　　　　　　 　　　　　（１２）<br />　　ｅin（ｄＢΘＶ）＝Ｖin（ｄＢΘＶ）＋６.０２   　　　　　　　　　　　　（１３）<br />　　其它参数到接收功率的转换公式有<br />　  Ｐr （ｄＢｍ）＝Ｖin （ｄＢμＶ）－Ｆ（ｄＢ）　　　      　　　　　　（１４）<br />上式中Ｆ为折算系数，Ｆ（ｄＢ）＝９０＋１０ｌｇＲ，Ｒ为接收设备的输入阻抗。当阻抗为５０Ω时，Ｆ＝１０６.９９ｄＢ，当阻抗为７５Ω时，Ｆ＝１０８.７５ｄＢ　。<br />　　Ｅ（ｄＢμＶ/m）＝Ｖin （ｄＢμＶ）＋Ｋ（ｄＢm-1 ）　　              （１５）<br />　　Ｓ（ｄＢＷ/m2）＝Ｖin（ｄＢＶ）＋Ｋ（ｄＢm-1 ）－２５.７６　   　　　（１６）<br />式中Ｋ为天线系数，详见第7节。<br /><br />3 射频功率<br />　　射频功率一般指电台、仪器射频级和天线系统中所研究频率上信号在一个特定的射频周期内输出到负载上的的功率算术平均值, 以下简称为功率。分为峰包功率、平均功率、载波功率等。习惯上, 以Ｐ表示。功率的线性单位通常有Ｗ、ｍＷ、μＷ,对应的电平单位分别为ｄＢW、ｄＢｍW(常记为ｄＢｍ)、ｄＢμW。不同词头的功率单位间的换算可利用（７）、（８）两式。发射功率一般用Ｐt（英文transmit有“发射”之意）表示，接收功率一般用Ｐr（英文receive有“接收”之意）　表示。<br />　　接收功率与其它参数的转换公式为<br />　  Ｖin （ｄＢμＶ）＝Ｐr （ｄＢｍ）＋Ｆ（ｄＢ）　　　　      　　　　　（１７）<br />　　Ｅ（ｄＢμＶ/m）＝Ｐr （ｄＢｍ）＋Ｆ（ｄＢ）＋Ｋ（ｄＢm-1 ）　　  　　（１８）<br />Ｓ（ｄＢＷ/m2）＝Ｐr （ｄＢｍ）＋Ｆ（ｄＢ）＋Ｋ（ｄＢm-1 ）－２５.７６（１９）<br /><br />4 电场强度<br />　　电场强度是长度为１米（ｍ）的天线所感应的电压，简称场强，习惯上以Ｅ表示。场强的线性单位通常有Ｖ/m、ｍＶ/m、μＶ/m,对应的电平单位分别为ｄＢＶ/m、ｄＢｍＶ/m、ｄＢμＶ/m(常记为ｄＢμ)。不同词头的场强单位间的换算可利用（３）、（４）两式。<br />　　场强与其它参数间的折算公式有<br />　　Ｖin（ｄＢΘＶ）＝Ｅ（ｄＢΘＶ/m）－Ｋ（ｄＢm-1 ）　　　　　　　　　 （２０）<br />　　Ｐr （ｄＢｍ）＝Ｅ（ｄＢμＶ/m）－Ｆ（ｄＢ）－Ｋ（ｄＢm-1 ）　　  　　（２１）<br />　　Ｓ（ｄＢＷ/m2）＝Ｅ（ｄＢＶ/m）－２５.７６　　　　　　　   　　　　　（２２）<br />　　Ｓ（ｄＢμＷ/cm2）＝Ｅ（ｄＢμＶ/m）－１２５.７６　　　　　　　   　　（２３）<br /><br />5 功率通量密度<br />　　功率通量密度是电波入射到单位面积上的辐射功率，简称功率密度，通常以Ｓ表示。平均功率密度是电波入射到单位面积上的平均辐射功率。功率密度的线性单位通常有 Ｗ/m2、ｍＷ/cm2、μＷ/cm2 、ｐＷ/m2，对应的电平单位分别为ｄＢＷ/m2、ｄＢｍＷ/cm2、ｄＢμＷ/cm2、ｄＢｐＷ/m2等。功率密度单位间的换算，面积单位相同的可利用（７）、（８）两式。面积单位不同的换算公式为<br />　　Ｓ（Θ Ｗ/m2）＝１００Ｓ（Θ Ｗ/cm2）　　　　　　　 　　　　　　　　（２４）<br />　　Ｓ（ｄＢΘＷ/m2）＝Ｓ（ｄＢΘ Ｗ/cm2）＋４０　　　　　 　　　　　 　（２５）<br />　　功率密度与场强间线性值的折算公式为<br />　　Ｓ（Ｗ/m2）＝Ｅ2（Ｖ/m）／１２０π　　　　　　　　　　　　　　    　（２６）<br />　　Ｓ（μＷ/cm2）＝Ｅ2（μＶ/m）／（１２０π×１０10）　　　　      　　（２７）<br />　　功率通量密度与其它参数的转换公式为<br />　　Ｅ（ｄＢＶ/m）＝Ｓ（ｄＢＷ/m2）＋２５.７６　　　　　　　　　　     　（２８）<br />　　Ｅ（ｄＢμＶ/m）＝Ｓ（ｄＢμＷ/cm2）＋１２５.７６　　　　　　    　　（２９）<br />　　Ｖin（ｄＢＶ）＝Ｓ（ｄＢＷ/m2）－Ｋ（ｄＢm-1 ）＋２５.７６　      　　（３０）<br />Ｐr （ｄＢｍ）＝Ｓ（ｄＢＷ/m2）－Ｆ（ｄＢ）－Ｋ（ｄＢm-1 ）＋２５.７６（３１）<br /><br />6 天线功率增益<br />　　天线在某方向上的辐射强度（每单位立体角内天线所辐射的功率）与天线从其信号源所得净功率的比值的４π倍称为天线在该方向上的功率增益，简称天线增益。天线增益的最大值称为天线峰值功率增益[2]。通常所说的天线增益便指的是天线峰值功率增益，而对非峰值功率增益常常指明是某方向上的增益。<br />　　对通常所说的天线增益，有一个更常见的相对于标准天线的定义：被研究天线在最大辐射方向的辐射强度与和被研究天线具有同等输入功率的标准天线在同一点所产生的最大辐射强度之比[3]。准确地说，这种定义下的天线增益应称为天线的相对增益。当以理想的各向同性辐射器（或称点源辐射器、无方向性天线）为标准天线时，相对增益的定义与前述峰值功率增益的定义是等价的。<br />　　发射天线增益一般用Ｇt　表示，接收天线增益一般用Ｇr　表示。天线增益的线性单位为倍，  以各向同性辐射器为标准天线的增益称绝对增益或无方向增益，其分贝单位为ｄＢ或ｄＢi （英文 isotropic意思是“各向同性的”）， 以半波振子天线为标准天线的分贝单位为ｄＢd（英文 dipole 和doublet均有“对称振子”、“偶极”之意），两者的转换公式为<br />　　Ｇ(相对于各向同性天线的倍数)＝１.６４Ｇ(相对于半波振子天线的倍数 )  　（３２）<br />Ｇ（ｄＢi）＝Ｇ（ｄＢd）＋２.１５　　　　　　　　　　　　   　　　 　（３３）<br /><br />7 天线系数<br />　　天线系数是天线所在点的场强与负载阻抗匹配情况下天线（或包括电缆的天线）输出端电压之比，常用Ｋ或Ｋe 表示（本文用Ｋ表示），单位为m-1 ，分贝表示为ｄＢm-1(天线系数的单位中m为长度单位米的符号)，即<br />　　　　　　　　Ｅ（ΘＶ/m）<br />　　Ｋ（m-1 ）＝——————　　　　　　　　　　　　　　　  　　　　　　（３４）<br />　　　　　　　　Ｖin（ΘＶ）<br />　　Ｋ（ｄＢm-1 ）＝Ｅ（ｄＢΘＶ/m）－Ｖin（ｄＢΘＶ）　      　　　　　　（３５）<br />　　文献［３］规定，天线系数包括天线的有效高度、变换器的损耗、电缆的损耗以及电缆与接收机之间的失配损耗等，而文献［４］称天线系数通常不含电缆损耗。　本文以文献［３］为准。天线系数与天线增益的转换公式为<br />　　Ｋ（ｄＢm-1 ）＝２０ｌｇｆ(MHZ)－Ｇr（ｄＢ d）+ｂr－３１.９２        （３６）<br />式中ｂr为电缆损耗，如果天线增益Ｇr中已包含电缆损耗，则应去掉此项。<br />另外，如果需要加长已知天线系数的天线的电缆，那么，实际的Ｋ值应加上加长电缆的损耗。<br /><a href="http://suncilang.bokee.com/">http://suncilang.bokee.com</a><br />８ 噪声系数<br />噪声系数是接收机或有源器件输入信噪功率比与输出信噪功率比之比。线性值用Fn表示，无量纲；分贝值用ＮＦ表示，有的文献称分贝表示的噪声系数为噪声指数。<br />Fn ＝ 1 + Te/T0<br />其中Te为输入等效噪声温度，T0为规定室温290K 。<br />ＮＦ（ｄＢ）＝１０ｌｇＦn<br /></p><img src ="http://www.cnitblog.com/weitom1982/aggbug/9361.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-04-19 10:52 <a href="http://www.cnitblog.com/weitom1982/archive/2006/04/19/9361.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows服务端口大全 </title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8422.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Fri, 31 Mar 2006 05:52:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8422.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/8422.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8422.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/8422.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/8422.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Windows																																																																														服务端口大全																																																																																							...&nbsp;&nbsp;<a href='http://www.cnitblog.com/weitom1982/archive/2006/03/31/8422.html'>阅读全文</a><img src ="http://www.cnitblog.com/weitom1982/aggbug/8422.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-31 13:52 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/31/8422.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转帖]Windows系统文件名详解 </title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8418.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Fri, 31 Mar 2006 05:49:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8418.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/8418.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8418.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/8418.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/8418.html</trackback:ping><description><![CDATA[
		<div class="postTitle">A　↑ <br />ACCESS.CHM - Windows帮助文件 <br />ACCSTAT.EXE - 辅助状态指示器 <br />ADVAPI32.DLL - 高级Win32应用程序接口 <br />AHA154X.MPD - SCSI驱动程序 <br />AM1500T.VXT - 网卡驱动程序 <br />AM2100.DOS - 网卡驱动程序 <br />APPSTART.ANI - 动画光标 <br />APPS.HLP - Windows帮助文件 <br />AUDIOCDC.HLP - "易码编码解码器"帮助文件 <br />AWARDPR32.EXE - 增加打印机工具 <br />B　↑ <br />BIGMEM.DRV - BIGMEM虚拟设备 <br />BILLADD.DLL - 动态链接库(支持MSW) <br />BIOS.VXD - 即插即用BIOS接口 <br />BUSLOGIC.MPD - SCSI驱动程序 <br /><br />C　↑ <br />CALC.EXE - 计算器应用程序 <br />CANNON800.DRV - 佳能打印机驱动程序 <br />CHOICE.COM - MSDOS命令 <br />CHS16.FON - 字体文件(16点阵中文) <br />CANYON.MID - MIDI文件例子 <br />CARDDRV.EXE - PCMCIA支持程序 <br />CDFS.VXD - CDROM文件系统 <br />CDPLAYER.EXE - CD播放器应用程序 <br />CDPLAYER.HLP - CD播放器帮助文件 <br />CHIPS.DRV - 芯片技术显示驱动程序 <br />CHKDSK.EXE - DOS磁盘检查工具 <br />CHOOSUSR.DLL - 网络客户 <br />CHOKD.WAV - 声音文件例子 <br />CIS.SCP - 脚本文件(演示如何建立与Compuserve的PPP连接) <br />CLAIRE~1.RMI - MINI序列 <br />CLIP.INF - 安装信息文件(剪粘板查看器) <br />CLOSEWIN.AVI - 影片剪辑(AVI)(如何关闭窗口) <br />CMC.DLL:Mail - API1.0公共信息调用 <br />COMBUFF.VXD - COM端虚拟设备 <br />COMCTL32.DLL - 32位Shell组件 <br />COMDLG32.DLL - 32位公共对话库 <br />COMIC.TIF - TrueType字体文件(Comic Sans Ms) <br />COMMAND.COM - 公共对话库 <br />COMMDLG.DLL - 16位公共对话库 <br />COMMON.HLP - OLE帮助文件 <br />COMPOBJ.DLL - OLE16/32互操作库 <br />CONAGEN.EXE - 32位控制支持 <br />CONFAPI.DLL - Microsoft网络组件 <br />CONFIG.SYS - 配置文件 <br />CONFIG.TXT - 自述文件(配置文件中如何使用命令) <br />CONTROL.EXE - "控制面板"应用程序 <br />COOL.DLL - 统一资源定位文件 <br />COPY.INF - 安装信息文件 <br />CP-1250.NLS - 自然语言支持文件 <br />CPQNDIS.DOS - 网卡驱动程序 <br />CPQNDIS3.VXD - Compaq以太控制器NDIS驱动程序 <br />CR3240.EXE - DOS6.22中文版CR3240打印机驱动程序 <br />CRTDLL.DLL - Microsoft C运行时间库 <br />CSETUP.EXE - MSDOS6.22中文设置程序 <br />CSETUP.WIN - CSetup.exe支持文件 <br />CSMAPPER.SYS - 系统文件(支持PCMCIA) <br />CSPMAN.DLL - 动态链接库(SoundBlaster 16 Driver) <br />CTRLPAN.EXE - MSDOS命令(系统控制台程序) <br />CTRLPAN.EXE - MSDOS6.22中文版控制程序 <br /><br />D　↑ <br />DBLBVFF.SYS - 双缓冲驱动程序 <br />DC21X4.SYS - NDIS3驱动程序 <br />DCIMAN.DLL - 显示控制接口 <br />DCIMAN32.DLL - 显示控制接口 <br />DDEML.DLL - DDE信息库 <br />DEBMP.DLL - 光栅显示设备 <br />DEBUG.EXE - Debug调试工具 <br />DECPSMW4.INF - 安装信息文件(DEC打印机安装) <br />DECLAN.VXD - DECLAN网卡驱动程序 <br />DEFRAG - 打开"选定驱动器"窗口 <br />DEL.INF - 安装信息文件 <br />DELTEMP.COM - 初始化帮助工具 <br />DELTREE.EXE - 删除目录工具 <br />DEMET.DLL - 向量显示工程 <br />DESKCP16.DLL - 16位桌面控制面板 <br />DESKTOP.MSN - Microsoft网络组件 <br />DESS.DLL - 表格显示工程 <br />DEWP.DLL - 字处理显示工程 <br />DIALER.CNT - 对话帮助 <br />DIALER.EXE - 电话拨号程序 <br />DIALER.HLP - 电话拨号帮助文件 <br />DIALMON.EXE - 拨号监视程序(IE2.0) <br />DIBENG.DLL - 独立设备的位同工程 <br />DICONIX.DRX - 打印机驱动 <br />DING.WAN - 声音文件例子 <br />DIRECTCC.EXE - 直接线缆连接应用程序 <br />DISKCOMP - 磁盘比较工具 <br />DISKCOPY.COM - 磁盘拷贝工具 <br />DISKDRV.INF - 安装信息 <br />DISPLAY.TXT - 显示卡README文件 <br />DMCOLOR.DLL - 通用打印驱动程序彩打支持库 <br />DOSKEY.COM - DOS命令 <br />DOSX.EXE - MSDOS配置程序 <br />DRAGDROP.AVI - 影片剪辑(AVI)(如何使用拖拽) <br />DRIVER.SYS - DOS驱动程序 <br />DRVSPACE.EXE - 磁盘压缩工具 <br />DRVSPACE.HLP - 磁盘空间管理帮助文件 <br /><br />E　↑ <br />EDIT.COM - DOS文字编辑程序 <br />EDLIN.EXE - DOS行编辑器 <br />EE16.VXD - 虚拟设备驱动程序 <br />EISA.VXD - 即插即用EISA总线计数器 <br />EK550C.ICM - 打印机简介 <br />EMM386.EXE - 扩展内存管理程序 <br />ENABLE.INF - 初始化信息 <br />ENGCT.EXE - MSN支持文件 <br />ESCP24SC.DRV - 设备驱动程序 <br />EUDCEDIT.CNF - 帮助索引文件(造字程序) <br />EUDCEDIT.EXE - 造字程序 <br />EUDCEDIT.HLP - 帮助文件(造字程序) <br />EUDCEDIT.INF - 安装信息文件(造字程序) <br />EVX16.DOS - 网卡驱动程序 <br />EWRK3.DOS - 网卡驱动程序 <br />EWRK3.SYS - 网卡驱动程序 <br />EXCEL.XLS - Excel5.0文件模板 <br />EXCEL4.XLS - Excel4.0文件模板 <br />EXCHANGE.TXT - Inbox和Exchange的自述文件 <br />EXCHNG.CNT - Mail/Exchange帮助文件内容 <br />EXCHNG.HLP - Mail/Exchange组件 <br />EXCHNG32.EXE - 对用户的交换机作初始设置 <br />EXPLORER.AVI - 影片剪辑(AVI)(如何使用资源管理器) <br />EXPLORER.EXE - "资源管理器"应用程序 <br />EXPO.HLP - 帮助文件(产品信息) <br />EXPOSTRT.EXE - 产品信息应用程序 <br />EXTRACT.EXE - 解压缩工具 <br />EXTRA.TXT - 自述文件(联机访问附加文件) <br /><br />F　↑ <br />FAQ.TXT - 疑难解答自述文件 <br />FAXCODEC.DLL - 传真编码/译码器 <br />FAXCOVER.EXE - 封面编辑器 <br />FC.EXE - DOS命令,比较两个文件 <br />FD16-700.MPD - SCSI驱动程序 <br />FD8XX.MPD - SCSI驱动程序 <br />FDISK.EXE - DOS命令,在硬盘上建立、删除及显示当前分区 <br />FILESEC.VXD - 文件存取控制管理器 <br />FILEXFER.CNT - 文件传输帮助文件内容 <br />FILEXFER.EXE - Microsoft文件传输 <br />FIND.AVI - 影片剪辑(如何使用查找) <br />FIND.EXE - 寻找指定字符串命令 <br />FINDMVI.DLL - 媒体视觉支持 <br />FINSTALL.DLL - 字库安装程序 <br />FINSTALL.HLP - 字库安装帮助文件 <br />FLSIMTD.VXD - PCMCIA支持 <br />FLSIMTD.VXD - PCMCIA支持 <br />FONT16.EXE - DOS6.22中文版16点阵字体驱动程序 <br />FONTS.INF - 字体选择初始化信息 <br />FONTVIEW.EXE - 字体浏览程序 <br />formAT.COM - DOS磁盘格式化工具 <br />FOUTLINE.EXE - 轮廓字体驱动程序 <br />FRAMEBUF.DRV - SVGA显示器驱动程序 <br />FTE.DLL - 声音浏览文件传输工程文件 <br />FTP.EXE - 文件传输协议TCP工具 <br />FURELI~1.RMI - MINI序列 <br />G　↑ <br />GBK.TXT - 中文Windows95GBK代码集字符定义表 <br />GDI.EXE - 简版WIN3.1图形界面 <br />GDI32.DLL - 32位GDI图形界面 <br />GENERAL.IDF - 一般MIDI指示器 <br />GRPCONV.EXE - Windows程序组转换器 <br />GUIDE.EXE - 应用程序(MSN) <br /><br />H　↑ <br />HARDWARE.TXT - 硬件自述文件 <br />HOSTS.SAM - TCP配置 <br />HPCLRLSK.ICM - 打印简介 <br />HPDESK.ICM - 打印机简介表 <br />HPDSKJET.DRV - 打印机驱动程序 <br />HPEISA.VXD - 网络适配器驱动程序 <br />HPJAHLP.CNT - JetAdmin程序帮助文件 <br />HPJD.DLL - HPJetAdmin支持程序 <br />HPLAN.DOS - 网络适配器驱动程序 <br />HPLJ300.DRV - HPLJ300DPI打印机驱动程序 <br />HPLJ300.EXE - MSDOS命令(HP打印机驱动) <br />HPLJ-31.SPD - 打印机驱动程序 <br />HPLJ600.DRV - HPLJ600DPI打印机驱动程序 <br />HPLJP-V4.INF - 打印机安装信息 <br />HPNETPRN.INF - HPJetAdmin支持程序 <br />HPPJXL31.SPD - 打印机驱动程序 <br />HPPLOT.DRV - 打印机驱动程序 <br />HPPLOT.HLP - 打印机驱动程序帮助文件 <br />HPPRARBK.DLL - HPJetAdmin支持程序 <br />HPPRARRK.HLP - HPJetAdmin支持程序帮助文件 <br />HPVCM.HPM - 打印机驱动程序 <br />HSFLOP.PDR - HSFLOP虚拟设备 <br />HTICONS.DLL - 终端设备动态链接库 <br />HYPERTRM.CNT - 终端设备帮助文件 <br />HYPERTRM.EXE - 终端设备应用程序 <br />HYPERTRM.HLP - "超级终端"帮助 <br />HZKBD.EXE - 常用输入方法程序 <br />HZVIO95.EXE - 显示驱动程序 <br /><br />I　↑ <br />I82593.DOS - 网络适配器驱动程序 <br />IB401917.SPD - 打印机驱动程序 <br />IBM20470.SPD - 打印机驱动程序 <br />IBM20K.DOS - 网络适配器驱动程序 <br />ICM32.DLL - 图象颜色匹配程序 <br />ICMOI.DLL - 用户界面颜色匹配程序 <br />ICONLIB.DLL - 图符库 <br />IEXPLORE.CNT - 帮助索引文件(IE) <br />IEXPLORE.EXE - InternetExplore <br />IEXPLORE.HLP - 帮助文件(IE) <br />IFSHLP.SYS - 文件系统安装帮助文件 <br />IFSMGR.VXD - 文件系统安装管理程序 <br />IMAGEOIT.EXE - 图象编辑器光标程序 <br />IMCLIENT.DLL - Microsoft网络组件 <br />IME.CNT - 帮助索引文件(中文输入法) <br />IME.HLP - Windows帮助文件 <br />IME.INF - 安装信息文件(中文输入法) <br />IMEGEN.CNF - 帮助索引文件(输入法生成器) <br />IMEGEN.EXE - 输入法生成器 <br />IMEGEN.HLP - 帮助文件(输入法生成器) <br />IMEINFO.INI - 输入法初始化文件 <br />IMM32.DLL - WIN32IMM应用程序界面 <br />INBOX.EXC - 邮件组件 <br />INDICDLL.DLL - 多语言组件 <br />INET.TXT - IE自述文件 <br />INET16.DLL - 动态链接库(支持IE2.0) <br />INETAB32.DLL - 动态链接库(支持Internet mail) <br />INETCFG.DLL - 动态链接库(支持IE2.0) <br />INETCPL.CPL - 控制面板文件(配置IE2.0) <br />INETMAIL.INF - 安装信息文件(Internet mail) <br />INETWIZ.EXE - Internet安装向导 <br />INformS.WPF - 样板文件 <br />INSTBE.BAT - Microsoft网络组件 <br />INSTDICT.EXE - MSDOS命令(输入法安装程序) <br />INTB.VXD - 13号中断虚拟设备 <br />INTL.CPL - 控制面板 <br />INT-MAIL.CNT - 帮助索引文件(Internet mail) <br />IOS.INI - 设置需要安全保护的程序 <br />IOSCLASS.DLL - CDROM安装程序 <br />IRMATR.DOS - 网络适配器驱动程序 <br />ISAPNP.VXD - ISA总线即插即用程序 <br />　↑ <br />JOY.CPL - 游戏杆控制面板 <br />JOYSTICK.INF - 多媒体安装信息 <br />JP350.DRV - 打印机驱动程序 <br />JUNGLE~1.WAV - 声音文件 <br /><br />K　↑ <br />KBDBE.KBD - 比利时键盘格式 <br />KBDBR.KBD - 巴西键盘格式 <br />KBDCA.KBD - 法国、加拿大键盘格式 <br />KBDOS.KBD - 美国键盘格式 <br />KDCOLOR1.SPD - 打印机驱动程序 <br />KERNEL32.DLL - 32位内核 <br />KEYB.COM - 将控制键盘程序装入内存 <br />KODAKCE.ICM - 柯达ICC配置文件 <br />KRNL386.EXE - Core应用程序 <br /><br />L　↑ <br />LABEL.EXE - DOS命令,设置磁盘名称 <br />LFNBK.EXE - 长文件名备份文件 <br />LFNBK.TXT - LFNBK的自述文件 <br />LICENSE.HLP - Windows帮助文件 <br />LMSCRIPT.EXE - LAN管理器文稿处理程序 <br />LOGIN.EXE - Win95登录NetWare文件 <br />LQ1600K.EXE - LQ1600K打印驱动程序 <br /><br />M　↑ <br />MAILMSG.DLL - 微软网络组件 <br />MAILOPT.INF - MAIL/MAPI设置文件 <br />MAPI.DLL - Mail/Exchange组件 <br />MCIAVI.DRV - 多媒体驱动程序 <br />MCICDA.DRV - MCICD声音驱动程序 <br />MCIOLE.DLL - MCIOLE句柄 <br />MCIPIONR.DRV - MCI光盘驱动程序 <br />MCISEQ.DRV - MCI定序器驱动程序 <br />MCIVISCA.DRV - MCIVCR驱动程序 <br />MCIWAVE.DRV - MCI Ware驱动程序 <br />MDMNOKIA.INF - 安装信息文件(modem) <br />MDMNOVA.INF - 安装信息文件(modem) <br />MDMVV.INF - 安装信息文件(modem) <br />MEMMAKER.EXE - 内存管理程序 <br />MEMMAKER.INF - 内存管理程序设置信息 <br />MFCUIA32.DLL - OLEI公共对话动态链接库 <br />MIDI.INF - 即插即用MIDI设备信息 <br />MINET32.DLL - 支持Internet Mail动态链接库 <br />MKECR5XX.MPD - SCSI驱动程序 <br />ML3XEC16.EXE - 应用程序(MAPI) <br />MLSHEXT.DLL - 微软核扩展库 <br />MMCI.DLL - 媒体类安装程序 <br />MMDEVLDR.VXD - 即插即用设备装载程序 <br />MMDRV.HLP - 多媒体帮助文件 <br />MMSOUND.DRV - 多媒体驱动程序 <br />MMSYSTEM.DLL - 多媒体系统内核 <br />MMTASK.TSK - 多媒体背景任务交换器 <br />MODE.COM - DOS命令 <br />MODERN.FON - 字体文件(modem) <br />MORE.COM - DOS命令 <br />MOUSE.DRV - 鼠标驱动程序 <br />MOVEWIN.AVI - 影片剪辑(如何移动窗口) <br />MPLAYER.EXE - 媒体播放程序 <br />MPR.DLL - WIN32网络接口动态链接库 <br />MSAB32.DLL - 微软网络地址簿 <br />MSBASE.INF - 设置信息 <br />MSCDEX.EXE - DOS MSCDEX CDROM扩展工具 <br />MSCDROM.INF - 类安装设置信息 <br />MSD.EXE - 微软诊断工具 <br />MSD.INI - 微软诊断初始化 <br />MSDET.INF - 系统检测设置信息 <br />MSDISP.INF - 显示设置信息 <br />MSDLG.EXE - 数据链接控制协议 <br />MSDOS.INF - 设置信息 <br />MSDOSDRV.TXT - 设备驱动程序自述文件 <br />MSFT.VRL - 统一资源定位文件 <br />MSGSRV32.EXE - Windows32位虚拟设备信息系统 <br />MSHDC.INF - 硬盘控制设置信息 <br />MSJSTICK.DRV - 即插即用游戏杆驱动程序 <br />MSMAIL.INF - Mail/MAPI初始化 <br />MSMOUSE.INF - 鼠标设置信息 <br />MSN.TXT - 微软网络自述文件 <br />MSNET32.DLL - 微软32位网络API库 <br />MSNEXCH.EXE - 微软网络设置程序 <br />MSNPSS.HLP - 微软网络帮助文件 <br />MSNVER.TXT - 微软网络帮助信息 <br />MSPAINT.EXE - 画图工具 <br />MSPCIC.DLL - PCMCIA类安装与控制工具 <br />MSPORTS.INF - 公共设置信息 <br />MSPP32.DLL - 微软网络打印支持程序 <br />MSPWL32.DLL - 口令清单管理库 <br />MSSBLST.DRV - 声霸卡驱动程序 <br />MSSBLSI.VXD - 声霸卡驱动程序 <br />MSSHRVI.DLL - 共享内核扩展程序 <br />MSSNDSYS.DRV - Windows声音系统驱动程序 <br />MSSP.VXP - Windows NT安全支持 <br />MSTCP.DLL - TCP用户界面 <br />MSVIEWUT.DLL - 显示设备服务数据链接库 <br />MTMMINIP.MPD - SCSI驱动程序 <br />MULLANG.INF - 多种语言字体支持设置信息 <br />MVIWAVE.DRV - 声音驱动程序 <br /><br />N　↑ <br />NBTSTAT.EXE - TCP工具 <br />NDDEAPI.DLL - Workgroups DDE共享接口 <br />NDDENB.DLL - 微软网络DDE NetBIOS接口 <br />NDISHLP.SYS - 实模式NDIS支持驱动程序 <br />NET.EXE - 实模式网络客户软件 <br />NET.INF - 网络检测信息 <br />NET.MSG - 网络客户信息 <br />NET3COM.INF - 网络设置信息 <br />NETAMD.INF - 网络设置信息 <br />NETAPI.DLL - 网络应用程序接口动态链接库 <br />NETAPI32.DLL - 32位网络API动态链接库 <br />NETAVXT.INF - MS内部传输文件 <br />NETBEUI.VXD - 32位NetBEUI协议 <br />NETBIOS.DLL - NetBIOSAPI库 <br />NETDCA.INF - 安装信息文件 <br />NETDDE.EXE - Windows网络动态数据交换 <br />NETDET.INI - NetWare检测文件 <br />NETDI.DLL - 网络设备安装 <br />NETH.MSG - 网络客户帮助信息 <br />NETOS.DLL - NOS检测DLL <br />NETWATCH.EXE - 网络观测程序 <br />NETWORK.TXT - 网络信息自述文件 <br />NOTEPAD.EXE - 记事本应用程序 <br />NODRIVER.INF - 即插即用设备信息 <br />NOTEPAD.EXE - NOTEPAD文件 <br />NSCL.VXD - NSCL虚拟设备 <br />NW16.DLL - NetWare客户 <br />NWAB32.DLL - 地址簿支持动态链接库 <br />NWLSCON.EXE - 登录文稿控制台程序 <br />NWLSPROC.EXE - NetWare登录处理器 <br />NWNET32.DLL - NetWare客户 <br />NWNP32.DLL - NetWare组件 <br />NWREDIR.VXD - NetWare重定向 <br />NWSERVER.VXD - NCP服务 <br />NWSP.VXD - NCP服务安全提供 <br /><br />O　↑ <br />OEMREVA.INF - 安装信息文件 <br />OLE2.DLL - OLE2.0动态链接库 <br />OLE2.INF - OLE设置信息 <br />OLE32.DLL - 32位OLE2.0组件 <br />OLEAUT32.DLL - OLE2-32自动化 <br />OLECL1.DLL - 对象链接与嵌入客户库 <br />OLEDLG.DLL - Windows OLE2.0用户接口支持 <br />OLESVR.DLL - 对象链接与嵌入服务端库 <br />OLETHK32.DLL - OLE形实替换程序库 <br /><br />P　↑ <br />PACKAGER.EXE - 对象包装程序 <br />PARALINK.VXD - 远程网络存取并行口驱动程序 <br />PBRVSH.EXE - "画图"应用程序 <br />PDOS95.BAT - 进入中文DOS状态 <br />PERF.VXD - 系统性能监视器 <br />PIFMGR.DLL - 程序信息文件管理服务程序 <br />PING.EXE - TCPPing工具 <br />PMSPL.DLL - LAN管理应用程序接口 <br />POWER.DRV - 高级电源管理驱动程序 <br />PPPMAC.VXD - Windows虚拟PPP驱动程序 <br />PRINT.EXE - DOS打印文件 <br />PRINTERS.TXT - 打印信息自述文件 <br />PROGMAN.EXE - 程序管理器 <br />PRTVPD.INF - 打印机升级设置信息 <br /><br />Q　↑ <br />QUIKVIEW.EXE - 快速查看 <br />QUIT.EXE - 退出中文DOS状态 <br /><br />R　↑ <br />README.TXT - Windows95自述文件 <br />REGEDIT.EXE - 注册编辑器 <br />REGSERV.EXE - 远程注册 <br />REGWIE.EXE - 注册工具 <br />REGSERV.INF - 远程注册 <br />RESTORE.EXE - DOS命令 <br />RNAAPP.EXE - 拨号网络应用程序 <br />RNASERV.DLL - 远程网络存取服务 <br />RNASETUP.DLL - 远程网络存取设置动态链接库 <br />RNATHUNK.DLL - 远程网络存取转换支持动态链接库 <br />RNAUI.DLL - 远程网络存取用户接口DLLRNDSRV32.DLL复制服务程序 <br />ROBOTZCL.WAV - 声音文件 <br />ROBOTZWI.WAV - 声音文件 <br />ROMAN.FON - 字型文件 <br />ROUTE.EXE - TCP/IP ROUTE命令 <br />RPCLTC1.DLL - 远程调用库 <br />RPCNS4.DLL - 远程调用库 <br />RPCPP.DLL - 远程调用打印驱动 <br />RPCRT4.DLL - 远程调用库 <br />RPCSS.EXE - 远程调用结点映象 <br />RPLBOOT.SYS - 远程程序装入 <br />RPLIMAGE.DLL - 远程程序装入磁盘映象器 <br />RSRC16.DLL - 资源计量器 <br />RSRCMTR.EXE - 资源计量器 <br />RSRCMTR.INF - 资源计量器 <br />RUMOR.EXE - DDE测试/游戏 <br />RUNDLL.EXE - 把DLL作为应用程序运行 <br />RUNDLL32.EXE - 32位壳组件 <br />S　↑ <br />S3.DRV - S3显示驱动 <br />S3.VXD - S3虚拟设备 <br />SACLIEN.DLL - Microsoft网络组件 <br />SAMPLEVIDEOS - 图象文件 <br />SAPNSP.DLL - Winsock数据连接库 <br />SAVE32.COM - 安装时所需的TSR文件 <br />SB16.VXD - 16位声卡虚拟设备 <br />SB16SND.DRV - 16位声卡驱动 <br />SBAWE.VXD - AWE声卡虚拟设备 <br />SBAWE32.DRV - AWE声卡驱动 <br />SBFM.DRV - 16位声卡驱动 <br />SCANDISK.BAT - MSDOS6.x Scandisk的替代存根模块SCANDISK.BAT磁盘诊断工具 <br />SCANDISK.INI - 磁盘诊断工具 <br />SCANDISK.PIF - 安装磁盘诊断工具时的PIF文件 <br />SCANDSKW.EXE - 磁盘扫描工具 <br />SCANPROG.EXE - 磁盘扫描工具 <br />SCRNSAVE.SCR - 屏幕保护 <br />SCSI.INF - SCSI安装文件文件名描述 <br />SCSIIHLP.VXD - SCSI支持文件 <br />SCSIPORT.PDR - SCSI虚拟设备口 <br />SECUR32.DLL - Microsoft Win32安全服务 <br />SECURCL.DLL - Microsoft网络组件 <br />SEIKO24E.DRV - 打印机驱动 <br />SEIKOSH9.DRV - 打印机驱动 <br />SERIAL.VXD - 串口VCOMM驱动器 <br />SERIFE.FON - 字型文件 <br />SERVER.HLP - 服务器帮助文件 <br />SETMDIR.EXE - SBS文件 <br />SETUP.BIN - 安装支持文件 <br />SETUP.BMP - 安装Wash位图文件 <br />SETUP.EXE - Windows95安装程序 <br />SETUP.INF - 安装信息文件 <br />SETUP.TXT - 安装时的README文件 <br />SETUP4.DLL - 安装支持文件 <br />SETUPPP.INF - 安装信息 <br />SETUPX.DLL - 安装支持 <br />SETVER.EXE - MSDOS版本显示,该程序可在网络上执行 <br />SF4029.EXE - 打印机驱动 <br />SHARE.EXE - MSDOS共享实用程序 <br />SHELL.INF - 安装壳信息 <br />SHELL.VXD - 虚拟壳设备 <br />SHELL2.INF - 颜色组合 <br />SHELL3.INF - 颜色组合 <br />SIZE1-1.CUR - 光标 <br />SIZE1-M.CUR - 光标 <br />SIZE4-M.CUR - 光标 <br />SIZENESW.ANI - 活动光标 <br />SIZEWE.ANI- 活动光标 <br />SKPSFA-1.SPD - 打印机驱动 <br />SLAN.DOS - 网络适配器驱动 <br />SLCD32.MPD - SCSI驱动器 <br />SLENH.DLL - 高级节能选项 <br />SMALLE.FON - 字型文件 <br />SMALLF.FON - 字型文件 <br />SMARTDRV.EXE - 超高速缓存程序 <br />SMARTND.DOS - 网络适配器驱动器 <br />SMC3000.DOS - 网络适配器驱动器 <br />SMC9000.VXD - 网络适配器驱动器 <br />SNAPSHOT.EXE - 抽点 <br />SNAPSHOT.VXD - 抽点虚拟设备 <br />SNDREC32.EXE - 录音机 <br />SNIP.VXD - 网络适配驱动器 <br />SOCKET.VXD - Windows虚拟Socket网卡驱动器SOCKET.VXD PCMCIA支持 <br />SOL.CNT - 纸牌游戏 <br />SOL.HLP - 纸牌游戏帮助文件 <br />SORT.EXE - MSDOS分类实用程序 <br />SOUNDREC.CNT - 录音机帮助文件内容 <br />SOUNDREC.HLP - 录音机帮助文件 <br />SPARROW.WPD - SCSI驱动器 <br />SPARROWX.MPD - SCSI驱动器 <br />SPOOL32.EXE - 打印机支持 <br />SPOOLER.VXD - 打印机共享虚拟设备 <br />SRAMMTD.VXD - PCMCIA支持 <br />SSERIFE.FON - 字型文件 <br />SSERIFF.FON - 字型文件 <br />SSFLYWIN.SCR - 屏幕保护 <br />SSSTARS.SCR - 屏幕保护 <br />STAR24E.DRV - 打印机驱动 <br />STAR9E.DRV - 打印机驱动 <br />START.EXE - 启动程序 <br />STATE.PBK - Microsoft网络组件 <br />STDOLE.TLB - OLE2.0文件 <br />STDOLE32.TLB - OLE2-32文件 <br />STEMO409.DLL - Windows95帮助文件的DLL <br />STLSO4SS.SPD - 打印机驱动程序 <br />STLS577U.SPD - 打印机驱动程序 <br />STORAGE.DLL - OLE存储器管理库 <br />STRN.DOS - 网络适配器驱动 <br />SUBST.EXE - MSDOS Subst实用程序 <br />SUEXPAND.DLL - LZ DLL安装 <br />SUHELPER.BIN - 安装支持 <br />SUPERVGA.DRV - 高级VGA显示驱动 <br />SURPORT.TXT - PSS支持信息 <br />SVCPROP.DLL - Microsoft网络组件 <br />SVRAPI.DLL - 32位公用服务器API实用程序 <br />SXCIEXT.DLL - Matrox显示驱动支持文件 <br />SYMBOLE.FON - 字型文件 <br />SYS.COM - MSDOS系统实用程序 <br />SYSCLASS.DLL - 系统类库安装 <br />SYSDETMG.DLL - 系统检测库 <br />SYSEDIT.EXE - 系统编辑器 <br />SYSLOGO.RLE - 系统标识 <br />SYSMON.EXE - 系统监控程序 <br />SYSMON.HLP - 系统监控帮助 <br />SYSTEM.DRV - 最小Win3.1标准模式 <br />SYSTHUNK.DLL - Windows系统形实替换程序库 <br />SYSTRAY.EXE - 高级节能管理 <br /><br />T　↑ <br />T128.MPD - SCSI驱动器 <br />T160.MPD - SCSI驱动器 <br />T20N3.VXD - 网络适配驱动器 <br />T30ND.DOS - 网络适配驱动器 <br />T338.MPD - SCSI驱动器 <br />TADA.WAV - 声音文件 <br />TAPI.DLL - API通话程序 <br />TAPI.INF - API通话安装信息文件 <br />TAPI32.DLL - 32位形实替换 <br />TAPIADDR.DLL - API通话程序 <br />TAPIEXE.EXE - API通话组件 <br />TAPIINI.EXE - API通话组件 <br />TASKMAM.EXE - 任务管理器 <br />TCCARC.DOS - 网络适配驱动器 <br />TCTOKCH.VXD - 网络适配驱动器 <br />TELEPHON.CPL - 通话帮助 <br />TESTPS.TXT - PostScript测试 <br />TEXTCHAT.EXE - Microsoft网络组件 <br />THEMIC-1.WAV - 声音文件 <br />THINKJET.DRV - 打印机驱动 <br />THREED.VBX - Windows95浏览 <br />T1850.DRV - 打印机驱动 <br />TIMEDATE.CPL - 时间/日期控制面板 <br />TIMES.TTF - 时间字型 <br />TIMESBD.TTF - 时间粗体字型 <br />TIMESBI.TTF - 时间粗斜体字型 <br />TIMESI.TTF - 时间斜体字型 <br />TIMEZONE.INF - 安装信息 <br />TIMLP232.SPD - 打印机驱动 <br />TIPS.txt - 提示和技巧自述文件 <br />TKPHZR32.SPD - 打印机驱动 <br />TLNK.DOS - 网络适配驱动器 <br />TLNK3.VXD - 网络适配驱动器 <br />TMV1.MPD - SCSI驱动器 <br />TOOLHELP.DLL - 16位开发工具帮助器 <br />TOSHIBA.DRV - 打印机驱动 <br />TOUR.EXE - 浏览文件 <br />TPHAIII.ICM - 打印机简介 <br />TRACERT.EXE - TCP/IP IRACEROUTE命令 <br />TREE.COM - MS DOS树实用程序 <br />TREEEDCL.DLL - Microsoft网络组件 <br />TREENVCL.DLL - Microsoft网络组件 <br />TRIUMPHI.SPD - 打印机驱动 <br />TSD32.DLL - 声音压缩管理器 <br />TSENG.DRV - ET4000W32显示驱动 <br />TTY.DRV - 打印机驱动 <br />TTY.HLP - TTY打印机驱动帮助 <br />TYPELIB.DLL - OLE2.0 <br /><br />U　↑ <br />U9415470.SPD - 打印机驱动 <br />UBNEI.DOS - 网络适配器驱动 <br />ULTRA124.MPD - SCSI驱动器 <br />ULTRA24F.MPD - SCSI驱动器 <br />UMDM16.DLL - 通用调制解调器驱动组件 <br />UMDM32.DLL - 通用调制解调器驱动组件 <br />UNIDRV.DLL - Microsoft通用打印机驱动库 <br />UNIDRV.HLP - 通用打印机驱动帮助 <br />UNIMODEM.VXD - 通用调制解调器驱动 <br />USER32.DLL - 32位用户 <br /><br />V　↑ <br />V86MMGR.VXD - V86MMGR虚拟设备 <br />VCACHE.VXD - VCache虚拟设备 <br />VCD.VXD - 虚拟COM驱动程序 <br />VCOMM.VXD - VCOMM驱动程序 <br />VCOND.VXD - Win32控制台 <br />VDMAD.VXD - VDMAD虚拟设备 <br />VER.DLL - 小型Win3.1安装程序16位版动态链接库 <br />VER.NEW - 版本检测与文件安装库 <br />VERSION.DLL - 32位版本动态链接库 <br />VERX.DLL - 安装程序使用的版本动态库 <br />VFAT.VXD - VFAT文件系统 <br />VFD.VXD - 软盘虚拟设备 <br />VFLATD.VXD - 虚拟平板帧缓存虚拟设备 <br />VGA.DRV - VGA显示驱动程序 <br />VIDCAP.INF - 即插即用VCD信息 <br />VIDEOT.VXD - 视频虚拟设备 <br />VIP.386 - TCP/IP虚拟IP设备 <br />VJOYD.VXD - 游戏棒虚拟设备 <br />VKD.VXD - 虚拟键盘设备 <br />VLB32.DLL - Mail/Exchange组件 <br />VMD.VXD - Win3.1虚拟鼠标驱动程序 <br />VMM.VXD - 虚拟存储管理设备 <br />VMM32.VXD - 虚拟存储管理设备 <br />VMOUSE.VXD - 虚拟鼠标驱动程序 <br />VNBT.386 - NetBIOS传输驱动程序 <br />VNETBIOS.VXD - VNETBIOS虚拟设备 <br />VNETSUP.VXD - 网络支持虚拟设备 <br />VPD.VXD - 虚拟LPT驱动程序 <br />VPICD.VXD - 虚拟可编程干扰控制器设备 <br />VPOWERD.VXD - 高级电源管理虚拟设备 <br />VREDIR.VXD - Microsoft网络32位客户端程序 <br />VSAMI.DLL - AMI文件语法分析程序 <br />VSASC8.DLL - ASCII文件语法分析程序 <br />VSBMP.DLL - BMP文件语法分析程序 <br />VSERVER.VXD - Microsoft网络32位服务器端程序 <br />VSGIF.DLL - GIF文件语法分析程序 <br />VSHARE.VXD - 32位共享虚拟设备驱动程序 <br />VSMSW.DLL - Win写文件语法分析 <br />VSPP.DLL - PowerPoint语法分析程序 <br />VSRTF.DLL - RTF文件语法分析程序 <br />VSTIFF.DLL - TIFF文件语法分析程序 <br />VSW6.DLL - Word6文件语法分析程序 <br />VSWORD.DLL - Word文件语法分析程序 <br />VSWP5.DLL - WordPerfect5文件语法分析程序 <br />VSXL5.DLL - Excel文件/图表语法分析程序 <br />VTCP.386 - TCP/IP虚拟TCP驱动程序 <br />VTDAPI.VXD - VTDAPI虚拟设备 <br />VTDI.386 - 传输驱动接口支持程序 <br />VXDLDR.VXD - 虚拟设备驱动程序装载器 <br /><br />W　↑ <br />WAVE.INF - 即插即用音波设备信息 <br />WDTOOOEX.MPD - SCSI驱动 <br />WGPOADMN.DLL - Mail/Exchange组件 <br />WHLP16T.DLL - 帮助动态链接库 <br />WIN87EM.DLL - 80387数学仿真库 <br />WINABC.HLP - 智能ABC帮助文件 <br />WINBX.HLP - 表形码输入法帮助文件 <br />WINCHA.HLP - 繁体仓颉输入法帮助文件 <br />WINDOWS.CNT - Windows95帮助文件内容 <br />WINDOWS.HLP - Windows95帮助文件 <br />WINFILE.CNT - 文件管理器帮助文件内容 <br />WINFILE.EXE - Windows工作组文件管理器 <br />WINFILE.HLP - 文件管理器帮助文件 <br />WINGB.HLP - 区位码输入法帮助文件 <br />WINHLP23.HLP - Windows帮助文件 <br />WINIME.HLP - 操作指南帮助文件 <br />WINNM.HLP - GBK内码输入法帮助文件 <br />WININIT.EXE - Windows初始化文件 <br />WINIPCFG.EXE - TCP/IP配置工具 <br />WINNEWS.TXT - Winnews信息 <br />WINPHO.HLP - 繁体注音输入法帮助文件 <br />WINPOPUP.EXE - POPUP工具 <br />WINREG.DLL - 远程注册支持 <br />WINPY.HLP - 全拼输入法帮助文件 <br />WINSOCK.DLL - Windows的套接API <br />WINSY.HLP - 双拼输入法帮助文件 <br />WINXSP.HLP - GBK双拼输入法帮助文件 <br />WINXZM.HLP - GBK郑码输入法帮助 <br />WINZM.HLP - 郑码输入法帮助文件 <br />WNASPI32.DLL - Windows DLL32位ASPI <br />WPSUNI.DRV - 传真驱动程序 <br />WPSUNIRE.DLL - WPS主机资源执行程序 <br /><br />X　↑ <br />XCOPY.EXE - DOS XCOPY工具 <br />XCOPY32.EXE - 文件拷贝程序 <br />XGA.DRV - XGA显示驱动程序<br /></div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/8418.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-31 13:49 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/31/8418.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows常用命令集。</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8383.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Fri, 31 Mar 2006 04:44:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8383.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/8383.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8383.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/8383.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/8383.html</trackback:ping><description><![CDATA[
		<div class="postTitle"> 开始→运行→输入的命令集锦<br />mstsc--远程桌面连接<br />logoff--注销命令<br />rononce －p --15秒关机<br />tsshutdn--60秒倒计时关机命令<br />iexpress--木马捆绑工具，系统自带<br />tourstart--xp简介（安装完成后出现的漫游xp程序）<br />winchat--XP自带局域网聊天<br />sndrec32--录音机<br />Nslookup--IP地址侦测器<br />explorer--打开资源管理器<br />lusrmgr.msc--本机用户和组<br />services.msc－－－本地服务设置<br />oobe/msoobe /a--检查XP是否激活<br />notepad--－打开记事本<br />cleanmgr--**整理<br />net start messenger--开始信使服务<br />compmgmt.msc－－－计算机管理<br />net stop messenger--－停止信使服务<br />conf----启动 netmeeting<br />dvdplay--－DVD播放器<br />charmap--－启动字符映射表<br />diskmgmt.msc－－－磁盘管理实用程序<br />calc----启动计算器<br />dfrg.msc--磁盘碎片整理程序<br />chkdsk.exe--－Chkdsk磁盘检查<br />devmgmt.msc－－－ 设备管理器<br />regsvr32 /u *.dll--停止dll文件运行<br />drwtsn32--－－ 系统医生<br />rononce －p --15秒关机<br />dxdiag--－－检查DirectX信息<br />regedt32--注册表编辑器<br />Msconfig.exe－－－系统配置实用程序<br />rsop.msc--组策略结果集<br />mem.exe--－显示内存使用情况<br />regedit.exe--注册表<br />progman--－程序管理器<br />winmsd--－－系统信息<br />perfmon.msc--计算机性能监测程序<br />winver--－－检查Windows版本<br />sfc /scannow--－扫描错误并复原<br />taskmgr--－任务管理器（2000／xp／2003）<br />wmimgmt.msc--打开windows管理体系结构(WMI)<br />wupdmgr--－windows更新程序<br />w脚本--－windows脚本宿主设置<br />write--－－－写字板<br />winmsd--－－系统信息<br />wiaacmgr--扫描仪和照相机向导<br />mem.exe--－显示内存使用情况<br />Msconfig.exe－－－系统配置实用程序<br />mplayer2--简易widnows media player<br />mspaint--－画图板<br />mplayer2--媒体播放机<br />magnify--－放大镜实用程序<br />mmc----－打开控制台<br />mobsync--－同步命令<br />dxdiag--－－检查DirectX信息<br />drwtsn32--－－系统医生<br />devmgmt.msc－－－设备管理器<br />dfrg.msc--磁盘碎片整理程序<br />diskmgmt.msc－－－磁盘管理实用程序<br />dcomcnfg--打开系统组件服务<br />ddeshare--打开DDE共享设置<br />dvdplay--－DVD播放器<br />net stop messenger--－停止信使服务<br />net start messenger--开始信使服务<br />notepad--－打开记事本<br />nslookup--网络管理的工具向导<br />ntbackup--系统备份和还原<br />narrator--屏幕“讲述人”<br />ntmsmgr.msc--移动存储管理器<br />ntmsoprq.msc－－－移动存储管理员操作请求<br />netstat －an--(TC)命令检查接口<br />syncapp--－创建一个公文包<br />sysedit--－系统配置编辑器<br />sigverif--文件签名验证程序<br />sndrec32--录音机<br />shrpubw--－创建共享文件夹<br />secpol.msc--－本地安全策略<br />syskey--－－系统加密，一旦加密就不能解开，保护windows<br />xp系统的双重密码<br />services.msc－－－本地服务设置<br />Sndvol32--音量控制程序<br />sfc.exe--－系统文件检查器<br />sfc /scannow－－－windows文件保护<br />taskmgr--－任务管理器<br />eventvwr--事件查看器<br />eudcedit--造字程序<br />explorer--打开资源管理器<br />packager--对象包装程序<br />perfmon.msc--计算机性能监测程序<br />progman--－程序管理器<br />regedit.exe--注册表<br />rsop.msc--组策略结果集<br />regedt32--注册表编辑器<br />regsvr32 /u *.dll--停止dll文件运行<br />regsvr32 /u zipfldr.dll--－－取消ZIP支持<br />cmd.exe--－CMD命令提示符<br />chkdsk.exe--－Chkdsk磁盘检查<br />certmgr.msc--证书管理实用程序<br />calc----启动计算器<br />charmap--－启动字符映射表<br />cliconfg--SQL SERVER 客户端网络实用程序<br />Clipbrd--－剪贴板查看器<br />conf----启动netmeeting<br />compmgmt.msc－－－计算机管理<br />cleanmgr--**整理<br />ciadv.msc--－－索引服务程序<br />osk----－打开屏幕键盘<br />odbcad32--ODBC数据源管理器<br />oobe/msoobe /a--检查XP是否激活<br />lusrmgr.msc--本机用户和组<br />Nslookup--IP地址侦测器<br />fsmgmt.msc--－共享文件夹管理器<br />utilman--－辅助工具管理器<br />gpedit.msc--－组策略</div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/8383.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-31 12:44 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/31/8383.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]简话设计模式 </title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8373.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Fri, 31 Mar 2006 03:59:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8373.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/8373.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8373.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/8373.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/8373.html</trackback:ping><description><![CDATA[
		<div class="postTitle">
				<b>第一章 引言</b>
		</div>
		<div class="postText">
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>1. 本文不适合…</b>
						<br />本文不适合想通过本文来装修房子的读者；</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">本文不适合面向对象编程高手，会浪费你的时间。如果你愿意抽出时间来阅读本文，并提出宝贵的建议，非常感谢！什么？你没有听说过设计模式？那你也敢称高手？</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>2. 本文适合…</b>
						<br />如果你对面向对象编程感兴趣，而又没有时间去读Gang of Four的“Design Patterns Elements of Reusable Object-Oriented Software”（以下简称《设计模式》）。那么，本篇文章将帮助你了解23种设计模式。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">我第一次读这本书是在每次晚睡之前，几乎每次都先睡着。《设计模式》以一种严谨，系统化的风格来论述23种设计模式，原书可以说是面向对象编程的一个基础教程，但是要领会其精髓，必须要花费一定的精力。本文的目的是为了帮助你更加方便地理解每一种设计模式，并不想成为原书的替代读物。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">本文无意于介绍面向对象的基本知识。因此，假设本文的读者已经对面向对象的封装性、继承性和多态性有足够的了解和认识。并能够认识到可复用的面向对象设计的两个原则： 
</p>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 针对接口编程，而不是针对实现编程；</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 优先使用对象组合，而不是类继承。</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>3. 设计模式是什么？</b>
						<br />设计模式概念是由建筑设计师Christopher Alexander提出：“每一个模式描述了一个在我们周围不断重复发生的问题，以及该问题的解决方案的核心。这样，你就能一次又一次地使用该方案而不必做重复劳动。”上述的定义是对设计模式的广义定义。我们将其应用到面向对象软件的领域内，就形成了对设计模式的狭义定义。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">我们可以简单的认为：设计模式就是解决某个特定的面向对象软件问题的特定方法。但严格的来说上述的认识是不准确的，难道面向对象软件中只有区区23个问题？当然不是。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">为了能够更加准确地理解这个概念，我们引入另外一个术语：框架（Framework）。框架这个词汇在当今有了各种各样的应用和含义。在设计模式中：框架（Framework）是构成一类特定软件可复用设计的一组相互协作的类。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">框架可以认为是一个适用于某个领域的软件包。这个软件包提供了相应领域的各个问题的解决方法。那么，它和设计模式有什么区别？ 
</p>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 设计模式和框架针对的问题域不同：</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>设计模式针对面向对象的问题域；框架针对特定业务的问题域；</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">　 
</p>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>● 设计模式比框架更为抽象：</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>设计模式在碰到具体问题后，才能产生代码；框架已经可以用代码表示。</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 设计模式是比框架更小的体系结构元素：</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>框架中可以包括多个设计模式。</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<i>Tips：设计模式就像是在武功中基本的招式。我们将这些招式合理地组合起来，就形成套路（框架）。</i>
				</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>
								<font color="#333399">4. 为什么要用设计模式？</font>
						</b>
						<br />作为程序员都知道良好程序的一个基本标准：高聚合，低耦合。面向对象语言比结构化语言要复杂的多，不良或者没有充分考虑的设计将会导致软件重新设计和开发。然而实际的设计过程中，设计人员更多的考虑如何解决业务问题，对于软件内部结构考虑较少；设计模式则补充了这个缺陷，它主要考虑如何减少对象之间的依赖性，降低耦合程度，使得系统更易于扩展，提高了对象可复用性。因此，设计人员正确的使用设计模式就可以优化系统内部的结构。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>第二章 概要简介</b>
				</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">在《设计模式》一书中，共包含23个模式。根据目的的不同，将它们分为三类： 
</p>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 创建型（Creational）：解决如何创建对象的问题。</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 结构型（Structural）：解决如何正确的组合类或对象的问题。</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 行为型（Behavioral）：解决类或对象之间如何交互和如何分配职责的问题。</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<i>Tips：设计模式中经常会用到抽象（Abstract）和具体（Concrete）这两个词。抽象的含义是指它所描述的类（方法）是接口类（方法）,具体的含义是指它所描述的类（方法）实现了相应的抽象类（方法）。</i>
				</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>第三章 抽象工厂(Abstract factory)</b>
				</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>1. 意图</b>
						<br />提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们具体的类。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>2. 分类</b>
						<br />创建型模式。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>
								<font color="#333399">3. 问题是什么？</font>
						</b>
						<br />对于不熟悉这个模式的人都会对工厂（Factory）这个词感到奇怪，为什么会用这个词？之后，我们还会碰到另一个模式——工厂方法（Factory method）,所以先解释一下工厂的意义：</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">房子是由墙，门，窗户，地板，天花板，柱子组成的。如果我们为客户编写一个建造房子的软件，我们会把墙，门，窗户，地板，天花板，柱子看成不同的类：WallClass, DoorClass, WindowClass, CeilingClass, PillarClass。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">现在我们建立一个新类A，这个类中有CreateWall(), CreateDoor(), CreateFloor(), CreateCeiling(), CreatePillar()五个方法，每个方法的功能就是创建并返回相应的对象。如果把WallClass, DoorClass, WindowClass, CeilingClass, FloorClass, PillarClass的实例看成产品的话，那么类A就像是一个生产这些产品的工厂。这就是使用工厂这个词的原因。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<i>Tips：A这个名字太糟，如果用HouseFactory会好一些。一般情况下，在你的系统使用某个模式，最好使用模式相应的关键字作为类或者方法的名字的一部分，这样，你的同伴或者系统的代码维护者就会明白你的用意。</i>
				</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">我们的软件完成了，客户非常满意。不过，我们的客户想把这个软件出口，他发现一个问题，这个软件太本地化了，建造出来的都是中国式的房屋。因此他希望我们的软件能够建造出不同地域风格的房子。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">这就是我们的问题！我们需要重新设计原系统，而且一次完成世界各地不同建筑风格是不可能的。我们会先完成部分风格（客户第一要投放软件的国家的），然后再增加其他的…</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>
								<font color="#333399">4. 解决方法</font>
						</b>
						<br />1) 建立一个抽象工厂（Abstract Factory）类HouseFactory，在这个类中声明： 
</p>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>CreateWall ()</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>CreateDoor ()</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>CreateFloor ()</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>CreateCeiling ()</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>CreatePillar ()</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">2) 建立相应的抽象产品（Abstract Product）类集：</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">Wall, Door, Floor, Ceiling, Pillar</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">3) 为不同风格建立相应的具体工厂（Concrete Factory）类（不要忘了实现关系），例如： 
</p>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>ChinaHouseFactory : HouseFactory</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>GreeceHouseFactory : HouseFactory</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>…</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">4) 为不同的风格建立相应的具体产品（Concrete Product）类（实现相应的抽象产品），例如： 
</p>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>ChinaWall : Wall</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>ChinaDoor : Door</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>…</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>GreeceWall : Wall</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>GreeceDoor : Door</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>…</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>5. 杂谈</b>
						<br />我想你一定明白如何灵活的创建和使用上面的一大堆类： 
</p>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 重复最后两个步骤，就可以方便的增加新风格；</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 使用前面两个步骤中声明的抽象类来实现操作。</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">抽象工厂模式的重点不是声明的那个抽象工厂类，而是它声明的一系列抽象产品类，我们通过使用这些抽象产品类可以操作我们已经实现或者还未实现的具体产品类，并且保证了它们的一致性。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">你可能已经发现这个软件不能建造你的两层别墅，因为它没有楼梯。为此，我们要定义Stair抽象类，还要增加CreateStair抽象方法；最重要的是我们要在已经完成的76种风格中增加相应的 Stair类，这可是个大麻烦。确实，抽象工厂模式在适应新的产品方面的能力是比较弱的。这是它的一个缺点。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">　</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>第四章 生成器(Builder)</b>
				</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>1. 意图<br /></b>将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>2. 分类<br /></b>创建型模式。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>3. 问题是什么？</b>
						<br />在抽象工厂一章中，我们了解到了在全球建房系统中如何支持多种房屋的风格。新的问题是：用户希望看到同样结构下，不同风格房屋的外观。比如：这个房子有一个地板，一个天花板，四面墙，一个门，一个窗户。他希望看到中国风格房屋和希腊风格房屋的相应式样。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>4. 解决方法</b>
						<br />
				</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">1) 创建一个生成器（Buider）类： 
</p>
				<table width="389" bgcolor="#ffffaa">
						<tbody>
								<tr>
										<td width="381">
												<font color="#0000cc">
														<pre>Class HouseBuider<br /> {<br />  BuildHouse(){}<br />  BuildWall(int){}<br />  BuildDoor(int){}<br />  BuildWindow(int) {}<br />  BuildFloor(){}<br />  BuildCeiling() {}<br />  BuildPillar(){}<br />  GetHouse() { return Null;}<br /> }<br /></pre>
												</font>
										</td>
								</tr>
						</tbody>
				</table>
				<p>在这个类中，我们对每一种房屋组成元素都定义了一个Build方法。并且定义了一个返回构造结果的方法GetHouse。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">2) 对每一种风格都定义一个具体的生成器（Concrete Builder）类： 
</p>
				<table width="298" bgcolor="#ffffaa">
						<tbody>
								<tr>
										<td width="290">
												<font color="#0000cc">
														<pre>ChinaHouseBuilder: HouseBuilder<br />GreeceHouseBuilder: HouseBuilder<br />…<br /></pre>
												</font>
										</td>
								</tr>
						</tbody>
				</table>
				<p>并且在这些类中重载父类的方法。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">3) 还有，各种类型的房屋类： 
</p>
				<table width="155" bgcolor="#ffffaa">
						<tbody>
								<tr>
										<td width="147">
												<font color="#0000cc">
														<pre>ChinaHouse<br />GreeceHouse<br />…<br /></pre>
												</font>
										</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">
						<b>
								<font color="#333399">5. 如何使用</font>
						</b>
						<br />我们可以用下面的方法使用上面的类来解决我们的问题。 
</p>
				<table bgcolor="#ffffaa">
						<tbody>
								<tr>
										<td>
												<font color="#0000cc">
														<pre>Class HosueSystem<br />{<br />object Create( builder HouseBuilder)<br />{<br /> builder.BuildHouse();<br /> builder.BuildFloor();<br /> builder.BuildCeiling();<br /> builder.BuildWall(1);<br /> builder.BuildWall(2);<br /> builder.BuildWall(3);<br /> builder.BuildWall(4);<br /> builder.Door(1);  // 在Wall1上建一个门<br /> builder.Window(2);  // 在Wall2上建一个窗户<br /><br /> return builder.GetHouse();<br />}<br />}<br /></pre>
												</font>
										</td>
								</tr>
						</tbody>
				</table>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">只要向通过HouseSystem.Create方法传入不同的生成器就可以得到不同风格的结果。</p>
				<p xmlns:fo="http://www.w3.org/1999/XSL/Format">事实上，HouseSystem也是生成器模式的一个参与者,叫做导向者（Director）。注意的问题： 
</p>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 生成器（HouseBuilder）类中要包含每一种构件元素的生成方法。比如：楼梯这个元素在某些建筑风格中没有，在其他风格中有，也要加上BuilderStair方法在HouseBuilder中。</td>
								</tr>
						</tbody>
				</table>
				<table cellspacing="5">
						<tbody>
								<tr>
										<td>
												<br />
										</td>
										<td>● 生成器（HouseBuilder）类不是抽象类，它的每一个生成方法一般情况下什么都不做。这样，具体生成器就不必考虑和它无关的元素的生成方法。</td>
								</tr>
						</tbody>
				</table>
				<p>
						<b>6. 杂谈<br /></b>
						<br />
						<br />1) 也许你有这样的想法：生成器模式似乎过于复杂，可以直接在具体House类中定义CreateHouse方法就可以了，例如： </p>
				<table width="403" bgcolor="#ffffaa">
						<tbody>
								<tr>
										<td width="395">
												<font color="#0000cc">
														<pre>Class ChinaHouse<br />{<br /> ChinaHouse CreateHouse()<br />{ ChinaHouse house;<br />house = new ChinaHouse();<br />house.Add(new Floor());<br />house.Add(new Ceiling());<br />house.Add(new Wall(1));<br />house.Add(new Wall(2));<br />house.Add(new Wall(3));<br />house.Add(new Wall(4));<br />house.Add(new Door(1));  // 在Wall1上建一个门<br />house.Add(new Window(2));  // 在Wall2上建一个窗户<br /><br />return house;<br />}<br />}<br /></pre>
												</font>
										</td>
								</tr>
						</tbody>
				</table>
				<p>
						<br />而生成器模式至少用了两个类来解决这个问题：导向者类和具体生成器类。<br /><br />那么，生成器模式好在哪里？答案就是职责分配。生成器模式将一个复杂对象的生成这一职责作了一个很好的分配。它把构造过程放到导向者的方法中，把装配过程放到具体生成器类中。我们看看下面的说明。<br /><br />2) HouseSystem类（导向者）可以非常精细的来构造House。而这个生成过程，对于产品类（ChinaHouse, GreeceHouse …）和生成器类 （ChinaHouseBuilder, GreeceHouseBuilder）都没有必要关心。具体生成器类则考虑装配元素的问题。<br /><br /><b>7. 活用<br /></b>生成器模式可以应用在以下的问题上：  </p>
				<p>● 将系统的文档格式转换到其他的格式上（每一种格式的文档都相当于一个产品）。 <br />● 编译问题（语法分析器是导向者，编译结果是产品）。</p>
		</div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/8373.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-31 11:59 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/31/8373.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>五种提高 SQL 性能的方法</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8347.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Fri, 31 Mar 2006 02:38:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8347.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/8347.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/31/8347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/8347.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/8347.html</trackback:ping><description><![CDATA[
		<table cellspacing="1" cellpadding="1" width="779" align="center" border="0">
				<tbody>
						<tr class="shdr" bgcolor="#ffffff">
								<td valign="top" width="22%" bgcolor="#ffffff">
								</td>
								<td valign="top" width="78%">
										<div class="post">
												<div class="postTitle"> </div>
												<div class="postText">
														<p>
																<a href="http://msdn.microsoft.com/msdnmag/columns/mmData.asp" target="_blank">Data Points Archive </a>
														</p>
														<p>有时， 为了让应用程序运行得更快，所做的全部工作就是在这里或那里做一些很小调整。啊，但关键在于确定如何进行调整！迟早您会遇到这种情况：应用程序中的 SQL 查询不能按照您想要的方式进行响应。它要么不返回数据，要么耗费的时间长得出奇。如果它降低了报告或您的企业应用程序的速度，用户必须等待的时间过长，他们就会很不满意。就像您的父母不想听您解释为什么在深更半夜才回来一样，用户也不会听你解释为什么查询耗费这么长时间。（“对不起，妈妈，我使用了太多的 LEFT JOIN。”）用户希望应用程序响应迅速，他们的报告能够在瞬间之内返回分析数据。就我自己而言，如果在 Web 上冲浪时某个页面要耗费十多秒才能加载（好吧，五秒更实际一些），我也会很不耐烦。</p>
														<p>为了解决这些问题，重要的是找到问题的根源。那么，从哪里开始呢？根本原因通常在于数据库设计和访问它的查询。在本月的专栏中，我将讲述四项技术，这些技术可用于提高基于 SQL Server? 的应用程序的性能或改善其可伸缩性。我将仔细说明 LEFT JOIN、CROSS JOIN 的使用以及 IDENTITY 值的检索。请记住，根本没有神奇的解决方案。调整您的数据库及其查询需要占用时间、进行分析，还需要大量的测试。这些技术都已被证明行之有效，但对您的应用程序而言，可能其中一些技术比另一些技术更适用。</p>
														<div>
														</div>
														<center>
																<img title="" height="6" alt="*" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/3squares.gif" width="30" border="0" />
														</center>
														<div style="HEIGHT: 18px">
														</div>
														<h5 style="PADDING-TOP: 2px">本页内容</h5>
														<table style="MARGIN-TOP: 7px; MARGIN-BOTTOM: 12px" cellspacing="0" cellpadding="0" border="0">
																<tbody>
																		<tr valign="top">
																				<td>
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#EEAA">
																								<img height="9" alt="&#xA;				从 INSERT 返回 IDENTITY&#xA;			" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
																						</a>
																				</td>
																				<td class="onThisPage">
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#EEAA">从 INSERT 返回 IDENTITY </a>
																				</td>
																		</tr>
																		<tr valign="top">
																				<td>
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#EDAA">
																								<img height="9" alt="&#xA;				内嵌视图与临时表&#xA;			" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
																						</a>
																				</td>
																				<td class="onThisPage">
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#EDAA">内嵌视图与临时表 </a>
																				</td>
																		</tr>
																		<tr valign="top">
																				<td>
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#ECAA">
																								<img height="9" alt="&#xA;				避免 LEFT JOIN 和 NULL&#xA;			" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
																						</a>
																				</td>
																				<td class="onThisPage">
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#ECAA">避免 LEFT JOIN 和 NULL </a>
																				</td>
																		</tr>
																		<tr valign="top">
																				<td>
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#EBAA">
																								<img height="9" alt="&#xA;				灵活使用笛卡尔乘积&#xA;			" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
																						</a>
																				</td>
																				<td class="onThisPage">
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#EBAA">灵活使用笛卡尔乘积 </a>
																				</td>
																		</tr>
																		<tr valign="top">
																				<td>
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#EAAA">
																								<img height="9" alt="&#xA;				拾遗补零&#xA;			" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
																						</a>
																				</td>
																				<td class="onThisPage">
																						<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#EAAA">拾遗补零 </a>
																				</td>
																		</tr>
																</tbody>
														</table>
														<a name="EEAA">
														</a>
														<h2>从 INSERT 返回 IDENTITY </h2>
														<p>我决定从遇到许多问题的内容入手：如何在执行 SQL INSERT 后检索 IDENTITY 值。通常，问题不在于如何编写检索值的查询，而在于在哪里以及何时进行检索。在 SQL Server 中，下面的语句可用于检索由最新在活动数据库连接上运行的 SQL 语句所创建的 IDENTITY 值：</p>
														<pre class="codeSample">SELECT @@IDENTITY</pre>
														<p>这个 SQL 语句并不复杂，但需要记住的一点是：如果这个最新的 SQL 语句不是 INSERT，或者您针对非 INSERT SQL 的其他连接运行了此 SQL，则不会获得期望的值。您必须运行下列代码才能检索紧跟在 INSERT SQL 之后且位于同一连接上的 IDENTITY，如下所示：</p>
														<pre class="codeSample">
																<div style="BORDER-RIGHT: #3c78b5 0.75pt dashed; PADDING-RIGHT: 8pt; BORDER-TOP: #3c78b5 0.75pt dashed; PADDING-LEFT: 8pt; BACKGROUND: #f0f0f0; PADDING-BOTTOM: 0cm; BORDER-LEFT: #3c78b5 0.75pt dashed; PADDING-TOP: 0cm; BORDER-BOTTOM: #3c78b5 0.75pt dashed">
																		<pre style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 7.5pt 11.25pt 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-line-height-alt: 9.75pt; mso-border-alt: dashed #3C78B5 .75pt; mso-padding-alt: 0cm 8.0pt 0cm 8.0pt">INSERT INTO Products (ProductName) VALUES ('Chalk')

SELECT @@IDENTITY</pre>
																</div>
														</pre>
														<p>在一个连接上针对 Northwind 数据库运行这些查询将返回一个名称为 Chalk 的新产品的 IDENTITY 值。所以，在使用 ADO 的 Visual Basic? 应用程序中，可以运行以下语句：</p>
														<pre class="codeSample">
																<div style="BORDER-RIGHT: #3c78b5 0.75pt dashed; PADDING-RIGHT: 8pt; BORDER-TOP: #3c78b5 0.75pt dashed; PADDING-LEFT: 8pt; BACKGROUND: #f0f0f0; PADDING-BOTTOM: 0cm; BORDER-LEFT: #3c78b5 0.75pt dashed; PADDING-TOP: 0cm; BORDER-BOTTOM: #3c78b5 0.75pt dashed">
																		<pre style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 7.5pt 11.25pt 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-line-height-alt: 9.75pt; mso-border-alt: dashed #3C78B5 .75pt; mso-padding-alt: 0cm 8.0pt 0cm 8.0pt">Set oRs = oCn.Execute("SET NOCOUNT ON;INSERT INTO Products _
(ProductName) VALUES ('Chalk');SELECT @@IDENTITY")

lProductID = oRs(0)</pre>
																</div>
														</pre>
														<p>此代码告诉 SQL Server 不要返回查询的行计数，然后执行 INSERT 语句，并返回刚刚为这个新行创建的 IDENTITY 值。SET NOCOUNT ON 语句表示返回的记录集有一行和一列，其中包含了这个新的 IDENTITY 值。如果没有此语句，则会首先返回一个空的记录集（因为 INSERT 语句不返回任何数据），然后会返回第二个记录集，第二个记录集中包含 IDENTITY 值。这可能有些令人困惑，尤其是因为您从来就没有希望过 INSERT 会返回记录集。之所以会发生此情况，是因为 SQL Server 看到了这个行计数（即一行受到影响）并将其解释为表示一个记录集。因此，真正的数据被推回到了第二个记录集。当然您可以使用 ADO 中的 NextRecordset 方法获取此第二个记录集，但如果总能够首先返回该记录集且只返回该记录集，则会更方便，也更有效率。</p>
														<p>此方法虽然有效，但需要在 SQL 语句中额外添加一些代码。获得相同结果的另一方法是在 INSERT 之前使用 SET NOCOUNT ON 语句，并将 SELECT @@IDENTITY 语句放在表中的 FOR INSERT 触发器中，如下面的代码片段所示。这样，任何进入该表的 INSERT 语句都将自动返回 IDENTITY 值。</p>
														<pre class="codeSample">
																<div style="BORDER-RIGHT: #3c78b5 0.75pt dashed; PADDING-RIGHT: 8pt; BORDER-TOP: #3c78b5 0.75pt dashed; PADDING-LEFT: 8pt; BACKGROUND: #f0f0f0; PADDING-BOTTOM: 0cm; BORDER-LEFT: #3c78b5 0.75pt dashed; PADDING-TOP: 0cm; BORDER-BOTTOM: #3c78b5 0.75pt dashed">
																		<pre style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 7.5pt 11.25pt 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-line-height-alt: 9.75pt; mso-border-alt: dashed #3C78B5 .75pt; mso-padding-alt: 0cm 8.0pt 0cm 8.0pt">CREATE TRIGGER trProducts_Insert ON Products FOR INSERT AS 
    SELECT @@IDENTITY 
GO</pre>
																</div>
														</pre>
														<p>触发器只在 Products 表上发生 INSERT 时启动，所以它总是会在成功 INSERT 之后返回一个 IDENTITY。使用此技术，您可以始终以相同的方式在应用程序中检索 IDENTITY 值。</p>
														<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
																<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#top">
																		<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
																</a>
																<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#top">返回页首</a>
														</div>
														<a name="EDAA">
														</a>
														<h2>内嵌视图与临时表 </h2>
														<p>某些时候，查询需要将数据与其他一些可能只能通过执行 GROUP BY 然后执行标准查询才能收集的数据进行联接。例如，如果要查询最新五个定单的有关信息，您首先需要知道是哪些定单。这可以使用返回定单 ID 的 SQL 查询来检索。此数据就会存储在临时表（这是一个常用技术）中，然后与 Products 表进行联接，以返回这些定单售出的产品数量：</p>
														<pre class="codeSample">
																<div style="BORDER-RIGHT: #3c78b5 0.75pt dashed; PADDING-RIGHT: 8pt; BORDER-TOP: #3c78b5 0.75pt dashed; PADDING-LEFT: 8pt; BACKGROUND: #f0f0f0; PADDING-BOTTOM: 0cm; BORDER-LEFT: #3c78b5 0.75pt dashed; PADDING-TOP: 0cm; BORDER-BOTTOM: #3c78b5 0.75pt dashed">
																		<pre style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 7.5pt 11.25pt 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-line-height-alt: 9.75pt; mso-border-alt: dashed #3C78B5 .75pt; mso-padding-alt: 0cm 8.0pt 0cm 8.0pt">CREATE TABLE #Temp1 (OrderID INT NOT NULL, _
                     OrderDate DATETIME NOT NULL)

INSERT INTO #Temp1 (OrderID, OrderDate)
SELECT     TOP 5 o.OrderID, o.OrderDate
FROM Orders o ORDER BY o.OrderDate DESC

SELECT     p.ProductName, SUM(od.Quantity) AS ProductQuantity
FROM     #Temp1 t 
    INNER JOIN [Order Details] od ON t.OrderID = od.OrderID
    INNER JOIN Products p ON od.ProductID = p.ProductID 
GROUP BY p.ProductName
ORDER BY p.ProductName

DROP TABLE #Temp1</pre>
																</div>
														</pre>
														<p>这些 SQL 语句会创建一个临时表，将数据插入该表中，将其他数据与该表进行联接，然后除去该临时表。这会导致此查询进行大量 I/O 操作，因此，可以重新编写查询，使用内嵌视图取代临时表。内嵌视图只是一个可以联接到 FROM 子句中的查询。所以，您不用在 tempdb 中的临时表上耗费大量 I/O 和磁盘访问，而可以使用内嵌视图得到同样的结果：</p>
														<pre class="codeSample">
																<div style="BORDER-RIGHT: #3c78b5 0.75pt dashed; PADDING-RIGHT: 8pt; BORDER-TOP: #3c78b5 0.75pt dashed; PADDING-LEFT: 8pt; BACKGROUND: #f0f0f0; PADDING-BOTTOM: 0cm; BORDER-LEFT: #3c78b5 0.75pt dashed; PADDING-TOP: 0cm; BORDER-BOTTOM: #3c78b5 0.75pt dashed">
																		<pre style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 7.5pt 11.25pt 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-line-height-alt: 9.75pt; mso-border-alt: dashed #3C78B5 .75pt; mso-padding-alt: 0cm 8.0pt 0cm 8.0pt">SELECT p.ProductName, 
    SUM(od.Quantity) AS ProductQuantity
FROM     (
    SELECT TOP 5 o.OrderID, o.OrderDate
    FROM     Orders o 
    ORDER BY o.OrderDate DESC
    ) t 
    INNER JOIN [Order Details] od ON t.OrderID = od.OrderID
    INNER JOIN Products p ON od.ProductID = p.ProductID 
GROUP BY
    p.ProductName
ORDER BY
    p.ProductName</pre>
																</div>
														</pre>
														<p>此查询不仅比前面的查询效率更高，而且长度更短。临时表会消耗大量资源。如果只需要将数据联接到其他查询，则可以试试使用内嵌视图，以节省资源。</p>
														<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
																<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#top">
																		<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
																</a>
																<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#top">返回页首</a>
														</div>
														<a name="ECAA">
														</a>
														<h2>避免 LEFT JOIN 和 NULL </h2>
														<p>当然，有很多时候您需要执行 LEFT JOIN 和使用 NULL 值。但是，它们并不适用于所有情况。改变 SQL 查询的构建方式可能会产生将一个花几分钟运行的报告缩短到只花几秒钟这样的天壤之别的效果。有时，必须在查询中调整数据的形态，使之适应应用程序所要求的显示方式。虽然 TABLE 数据类型会减少大量占用资源的情况，但在查询中还有许多区域可以进行优化。SQL 的一个有价值的常用功能是 LEFT JOIN。它可以用于检索第一个表中的所有行、第二个表中所有匹配的行、以及第二个表中与第一个表不匹配的所有行。例如，如果希望返回每个客户及其定单，使用 LEFT JOIN 则可以显示有定单和没有定单的客户。</p>
														<p>此工具可能会被过度使用。LEFT JOIN 消耗的资源非常之多，因为它们包含与 NULL（不存在）数据匹配的数据。在某些情况下，这是不可避免的，但是代价可能非常高。LEFT JOIN 比 INNER JOIN 消耗资源更多，所以如果您可以重新编写查询以使得该查询不使用任何 LEFT JOIN，则会得到非常可观的回报（请参阅图 1 中的图）。</p>
														<p>图 1 查询 </p>
														<p>加快使用 LEFT JOIN 的查询速度的一项技术涉及创建一个 TABLE 数据类型，插入第一个表（LEFT JOIN 左侧的表）中的所有行，然后使用第二个表中的值更新 TABLE 数据类型。此技术是一个两步的过程，但与标准的 LEFT JOIN 相比，可以节省大量时间。一个很好的规则是尝试各种不同的技术并记录每种技术所需的时间，直到获得用于您的应用程序的执行性能最佳的查询。</p>
														<p>测试查询的速度时，有必要多次运行此查询，然后取一个平均值。因为查询（或存储过程）可能会存储在 SQL Server 内存中的过程缓存中，因此第一次尝试耗费的时间好像稍长一些，而所有后续尝试耗费的时间都较短。另外，运行您的查询时，可能正在针对相同的表运行其他查询。当其他查询锁定和解锁这些表时，可能会导致您的查询要排队等待。例如，如果您进行查询时某人正在更新此表中的数据，则在更新提交时您的查询可能需要耗费更长时间来执行。</p>
														<p>避免使用 LEFT JOIN 时速度降低的最简单方法是尽可能多地围绕它们设计数据库。例如，假设某一产品可能具有类别也可能没有类别。如果 Products 表存储了其类别的 ID，而没有用于某个特定产品的类别，则您可以在字段中存储 NULL 值。然后您必须执行 LEFT JOIN 来获取所有产品及其类别。您可以创建一个值为“No Category”的类别，从而指定外键关系不允许 NULL 值。通过执行上述操作，现在您就可以使用 INNER JOIN 检索所有产品及其类别了。虽然这看起来好像是一个带有多余数据的变通方法，但可能是一个很有价值的技术，因为它可以消除 SQL 批处理语句中消耗资源较多的 LEFT JOIN。在数据库中全部使用此概念可以为您节省大量的处理时间。请记住，对于您的用户而言，即使几秒钟的时间也非常重要，因为当您有许多用户正在访问同一个联机数据库应用程序时，这几秒钟实际上的意义会非常重大。 </p>
														<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
																<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#top">
																		<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
																</a>
																<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#top">返回页首</a>
														</div>
														<a name="EBAA">
														</a>
														<h2>灵活使用笛卡尔乘积 </h2>
														<p>对于此技巧，我将进行非常详细的介绍，并提倡在某些情况下使用笛卡尔乘积。出于某些原因，笛卡尔乘积 (CROSS JOIN) 遭到了很多谴责，开发人员通常会被警告根本就不要使用它们。在许多情况下，它们消耗的资源太多，从而无法高效使用。但是像 SQL 中的任何工具一样，如果正确使用，它们也会很有价值。例如，如果您想运行一个返回每月数据（即使某一特定月份客户没有定单也要返回）的查询，您就可以很方便地使用笛卡尔乘积。<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/art/figures3.html" target="_blank"> 图 2 </a>中的 SQL 就执行了上述操作。</p>
														<p>虽然这看起来好像没什么神奇的，但是请考虑一下，如果您从客户到定单（这些定单按月份进行分组并对销售额进行小计）进行了标准的 INNER JOIN，则只会获得客户有定单的月份。因此，对于客户未订购任何产品的月份，您不会获得 0 值。如果您想为每个客户都绘制一个图，以显示每个月和该月销售额，则可能希望此图包括月销售额为 0 的月份，以便直观标识出这些月份。如果使用 <a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/art/figures3.html" target="_blank">图 2 </a>中的 SQL，数据则会跳过销售额为 0 美元的月份，因为在定单表中对于零销售额不会包含任何行（假设您只存储发生的事件）。</p>
														<p>
																<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/art/figures3.html" target="_blank">图 3 </a>中的代码虽然较长，但是可以达到获取所有销售数据（甚至包括没有销售额的月份）的目标。首先，它会提取去年所有月份的列表，然后将它们放入第一个 TABLE 数据类型表 (@tblMonths) 中。下一步，此代码会获取在该时间段内有销售额的所有客户公司的名称列表，然后将它们放入另一个 TABLE 数据类型表 (@tblCus-tomers) 中。这两个表存储了创建结果集所必需的所有基本数据，但实际销售数量除外。 第一个表中列出了所有月份（12 行），第二个表中列出了这个时间段内有销售额的所有客户（对于我是 81 个）。并非每个客户在过去 12 个月中的每个月都购买了产品，所以，执行 INNER JOIN 或 LEFT JOIN 不会返回每个月的每个客户。这些操作只会返回购买产品的客户和月份。</p>
														<p>笛卡尔乘积则可以返回所有月份的所有客户。笛卡尔乘积基本上是将第一个表与第二个表相乘，生成一个行集合，其中包含第一个表中的行数与第二个表中的行数相乘的结果。因此，笛卡尔乘积会向表 @tblFinal 返回 972 行。最后的步骤是使用此日期范围内每个客户的月销售额总计更新 @tblFinal 表，以及选择最终的行集。</p>
														<p>如果由于笛卡尔乘积占用的资源可能会很多，而不需要真正的笛卡尔乘积，则可以谨慎地使用 CROSS JOIN。例如，如果对产品和类别执行了 CROSS JOIN，然后使用 WHERE 子句、DISTINCT 或 GROUP BY 来筛选出大多数行，那么使用 INNER JOIN 会获得同样的结果，而且效率高得多。如果需要为所有的可能性都返回数据（例如在您希望使用每月销售日期填充一个图表时），则笛卡尔乘积可能会非常有帮助。但是，您不应该将它们用于其他用途，因为在大多数方案中 INNER JOIN 的效率要高得多。</p>
														<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
																<a href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#top">
																		<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
																</a>
																<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/data/sqlserver/FiveWaystoRevupYourSQLPerformanCE.mspx#top">返回页首</a>
														</div>
														<a name="EAAA">
														</a>
														<h2>拾遗补零 </h2>
														<p>这里介绍其他一些可帮助提高 SQL 查询效率的常用技术。假设您将按区域对所有销售人员进行分组并将他们的销售额进行小计，但是您只想要那些数据库中标记为处于活动状态的销售人员。您可以按区域对销售人员分组，并使用 HAVING 子句消除那些未处于活动状态的销售人员，也可以在 WHERE 子句中执行此操作。在 WHERE 子句中执行此操作会减少需要分组的行数，所以比在 HAVING 子句中执行此操作效率更高。HAVING 子句中基于行的条件的筛选会强制查询对那些在 WHERE 子句中会被去除的数据进行分组。</p>
														<p>另一个提高效率的技巧是使用 DISTINCT 关键字查找数据行的单独报表，来代替使用 GROUP BY 子句。在这种情况下，使用 DISTINCT 关键字的 SQL 效率更高。请在需要计算聚合函数（SUM、COUNT、MAX 等）的情况下再使用 GROUP BY。另外，如果您的查询总是自己返回一个唯一的行，则不要使用 DISTINCT 关键字。在这种情况下，DISTINCT 关键字只会增加系统开销。</p>
														<p>您已经看到了，有大量技术都可用于优化查询和实现特定的业务规则，技巧就是进行一些尝试，然后比较它们的性能。最重要的是要测试、测试、再测试。在此专栏的将来各期内容中，我将继续深入讲述 SQL Server 概念，包括数据库设计、好的索引实践以及 SQL Server 安全范例。</p>
														<p>如有向 Johnny 提出的问题和建议，请发送电子邮件到 <a href="mailto:mmdata@microsoft.com" target="_blank">mmdata@microsoft.com </a></p>
														<p>Johnny Papa 是北卡罗来纳州罗利市的 MJM 研究公司的信息技术副总裁，他著有?Professional ADO 25 RDS Programming with ASP 30?? (Wrox, 2000)，并经常在行业会议中做演讲。要与他联系，请发送电子邮件到<a href="mailto:datapoints@lancelotweb.com" target="_blank"> datapoints@lancelotweb.com </a></p>
														<p>摘自<a href="http://msdn.microsoft.com/msdnmag/default.aspx" target="_blank"> MSDN Magazine 2002 年 7 月 </a>刊。可以在您当地的报摊上购买此杂志，但最好立即<a href="http://msdn.microsoft.com/msdnmag/subscribe.aspx" target="_blank"> 订阅 </a></p>
												</div>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/8347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-31 10:38 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/31/8347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据结构学习笔记（转载）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/30/8298.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Thu, 30 Mar 2006 05:44:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/30/8298.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/8298.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/30/8298.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/8298.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/8298.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 数据结构笔记（1）								第一章 概  论		1.数据：信息的载体,能被计算机识别、存储和加工处理。		2.数据元素：数据的基本单位，可由若干个数据项组成，数据项是具有独立含义的最小标识单位。		3.数据结构：数据之间的相互关系，即数据的组织形式。它包括：1）数据的逻辑结构，从逻辑关系上描述数据，与数据存储无关，独立于计算机；2）数据的存储结构，是逻辑结构用计算机语...&nbsp;&nbsp;<a href='http://www.cnitblog.com/weitom1982/archive/2006/03/30/8298.html'>阅读全文</a><img src ="http://www.cnitblog.com/weitom1982/aggbug/8298.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-30 13:44 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/30/8298.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习网站（资料）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/30/8297.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Thu, 30 Mar 2006 05:40:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/30/8297.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/8297.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/30/8297.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/8297.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/8297.html</trackback:ping><description><![CDATA[
		<div class="postTitle"> 学习OPcode:<br /><a href="http://www.luocong.com/learningopcode/index.htm">http://www.luocong.com/learningopcode/index.htm</a><br /><br />驱动开发论坛:<br /><a href="http://bbs.zndev.com/index.php">http://bbs.zndev.com/index.php</a><br />Sysinternals:<br /><a href="http://sysinternals.com/">http://sysinternals.com/</a><br /><a href="http://www.osronline.com/">http://www.osronline.com/</a><br /><br />驱动开发优秀网站:<br /><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://tie.163.net/">http://tie.163.net</a></span><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://www.cetinet.com/">http://www.cetinet.com/</a></span><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://jiaomcu.shareyou.net/more.htm">http://jiaomcu.shareyou.net/more.htm</a></span><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://www.lvr.com/usbcode.htm">http://www.lvr.com/usbcode.htm</a></span><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://www.chinadz.com/icver/0038.htm">http://www.chinadz.com/icver/0038.htm</a></span><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://sdkh.51.net/dz/usb.htm">sdkh.51.net/dz/usb.htm</a> </span><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://www-eu5.semiconductors.philips.com/pip/pdiusbd12.html">http://www-eu5.semiconductors.philips.com/pip/pdiusbd12.html</a></span><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://www.beyondlogic.org/">http://www.beyondlogic.org/</a>                            </span><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://www.usbdeveloper.com/">http://www.usbdeveloper.com/</a></span><br /><span><a class="linkification-ext" id="linkification-flag-id" href="http://www.beyondlogic.org/pardebug/pdebug.htm">http://www.beyondlogic.org/pardebug/pdebug.htm</a></span><br /><br /><br />linux相关资源:<br /><br />1. 开源/文档/社区/信息资源<br /><span>1.01 <a class="linkification-ext" id="linkification-flag-id" href="http://www.kernel.org/">http://www.kernel.org</a></span><br />     Linux内核主页<br /><br /><span>1.02 <a class="linkification-ext" id="linkification-flag-id" href="http://www.gnu.org/">http://www.gnu.org</a> or <a class="linkification-ext" href="http://www.fsf.org/">http://www.fsf.org</a></span><br />     GNU/FSF主页<br /><br /><span>1.03 <a class="linkification-ext" id="linkification-flag-id" href="http://www.opensource.org/">http://www.opensource.org</a></span><br />     Open Source权威网站<br /><br /><span>1.04 <a class="linkification-ext" id="linkification-flag-id" href="http://www.osdl.org/">http://www.osdl.org</a></span><br />     OSDL(Open Source Development Labs, Linus Torvalds的家)主页<br /><br /><span>1.05 <a class="linkification-ext" id="linkification-flag-id" href="http://www.sourceforge.net/">http://www.sourceforge.net</a></span><br />     大型开放源码软件网站<br /><br /><span>1.06 <a class="linkification-ext" id="linkification-flag-id" href="http://freshmeat.net/">http://freshmeat.net/</a></span><br />     大型开放源码软件网站<br /><br /><span>1.07 <a class="linkification-ext" id="linkification-flag-id" href="http://osdir.com/">http://osdir.com</a></span><br />     开放源码目录，提供许多开放源码软件的索引和链接<br /><br /><span>1.08 <a class="linkification-ext" id="linkification-flag-id" href="http://www.rpmfind.net/">http://www.rpmfind.net</a></span><br />     提供RPM包的搜索和链接<br /><br /><span>1.09 <a class="linkification-ext" id="linkification-flag-id" href="http://oss.sgi.com/projects/">http://oss.sgi.com/projects/</a></span><br />     SGI的开放源码Linux项目<br /><br /><span>1.10 <a class="linkification-ext" id="linkification-flag-id" href="http://oss.software.ibm.com/linux/">http://oss.software.ibm.com/linux/</a></span><br />     IBM的开放源码Linux项目<br /><br /><span>1.11 <a class="linkification-ext" id="linkification-flag-id" href="http://www-124.ibm.com/developerworks/oss/">http://www-124.ibm.com/developerworks/oss/</a></span><br />     IBM developerWorks的开放源码Linux项目<br /><br /><span>1.12 <a class="linkification-ext" id="linkification-flag-id" href="http://www.kerneltrap.org/">http://www.kerneltrap.org</a></span><br />     内核开发相关信息和论坛<br /><br /><span>1.13 <a class="linkification-ext" id="linkification-flag-id" href="http://kernelnewbies.org/">http://kernelnewbies.org</a></span><br />     很好的内核学习网站<br /><br /><span>1.14 <a class="linkification-ext" id="linkification-flag-id" href="http://www.kernelhacking.org/">http://www.kernelhacking.org/</a></span><br />     kernelhacking-HOWTO文档<br /><br /><span>1.15 <a class="linkification-ext" id="linkification-flag-id" href="http://www.tldp.org/">http://www.tldp.org</a></span><br />     Linux文档<br /><br /><span>1.16 <a class="linkification-ext" id="linkification-flag-id" href="http://www.nongnu.org/lkdp/">http://www.nongnu.org/lkdp/</a></span><br />     Linux内核文档<br /><br /><span>1.17 <a class="linkification-ext" id="linkification-flag-id" href="http://linux-mm.org/">http://linux-mm.org/</a></span><br />     Linux内核mm文档<br /><br /><span>1.18 <a class="linkification-ext" id="linkification-flag-id" href="http://www.linuxforum.net/">http://www.linuxforum.net</a></span><br />     中国Linux论坛<br /><br /><span>1.19 <a class="linkification-ext" id="linkification-flag-id" href="http://www.aka.org.cn/">http://www.aka.org.cn</a></span><br />     中国信息技术论坛－阿卡（AKA）<br /><br /><span>1.20 <a class="linkification-ext" id="linkification-flag-id" href="http://www.lisoleg.net/">http://www.lisoleg.net</a></span><br />     利索脚(Linux Source Learning Group)<br /><br /><span>1.21 <a class="linkification-ext" id="linkification-flag-id" href="http://www.linuxfans.org/">http://www.linuxfans.org/</a></span><br />     中国Linux公社<br /><br /><span>1.22 <a class="linkification-ext" id="linkification-flag-id" href="http://www-900.ibm.com/developerWorks/cn/linux">http://www-900.ibm.com/developerWorks/cn/linux</a></span><br />     IBM developerWorks Linux专区<br /><br /><span>1.23 <a class="linkification-ext" id="linkification-flag-id" href="http://www.linuxaid.com.cn/">http://www.linuxaid.com.cn</a></span><br />     LinuxAid技术支持中心<br /><br /><span>1.24 <a class="linkification-ext" id="linkification-flag-id" href="http://lxr.linux.no/source/">http://lxr.linux.no/source/</a></span><br />     Cross-Referencing Linux，可在线查看Linux内核源代码<br /><br /><span>1.25 <a class="linkification-ext" id="linkification-flag-id" href="http://www.linux.org/">http://www.linux.org</a></span><br />     Linux信息资源<br /><br /><span>1.26 <a class="linkification-ext" id="linkification-flag-id" href="http://www.linuxdevices.com/">http://www.linuxdevices.com</a></span><br />     嵌入式Linux信息资源<br /><br /><span>1.27 <a class="linkification-ext" id="linkification-flag-id" href="http://www.linuxjournal.com/webindex.php">http://www.linuxjournal.com/webindex.php</a></span><br />     Linux Journal杂志在线文章<br /><br /><span>1.28 <a class="linkification-ext" id="linkification-flag-id" href="http://www.joyfire.net/">http://www.joyfire.net/</a></span><br />     本站joyfire大侠维护的站点<br /><br /><span>1.29 <a class="linkification-ext" id="linkification-flag-id" href="http://lwn.net/">http://lwn.net</a></span><br />     Linux Weekly News<br /><br /><span>1.30 <a class="linkification-ext" id="linkification-flag-id" href="http://www.ctyme.com/intr/int.htm">http://www.ctyme.com/intr/int.htm</a></span><br />     关于BIOS系统调用，很全<br />2. 项目资源<br /><span>2.01 <a class="linkification-ext" id="linkification-flag-id" href="http://perso.wanadoo.es/xose/linux/linux_ports.html">http://perso.wanadoo.es/xose/linux/linux_ports.html</a></span><br />     Linux移植项目链接资源<br /><br /><span>2.02 <a class="linkification-ext" id="linkification-flag-id" href="http://www.uclinux.org/">http://www.uclinux.org</a></span><br />     uClinux主页<br /><br /><span>2.03 <a class="linkification-ext" id="linkification-flag-id" href="http://www.fsmlabs.com/">http://www.fsmlabs.com/</a> or <a class="linkification-ext" href="http://www.rtlinux.org/">http://www.rtlinux.org</a></span><br />     RTLinux(Real-Time Linux)主页<br /><br /><span>2.04 <a class="linkification-ext" id="linkification-flag-id" href="http://mail.aero.polimi.it/%7Ertai/">http://mail.aero.polimi.it/~rtai/</a></span><br />     RTAI(Real Time Application Interface for Linux)主页<br /><br /><span>2.05 <a class="linkification-ext" id="linkification-flag-id" href="http://www.ittc.ku.edu/kurt/">http://www.ittc.ku.edu/kurt/</a></span><br />     KURT-Linux(Kansas University Real-Time Linux)主页<br /><br /><span>2.06 <a class="linkification-ext" id="linkification-flag-id" href="http://www.arm.linux.org.uk/">http://www.arm.linux.org.uk/</a></span><br />     ARM Linux主页<br /><br /><span>2.07 <a class="linkification-ext" id="linkification-flag-id" href="http://www.linux-mips.org/">http://www.linux-mips.org/</a></span><br />     Linux/MIPS主页<br /><br /><span>2.08 <a class="linkification-ext" id="linkification-flag-id" href="http://penguinppc.org/">http://penguinppc.org/</a></span><br />     Linux/PowerPC主页<br /><br /><span>2.09 <a class="linkification-ext" id="linkification-flag-id" href="http://www.denx.de/">http://www.denx.de</a></span><br />     Denx Software Engineering, PowerPC系列嵌入式Linux资源<br /><br /><span>2.10 <a class="linkification-ext" id="linkification-flag-id" href="http://www.netfilter.org/">http://www.netfilter.org/</a> or <a class="linkification-ext" href="http://www.iptables.org/">http://www.iptables.org/</a></span><br />     netfilter/iptables项目<br /><br /><span>2.11 <a class="linkification-ext" id="linkification-flag-id" href="http://www.linuxfromscratch.org/">http://www.linuxfromscratch.org</a></span><br />     LFS(Linux From Scratch)项目<br /><br /><span>2.12 <a class="linkification-ext" id="linkification-flag-id" href="http://www.uclibc.org/">http://www.uclibc.org</a></span><br />     uClibc(C library for developing embedded Linux systems)主页<br /><br /><span>2.13 <a class="linkification-ext" id="linkification-flag-id" href="http://www.linuxvirtualserver.org/">http://www.LinuxVirtualServer.org</a></span><br />     章文嵩主持的Linux Virtual Server项目<br /><br /><span>2.14 <a class="linkification-ext" id="linkification-flag-id" href="http://linux-ha.org/">http://linux-ha.org</a></span><br />     High-Availability Linux项目<br /><br /><span>2.15 <a class="linkification-ext" id="linkification-flag-id" href="http://www.lids.org/">http://www.lids.org</a></span><br />     本站vertex大侠主持的LIDS(Linux Intrusion Detection System)项目<br /><br /><span>2.16 <a class="linkification-ext" id="linkification-flag-id" href="http://www.minigui.org/">http://www.minigui.org/</a></span><br />     本站Kongming大侠主持的MiniGUI项目<br /><br /><span>2.17 <a class="linkification-ext" id="linkification-flag-id" href="http://user-mode-linux.sourceforge.net/">http://user-mode-linux.sourceforge.net/</a></span><br />     User-Mode Linux项目<br /> <br /><span>2.18 <a class="linkification-ext" id="linkification-flag-id" href="http://lse.sourceforge.net/">http://lse.sourceforge.net/</a></span><br />     Linux Scalability Effort项目<br /><br /><span>2.19 <a class="linkification-ext" id="linkification-flag-id" href="http://linuxperf.nl.linux.org/">http://linuxperf.nl.linux.org/</a></span><br />     Linux Performance Tuning项目<br /><br /><span>2.20 <a class="linkification-ext" id="linkification-flag-id" href="http://euclid.nmu.edu/%7Ebenchmark/">http://euclid.nmu.edu/~benchmark/</a></span><br />     Linux Benchmark项目 </div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/8297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-30 13:40 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/30/8297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>『IT视界』 [大话IT]谈谈Windows程序中的字符编码（转）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7905.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Tue, 21 Mar 2006 08:16:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7905.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7905.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7905.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7905.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7905.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 作者：																																																寒潭惊鹤影																 														提交日期：														2005-6-11 07:59:00																																																								...&nbsp;&nbsp;<a href='http://www.cnitblog.com/weitom1982/archive/2006/03/21/7905.html'>阅读全文</a><img src ="http://www.cnitblog.com/weitom1982/aggbug/7905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-21 16:16 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/21/7905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>评价一下UTF-8与UNICODE相互转换的代码 （转）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7903.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Tue, 21 Mar 2006 08:09:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7903.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7903.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7903.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7903.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7903.html</trackback:ping><description><![CDATA[
		<div class="post">
				<h2> </h2>
				<font face="Verdana" color="#000000" size="2">上周,我花了很多心思使用模板写了一个UTF-8与UNICODE相互转换的功能(见文件</font>
				<a href="http://www.cnblogs.com/Files/kb/Code.rar">
						<font face="Verdana" color="#000080" size="2">code.rar</font>
				</a>
				<font face="Verdana" color="#000000" size="2">),刚开始感觉还可以,但这几天慢慢的觉得,为什么不直接提供两个函数呢,这样不是简单方便吗?我这样的设计又能带来额外的什么好处呢?刚开始我是想提供比较方便好用以及容易扩展与维护的代码,但现在感觉到与直接提供C式的函数并没有多少额外的好处.或许这样的简单功能根本就用不着这样复杂的代码吧.正如Eric Raymond对C++的评价一样,它"使程序员倾向于写复杂的代码".<br />我想大家看看我的代码,给我一点意见和建议.</font>
				<p class="postfoot">posted on 2005-09-29 20:34 <a href="http://www.cppblog.com/kb/">可冰</a> 阅读(541) <a href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#Post">评论(8)</a>  <a href="http://www.cppblog.com/kb/admin/EditPosts.aspx?postid=491">编辑</a> <a href="http://www.cppblog.com/kb/AddToFavorite.aspx?id=491">收藏</a><a title="功能强大的网络收藏夹，一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();">收藏至365Key</a> 所属分类: <a href="http://www.cppblog.com/kb/category/53.html">C++</a> 、<a href="http://www.cppblog.com/kb/category/55.html">UTF-8</a></p>
		</div>
		<img height="1" src="http://www.cppblog.com/kb/aggbug/491.html?webview=1" width="1" />
		<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://www.cppblog.com/kb/archive/2005/09/29/491.html"
dc:identifier="http://www.cppblog.com/kb/archive/2005/09/29/491.html"
dc:title="评价一下UTF-8与UNICODE相互转换的代码"
trackback:ping="http://www.cppblog.com/kb/services/trackbacks/491.aspx" />
</rdf:RDF>
-->
		<div id="comments">
				<h3>Feedback</h3>
				<font color="#999966" size="2">
				</font>
				<h4>
						<a title="permalink: re: 评价一下UTF-8与UNICODE相互转换的代码" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#494">#</a> <a name="494"></a>re: 评价一下UTF-8与UNICODE相互转换的代码 <span>2005-09-29 21:27 </span><a id="Comments1_CommentList_ctl00_NameLink" href="http://www.cppblog.com/cpunion" target="_blank">cpunion</a></h4>
				<p>下载不了。 <br /><br />前几天看你写了个模板方式的，感觉是不必要，模板一般用在批量产生代码、加强类型检查、提高效率、普通代码不好解决问题的时候。  <a onclick="return SetReplyAuhor(&quot;cpunion&quot;)" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#post">回复</a><a id="Comments1_CommentList_ctl00_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl00$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl00_EditLink"></a></p>
				<h4>
						<a title="permalink: re: 评价一下UTF-8与UNICODE相互转换的代码" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#497">#</a> <a name="497"></a>re: 评价一下UTF-8与UNICODE相互转换的代码 <span>2005-09-29 23:05 </span><a id="Comments1_CommentList_ctl01_NameLink" href="http://www.cppblog.com/kb/" target="_blank">可冰</a></h4>
				<p>谢谢提醒.我已经将文件转放在博客园上,现在可以下载了.  <a onclick="return SetReplyAuhor(&quot;可冰&quot;)" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#post">回复</a><a id="Comments1_CommentList_ctl01_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl01$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl01_EditLink"></a></p>
				<h4>
						<a title="permalink: re: 评价一下UTF-8与UNICODE相互转换的代码" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#501">#</a> <a name="501"></a>re: 评价一下UTF-8与UNICODE相互转换的代码 <span>2005-09-29 23:18 </span><a id="Comments1_CommentList_ctl02_NameLink" href="http://www.cppblog.com/cpunion" target="_blank">cpunion</a></h4>
				<p>直接使用2个函数，unicodeToUtf8, utf8ToUnicode更简单。 <br /><br />从你的模板参数可以得知，2个int值的模板参数将推导出2个类型，最终还是被映射到2个不同的算法上了，不如简单地做： <br /><br />string convert (const wstring&amp; src); <br /><br />wstring convert (const string&amp; src);  <a onclick="return SetReplyAuhor(&quot;cpunion&quot;)" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#post">回复</a><a id="Comments1_CommentList_ctl02_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl02$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl02_EditLink"></a></p>
				<h4>
						<a title="permalink: re: 评价一下UTF-8与UNICODE相互转换的代码" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#503">#</a> <a name="503"></a>re: 评价一下UTF-8与UNICODE相互转换的代码 <span>2005-09-29 23:30 </span><a id="Comments1_CommentList_ctl03_NameLink" href="http://www.cppblog.com/kb/" target="_blank">可冰</a></h4>
				<p>嗯,确实是. <br />你说的是对的,模板不能滥用,"模板一般用在批量产生代码、加强类型检查、提高效率、普通代码不好解决问题的时候".以后我会记住的. <br />其实,我确实可能是有一点追求复杂代码的倾向,写代码时考虑代码最多,而不是具体的运用.在这一点上我是走错路了. <br />以后一定要改!  <a onclick="return SetReplyAuhor(&quot;可冰&quot;)" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#post">回复</a><a id="Comments1_CommentList_ctl03_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl03$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl03_EditLink"></a></p>
				<h4>
						<a title="permalink: re: 评价一下UTF-8与UNICODE相互转换的代码" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#506">#</a> <a name="506"></a>re: 评价一下UTF-8与UNICODE相互转换的代码 <span>2005-09-30 09:02 </span><a id="Comments1_CommentList_ctl04_NameLink" target="_blank">ilovevc</a></h4>
				<p>恕我直言, 你这个程序写得并不好, 一看就是看设计模式走火入魔的一种. <br />1. singleton根本就不需要, 而且在没有GC的C++中还带来了释放的问题. 你就提供几个static 成员函数就可以了. <br />2. 过多的类层次,什么ConcreteConvert, 虚函数根本没有必要, 实际上最后就是两个类, 每个类有一个static member function进行转换就可以了. <br />3. 使用模板可以, 但是你这个模板没有太多意思. 可以考虑使用iterator的concept, 例如 convert(In src_first, In src_last, Out out_first), 这样可以很灵活, 例如使用一个string的back_inserter作为Out参数就可以自动分配内存. <br />4. 界面不直观. 看你的cpp文件就知道. 我认为的界面可能有一下形式: <br />uncode_convert&lt;utf-8, unicode&gt;(......); <br />unicode_convert&lt;unicode, utf-8&gt;(....); <br /><br />总之, 本质原因我认为并不是你过于**追究**复杂代码, 而是你解决问题的时候使用了复杂的方式.   <a onclick="return SetReplyAuhor(&quot;ilovevc&quot;)" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#post">回复</a><a id="Comments1_CommentList_ctl04_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl04$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl04_EditLink"></a></p>
				<h4>
						<a title="permalink: re: 评价一下UTF-8与UNICODE相互转换的代码" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#508">#</a> <a name="508"></a>re: 评价一下UTF-8与UNICODE相互转换的代码 <span>2005-09-30 13:13 </span><a id="Comments1_CommentList_ctl05_NameLink" href="http://www.cppblog.com/kb/" target="_blank">可冰</a></h4>
				<p>谢谢你的批评.我也正是认识到这个问题后来向大家寻求帮助的. <br />另外你给我建议很不错的,可以考虑那样的实现.  <a onclick="return SetReplyAuhor(&quot;可冰&quot;)" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#post">回复</a><a id="Comments1_CommentList_ctl05_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl05$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl05_EditLink"></a></p>
				<h4>
						<a title="permalink: re: 评价一下UTF-8与UNICODE相互转换的代码" href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#3260">#</a> <a name="3260"></a>re: 评价一下UTF-8与UNICODE相互转换的代码 <span>2006-02-15 03:33 </span><a id="Comments1_CommentList_ctl06_NameLink" target="_blank">Edward</a></h4>
				<p>请教： <br />I build a function: <br /><br />wstring mbstowcs(const string &amp;str) { <br />size_t len=mbstowcs(NULL, str.c_str(), str.length()); <br />wchar_t *pwc = (wchar_t *)malloc( len* sizeof( wchar_t )); <br />len=mbstowcs(pwc, str.c_str(), str.length()); <br />return wstring(pwc,len); <br />} <br /><br />"str" is a chinese string. but after convertion, "pwc" is a string that I couldn't read. 乱码。Why? 我的计算机是英文windwos,但可以输入和显示汉字。 <br /></p>
		</div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/7903.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-21 16:09 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/21/7903.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>面向组件还是面向对象 （转－软件工程相关）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7893.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Tue, 21 Mar 2006 05:25:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7893.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7893.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7893.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7893.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7893.html</trackback:ping><description><![CDATA[
		<div class="post">
				<div class="posthead">
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">组件（</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt">
								<font face="Times New Roman">Component</font>
						</span>
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）应该是在现代软件工程中，除了对象（</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt">
								<font face="Times New Roman">Object</font>
						</span>
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）之外的第二个炙手可热的词了。然而，什么是一个组件？是一个某些逻辑集合的实现？还是一个承载这些实现的物理实体（例如</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt">
								<font face="Times New Roman">DLL</font>
						</span>
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）？还是一个包括了逻辑实现、物理载体以及相关的类型信息、安全策略和版本信息的一个大而全的集合？也许你会说任何一种解释都是正确的。的确，不同的环境中，</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt">
								<font face="Times New Roman">Component</font>
						</span>
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有着不同的含义，但是，在</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt">
								<font face="Times New Roman">.NET</font>
						</span>
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，我们就可以把一个</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt">
								<font face="Times New Roman">.NET Class</font>
						</span>
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当作一个</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt">
								<font face="Times New Roman">Component</font>
						</span>
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
				</div>
				<div class="postbody">
						<div>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
										</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
												<o:p>
														<hr id="[object]" />
												</o:p>
										</span>
								</p>
								<p>
								</p>
								<p>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">既然类和组件有着这么多类似的地方，那么传统的面向对象编程和面向组件编程有什么区别呢？简单的说，面向对象关注的是组合在一个二进制可执行文件中的各个类的关系，而面向组件的编程关注的是在彼此独立的基础上模块之间的交互性，这种交互性使得你并不需要熟悉它们内部的工作原理。</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<o:p>
												</o:p>
										</span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<b style="mso-bidi-font-weight: normal">
												<span style="FONT-FAMILY: 新宋体; mso-bidi-font-size: 10.5pt">
														<font size="3">分而治之<font face="新宋体"><span lang="EN-US"> VS </span>集大成<span lang="EN-US"><o:p></o:p></span></font></font>
												</span>
										</b>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这两种方法最基本的不同在于它们对最终的应用程序的观点。在传统的面向对象编程中，尽管你可以精心的把所有的商业逻辑分布在不同的类中，一旦这些类被编译，它们就被固化成了一个巨大的二进制代码。所有的类共享同一个物理单元（通常是一个可执行文件）、被操作系统认为是同一个进程，使用同一个地址空间以及共享相同的安全策略等等。如果多个开发者在同一份代码上进行开发，他们甚至还要共享源文件。在这种情况下，修改一个类可能会让整个项目被重新链接，并重新进行必要的测试，更严重的，还有可能要修改其他的类。但是，在面向组件开发中，应用程序是由一系列可以互相交互的二进制模块组合而成的。</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<o:p>
												</o:p>
										</span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个具体的二进制组件可能并不能完成什么工作。有些组件是为了提供一些常规服务而编写的，例如通信的封装或者文件访问组件。也有一些是为了某些特定应用而专门开发的。一个应用程序的设计者可以通过把这些不同的组件提供的功能粘合在一起来实现他们需要的商业逻辑。很多面向组件的技术——例如：</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<font face="Times New Roman">COM</font>
										</span>
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<font face="Times New Roman">J2EE</font>
										</span>
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<font face="Times New Roman">CORBA</font>
										</span>
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<font face="Times New Roman">.NET</font>
										</span>
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都为二进制组件提供了的无缝链接的机制。而唯一的不同就是你需要在组件通信上花费的力气。</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<o:p>
												</o:p>
										</span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">把一个二进制应用程序分解成不同的二进制组件的动机和把不同的类放到不同的文件中是类似的。后者使得不同的类的开发人员可以彼此独立的工作，尽管即时修改了一个类也要重新链接整个应用程序，但是你只需要重新编译被修改的部分就可以了。</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<o:p>
												</o:p>
										</span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">但是，面向组件的开发还是和简单软件项目的管理更复杂一些。因为一个面向组件的应用程序是一个二进制代码块的集合，你可以把组件当作是</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<font face="Times New Roman">LEGO</font>
										</span>
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的积木块一样，随心所欲的拆装它们。如果你需要修改一个组件的实现，只需要修改那个组件就可以了，而组件的客户机不需要重新编译也不需要重新开发。对于那些不常用到的组件，组件甚至可以在一个程序运行的时候被更新。这些改进和增强使得组件可以立即进行更新，而所有该组件的客户都将立即受益。无论是在同一台机器上还是通过网络远程访问。</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<o:p>
												</o:p>
										</span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">面向组件的应用程序也更易于扩展。当你需要实现新的需求的时候，你可以提供一个新的组件，而不去影响那些和新需求无关的组件。这些特点使得面向组件的开发降低了大型软件项目长期维护的成本，这是一个最实际的商业问题，也正是如此，组件技术才如此迅速的被接受。</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<o:p>
												</o:p>
										</span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">面向组件的应用程序通常可以更快的响应市场，因为你可以有很大的选择空间，不仅仅是自己开发的组件，还可以从第三方厂商来购买某些组件，从而避免了重复制造轮子。这里，</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<font face="Times New Roman">VB</font>
										</span>
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就是一个很好的例子，丰富的</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<font face="Times New Roman">ActiveX</font>
										</span>
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">控件使得很多人在快速开发中得到了享受。</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<o:p>
												</o:p>
										</span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<b style="mso-bidi-font-weight: normal">
												<span style="FONT-FAMILY: 新宋体; mso-bidi-font-size: 10.5pt">
														<font size="3">接口还是继承<span lang="EN-US"><o:p></o:p></span></font>
												</span>
										</b>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">面向对象和面向组件另一个重要的不同在于这两种技术在继承和重用模型上的侧重点不同。<span lang="EN-US"><o:p></o:p></span></span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">在面向对象的分析和设计中，应用程序通常被分解成复杂的类继承结构。类的设计和要解决的商业问题紧密结合。你可以从已有基类继承并特化其行为来实现代码重用。问题在于，这是一种很糟糕的重用的方法。当你从一个基类派生一个子类的时候，你必须对基类的实现有透彻的理解才可能保证不出问题。例如：修改一个成员变量会不会带来副作用？这会对基类中的代码有什么影响？重载基类的方法会不会破坏那些想使用基类版本的客户的行为？等等。<span lang="EN-US"><o:p></o:p></span></span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">这种形式的重用被称为白盒重用（<font face="新宋体"><span lang="EN-US">White-box reuse</span>）<span lang="EN-US">,</span>因为当你重用的时候你就需要去了解基类实现的细节。显然。白盒重用在可扩展性较高的大型应用中并不经济，也很难得到第三方<span lang="EN-US">Framework</span>厂商的支持。<span lang="EN-US"><o:p></o:p></span></font></span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">面向组件的开发采用了黑盒重用（<font face="新宋体"><span lang="EN-US">Black-box reuse</span>）的方法，它可以让你对组件内部全然不知的情况下来使用组件公开的接口。这样，你就可以远离那些复杂的继承关系。而面向组件的开发者也可以把更多的精力放在制定组件和客户的沟通的接口上了。<span lang="EN-US"><o:p></o:p></span></font></span>
								</p>
								<p style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
										<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">最后，面向对象编程提供了有限的工具和设计模式来处理和应用程序运行时相关的问题，例如多线程、并发管理、安全、分布式应用和版本控制等。面向对象的开发者当面对这些“公共需求”的时候，或多或少的需要自己来解决问题。但是面向组件的开发方式却使你在这方面要灵活的多。</span>
										<span lang="EN-US" style="FONT-SIZE: 10pt">
												<o:p>
												</o:p>
										</span>
								</p>
						</div>
				</div>
		</div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/7893.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-21 13:25 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/21/7893.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>只在多态基类中声明虚析构函数 （别人写的）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7892.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Tue, 21 Mar 2006 05:20:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7892.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7892.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7892.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7892.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7892.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Posted on 2005-11-10 16:43 nacci 阅读(346) 评论(3)  编辑 收藏收藏至365Key 所属分类: C++ Experience-->																												关于virtual desctructor的详细讨论。同样来自于《Effective C++》3rd Edition。										...&nbsp;&nbsp;<a href='http://www.cnitblog.com/weitom1982/archive/2006/03/21/7892.html'>阅读全文</a><img src ="http://www.cnitblog.com/weitom1982/aggbug/7892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-21 13:20 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/21/7892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内存。二重指针，指针的高级使用 （转）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7870.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Tue, 21 Mar 2006 02:04:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7870.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7870.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7870.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7870.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7870.html</trackback:ping><description><![CDATA[
		<div class="postTitle">内存分配方式有三种：<br />（1） 从静态存储区域分配。内存在程序编译的时候就已经分配好，这块内存在程序的<br />整个运行期间都存在。例如全局变量，static 变量。<br />（2） 在栈上创建。在执行函数时，函数内局部变量的存储单元都可以在栈上创建，函<br />数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集<br />中，效率很高，但是分配的内存容量有限。<br />（3） 从堆上分配，亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多<br />少的内存，程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期<br />由我们决定，使用非常灵活，但问题也最多。</div>
		<p>?? 内存分配未成功，却使用了它。<br />编程新手常犯这种错误，因为他们没有意识到内存分配会不成功。常用解决办法是，<br />在使用内存之前检查指针是否为NULL。如果指针p 是函数的参数，那么在函数的入口<br />处用assert(p!=NULL)进行检查。如果是用malloc 或new 来申请内存，应该用if(p==NULL)<br />或if(p!=NULL)进行防错处理。</p>
		<p>?? 内存分配虽然成功，但是尚未初始化就引用它。</p>
		<p>?? 内存分配成功并且已经初始化，但操作越过了内存的边界。</p>
		<p>?? 忘记了释放内存，造成内存泄露。<br />含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足，你<br />看不到错误。终有一次程序突然死掉，系统出现提示：内存耗尽。<br />动态内存的申请与释放必须配对，程序中malloc 与free 的使用次数一定要相同，否<br />则肯定有错误（new/delete 同理）。</p>
		<p>?? 释放了内存却继续使用它。<br />有三种情况：<br />（1）程序中的对象调用关系过于复杂，实在难以搞清楚某个对象究竟是否已经释放了内<br />存，此时应该重新设计数据结构，从根本上解决对象管理的混乱局面。<br />（2）函数的return 语句写错了，注意不要返回指向“栈内存”的“指针”或者“引用”，<br />因为该内存在函数体结束时被自动销毁。<br />（3）使用free 或delete 释放了内存后，没有将指针设置为NULL。导致产生“野指针”</p>
		<p> </p>
		<p>
				<br />指针参数是如何传递内存的？<br />如果函数的参数是一个指针，不要指望用该指针去申请动态内存</p>
		<p>
				<br />Test 函数的语句GetMemory(str, 200)并没有使str 获得期望的内存，str 依旧是NULL，<br />为什么？</p>
		<p>void GetMemory(char *p, int num)<br />{<br />p = (char *)malloc(sizeof(char) * num);<br />}<br />void Test(void)<br />{<br />char *str = NULL;<br />GetMemory(str, 100); // str 仍然为 NULL<br />strcpy(str, "hello"); // 运行错误<br />}</p>
		<p>毛病出在函数GetMemory 中。编译器总是要为函数的每个参数制作临时副本，指针<br />参数p 的副本是 _p，编译器使 _p = p。如果函数体内的程序修改了_p 的内容，就导致<br />参数p 的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中，_p 申请<br />了新的内存，只是把_p 所指的内存地址改变了，但是p 丝毫未变。所以函数GetMemory<br />并不能输出任何东西。事实上，每执行一次GetMemory 就会泄露一块内存，因为没有用<br />free 释放内存。<br />如果非得要用指针参数去申请内存，那么应该改用“指向指针的指针”<br />void GetMemory2(char **p, int num)<br />{<br />*p = (char *)malloc(sizeof(char) * num);<br />}<br />void Test2(void)<br />{<br />char *str = NULL;<br />GetMemory2(&amp;str, 100); // 注意参数是 &amp;str，而不是str<br />strcpy(str, "hello");<br />cout&lt;&lt; str &lt;&lt; endl;<br />free(str);<br />}</p>
		<p>由于“指向指针的指针”这个概念不容易理解，我们可以用函数返回值来传递动态<br />内存。这种方法更加简单<br />char *GetMemory3(int num)<br />{<br />char *p = (char *)malloc(sizeof(char) * num);<br />return p;<br />}<br />void Test3(void)<br />{<br />char *str = NULL;<br />str = GetMemory3(100);<br />strcpy(str, "hello");<br />cout&lt;&lt; str &lt;&lt; endl;<br />free(str);<br />}<br />用函数返回值来传递动态内存这种方法虽然好用，但是常常有人把return 语句用错<br />了。这里强调不要用return 语句返回指向“栈内存”的指针，因为该内存在函数结束时<br />自动消亡<br />char *GetString(void)<br />{<br />char p[] = "hello world";<br />return p; // 编译器将提出警告<br />}<br />void Test4(void)<br />{<br />char *str = NULL;<br />str = GetString(); // str 的内容是垃圾<br />cout&lt;&lt; str &lt;&lt; endl;<br />}<br />用调试器逐步跟踪Test4，发现执行str = GetString 语句后str 不再是NULL 指针，<br />但是str 的内容不是“hello world”而是垃圾。<br />char *GetString2(void)<br />{<br />char *p = "hello world";<br />return p;<br />}<br />void Test5(void)<br />{<br />char *str = NULL;<br />str = GetString2();<br />cout&lt;&lt; str &lt;&lt; endl;<br />}<br />函数Test5 运行虽然不会出错，但是函数GetString2 的设计概念却是错误的。因为<br />GetString2 内的“hello world”是常量字符串，位于静态存储区，它在程序生命期内<br />恒定不变。无论什么时候调用GetString2，它返回的始终是同一个“只读”的内存块。</p>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/7870.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-21 10:04 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/21/7870.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字节对齐问题的一个例子和讨论。（转）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7867.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Tue, 21 Mar 2006 01:52:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7867.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7867.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/21/7867.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7867.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7867.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<p>老师提出一个很有意思的问题：<br /></p>
				<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">
						<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">class</span>
						<span style="COLOR: #000000"> b<br /><img id="Codehighlighter1_8_55_Open_Image" onclick="this.style.display='none'; Codehighlighter1_8_55_Open_Text.style.display='none'; Codehighlighter1_8_55_Closed_Image.style.display='inline'; Codehighlighter1_8_55_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_8_55_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_8_55_Closed_Text.style.display='none'; Codehighlighter1_8_55_Open_Image.style.display='inline'; Codehighlighter1_8_55_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
						<span id="Codehighlighter1_8_55_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/Images/dot.gif" />
						</span>
						<span id="Codehighlighter1_8_55_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> c1;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">long</span>
								<span style="COLOR: #000000"> l;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> c2;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">double</span>
								<span style="COLOR: #000000"> d;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
						</span>
						<span style="COLOR: #000000">;</span>
				</div>与 
<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"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> b<br /><img id="Codehighlighter1_8_62_Open_Image" onclick="this.style.display='none'; Codehighlighter1_8_62_Open_Text.style.display='none'; Codehighlighter1_8_62_Closed_Image.style.display='inline'; Codehighlighter1_8_62_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_8_62_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_8_62_Closed_Text.style.display='none'; Codehighlighter1_8_62_Open_Image.style.display='inline'; Codehighlighter1_8_62_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_8_62_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_8_62_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> c1;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> c2;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000"> l;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000"> d;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;</span></div>在存储的时候用的空间是不一样大的，前者是24，后者是16，为什么？<br />-------------------------------------------------------------------------------------------------------------------------<br />我在自己的机器上也运行了，的确如此，我知道16是怎么来的， char是2，long是4，double是8，2+2+4+8=16，而24我就太明白了，说地址是4字节的，char是2，要空两个字节，那第一个也应该是20阿，怎么会是24呢？有明白人的给讲讲！ </div>
		<div class="postfoot">posted on 2005-11-11 12:56 <a href="http://www.cppblog.com/yunduan5158/"><font color="#000080">Merlin</font></a> 阅读(420) <a href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#Post"><font color="#000080">评论(13)</font></a>  <a href="http://www.cppblog.com/yunduan5158/admin/EditPosts.aspx?postid=1064"><font color="#000080">编辑</font></a> <a href="http://www.cppblog.com/yunduan5158/AddToFavorite.aspx?id=1064"><font color="#000080">收藏</font></a><a title="功能强大的网络收藏夹，一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();"><font color="#000080">收藏至365Key</font></a> 所属分类: <a href="http://www.cppblog.com/yunduan5158/category/174.html"><font color="#000080">C++</font></a></div>
		<img height="1" src="http://www.cppblog.com/yunduan5158/aggbug/1064.html?webview=1" width="1" />
		<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html"
dc:identifier="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html"
dc:title="一个有意思的问题"
trackback:ping="http://www.cppblog.com/yunduan5158/services/trackbacks/1064.aspx" />
</rdf:RDF>
-->
		<a name="评论">
				<br />
				<div id="comments">
						<h3>评论</h3>
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1073">
												<font color="#000080">#</font>
										</a> <a name="1073"></a>re: 一个有意思的问题 <span>2005-11-11 13:32 </span><a id="Comments1_CommentList_ctl00_NameLink" href="http://www.cppblog.com/windcsn/" target="_blank"><font color="#000080">笨笨</font></a></div>
								<div class="postText">你的程序是按照8个字节对齐的 <br />  <a onclick="return SetReplyAuhor(&quot;笨笨&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl00_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl00$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl00_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1077">
												<font color="#000080">#</font>
										</a> <a name="1077"></a>re: 一个有意思的问题 <span>2005-11-11 14:00 </span><a id="Comments1_CommentList_ctl01_NameLink" href="http://www.cppblog.com/nacci/" target="_blank"><font color="#000080">nacci</font></a></div>
								<div class="postText">建议你为每个类定义构造函数，然后分别生成对象后，观察每个对象的内存布局。在b中，为了和double d对齐，为c2保留了8 bytes的空间。  <a onclick="return SetReplyAuhor(&quot;nacci&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl01_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl01$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl01_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1080">
												<font color="#000080">#</font>
										</a> <a name="1080"></a>re: 一个有意思的问题 <span>2005-11-11 16:37 </span><a id="Comments1_CommentList_ctl02_NameLink" href="http://www.cppblog.com/yunduan5158/" target="_blank"><font color="#000080">Merlin</font></a></div>
								<div class="postText">为什么就char要对齐阿，而long不用对齐阿？ <br /><br />class b <br />{ <br />char c1; <br /><br />long l; <br /><br />char c2; <br /><br />long l1; <br /><br />double d; <br /><br /><br />};//sizeof(b)=24! <br />这里面到底是怎么回事啊？  <a onclick="return SetReplyAuhor(&quot;Merlin&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl02_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl02$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl02_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1081">
												<font color="#000080">#</font>
										</a> <a name="1081"></a>re: 一个有意思的问题 <span>2005-11-11 16:56 </span><a id="Comments1_CommentList_ctl03_NameLink" href="http://www.cppblog.com/shootingstars/" target="_blank"><font color="#000080">shootingstars</font></a></div>
								<div class="postText">字节对齐是为了提高从内存中获取变量的效率。 <br />如果数据总线的宽度是32位，那么每次从内存中取数据都是从4的倍数取的。如果不对齐的话，有可能取一个int型数据需要两次操作。 <br /><br />编译器一般都可以使用编译指令来控制是否需要字节对齐。  <a onclick="return SetReplyAuhor(&quot;shootingstars&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl03_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl03$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl03_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1082">
												<font color="#000080">#</font>
										</a> <a name="1082"></a>re: 一个有意思的问题 <span>2005-11-11 17:00 </span><a id="Comments1_CommentList_ctl04_NameLink" href="http://www.cppblog.com/windcsn/" target="_blank"><font color="#000080">笨笨</font></a></div>
								<div class="postText">如果你是VC的话，使用 <br />#pragma pack(push,8) <br />#pragma pack(1)//使用一个字节对齐 <br />你在这里写代码 <br />#pragma pack(pop,8) <br /><br />这种情况不能乱用，因为会降低效率 <br />WINDOWS核心编程介绍字节对齐的原因  <a onclick="return SetReplyAuhor(&quot;笨笨&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl04_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl04$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl04_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1085">
												<font color="#000080">#</font>
										</a> <a name="1085"></a>re: 一个有意思的问题 <span>2005-11-11 21:44 </span><a id="Comments1_CommentList_ctl05_NameLink" href="http://www.cppblog.com/yunduan5158/" target="_blank"><font color="#000080">Merlin</font></a></div>
								<div class="postText">谢谢了！  <a onclick="return SetReplyAuhor(&quot;Merlin&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl05_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl05$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl05_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1100">
												<font color="#000080">#</font>
										</a> <a name="1100"></a>re: 一个有意思的问题 <span>2005-11-12 12:30 </span><a id="Comments1_CommentList_ctl06_NameLink" href="http://www.cppblog.com/yunduan5158/" target="_blank"><font color="#000080">Merlin</font></a></div>
								<div class="postText">当CPU的访问正确对齐的数据时，它的运行效率最高，当数据大小的数据模数的内存地址是0时，数据是对齐的。例如：WORD值应该是总是从被2除尽的地址开始，而DWORD值应该总是从被4除尽的地址开始，数据对齐不是内存结构的一部分，而是CPU结构的一部分。当CPU试图读取的数据值没有正确的对齐时，CPU可以执行两种操作之一：产生一个异常条件；执行多次对齐的内存访问，以便读取完整的未对齐的数据，若多次执行内存访问，应用程序的运行速度就会慢。在最好的情况下，是两倍的时间，有时更长。 <br />-------------《Windows核心编程》 <br />不过我还有一点不明白的： <br />struct s <br />{ <br /><br />char a; <br /><br />long int d; <br /><br />double c; <br /><br /><br />};//此时是16 <br />struct s <br />{ <br /><br />char a; <br /><br />long int d; <br /><br />double c; <br /><br />char a1; <br /><br /><br />};//而此时是24 <br />也就是说a1用了8个，我觉得就没有道理啊，不是当数据大小的数据模数的内存地址是0时，数据是对齐的么？ char没有必要用8个阿！有没有人明白，帮解释一下！  <a onclick="return SetReplyAuhor(&quot;Merlin&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl06_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl06$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl06_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1105">
												<font color="#000080">#</font>
										</a> <a name="1105"></a>re: 一个有意思的问题 <span>2005-11-12 21:21 </span><a id="Comments1_CommentList_ctl07_NameLink" href="http://www.cppblog.com/windcsn/" target="_blank"><font color="#000080">笨笨</font></a></div>
								<div class="postText">哎，编译器默认是8个行不行呀？  <a onclick="return SetReplyAuhor(&quot;笨笨&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl07_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl07$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl07_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1108">
												<font color="#000080">#</font>
										</a> <a name="1108"></a>re: 一个有意思的问题 <span>2005-11-12 22:49 </span><a id="Comments1_CommentList_ctl08_NameLink" target="_blank">fireup</a></div>
								<div class="postText">编译器默认的对齐是8字节对齐。 <br /><br />两个结构在内存中的分配分别如下图 <br />0 4 8 <br />+-------+-------+ <br />|char |long | 0-7 <br />+-------+-------+ <br />|char | 8-15 <br />+---------------+ <br />|double | 16-23 <br />+---------------+ <br /><br />0 4 8 <br />+-------+-------+ <br />|c|c| |long | 0-7 <br />+-------+-------+ <br />|double | 8-15 <br />+---------------+ <br /><br />  <a onclick="return SetReplyAuhor(&quot;fireup&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl08_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl08$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl08_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1111">
												<font color="#000080">#</font>
										</a> <a name="1111"></a>re: 一个有意思的问题 <span>2005-11-13 11:10 </span><a id="Comments1_CommentList_ctl09_NameLink" href="http://www.cppblog.com/SEMAN/" target="_blank"><font color="#000080">味全每日C++</font></a></div>
								<div class="postText">还是应该注意这一点 #pragma pack(8) <br />默认32位是8 ，不排除有的时候让你计算 #pragma pack(4) 的情况..  <a onclick="return SetReplyAuhor(&quot;味全每日C++&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl09_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl09$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl09_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#1339">
												<font color="#000080">#</font>
										</a> <a name="1339"></a>re: 一个有意思的问题 <span>2005-11-27 02:09 </span><a id="Comments1_CommentList_ctl10_NameLink" href="http://www.cppblog.com/qywyh/" target="_blank"><font color="#000080">豪</font></a></div>
								<div class="postText">学习  <a onclick="return SetReplyAuhor(&quot;豪&quot;)" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#post"><font color="#000080">回复</font></a><br /><a id="Comments1_CommentList_ctl10_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl10$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl10_EditLink"></a></div>
						</div>
						<br />
						<div class="post">
								<div class="postTitle">
										<a title="permalink: re: 一个有意思的问题" href="http://www.cppblog.com/yunduan5158/archive/2005/11/11/1064.html#2263">
												<font color="#000080">#</font>
										</a> <a name="2263"></a>re: 一个有意思的问题 <span>2005-12-30 10:48 </span><a id="Comments1_CommentList_ctl11_NameLink" target="_blank">发</a></div>
								<div class="postText">当CPU的访问正确对齐的数据时，它的运行效率最高，当数据大小的数据模数的内存地址是0时，数据是对齐的。例如：WORD值应该是总是从被2除尽的地址开始，而DWORD值应该总是从被4除尽的地址开始，数据对齐不是内存结构的一部分，而是CPU结构的一部分。当CPU试图读取的数据值没有正确的对齐时，CPU可以执行两种操作之一：产生一个异常条件；执行多次对齐的内存访问，以便读取完整的未对齐的数据，若多次执行内存访问，应用程序的运行速度就会慢。在最好的情况下，是两倍的时间，有时更长。 <br />-------------《Windows核心编程》 <br />不过我还有一点不明白的： <br />struct s <br />{ <br /><br />char a; <br /><br />long int d; <br /><br />double c; <br /><br /><br />};//此时是16 <br />struct s <br />{ <br /><br />char a; <br /><br />long int d; <br /><br />double c; <br /><br />char a1; <br /><br /><br />};//而此时是24 <br />也就是说a1用了8个，我觉得就没有道理啊，不是当数据大小的数据模数的内存地址是0时，数据是对齐的么？ char没有必要用8个阿！有没有人明白，帮解释一下！ <br />///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// <br /><br />除了结构体内的成员变量要求对齐外，结构自身也是需要对齐的。结构体成员的对齐是用成员本身的大小和#pragma pack(push,n)中的n中较小的数对齐，例如如果成员大小为2，而你指定的对齐方式是4，则该成员按2对齐；结构本身的对其是用结构中最大成员的大小和#pragma pack(push,n)中的n较小的数对齐，例如如果结构中最大成员大小8，而你指定对齐是16，则结构本身按8对齐。 <br /><br />对于 <br />struct s <br />{ <br /><br />char a; <br /><br />long int d; <br /><br />double c; <br /><br /><br />};//此时是16 <br />编译器默认的一般是8字节对齐。 <br />a大小是1，它就按1字节对齐（因为比指定的8小），存储在0偏移的地方；b大小4，它就按4字节对齐（因为比指定的8小），存在偏移4--7的位置，c大小8，它按8字节对齐，存在偏移8--15的位置。这样3个成员共占用了16字节。由于该结构最大成员c大小为8，所以结构按8字节对齐，16按8园整还是16，因此sizeof s = 16。 <br /><br />而对于 <br />struct s <br />{ <br /><br />char a; <br /><br />long int d; <br /><br />double c; <br /><br />char a1; <br /><br /><br />};//而此时是24 <br />前3个成员和上面一样存储，即a在0位置，d在4--7位置，c在8--16位置，但a1按一字节对齐，存在偏移17位置，这样4个成员占用了17字节；整个结构还要按8对齐（因为结构最大成员c大小为8），17按8圆整后是24，因此此时sizeof s = 24。 <br /><br />如果你指定编译器按4字节对齐，即你在开头加上#pragma pack(push,4) <br />则对于前者为12，后者为16。 <br />我用的是vc7.1。 <br /></div>
						</div>
				</div>
		</a>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/7867.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-21 09:52 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/21/7867.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>范型编程的一点文字。</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7848.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 20 Mar 2006 15:35:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7848.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7848.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7848.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7848.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7848.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 泛型编程 ，知多少？				归纳起来，泛型比非泛型具有下面两个优点：		1、  更加安全		在非泛型编程中，虽然所有的东西都可以作为Object传递，但是在传递的过程中免不了要进行类型转换。而类型转换在运行时是不安全的。使用泛型编程将可以减少不必要的类型转换，从而提高安全性。		2、  效率更高		在非泛型编程中，将简单类型作为Object传递时会引起Boxing和Unbo...&nbsp;&nbsp;<a href='http://www.cnitblog.com/weitom1982/archive/2006/03/20/7848.html'>阅读全文</a><img src ="http://www.cnitblog.com/weitom1982/aggbug/7848.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-20 23:35 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/20/7848.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序控制台的建立</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7844.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 20 Mar 2006 15:31:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7844.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7844.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7844.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7844.html</trackback:ping><description><![CDATA[
		<div class="post">
				<div class="postTitle">
						<a id="viewpost1_TitleUrl" href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html">为你的程序创建一个控制台 </a>
				</div>
				<div class="postText">
						<p>经常看到一些程序在运行的时候有一个WINDOWS控制台，感觉非常COOL。实际上有的时候帮助你监视系统运行是很方便的，那么怎么样创建一个控制台呢？</p>
						<p>实际上WINDOWS为你提供了一系列的API来完成这个功能，例如：<strong>ReadConsole,WriteConsole等，</strong>具体参见MSDN。</p>
						<p>下面我们用一段代码来说明如何创建Console.</p>
						<p>1。首先调用AllocConsole函数来为你进程创建一个Console，该API是将当前进程Attache到一个新创建的Console上。你还可以通过调用SetConsoleTitle(tstrName);来设置Console的Title.</p>
						<p>2。使用WriteConsoleOutput来将信息输出到Console上；在输出之前，先要得到Console的HANDLE,这通过GetStdHandle(STD_OUTPUT_HANDLE)来得到，然后将信息组织成Console的格式，然后输出。</p>
						<p>3。关闭CONSOLE。当不需要这个CONSOLE的时候，调用FreeConsole来将当前进程从Console中Detach中。</p>
						<p>4。通过创建一个进程来为监视你的CONSOLE输入和输出；你可以创建一个线程然后来，在线程中取得标准输入和输出CONSOLE的HANDLE，然后循环监视其事件，再对不同的事件进行处理。</p>
						<p>详细代码参见：<a href="http://blog.csdn.net/windcsn/archive/2005/11/27/537737.aspx">http://blog.csdn.net/windcsn/archive/2005/11/27/537737.aspx</a><a href="http://tb.blog.csdn.net/TrackBack.aspx?PostId=537737"></a></p>
				</div>
				<div class="postfoot">posted on 2005-11-27 15:49 <a href="http://www.cppblog.com/windcsn/">笨笨</a> 阅读(268) <a href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#Post">评论(5)</a>  <a href="http://www.cppblog.com/windcsn/admin/EditPosts.aspx?postid=1342">编辑</a> <a href="http://www.cppblog.com/windcsn/AddToFavorite.aspx?id=1342">收藏</a><a title="功能强大的网络收藏夹，一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();">收藏至365Key</a></div>
		</div>
		<img height="1" src="http://www.cppblog.com/windcsn/aggbug/1342.html?webview=1" width="1" />
		<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html"
dc:identifier="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html"
dc:title="为你的程序创建一个控制台 "
trackback:ping="http://www.cppblog.com/windcsn/services/trackbacks/1342.aspx" />
</rdf:RDF>
-->
		<a name="feedback">
		</a>
		<div id="comments">
				<h3>Feedback</h3>
				<div class="post">
						<div class="postTitle">
								<a title="permalink: re: 为你的程序创建一个控制台 " href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#1349">#</a> <a name="1349"></a>re: 为你的程序创建一个控制台 <span>2005-11-28 01:22 </span><a id="Comments1_CommentList_ctl00_NameLink" href="http://www.cppblog.com/eXile/" target="_blank">eXile</a></div>
						<div class="postText">你说的是在GUI程序中使用控制台吧, 对于VC, 其实有一个简单的方法: <br />在选项 Post-builder step 里新建command, 输入: <br />editbin /SUBSYSTEM:CONSOLE $(OUTDIR)\filename.exe <br />(其中 filename 为可执行文件名) <br />则可以使用 printf 或者 std::cout 在控制台中输出了.  <a onclick="return SetReplyAuhor(&quot;eXile&quot;)" href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#post">回复</a><br /><a id="Comments1_CommentList_ctl00_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl00$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl00_EditLink"></a></div>
				</div>
				<br />
				<div class="post">
						<div class="postTitle">
								<a title="permalink: re: 为你的程序创建一个控制台 " href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#1362">#</a> <a name="1362"></a>re: 为你的程序创建一个控制台 <span>2005-11-28 13:15 </span><a id="Comments1_CommentList_ctl01_NameLink" href="http://www.cppblog.com/sandy/" target="_blank">小明</a></div>
						<div class="postText">最好能重定向cout,cerr到文件中去 <br />SDL就是这样做的  <a onclick="return SetReplyAuhor(&quot;小明&quot;)" href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#post">回复</a><br /><a id="Comments1_CommentList_ctl01_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl01$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl01_EditLink"></a></div>
				</div>
				<br />
				<div class="post">
						<div class="postTitle">
								<a title="permalink: re: 为你的程序创建一个控制台 " href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#1374">#</a> <a name="1374"></a>re: 为你的程序创建一个控制台 <span>2005-11-28 21:23 </span><a id="Comments1_CommentList_ctl02_NameLink" href="http://www.cppblog.com/windcsn/" target="_blank">笨笨</a></div>
						<div class="postText">To eXile:可以吗？我怎么不成功  <a onclick="return SetReplyAuhor(&quot;笨笨&quot;)" href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#post">回复</a><br /><a id="Comments1_CommentList_ctl02_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl02$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl02_EditLink"></a></div>
				</div>
				<br />
				<div class="post">
						<div class="postTitle">
								<a title="permalink: re: 为你的程序创建一个控制台 " href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#1446">#</a> <a name="1446"></a>re: 为你的程序创建一个控制台 <span>2005-11-30 17:43 </span><a id="Comments1_CommentList_ctl03_NameLink" href="http://www.cppblog.com/eXile/" target="_blank">eXile</a></div>
						<div class="postText">没有理由啊! 估计是你拼写错误. <br /><br />在 Project | Setting...中设置, 如果你的可执行文件名为 HelloWorld.exe， <br />则你新建的 command 就为 <br /><br />editbin　　 /SUBSYSTEM:CONSOLE 　　$(OUTDIR)\HelloWorld.exe <br /><br />如果还不行, 那......只有天知道了. <br />  <a onclick="return SetReplyAuhor(&quot;eXile&quot;)" href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#post">回复</a><br /><a id="Comments1_CommentList_ctl03_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl03$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl03_EditLink"></a></div>
				</div>
				<br />
				<div class="post">
						<div class="postTitle">
								<a title="permalink: re: 为你的程序创建一个控制台 " href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#1458">#</a> <a name="1458"></a>re: 为你的程序创建一个控制台 <a name="Post"></a><span>2005-12-01 09:37 </span><a id="Comments1_CommentList_ctl04_NameLink" href="http://www.cppblog.com/windcsn/" target="_blank">笨笨</a></div>
						<div class="postText">是的，实验成功了，上次放错了地方，放到生成后事件中就可以了，但这种情况适合那些只输出的情况，如果需要moniter控制台就不行了  <a onclick="return SetReplyAuhor(&quot;笨笨&quot;)" href="http://www.cppblog.com/windcsn/archive/2005/11/27/1342.html#post">回复</a><br /></div>
				</div>
		</div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/7844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-20 23:31 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/20/7844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大数运算全部源代码 </title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7839.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 20 Mar 2006 15:26:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7839.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7839.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7839.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7839.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7839.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这个程序应该是我在2004年写的当时还只是一个读化工专业的大四学生基本上对什么编程规范、什么算法，什么性能优化没什么了解只是简单地用字符串模拟实现了任意大整数的四则运算现在看来当然很幼稚了不过为保持原来面目，一直没改，留做纪念。供有需要的朋友参考敬请指教  1//long integer operation , inclue addition,substracttion,multiplicaton...&nbsp;&nbsp;<a href='http://www.cnitblog.com/weitom1982/archive/2006/03/20/7839.html'>阅读全文</a><img src ="http://www.cnitblog.com/weitom1982/aggbug/7839.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-20 23:26 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/20/7839.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++指针探讨 (二) 函数指针 </title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7838.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 20 Mar 2006 15:24:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7838.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7838.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7838.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7838.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7838.html</trackback:ping><description><![CDATA[
		<div class="posthead">　　在C/C++中，数据指针是最直接，也最常用的，因此，理解起来也比较容易。而函数指针，作为运行时动态调用（比如回调函数 CallBack Function）是一种常见的，而且是很好用的手段。</div>
		<div class="postbody">
				<div class="pgcontent">
						<p>　　我们先简单的说一下函数指针。（这一部份没什么价值，纯是为了引出下一节的内容）<br />    <br />　2 常规函数指针</p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">        </span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000">(</span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">fp)();<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span>
						</div>
						<p>　　fp 是一个典型的函数指针，用于指向无参数，无返回值的函数。</p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">        </span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000">(</span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">fp2)(</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000">);<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span>
						</div>
						<p>　　fp2 也是一个函数指针，用于指向有一个整型参数，无返回值的函数。<br />　　当然，有经验人士一般都会建议使用typedef来定义函数指针的类型，如：</p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">        typedef </span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000">(</span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000"> FP)();<br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />        FP fp3; </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 和上面的fp一样的定义。</span>
						</div>
						<p>　　函数指针之所以让初学者畏惧，最主要的原因是它的括号太多了；某些用途的函数指针，往往会让人陷在括号堆中出不来，这里就不举例了，因为不是本文讨论的范围；typedef 方法可以有效的减少括号的数量，以及理清层次，所以受到推荐。本文暂时只考虑简单的函数指针，因此暂不用到typedef。<br /><br />　　假如有如下两个函数：</p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">  </span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000"> f1()<br /><img id="Codehighlighter1_14_61_Open_Image" onclick="this.style.display='none'; Codehighlighter1_14_61_Open_Text.style.display='none'; Codehighlighter1_14_61_Closed_Image.style.display='inline'; Codehighlighter1_14_61_Closed_Text.style.display='inline';" src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_14_61_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_14_61_Closed_Text.style.display='none'; Codehighlighter1_14_61_Open_Image.style.display='inline'; Codehighlighter1_14_61_Open_Text.style.display='inline';" src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" />  </span>
								<span id="Codehighlighter1_14_61_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.cnblogs.com/Images/dot.gif" />
								</span>
								<span id="Codehighlighter1_14_61_Open_Text">
										<span style="COLOR: #000000">{<br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />      std::cout </span>
										<span style="COLOR: #000000">&lt;&lt;</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">call f </span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #000000">&lt;&lt;</span>
										<span style="COLOR: #000000"> std::endl;<br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />  }</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  <br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000"> f2(</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000"> a)<br /><img id="Codehighlighter1_85_147_Open_Image" onclick="this.style.display='none'; Codehighlighter1_85_147_Open_Text.style.display='none'; Codehighlighter1_85_147_Closed_Image.style.display='inline'; Codehighlighter1_85_147_Closed_Text.style.display='inline';" src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_85_147_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_85_147_Closed_Text.style.display='none'; Codehighlighter1_85_147_Open_Image.style.display='inline'; Codehighlighter1_85_147_Open_Text.style.display='inline';" src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" />  </span>
								<span id="Codehighlighter1_85_147_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.cnblogs.com/Images/dot.gif" />
								</span>
								<span id="Codehighlighter1_85_147_Open_Text">
										<span style="COLOR: #000000">{<br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />      std::cout </span>
										<span style="COLOR: #000000">&lt;&lt;</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">call f2( </span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #000000">&lt;&lt;</span>
										<span style="COLOR: #000000"> a </span>
										<span style="COLOR: #000000">&lt;&lt;</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000"> )</span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #000000">&lt;&lt;</span>
										<span style="COLOR: #000000"> std::endl;<br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />  }</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
						</div>
						<p>　　现在需要通过函数指针来调用，我们需要给指针指定函数：</p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">  fp </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">f1; </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 也可以用：fp = f1;</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">  fp2</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">f2; </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 也可以用：fp2= f2;</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">  </span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000"> (</span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">fp3)() </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">f1; </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 也可以用：void (*fp3)() = f1;  <br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000">调用时如下：</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">  fp(); </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 或 (*fp)();</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">  fp2(</span>
								<span style="COLOR: #000000">1</span>
								<span style="COLOR: #000000">); </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 或 (*fp2)(1);</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">  fp3();  </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 或 (*fp3)();<br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span>
						</div>
						<p>　　对于此两种调用方法，效果完全一样，我推荐用前一种。后一种不仅仅是多打了键盘，而且也损失了一些灵活性。这里暂且不说它。<br />  <br />　　C++强调类型安全。也就是说，不同类型的变量是不能直接赋值的，否则轻则警告，重则报错。这是一个很有用的特性，常常能帮我们找到问题。因此，有识之士认为，C++中的任何一外警告都不能忽视。甚至有人提出，编译的时候不能出现任何警告信息，也就是说，警告应该当作错误一样处理。<br />  <br />　　比如，我们把f1赋值给fp2，那么C++编译器(vc7.1)就会报错：</p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">  fp2 </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">f1; </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> error C2440: “=” : 无法从“void (__cdecl *)(void)”转换为“void (__cdecl *)(int)”</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">  fp1 </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">f1; </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> OK<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span>
						</div>
						<p>　　这样，编译器可以帮我们找出编码上的错误，节省了我们的排错时间。<br />  <br />　　考虑一下C++标准模板库的sort函数：</p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">  </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 快速排序函数</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">  template&lt;typename RandomAccessIterator, typename BinaryPredicate&gt;<br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />     </span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000"> sort(<br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />        RandomAccessIterator _First, </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 需排序数据的第一个元素位置</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">        RandomAccessIterator _Last,  </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 需排序数据的最后一个元素位置（不参与排序）</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">        BinaryPredicate _Comp     </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 排序使用的比较算法(可以是函数指针、函数对象等)</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">     );</span>
						</div>
						<p>　　比如，我们有一个整型数组：</p>
						<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">
								<img id="Codehighlighter1_13_23_Open_Image" onclick="this.style.display='none'; Codehighlighter1_13_23_Open_Text.style.display='none'; Codehighlighter1_13_23_Closed_Image.style.display='inline'; Codehighlighter1_13_23_Closed_Text.style.display='inline';" src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_13_23_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_13_23_Closed_Text.style.display='none'; Codehighlighter1_13_23_Open_Image.style.display='inline'; Codehighlighter1_13_23_Open_Text.style.display='inline';" src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" />
								<span style="COLOR: #000000">  </span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000"> n[</span>
								<span style="COLOR: #000000">5</span>
								<span style="COLOR: #000000">] </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span id="Codehighlighter1_13_23_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.cnblogs.com/Images/dot.gif" />
								</span>
								<span id="Codehighlighter1_13_23_Open_Text">
										<span style="COLOR: #000000">{</span>
										<span style="COLOR: #000000">3</span>
										<span style="COLOR: #000000">,</span>
										<span style="COLOR: #000000">2</span>
										<span style="COLOR: #000000">,</span>
										<span style="COLOR: #000000">1</span>
										<span style="COLOR: #000000">,</span>
										<span style="COLOR: #000000">8</span>
										<span style="COLOR: #000000">,</span>
										<span style="COLOR: #000000">9</span>
										<span style="COLOR: #000000">}</span>
								</span>
								<span style="COLOR: #000000">;<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span>
						</div>
						<p>　　要对它进行升序排序，我们需定义一个比较函数：</p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">  </span>
								<span style="COLOR: #0000ff">bool</span>
								<span style="COLOR: #000000"> less(</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000"> a, </span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000"> b)<br /><img id="Codehighlighter1_28_53_Open_Image" onclick="this.style.display='none'; Codehighlighter1_28_53_Open_Text.style.display='none'; Codehighlighter1_28_53_Closed_Image.style.display='inline'; Codehighlighter1_28_53_Closed_Text.style.display='inline';" src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_28_53_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_28_53_Closed_Text.style.display='none'; Codehighlighter1_28_53_Open_Image.style.display='inline'; Codehighlighter1_28_53_Open_Text.style.display='inline';" src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" />  </span>
								<span id="Codehighlighter1_28_53_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.cnblogs.com/Images/dot.gif" />
								</span>
								<span id="Codehighlighter1_28_53_Open_Text">
										<span style="COLOR: #000000">{<br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />      </span>
										<span style="COLOR: #0000ff">return</span>
										<span style="COLOR: #000000"> a </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000"> b; <br /><img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />  }</span>
								</span>
						</div>
						<p>　　然后用：</p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">  sort(n, n</span>
								<span style="COLOR: #000000">+</span>
								<span style="COLOR: #000000">5</span>
								<span style="COLOR: #000000">, less);</span>
						</div>
						<p>　　要是想对它进行降序排序，我们只要换一个比较函数就可以了。C/C++的标准模板已经提供了less和great函数，因此我们可以直接用下面的语句来比较：  </p>
						<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">
								<img src="http://ly4cn.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">  sort(n, n</span>
								<span style="COLOR: #000000">+</span>
								<span style="COLOR: #000000">5</span>
								<span style="COLOR: #000000">, great);</span>
						</div>
						<p>
								<br />　　这样，不需要改变sort函数的定义，就可以按任意方法进行排序，是不是很灵活？  <br />　　这种用法以C++的标准模板库(STL)中非常流行。另外，操作系统中也经常使用回调(CallBack)函数，实际上，所谓回调函数，本质就是函数指针。</p>
						<p>　　看起来很简单吧，这是最普通的C语言指针的用法。本来这是一个很美妙的事情，但是当C++来临时，世界就开始变了样。<br />　　假如，用来进行sort的比较函数是某个类的成员，那又如何呢？<br /></p>
				</div>
		</div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/7838.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-20 23:24 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/20/7838.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA和C＋＋的一点比较（转）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7837.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 20 Mar 2006 14:36:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7837.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7837.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7837.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7837.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7837.html</trackback:ping><description><![CDATA[
		<div class="post">
				<div class="posthead">
						<h2>
								<a class="singleposttitle" id="viewpost1_TitleUrl" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html">Java中最值得C++借鉴的特性s</a>
						</h2>Posted on 2006-01-25 11:40 <a href="http://www.cppblog.com/sandy/">小明</a> 阅读(594) <a href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#Post">评论(8)</a>  <a href="http://www.cppblog.com/sandy/admin/EditPosts.aspx?postid=3018">编辑</a> <a href="http://www.cppblog.com/sandy/AddToFavorite.aspx?id=3018">收藏</a><a title="功能强大的网络收藏夹，一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();">收藏至365Key</a> 所属分类: <a href="http://www.cppblog.com/sandy/category/767.html">C/C++</a><img height="1" src="http://www.cppblog.com/sandy/aggbug/3018.html?webview=1" width="1" /><!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html"
dc:identifier="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html"
dc:title="Java中最值得C++借鉴的特性s"
trackback:ping="http://www.cppblog.com/sandy/services/trackbacks/3018.aspx" />
</rdf:RDF>
--></div>
				<div class="postbody">1995年出现的Java语言确实是一门伟大的语言，尽管它也不是完美的语言，而C++是一门比较"古老"的预言了，Java中有很多值得C++借鉴的东西。不知道未来的C++ 0x标准出来以后，C++会变成怎样?<br /><br /><br /><strong>1.强大的反射机制和RTTI特性</strong><br />这个特性是当前流行的J2EE framework的基础，如Spring,Hibernate,无不利用了Java强大的反射机制。<br />Java可以在运行期动态创建class,并且invoke某一个方法。<br /><br /><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">MyClass helper </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (MyClass) Class.forName(className).newInstance();</span></div><br /><strong>2.内建对多线程的支持和synchronized关键字<br /></strong>C++标准本没有提供比如创建thread的方法，不过现在出现了boost::thread应该是将来的C++标准。Java中有synchronized这个关键字，这是一种很简单，安全的锁机制。多线程编程很重要，但是也很复杂。希望新的C++ 0x标准能支持。<br /><br /><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: #0000ff">synchronized</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> initConfig() {<br />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">loaded) {<br />      load();<br />      loaded </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br />    }<br />  }</span></div><br /><strong>3.匿名类</strong><br />匿名类可以有效的减少类的数目，是一种很有用的语言特性<br /><br /><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: #0000ff">new</span><span style="COLOR: #000000"> Thread(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Runnable() {<br />              </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> run() {<br />                downloader.download();<br />              }<br />            }).start();</span></div>上面是启动一个新的thread来执行下载任务<br /><br /><strong>4.final关键字</strong><br />final使得更有效的表达设计者不希望被继承的意图。Java里面的final不等于C++的const。final用于class前面表示class不希望被继承，用于成员函数之前表示不希望被覆盖。这对于类库的设计是很重要的。毕竟不是每个类都为被继承做好了准备。<br /><br /><strong>5.构造函数可以互相调用<br /></strong>这个特性使得写构造函数更加方便<br /><br /><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: #0000ff">class</span><span style="COLOR: #000000"> Test<br />{<br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Test()<br />    {<br />          </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />    }<br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Test(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i)<br />    {<br />          </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> i;<br />    }<br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i;<br />}</span></div><br /><strong>6.package的概念<br /></strong>package不但有比C++ namespace更加强大避免冲突的功能，而且提供了一种更清晰的源代码结构。<br />比如java中<br />package com.cppblog.io.*; <br />C++要实现这样的，必须 <br />namespace com <br />{ <br />   namespace cppblog <br />   { <br />       namespace io <br />       { <br />       } <br />   } <br />} <br /><br /><strong>7.finally关键字<br /></strong>finally使得exception设计更加完备.很遗憾,C++里面只有try catch,虽然可以通过一些方法来work around，但是毕竟不是很方便。<br /><br /><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: #0000ff">try</span><span style="COLOR: #000000">{<br />    openConnection();<br />}<br /></span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">(ConnectionException e){<br />    e.printStackTrace();<br />}<br /></span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000">{<br />    closeConnection();<br />}<br /></span></div><br /><br /><br /></div>
		</div>
		<h3>Feedback</h3>
		<div class="post">
				<div class="posthead">
						<h2>
								<a title="permalink: re: Java中最值得C++借鉴的特性s" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#3031">#</a> <a name="3031"></a>re: Java中最值得C++借鉴的特性s  <a onclick="return SetReplyAuhor(&quot;Becky&quot;)" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#post">回复</a><a id="Comments1_CommentList_ctl00_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl00$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl00_EditLink"></a></h2>2006-01-26 11:31 by <a id="Comments1_CommentList_ctl00_NameLink" target="_blank">Becky</a></div>
				<div class="postbody">终于写了一点偶能看得懂的文章了。</div>
		</div>
		<div class="post">
				<div class="posthead">
						<h2>
								<a title="permalink: re: Java中最值得C++借鉴的特性s" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#3035">#</a> <a name="3035"></a>re: Java中最值得C++借鉴的特性s  <a onclick="return SetReplyAuhor(&quot;cyt&quot;)" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#post">回复</a><a id="Comments1_CommentList_ctl01_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl01$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl01_EditLink"></a></h2>2006-01-27 11:17 by <a id="Comments1_CommentList_ctl01_NameLink" href="http://www.cppblog.com/cyt/" target="_blank">cyt</a></div>
				<div class="postbody">想法是好，但太不了解C++了。</div>
		</div>
		<div class="post">
				<div class="posthead">
						<h2>
								<a title="permalink: re: Java中最值得C++借鉴的特性s" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#3038">#</a> <a name="3038"></a>re: Java中最值得C++借鉴的特性s  <a onclick="return SetReplyAuhor(&quot;思春贴调查员(Khan)&quot;)" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#post">回复</a><a id="Comments1_CommentList_ctl02_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl02$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl02_EditLink"></a></h2>2006-01-27 13:33 by <a id="Comments1_CommentList_ctl02_NameLink" href="http://www.cppblog.com/khan" target="_blank">思春贴调查员(Khan)</a></div>
				<div class="postbody">c++中也有匿名对象吧，只是由于匿名对象通常产生在栈中，很难保证被安全释放 <br />早些年也用java做过东西</div>
		</div>
		<div class="post">
				<div class="posthead">
						<h2>
								<a title="permalink: re: Java中最值得C++借鉴的特性s" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#3041">#</a> <a name="3041"></a>re: Java中最值得C++借鉴的特性s  <a onclick="return SetReplyAuhor(&quot;huangyi&quot;)" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#post">回复</a><a id="Comments1_CommentList_ctl03_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl03$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl03_EditLink"></a></h2>2006-01-27 14:09 by <a id="Comments1_CommentList_ctl03_NameLink" href="http://www.cppblog.com/suppercabbage/" target="_blank">huangyi</a></div>
				<div class="postbody">强大的反射机制 应该不会有 需要运行时的标准 制定标准估计太复杂 毕竟c++不是java 不过rtti肯定会有所加强 <br /><br />内建对多线程的支持和synchronized关键字 同意 <br /><br />匿名类 匿名函数这些东西 也同意 虽然不认为很有必要 应用性强的代码可以用python等脚本配合 <br /><br />final关键字 同意 <br /><br />构造函数可以互相调用 貌似有了吧 <br /><br />package的概念 我觉得是对源代码结构的限制 不喜欢 <br /><br />finally关键字 同意</div>
		</div>
		<div class="post">
				<div class="posthead">
						<h2>
								<a title="permalink: re: Java中最值得C++借鉴的特性s" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#3145">#</a> <a name="3145"></a>re: Java中最值得C++借鉴的特性s  <a onclick="return SetReplyAuhor(&quot;mis98zb&quot;)" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#post">回复</a><a id="Comments1_CommentList_ctl04_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl04$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl04_EditLink"></a></h2>2006-02-09 12:08 by <a id="Comments1_CommentList_ctl04_NameLink" target="_blank">mis98zb</a></div>
				<div class="postbody">不能 <br />namespace A::B::C::D{ <br />. <br />. <br />. <br />} <br />让人觉得很不爽！！！！！！！！</div>
		</div>
		<div class="post">
				<div class="posthead">
						<h2>
								<a title="permalink: re: Java中最值得C++借鉴的特性s" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#3193">#</a> <a name="3193"></a>re: Java中最值得C++借鉴的特性s  <a onclick="return SetReplyAuhor(&quot;3&amp;#215;7=51&quot;)" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#post">回复</a><a id="Comments1_CommentList_ctl05_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl05$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl05_EditLink"></a></h2>2006-02-11 16:36 by <a id="Comments1_CommentList_ctl05_NameLink" href="http://www.cppblog.com/3751/" target="_blank">3×7=51</a></div>
				<div class="postbody">
						<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: #0000ff">union</span> Test <br />{ <br />  <span style="COLOR: #0000ff">struct</span><br />  { <br />    short low; <br />    short high; <br />  }; <br />  int content; <br />};</div>
						<br />里面的struct即为匿名类，不过和java的匿名类不是一个东西。怎么说了各有所长。其实.net里面可以指定结构成员layout的的特性也蛮不错的，我特喜欢，不过最近很久没玩.net了。</div>
		</div>
		<div class="post">
				<div class="posthead">
						<h2>
								<a title="permalink: re: Java中最值得C++借鉴的特性s" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#3313">#</a> <a name="3313"></a>re: Java中最值得C++借鉴的特性s  <a onclick="return SetReplyAuhor(&quot;晓晓&quot;)" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#post">回复</a><a id="Comments1_CommentList_ctl06_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl06$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl06_EditLink"></a></h2>2006-02-17 16:31 by <a id="Comments1_CommentList_ctl06_NameLink" target="_blank">晓晓</a></div>
				<div class="postbody">有朋友能告诉我在MFC中用socket的具体方法吗?</div>
		</div>
		<div class="post">
				<div class="posthead">
						<h2>
								<a title="permalink: re: Java中最值得C++借鉴的特性s" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#3724">#</a> <a name="3724"></a>re: Java中最值得C++借鉴的特性s<a name="Post"></a>  <a onclick="return SetReplyAuhor(&quot;hsen&quot;)" href="http://www.cppblog.com/sandy/archive/2006/01/25/3018.html#post">回复</a><a id="Comments1_CommentList_ctl07_DeleteLink" href="javascript:__doPostBack('Comments1$CommentList$ctl07$DeleteLink','')"></a>  <a id="Comments1_CommentList_ctl07_EditLink"></a></h2>2006-03-04 20:25 by <a id="Comments1_CommentList_ctl07_NameLink" target="_blank">hsen</a></div>
				<div class="postbody">C++中不能被继承可以这样写， <br /><br />class T{ <br />private: <br />T(){} <br />public: <br />virtual ~(){} <br />T* Create(){return new T;} <br />} <br /></div>
		</div>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/7837.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-20 22:36 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/20/7837.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据结构的一点参考文字（摘录的）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7822.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 20 Mar 2006 09:08:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7822.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7822.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7822.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7822.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7822.html</trackback:ping><description><![CDATA[
		<div class="postTitle">Web开发者向桌面应用开发转型之数据结构学习 </div>
		<br />任何应用程序其实就是对于数据的操作，完成商业逻辑。操作的方法无异于添加、修改、更新、删除、查找、访问等。而操作的过程中需要对数据进行存储，抑或为了加快速度，可能对数据进行二次存储（缓存）。对数据进行存储就设计到数据结构的概念，可以说就是设计一个存储数据的容器，容纳数据且支持对数据的操作。针对不同的需求，数据结构的设计也不同，比如装石头，我们可以用篮子，而装水就不可以。任何一本数据结构的书大概讲的差不多，无论是何种语言，只要支持数据结构的设计都可以实现书本中讲到的结构：数组、列表、栈、队列、树、图、哈西表等。每一种结构都是对显示世界中模型的一种抽象，比如数组可以表示向量、或者集合模型，列表和数组类似，只不过各有优缺点，它删除、插入速度快，而不支持随即访问，树一般是搜索用。开始听海天一线说不明白数据结构怎么用，我觉得很奇怪，细细思考才发现问题。在Web开发中，数据一般都在数据库中，所以对数据的操作都是在数据库里面实现了，而应用开发中很少需要自己关心，所以转向桌面应用开发（具体到C++）就不明白数据结构了，其实就相当于数据库里面的操作。<br /><br />当然，数据结构各种语言基本都实现了并各自有扩展，我们学习数据结构，学习的抽象问题的思想，而不是会使用数据结构，或者会设计一个具体的容器。STL(SGI公司开发)里面有vector、list、deque、set、map等，且据说这个可以移植，MFC有CArray、CMap、CList等，在Java里面也有Array、HashTable至少（因为我了解很少），Boost里面也有全部实现。所以真正开发中，我们可以根据语言和实际选择已有的实现，除非已有的容器无法满足需求，我们可以对已有容器封装来设计或者完全自己实现。一般新建一个基于控制台的项目设计数据结构，并加入数据检验正确性，当正确后在加入到项目中使用。<br /><br />建议看一下别人设计的数据结构源码，最好是公认的或者流行的，有模板知识的可以看下STL的实现，对于模板有很强的认识且C++语法掌握很好的建议看看Boost，说句实话，我自己不行，只看了2个结构，一个Any，一个Array，别的没有继续看下去，太难！！<br /><br />具体到学习数据结构里面的小问题，建议看书，本文只是本人对数据结构的一个浅薄认识，如果学习中遇到问题，可以提出来，尽本人最大努力提供帮助。<br /><img src ="http://www.cnitblog.com/weitom1982/aggbug/7822.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-20 17:08 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/20/7822.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++字符串完全指引之二 —— 字符串封装类（转）</title><link>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7817.html</link><dc:creator>高山流水</dc:creator><author>高山流水</author><pubDate>Mon, 20 Mar 2006 08:38:00 GMT</pubDate><guid>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7817.html</guid><wfw:comment>http://www.cnitblog.com/weitom1982/comments/7817.html</wfw:comment><comments>http://www.cnitblog.com/weitom1982/archive/2006/03/20/7817.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/weitom1982/comments/commentRss/7817.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/weitom1982/services/trackbacks/7817.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="80%" border="0">
				<tbody>
						<tr>
								<td>
										<p align="center">
												<b>
														<br />
												</b>原著：Michael Dunn<br /><br />作者：<a href="mailto:cjsun@insun.hit.edu.cn"><font color="#6fbc4c">Chengjie Sun</font></a></p>
										<p>
												<br />原文出处：<a href="http://www.codeproject.com/string/cppstringguide2.asp" target="_blank"><font color="#6fbc4c">CodeProject：The Complete Guide to C++ Strings, Part II</font></a><br /><br /><br /><br /><font color="#6fbc4c"><img src="http://www.vckbase.com/document/image/paragraph.gif" /></font><b>引言</b><br /><br />　　因为C语言风格的字符串容易出错且不易管理，黑客们甚至利用可能存在的缓冲区溢出bug把C语言风格的字符串作为攻击目标，所以出现了很多字符串封装类。不幸的是，在某些场合下我们不知道该使用哪个字符串类，也不知道怎样把一个C风格的字符串转换成一个字符串封装类。<br />　　这篇文章将介绍所有在Win32 API, MFC, STL, WTL 和 Visual C++ 运行库中出现的字符串类型。我将描述每一个类的用法，告诉大家怎样创建每一个类的对象以及怎样把一个类转换成其他类。受控字符串和Visual C++ 7中的类两部分是Nish完成的。<br />　　为了更好的从这篇文章中受益，你必须要明白不同的字符类型和编码，这些内容我在<a href="http://www.vckbase.com/document/viewdoc/?id=1082" target="_blank"><font color="#4a664d">第一部分</font></a>中介绍过。</p>
										<pre>Rule #1 of string classes</pre>
										<p>　　使用cast来实现类型转换是不好的做法，除非有文档明确指出这种转换可以使用。<br />促使我写这两篇文章的原因是字符串类型转换中经常遇到的一些问题。当我们使用cast把字符串从类型X转换到类型Z的时候，我们不知道为什么代码不能正常工作。各种各样的字符串类型，尤其是BSTR，几乎没有在任何一个地方的文档中被明确的指出可以用cast来实现类型转换。所以我想一些人可能会使用cast来实现类型转换并希望这种转换能够正常工作。<br />　　除非源字符串是一个被明确指明支持转换操作符的字符串包装类，否则cast不对字符串做任何转换。对常量字符串使用cast不会起到任何作用，所以下面的代码： </p>
										<pre>void SomeFunc ( LPCWSTR widestr );
main()
{
  SomeFunc ( (LPCWSTR) "C:\\foo.txt" );  // WRONG!
}      </pre>　　肯定会失败。它可以被编译，因为cast操作会撤消编译器的类型检查。但是，编译可以通过并不能说明代码是正确的。<br />　　在下面的例子中，我将会指明cast在什么时候使用是合法的。<pre>C-style strings and typedefs</pre><p>　　正如我在第一部分中提到的，windows APIs 是用TCHARs来定义的，在编译时，它可以根据你是否定义_MBCS或者_UNICODE被编译成MBCS或者Unicode字符。你可以参看第一部分中对TCHAR的完整描述，这里为了方便，我列出了字符的typedefs</p><table id="AutoNumber1" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="4" cellpadding="4" width="80%" bgcolor="#ffffff" border="1"><tbody><tr><td align="middle" width="19%"><b>Type</b></td><td align="middle" width="81%"><b>Meaning</b></td></tr><tr><td align="middle" width="19%">WCHAR</td><td align="middle" width="81%">Unicode character (wchar_t)</td></tr><tr><td align="middle" width="19%">TCHAR</td><td align="middle" width="81%">MBCS or Unicode character, depending on preprocessor settings</td></tr><tr><td align="middle" width="19%">LPSTR</td><td align="middle" width="81%"> string of char (char*)</td></tr><tr><td align="middle" width="19%">LPCSTR</td><td align="middle" width="81%">constant string of char (const char*)</td></tr><tr><td align="middle" width="19%">LPWSTR</td><td align="middle" width="81%"> string of WCHAR (WCHAR*)</td></tr><tr><td align="middle" width="19%">LPCWSTR</td><td align="middle" width="81%"> constant string of WCHAR (const WCHAR*)</td></tr><tr><td align="middle" width="19%">LPTSTR</td><td align="middle" width="81%"> string of TCHAR (TCHAR*)</td></tr><tr><td align="middle" width="19%">LPCTSTR</td><td align="middle" width="81%"> constant string of TCHAR (const TCHAR*)</td></tr></tbody></table><p>　　一个增加的字符类型是OLETYPE。它表示自动化接口（如word提供的可以使你操作文档的接口）中使用的字符类型。这种类型一般被定义成wchar_t，然而如果你定义了OLE2ANSI预处理标记，OLECHAR将会被定义成char类型。我知道现在已经没有理由定义OLE2ANSI（从MFC3以后，微软已经不使用它了），所以从现在起我将把OLECHAR当作Unicode字符。<br />这里给出你将会看到的一些OLECHAR相关的typedefs：</p><table id="AutoNumber2" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="3" cellpadding="3" width="71%" bgcolor="#ffffff" border="1"><tbody><tr><td align="middle" width="18%"><b>Type</b></td><td align="middle" width="82%"><b>Meaning</b></td></tr><tr><td align="middle" width="18%">OLECHAR </td><td align="middle" width="82%">Unicode character (wchar_t)</td></tr><tr><td align="middle" width="18%">LPOLESTR</td><td align="middle" width="82%"> string of OLECHAR (OLECHAR*)</td></tr><tr><td align="middle" width="18%">LPCOLESTR </td><td align="middle" width="82%">constant string of OLECHAR (const OLECHAR*)</td></tr></tbody></table><p>　　还有两个用于包围字符串和字符常量的宏定义，它们可以使同样的代码被用于MBCS和Unicode builds ：</p><table id="AutoNumber3" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="3" cellpadding="3" width="80%" bgcolor="#ffffff" border="1"><tbody><tr><td align="middle" width="14%"><b>Type </b></td><td align="middle" width="86%"><b>Meaning</b></td></tr><tr><td align="middle" width="14%">_T(x)</td><td align="middle" width="86%">Prepends L to the literal in Unicode builds.</td></tr><tr><td align="middle" width="14%">OLESTR(x)</td><td align="middle" width="86%">Prepends L to the literal to make it an LPCOLESTR. </td></tr></tbody></table><p>　　在文档或例程中，你还会看到好多_T的变体。有四个等价的宏定义，它们是TEXT, _TEXT, __TEXT和__T，它们都起同样的做用。<br /><br /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>COM 中的字符串 —— BSTR 和 VARIANT</b><br /><br />　　很多自动化和COM接口使用BSTR来定义字符串。BSTRs中有几个"陷阱"，所以这里我用单独的部分来说明它。<br />　　BSTR 是 Pascal-style 字符串（字符串长度被明确指出）和C-style字符串（字符串的长度要通过寻找结束符来计算）的混合产物。一个BSTR是一个Unicode字符串，它的长度是预先考虑的，并且它还有一个0字符作为结束标记。下面是一个BSTR的示例：<br /><br />　</p><table id="AutoNumber4" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="3" cellpadding="3" width="73%" bgcolor="#ffffff" border="1"><tbody><tr><td align="middle" width="20%">06 00 00 00</td><td align="middle" width="20%">42 00</td><td align="middle" width="20%">6F 00</td><td align="middle" width="20%">62 00</td><td align="middle" width="20%">00 00</td></tr><tr><td align="middle" width="20%">--length--</td><td align="middle" width="20%">B</td><td align="middle" width="20%">o</td><td align="middle" width="20%">b</td><td align="middle" width="20%">EOS</td></tr></tbody></table><p>　　注意字符串的长度是如何被加到字符串数据中的。长度是DWORD类型的，保存了字符串中包含的字节数，但不包括结束标记。在这个例子中，"Bob"包含3个Unicode字符（不包括结束符），总共6个字节。字符串的长度被预先存储好，以便当一个BSTR在进程或者计算机之间被传递时，COM库知道多少数据需要传送。（另一方面，一个BSTR能够存储任意数据块，而不仅仅是字符，它还可以包含嵌入在数据中的0字符。然而，由于这篇文章的目的，我将不考虑那些情况）。<br />　　在 C++ 中，一个 BSTR 实际上就是一个指向字符串中第一个字符的指针。它的定义如下： </p><pre>BSTR bstr = NULL;
  bstr = SysAllocString ( L"Hi Bob!" ); 
  if ( NULL == bstr )
    // out of memory error 
  // Use bstr here...
 SysFreeString ( bstr );      </pre>自然的，各种各样的BSTR封装类为你实现内存管理。<br />　　另外一个用在自动化接口中的变量类型是VARIANT。它被用来在无类型（typeless）语言，如Jscript和VBScript，来传递数据。一个VARIANT可能含有很多不同类型的数据，例如long和IDispatch*。当一个VARIANT包含一个字符串，字符串被存成一个BSTR。当我后面讲到VARIANT封装类时，我会对VARIANT多些介绍。<br /><br /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>字符串封装类</b><br /><br />　　到目前为止，我已经介绍了各种各样的字符串。下面，我将说明封装类。对于每个封装类，我将展示怎样创建一个对象及怎样把它转换成一个C语言风格的字符串指针。C语言风格的字符串指针对于API的调用，或者创建一个不同的字符串类对象经常是必需的。我不会介绍字符串类提供的其他操作，比如排序和比较。<br />　　重复一遍，除非你确切的明白结果代码将会做什么，否则不要盲目地使用cast来实现类型转换。<br /><br /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>CRT提供的类</b><br /><br /><b><i>_bstr_t</i></b><br />　　_bstr_t是一个对BSTR的完整封装类，实际上它隐藏了底层的BSTR。它提供各种构造函数和操作符来访问底层的C语言风格的字符串。然而，_bstr_t却没有访问BSTR本身的操作符，所以一个_bstr_t类型的字符串不能被作为输出参数传给一个COM方法。如果你需要一个BSTR*参数，使用ATL类CComBSTR是比较容易的方式。<br />　　一个_bstr_t字符串能够传给一个接收参数类型为BSTR的函数，只是因为下列3个条件同时满足。首先，_bstr_t有一个向wchar_t*转换的转换函数；其次，对编译器而言，因为BSTR的定义，wchar_t*和BSTR有同样的含义；第三，_bstr_t内部含有的wchar_t*指向一片按BSTR的形式存储数据的内存。所以，即使没有文档说明，_bstr_t可以转换成BSTR，这种转换仍然可以正常进行。 <pre>// Constructing
_bstr_t bs1 = "char string";       // construct from a LPCSTR
_bstr_t bs2 = L"wide char string"; // construct from a LPCWSTR
_bstr_t bs3 = bs1;                 // copy from another _bstr_t
_variant_t v = "Bob";
_bstr_t bs4 = v;                   // construct from a _variant_t that has a string
 
// Extracting data
LPCSTR psz1 = bs1;              // automatically converts to MBCS string
LPCSTR psz2 = (LPCSTR) bs1;     // cast OK, same as previous line
LPCWSTR pwsz1 = bs1;            // returns the internal Unicode string
LPCWSTR pwsz2 = (LPCWSTR) bs1;  // cast OK, same as previous line
BSTR    bstr = bs1.copy();      // copies bs1, returns it as a BSTR
 
  // ...
SysFreeString ( bstr );      </pre>　　注意_bstr_t也提供char*和wchar_t*之间的转换操作符。这是一个值得怀疑的设计，因为即使它们是非常量字符串指针，你也一定不能使用这些指针去修改它们指向的缓冲区的内容，因为那将破坏内部的BSTR结构。<br /><br /><b><i>_variant_t</i></b><br />　　_variant_t是一个对VARIANT的完整封装，它提供很多构造函数和转换函数来操作一个VARIANT可能包含的大量的数据类型。这里，我将只介绍与字符串有关的操作。 <pre>// Constructing
_variant_t v1 = "char string";       // construct from a LPCSTR
_variant_t v2 = L"wide char string"; // construct from a LPCWSTR
_bstr_t bs1 = "Bob";
_variant_t v3 = bs1;                 // copy from a _bstr_t object
 
// Extracting data
_bstr_t bs2 = v1;           // extract BSTR from the VARIANT
_bstr_t bs3 = (_bstr_t) v1; // cast OK, same as previous line      </pre><b>注意</b>：<br />　　如果类型转换不能被执行，_variant_t方法能够抛出异常，所以应该准备捕获_com_error异常。<br /><br /><b>还需要注意的是</b>：<br />　　没有从一个_variant_t变量到一个MBCS字符串的直接转换。你需要创建一个临时的_bstr_t变量，使用提供Unicode到MBCS转换的另一个字符串类或者使用一个ATL转换宏。<br />　　不像_bstr_t，一个_variant_t变量可以被直接作为参数传递给一个COM方法。_variant_t<br />　　继承自VARIANT类型，所以传递一个_variant_t来代替VARIANT变量是C++语言所允许的。<br /><br /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>STL 类</b><br />　　STL只有一个字符串类，basic_string。一个basic_string管理一个以0做结束符的字符串数组。字符的类型是basic_string模般的参数。总的来说，一个basic_string类型的变量应该被当作不透明的对象。你可以得到一个指向内部缓冲区的只读指针，但是任何写操作必须使用basic_string的操作符和方法。<br />　　basic_string有两个预定义的类型：包含char的string类型和包含wchar_t的wstring类型。这里没有内置的包含TCHAR的类型，但是你可以使用下面列出的代码来实现。 <pre>// Specializations
typedef basic_string<tchar /> tstring; // string of TCHARs
 
// Constructing
string str = "char string";         // construct from a LPCSTR
wstring wstr = L"wide char string"; // construct from a LPCWSTR
tstring tstr = _T("TCHAR string");  // construct from a LPCTSTR
 
// Extracting data
LPCSTR psz = str.c_str();    // read-only pointer to str''s buffer
LPCWSTR pwsz = wstr.c_str(); // read-only pointer to wstr''s buffer
LPCTSTR ptsz = tstr.c_str(); // read-only pointer to tstr''s buffer
</pre>　　不像_bstr_t，一个basic_string变量不能在字符集之间直接转换。然而，你可以传递由c_str()返回的指针给另外一个类的构造函数（如果这个类的构造函数接受这种字符类型）。例如： <pre>// Example, construct _bstr_t from basic_string
_bstr_t bs1 = str.c_str();  // construct a _bstr_t from a LPCSTR
_bstr_t bs2 = wstr.c_str(); // construct a _bstr_t from a LPCWSTR      </pre><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>ATL 类</b><br /><br /><b><i>CComBSTR</i></b><br />　　CComBSTR 是 ATL 中的 BSTR 封装类，它在某些情况下比_bstr_t有用的多。最引人注意的是CComBSTR允许访问底层的BSTR，这意味着你可以传递一个CComBSTR对象给COM的方法。CComBSTR对象能够替你自动的管理BSTR的内存。例如，假设你想调用下面这个接口的方法： <pre>// Sample interface:
struct IStuff : public IUnknown
{
  // Boilerplate COM stuff omitted...
  STDMETHOD(SetText)(BSTR bsText);
  STDMETHOD(GetText)(BSTR* pbsText);
};      </pre>　　CComBSTR有一个操作符--BSTR方法，所以它能直接被传给SetText()函数。还有另外一个操作--&amp;，这个操作符返回一个BSTR*。所以，你可以对一个CComBSTR对象使用&amp;操作符，然后把它传给需要BSTR*参数的函数。 <pre>CComBSTR bs1;
CComBSTR bs2 = "new text";
 
  pStuff-&gt;GetText ( &amp;bs1 );       // ok, takes address of internal BSTR
  pStuff-&gt;SetText ( bs2 );        // ok, calls BSTR converter
  pStuff-&gt;SetText ( (BSTR) bs2 ); // cast ok, same as previous line      </pre>　　CComBSTR有和_bstr_t相似的构造函数，然而却没有内置的向MBCS字符串转换的函数。因此，你需要使用一个ATL转换宏。 <pre>// Constructing
CComBSTR bs1 = "char string";       // construct from a LPCSTR
CComBSTR bs2 = L"wide char string"; // construct from a LPCWSTR
CComBSTR bs3 = bs1;                 // copy from another CComBSTR
CComBSTR bs4;

  bs4.LoadString ( IDS_SOME_STR );  // load string from string table
// Extracting data
BSTR bstr1 = bs1;        // returns internal BSTR, but don''t modify it!
BSTR bstr2 = (BSTR) bs1; // cast ok, same as previous line
BSTR bstr3 = bs1.Copy(); // copies bs1, returns it as a BSTR
BSTR bstr4;
  bstr4 = bs1.Detach();  // bs1 no longer manages its BSTR
  // ...
  SysFreeString ( bstr3 );
  SysFreeString ( bstr4 );      </pre>　　注意在上个例子中使用了Detach()方法。调用这个方法后，CComBSTR对象不再管理它的BSTR字符串或者说它对应的内存。这就是bstr4需要调用SysFreeString()的原因。<br />　　做一个补充说明：重载的&amp;操作符意味着在一些STL容器中你不能直接使用CComBSTR变量，比如list。容器要求&amp;操作符返回一个指向容器包含的类的指针，但是对CComBSTR变量使用&amp;操作符返回的是BSTR*，而不是CComBSTR*。然而，有一个ATL类可以解决这个问题，这个类是CAdapt。例如，你可以这样声明一个CComBSTR的list：<pre>std::list&lt; CAdapt<ccombstr /> &gt; bstr_list;</pre><p>　　CAdapt提供容器所需要的操作符，但这些操作符对你的代码是透明的。你可以把一个bstr_list当作一个CComBSTR的list来使用。<br /><br /><b><i>CComVariant</i></b><br />　　CComVariant是VARIANT的封装类。然而，不像_variant_t，在CComVariant中VARIANT没有被隐藏。事实上你需要直接访问VARIANT的成员。CComVariant提供了很多构造函数来对VARIANT能够包含的多种类型进行处理。这里，我将只介绍和字符串相关的操作。 </p><pre>// Constructing
CComVariant v1 = "char string";       // construct from a LPCSTR
CComVariant v2 = L"wide char string"; // construct from a LPCWSTR
CComBSTR bs1 = "BSTR bob";
CComVariant v3 = (BSTR) bs1;          // copy from a BSTR
 
// Extracting data
CComBSTR bs2 = v1.bstrVal;            // extract BSTR from the VARIANT      </pre>　　不像_variant_t，这里没有提供针对VARIANT包含的各种类型的转换操作符。正如上面介绍的，你必须直接访问VARIANT的成员并且确保这个VARIANT变量保存着你期望的类型。如果你需要把一个CComVariant类型的数据转换成一个BSTR类型的数据，你可以调用ChangeType()方法。 <pre>CComVariant v4 = ... // Init v4 from somewhere
CComBSTR bs3;
 
  if ( SUCCEEDED( v4.ChangeType ( VT_BSTR ) ))
    bs3 = v4.bstrVal;      </pre>　　像_variant_t一样，CComVariant也没有提供向MBCS字符串转换的转换操作。你需要创建一个_bstr_t类型的中间变量，使用提供从Unicode到MBCS转换的另一个字符串类，或者使用一个ATL的转换宏。<br /><br /><tchar /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>ATL转换宏</b><br /><br />　　ATL：转换宏是各种字符编码之间进行转换的一种很方便的方式，在函数调用时，它们显得非常有用。ATL转换宏的名称是根据下面的模式来命名的[源类型]2[新类型]或者[源类型]2C[新类型]。据有第二种形式的名字的宏的转换结果是常量指针（对应名字中的"C"）。各种类型的简称如下：<pre>A: MBCS string, char* (A for ANSI)
W: Unicode string, wchar_t* (W for wide)
T: TCHAR string, TCHAR*
OLE: OLECHAR string, OLECHAR* (in practice, equivalent to W)
BSTR: BSTR (used as the destination type only)</pre><p>　　所以，W2A()宏把一个Unicode字符串转换成一个MBCS字符串。T2CW()宏把一个TCHAR字符串转转成一个Unicode字符串常量。<br />　　为了使用这些宏，需要先包含atlconv.h头文件。你甚至可以在非ATL工程中包含这个头文件来使用其中定义的宏，因为这个头文件独立于ATL中的其他部分，不需要一个_Module全局变量。当你在一个函数中使用转换宏时，需要把USES_CONVERSION宏放在函数的开头。它定义了转换宏所需的一些局部变量。<br />　　当转换的目的类型是除了BSTR以外的其他类型时，被转换的字符串是存在栈中的。所以，如果你想让字符串的生命周期比当前的函数长，你需要把这个字符串拷贝到其他的字符串类中。当目的类型是BSTR时，内存不会自动被释放，你必须把返回值赋给一个BSTR变量或者一个BSTR封装类以避免内存泄漏。<br />　　下面是一些各种转换宏的使用例子： </p><pre>// Functions taking various strings:
void Foo ( LPCWSTR wstr );
void Bar ( BSTR bstr );
// Functions returning strings:
void Baz ( BSTR* pbstr );
#include <atlconv.h />
main()
{
using std::string;
USES_CONVERSION;    // declare locals used by the ATL macros
// Example 1: Send an MBCS string to Foo()
LPCSTR psz1 = "Bob";
string str1 = "Bob";
 
  Foo ( A2CW(psz1) );
  Foo ( A2CW(str1.c_str()) );
 
// Example 2: Send a MBCS and Unicode string to Bar()
LPCSTR psz2 = "Bob";
LPCWSTR wsz = L"Bob";
BSTR bs1;
CComBSTR bs2;
 
  bs1 = A2BSTR(psz2);         // create a BSTR
  bs2.Attach ( W2BSTR(wsz) ); // ditto, assign to a CComBSTR 
  Bar ( bs1 );
  Bar ( bs2 );
 
  SysFreeString ( bs1 );      // free bs1 memory
  // No need to free bs2 since CComBSTR will do it for us.
 
// Example 3: Convert the BSTR returned by Baz()
BSTR bs3 = NULL;
string str2;
  Baz ( &amp;bs3 );          // Baz() fills in bs3
  str2 = W2CA(bs3);      // convert to an MBCS string
  SysFreeString ( bs3 ); // free bs3 memory
}      </pre>　　正如你所看见的，当你有一个和函数所需的参数类型不同的字符串时，使用这些转换宏是非常方便的。 <br /><br /><tchar /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>MFC类</b><br /><br /><b><i>CString</i></b><br />　　因为一个MFC CString类的对象包含TCHAR类型的字符，所以确切的字符类型取决于你所定义的预处理符号。大体来说，CString 很像STL string，这意味着你必须把它当成不透明的对象，只能使用CString提供的方法来修改CString对象。CString有一个string所不具备的优点：CString具有接收MBCS和Unicode两种字符串的构造函数，它还有一个LPCTSTR转换符，所以你可以把CString对象直接传给一个接收LPCTSTR的函数而不需要调用c_str()函数。 <pre>// Constructing
CString s1 = "char string";  // construct from a LPCSTR
CString s2 = L"wide char string";  // construct from a LPCWSTR
CString s3 ( '' '', 100 );  // pre-allocate a 100-byte buffer, fill with spaces
CString s4 = "New window text";
 
  // You can pass a CString in place of an LPCTSTR:
  SetWindowText ( hwndSomeWindow, s4 );
 
  // Or, equivalently, explicitly cast the CString:
  SetWindowText ( hwndSomeWindow, (LPCTSTR) s4 );        </pre>　　你可以从你的字符串表中装载一个字符串，CString的一个构造函数和LoadString()函数可以完成它。Format()方法能够从字符串表中随意的读取一个具有一定格式的字符串。　　　　　 <pre>// Constructing/loading from string table
CString s5 ( (LPCTSTR) IDS_SOME_STR );  // load from string table
CString s6, s7; 
  // Load from string table.
  s6.LoadString ( IDS_SOME_STR );
 
  // Load printf-style format string from the string table:
  s7.Format ( IDS_SOME_FORMAT, "bob", nSomeStuff, ... );  </pre>　　第一个构造函数看起来有点奇怪，但是这实际上是文档说明的装入一个字符串的方法。 注意，对一个CString变量，你可以使用的唯一合法转换符是LPCTSTR。转换成LPTSTR（非常量指针）是错误的。养成把一个CString变量转换成LPTSTR的习惯将会给你带来伤害，因为当你的程序后来崩溃时，你可能不知道为什么，因为你到处都使用同样的代码而那时它们都恰巧正常工作。正确的得到一个指向缓冲区的非常量指针的方法是调用GetBuffer()方法。下面是正确的用法的一个例子，这段代码是给一个列表控件中的项设定文字： <pre>CString str = _T("new text");
LVITEM item = {0};
  item.mask = LVIF_TEXT;
  item.iItem = 1;
  item.pszText = (LPTSTR)(LPCTSTR) str; // WRONG!
  item.pszText = str.GetBuffer(0);      // correct
 
  ListView_SetItem ( &amp;item );
str.ReleaseBuffer();  // return control of the buffer to str      </pre>　　pszText成员是一个LPTSTR变量，一个非常量指针，因此你需要对str调用GetBuffer()。GetBuffer()的参数是你需要CString为缓冲区分配的最小长度。如果因为某些原因，你需要一个可修改的缓冲区来存放1K TCHARs，你需要调用GetBuffer(1024)。把0作为参数时，GetBuffer()返回的是指向字符串当前内容的指针。<br />　　上面划线的语句可以被编译，在这种情况下，甚至可以正常起作用。但这并不意味着这行代码是正确的。通过使用非常量转换，你已经破坏了面向对象的封装，并对CString的内部实现作了某些假定。如果你有这样的转换习惯，你终将会陷入代码崩溃的境地。你会想代码为什么不能正常工作了，因为你到处都使用同样的代码而那些代码看起来是正确的。<br />　　你知道人们总是抱怨现在的软件的bug是多么的多吗？软件中的bug是因为程序员写了不正确的代码。难道你真的想写一些你知道是错误的代码来为所有的软件都满是bug这种认识做贡献吗？花些时间来学习使用CString的正确方法让你的代码在任何时间都正常工作把。<br />　　CString 有两个函数来从一个 CString 创建一个 BSTR。它们是 AllocSysString() 和SetSysString()。 <pre>// Converting to BSTR
CString s5 = "Bob!";
BSTR bs1 = NULL, bs2 = NULL;
  bs1 = s5.AllocSysString();
  s5.SetSysString ( &amp;bs2 );
  SysFreeString ( bs1 );
  SysFreeString ( bs2 );      </pre><b><i>COleVariant</i></b><br />　　COleVariant和CComVariant.很相似。COleVariant继承自VARIANT，所以它可以传给接收VARIANT的函数。然而，不像CComVariant，COleVariant只有一个LPCTSTR构造函数。没有对LPCSTR 和LPCWSTR的构造函数。在大多数情况下这不是一个问题，因为不管怎样你的字符串很可能是LPCTSTRs，但这是一个需要意识到的问题。COleVariant还有一个接收CString参数的构造函数。 <pre>// Constructing
CString s1 = _T("tchar string");
COleVariant v1 = _T("Bob"); // construct from an LPCTSTR
COleVariant v2 = s1; // copy from a CString      </pre>　　像CComVariant一样，你必须直接访问VARIANT的成员。如果需要把VARIANT转换成一个字符串，你应该使用ChangeType()方法。然而，COleVariant::ChangeType()如果失败会抛出异常，而不是返回一个表示失败的HRESULT代码。 <pre>// Extracting data
COleVariant v3 = ...; // fill in v3 from somewhere
BSTR bs = NULL;
  try
    {
    v3.ChangeType ( VT_BSTR );
    bs = v3.bstrVal;
    }
  catch ( COleException* e )
    {
    // error, couldn''t convert
    }
  SysFreeString ( bs );      </pre><br /><tchar /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>WTL 类</b><br /><br /><b><i>CString</i></b><br />　　WTL的CString的行为和MFC的 CString完全一样，所以你可以参考上面关于MFC的 CString的介绍。<br /><br /><tchar /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>CLR 和 VC 7 类</b><br /><br />　　System::String是用来处理字符串的.NET类。在内部，一个String对象包含一个不可改变的字符串序列。任何对String对象的操作实际上都是返回了一个新的String对象，因为原始的对象是不可改变的。String的一个特性是如果你有不止一个String对象包含相同的字符序列，它们实际上是指向相同的对象的。相对于C++的使用扩展是增加了一个新的字符串常量前缀S，S用来代表一个受控的字符串常量（a managed string literal）。 <pre>// Constructing
String* ms = S"This is a nice managed string";      </pre>　　你可以传递一个非受控的字符串来创建一个String对象，但是样会比使用受控字符串来创建String对象造成效率的微小损失。这是因为所有以S作为前缀的相同的字符串实例都代表同样的对象，但这对非受控对象是不适用的。下面的代码清楚地阐明了这一点： <pre>String* ms1 = S"this is nice";
String* ms2 = S"this is nice";
String* ms3 = L"this is nice";
  Console::WriteLine ( ms1 == ms2 ); // prints true
  Console::WriteLine ( ms1 == ms3);  // prints false      </pre>正确的比较可能没有使用S前缀的字符串的方法是使用String::CompareTo() <pre>  Console::WriteLine ( ms1-&gt;CompareTo(ms2) );
  Console::WriteLine ( ms1-&gt;CompareTo(ms3) );      </pre>　　上面的两行代码都会打印0，0表示两个字符串相等。 String和MFC 7 CString之间的转换是很容易的。CString有一个向LPCTSTR的转换操作，而String有两个接收char* 和 wchar_t*的构造函数，因此你可以把一个CString变量直接传给一个String的构造函数。 <pre>CString s1 ( "hello world" );
String* s2 ( s1 );  // copy from a CString      </pre>反方向的转换也很类似 <pre>String* s1 = S"Three cats";
CString s2 ( s1 );      </pre>　　这也许会使你感到一点迷惑，但是它确实是起作用的。因为从VS.NET 开始，CString 有了一个接收String 对象的构造函数。 <pre>  CStringT ( System::String* pString );      </pre>对于一些快速操作，你可能想访问底层的字符串： <pre>String* s1 = S"Three cats";
  Console::WriteLine ( s1 );
const __wchar_t __pin* pstr = PtrToStringChars(s1);
  for ( int i = 0; i &lt; wcslen(pstr); i++ )
    (*const_cast&lt;__wchar_t*&gt;(pstr+i))++;
  Console::WriteLine ( s1 );      </pre>　　PtrToStringChars()返回一个指向底层字符串的const __wchar_t* ，我们需要固定它，否则垃圾收集器或许会在我们正在管理它的内容的时候移动了它。 <br /><br /><tchar /><tchar /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>在 printf-style 格式函数中使用字符串类</b><br /><br />　　当你在printf()或者类似的函数中使用字符串封装类时你必须十分小心。这些函数包括sprintf()和它的变体，还有TRACE和ATLTRACE宏。因为这些函数没有对添加的参数的类型检查，你必须小心，只能传给它们C语言风格的字符串指针，而不是一个完整的字符串类。<br />　　例如，要把一个_bstr_t 字符串传给ATLTRACE()，你必须使用显式转换(LPCSTR) 或者(LPCWSTR)：<pre>_bstr_t bs = L"Bob!";
ATLTRACE("The string is: %s in line %d\n", (LPCSTR) bs, nLine);</pre><p>　　如果你忘了使用转换符而把整个_bstr_t对象传给了函数，将会显示一些毫无意义的输出，因为_bstr_t保存的内部数据会全部被输出。<br /><br /><tchar /><tchar /><img src="http://www.vckbase.com/document/image/paragraph.gif" /><b>所有类的总结</b><br /><br />　　两个字符串类之间进行转换的常用方式是：先把源字符串转换成一个C语言风格的字符串指针，然后把这个指针传递给目的类型的构造函数。下面这张表显示了怎样把一个字符串转换成一个C语言风格的字符串指针以及哪些类具有接收C语言风格的字符串指针的构造函数。</p><table id="AutoNumber5" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="0" cellpadding="0" width="80%" bgcolor="#ffffff" border="1"><tbody><tr><td align="middle" width="7%"><b><font size="1">Class  </font></b></td><td align="middle" width="10%"><tchar /><b><font size="1">string type </font></b></td><td align="middle" width="14%"><tchar /><b><font size="1">convert to char*? </font></b></td><td align="middle" width="12%"><tchar /><b><font size="1">convert to const char*? </font></b></td><td align="middle" width="12%"><tchar /><b><font size="1">convert to wchar_t*? </font></b></td><td align="middle" width="11%"><tchar /><b><font size="1">convert to const wchar_t*? </font></b></td><td align="middle" width="11%"><tchar /><b><font size="1">convert to BSTR? </font></b></td><td align="middle" width="11%"><tchar /><b><font size="1">construct from char*? </font></b></td><td align="middle" width="12%"><tchar /><b><font size="1">construct from wchar_t*?</font></b></td></tr><tr><td width="7%">_bstr_t</td><td width="10%">BSTR</td><td width="14%">yes cast<sup>1</sup></td><td width="12%">yes cast</td><td width="12%"><tchar /><tchar />yes cast<tchar /><tchar /><tchar /><tchar /><tchar /><sup>1</sup></td><td width="11%"><tchar /><tchar /><tchar />yes cast</td><td width="11%">yes<sup>2</sup></td><td width="11%"><tchar /><tchar />yes</td><td width="12%"><tchar /><tchar />yes</td></tr><tr><td width="7%">_variant_t</td><td width="10%">BSTR</td><td width="14%">no</td><td width="12%">no</td><td width="12%">no</td><td width="11%">cast to<br />_bstr_t<sup>3</sup></td><td width="11%"><tchar /><tchar />cast to<br />_bstr_t<sup>3</sup></td><td width="11%"><tchar /><tchar />yes</td><td width="12%"><tchar /><tchar />yes</td></tr><tr><td width="7%">string</td><td width="10%">MBCS</td><td width="14%"><tchar /><tchar />no</td><td width="12%">yes c_str() method</td><td width="12%"><tchar /><tchar />no</td><td width="11%">no</td><td width="11%">no</td><td width="11%"><tchar /><tchar />yes</td><td width="12%">no</td></tr><tr><td width="7%">wstring</td><td width="10%">Unicode</td><td width="14%"><tchar /><tchar />no</td><td width="12%"><tchar /><tchar />no</td><td width="12%"><tchar /><tchar />no</td><td width="11%"><tchar /><tchar />yes c_str() method</td><td width="11%">no</td><td width="11%">no</td><td width="12%"><tchar /><tchar />yes</td></tr><tr><td width="7%">CComBSTR</td><td width="10%">BSTR</td><td width="14%"><tchar /><tchar />no</td><td width="12%"><tchar /><tchar />no</td><td width="12%"><tchar /><tchar />no</td><td width="11%">yes cast to BSTR</td><td width="11%">yes cast</td><td width="11%"><tchar /><tchar />yes</td><td width="12%"><tchar /><tchar />yes</td></tr><tr><td width="7%">CComVariant</td><td width="10%"><tchar /><tchar />BSTR</td><td width="14%"><tchar /><tchar /><tchar />no</td><td width="12%"><tchar /><tchar /><tchar />no</td><td width="12%"><tchar /><tchar /><tchar />no</td><td width="11%">yes<sup>4</sup></td><td width="11%"><tchar /><tchar />yes<tchar /><tchar /><tchar /><tchar /><tchar /><sup>4</sup></td><td width="11%"><tchar /><tchar />yes</td><td width="12%"><tchar /><tchar />yes</td></tr><tr><td width="7%">CString </td><td width="10%">TCHAR</td><td width="14%"><tchar /><tchar /><tchar />no<sup>6</sup></td><td width="12%">in MBCS<br />builds, cast</td><td width="12%"><tchar /><tchar /><tchar />no<tchar /><tchar /><tchar /><tchar /><tchar /><tchar /><sup>6</sup></td><td width="11%">in Unicode<br />builds, cast</td><td width="11%">no<sup>5</sup></td><td width="11%"><tchar /><tchar />yes</td><td width="12%"><tchar /><tchar />yes</td></tr><tr><td width="7%">COleVariant</td><td width="10%"><tchar /><tchar />BSTR</td><td width="14%"><tchar /><tchar /><tchar />no</td><td width="12%"><tchar /><tchar /><tchar />no</td><td width="12%"><tchar /><tchar /><tchar />no</td><td width="11%"><tchar /><tchar />yes<tchar /><tchar /><tchar /><tchar /><tchar /><tchar /><tchar /><sup>4</sup></td><td width="11%"><tchar /><tchar />yes<tchar /><tchar /><tchar /><tchar /><tchar /><tchar /><tchar /><sup>4</sup></td><td width="11%"><tchar /><tchar />in MBCS<br />builds</td><td width="12%"><tchar /><tchar />in Unicode<br />builds</td></tr><tr><td width="80%" colspan="9"><dir><li>1、即使 _bstr_t 提供了向非常量指针的转换操作符，修改底层的缓冲区也会已引起GPF如果你溢出了缓冲区或者造成内存泄漏。 
</li><li>2<tchar /><tchar />、_bstr_t 在内部用一个 wchar_t* 来保存 BSTR，所以你可以使用 const wchar_t* 来访问BSTR。这是一个实现细节，你可以小心的使用它，将来这个细节也许会改变。 
</li><li>3<tchar /><tchar />、如果数据不能转换成BSTR会抛出一个异常。 
</li><li>4<tchar /><tchar />、使用 ChangeType()，然后访问 VARIANT 的 bstrVal 成员。在MFC中，如果数据转换不成功将会抛出异常。 
</li><li>5<tchar /><tchar />、这里没有转换 BSTR 函数，然而 AllocSysString() 返回一个新的BSTR。 
</li><li>6<tchar /><tchar />、使用 GetBuffer() 方法，你可以暂时地得到一个非常量的TCHAR指针。 </li></dir></td></tr></tbody></table><p><br /></p></td>
						</tr>
						<tr>
								<td>
										<tchar />
										<tchar />
										<tchar />
										<img src="http://www.vckbase.com/document/image/paragraph.gif" />
										<b>作者简介<br /><br /></b>
										<i>Michael Dunn：<br />　　</i>Michael Dunn居住在阳光城市洛杉矶。他是如此的喜欢这里的天气以致于想一生都住在这里。他在4年级时开始编程，那时用的电脑是Apple //e。1995年，在UCLA获得数学学士学位，随后在Symantec公司做QA工程师，在 Norton AntiVirus 组工作。他自学了 Windows 和 MFC 编程。1999-2000年，他设计并实现了 Norton AntiVirus的新界面。<br />　　Michael 现在在 Napster（一个提供在线订阅音乐服务的公司）做开发工作，他还开发了UltraBar，一个IE工具栏插件，它可以使网络搜索更加容易，给了 googlebar 以沉重打击；他还开发了 CodeProject SearchBar；与人共同创建了 Zabersoft 公司，该公司在洛杉矶和丹麦的 Odense 都设有办事处。<br />　　他喜欢玩游戏。爱玩的游戏有 pinball, bike riding，偶尔还玩 PS, Dreamcasth 和 MAME 游戏。他因忘了自己曾经学过的语言：法语、汉语、日语而感到悲哀。<br /><br /><i>Nishant S(Nish)</i>：<br />　　Nish是来自印度 Trivandrum,的 Microsoft Visual C++ MVP。他从1990年开始编码。现在，Nish为作为合同雇员在家里为 CodeProject 工作。　　　<br />　　他还写了一部浪漫戏剧《<tchar /><tchar />Summer Love and Some more Cricket<tchar /><tchar />》和一本编程书籍《<tchar />Extending MFC applications with the .NET Framework<tchar />》。他还管理者MVP的一个网站http://www.voidnish.com/ 。在这个网站上，你可以看到他的很多关于编程方面的思想和文章。<br />Nish 还计划好<tchar />了<tchar />旅游，他希望自一生中能够到达地球上尽可能多的地方。</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/weitom1982/aggbug/7817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/weitom1982/" target="_blank">高山流水</a> 2006-03-20 16:38 <a href="http://www.cnitblog.com/weitom1982/archive/2006/03/20/7817.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>