﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Where there is a dream ,there is hope-随笔分类-C/C++</title><link>http://www.cppblog.com/Husiwa/category/15324.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 10 Oct 2011 08:14:47 GMT</lastBuildDate><pubDate>Mon, 10 Oct 2011 08:14:47 GMT</pubDate><ttl>60</ttl><item><title>EFFECTIVE-STL-1</title><link>http://www.cppblog.com/Husiwa/archive/2011/10/10/157956.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Mon, 10 Oct 2011 05:33:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/10/10/157956.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/157956.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/10/10/157956.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/157956.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/157956.html</trackback:ping><description><![CDATA[条款一 仔细选择你的容器<br />*vector&lt;char&gt;可以作为string的替代品<br />*vector list deque ，vector是一种可以默认使用的序列类型，当很频繁的对序列中进行插入和删除的时候应该用list，大部分发生在尾部的话用deque这种数据结构<br />*连续内存容器和基于节点的容器的区别<br />连续容器vector/string/deque在一个或者多个内存块中保存它们的元素，如果新元素被插入或者已存元素被删除，其他在同一个内存块中的元素必须向上或者向下移动来为新元素提供空间或者填充原来被删除的元素所占的空间，这种移动影响了效率。<br />基于节点的list，插入或者删除的时候不需要移动<br />*序列容器在任意位置插入一个新元素，关联容器不可以<br />*容器中的数据的内存布局需要兼容C吗，如果是，那只能用vector<br />*查找速度，散列容器》排序的vector&gt;标准的关联容器<br />*需要可靠的插入和删除的能力，如果是需要使用基于节点的容器<br />*需要迭代器、指针、引用的实效次数减少到最小，如果是，使用介于节点的容器，一般来说，在连续容器上的插入和删除会使所有指向容器的迭代器指针和引用实效<img src ="http://www.cppblog.com/Husiwa/aggbug/157956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-10-10 13:33 <a href="http://www.cppblog.com/Husiwa/archive/2011/10/10/157956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DEBUG版本有错，Release版本无错的原因</title><link>http://www.cppblog.com/Husiwa/archive/2011/03/20/142286.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Sun, 20 Mar 2011 10:17:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/03/20/142286.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/142286.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/03/20/142286.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/142286.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/142286.html</trackback:ping><description><![CDATA[&nbsp;<a href="http://blog.163.com/liuyuelin007@126/blog/static/213387692007411151568/">http://blog.163.com/liuyuelin007@126/blog/static/213387692007411151568/</a><br><br><a href="http://blog.csdn.net/lychee007/archive/2009/05/31/4227419.aspx">http://blog.csdn.net/lychee007/archive/2009/05/31/4227419.aspx</a><br><br><a href="http://social.microsoft.com/Forums/es-ES/visualcpluszhchs/thread/ff6ddac2-a69d-4c02-ad20-d73cb4335c24">http://social.microsoft.com/Forums/es-ES/visualcpluszhchs/thread/ff6ddac2-a69d-4c02-ad20-d73cb4335c24</a><br><br><a href="http://hi.baidu.com/237rxd/blog/item/35a51efa18e098859e5146b9.html">http://hi.baidu.com/237rxd/blog/item/35a51efa18e098859e5146b9.html</a><br><br><a href="http://topic.csdn.net/t/20050712/20/4140158.html">http://topic.csdn.net/t/20050712/20/4140158.html</a>
<img src ="http://www.cppblog.com/Husiwa/aggbug/142286.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-03-20 18:17 <a href="http://www.cppblog.com/Husiwa/archive/2011/03/20/142286.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>memcpy memset strcpy</title><link>http://www.cppblog.com/Husiwa/archive/2011/03/15/141839.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Tue, 15 Mar 2011 00:06:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/03/15/141839.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/141839.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/03/15/141839.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/141839.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/141839.html</trackback:ping><description><![CDATA[不少笔试题都把这三个函数放一起比较，其实他们三个没啥可比性，就是三个不同的函数而已<br><br>
<p align=left><strong><span>Memset&nbsp;</span></strong><span>用来对一段内存空间全部设置为某个字符，一般用在对定义的字符串进行初始化为</span><span>&#8216; &#8217;</span><span>或</span><span>&#8216;\<st1:chmetcnv w:st="on" UnitName="&#8217;" SourceValue="0" HasSpace="False" Negative="False" NumberType="1" TCSC="0">0&#8217;</st1:chmetcnv></span><span>；<br></span></p>
<p align=left><span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">主要应用是初始化某个内存空间<br></span><span><br>例</span><span>:char a[100];memset(a, '\0', sizeof(a));</span></p>
<p align=left><span>memset</span><span>可以方便的清空一个结构类型的变量或数组。</span><span> </span></p>
<p align=left><span>如：</span></p>
<p align=left><span>struct sample_struct<br>{<br>&nbsp;char &nbsp; csName[16];<br>&nbsp;int &nbsp; &nbsp;iSeq;<br>&nbsp;int &nbsp; &nbsp;iType;<br>};</span></p>
<p align=left><span>对于变量</span><span><br>struct sample_strcut &nbsp;stTest; </span></p>
<p align=left><span>一般情况下，清空</span><span>stTest</span><span>的方法：</span></p>
<p align=left><span>stTest.csName[0]='\0';<br>stTest.iSeq=0;<br>stTest.iType=0; </span></p>
<p align=left><span>用</span><span>memset</span><span>就非常方便：</span><span><br>memset(&amp;stTest,0,sizeof(struct sample_struct));</span></p>
<p align=left><span>如果是数组：</span></p>
<p align=left><span>&nbsp;struct sample_struct &nbsp; TEST[10];<br></span><span>则</span><span><br>memset(TEST,0,sizeof(struct sample_struct)*10);<br><br></p>
<p align=left><strong><span>memcpy&nbsp;</span></strong><span>用来做内存拷贝，你可以拿它拷贝任何数据类型的对象，可以指定拷贝的数据长度。<br></span></p>
<p align=left>memcpy<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">是用于</span><span lang=EN-US style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">copy</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">源空间的数据到目的空间中</span><span><br>例：</span><span>char a[100],b[50]; memcpy(b, a, sizeof(b));</span><span>注意如用</span><span>sizeof(a)</span><span>，会造成</span><span>b</span><span>的内存地址溢出。<br><br></p>
<p align=left><strong><span>Strcpy<span>&nbsp;&nbsp; </span></span></strong><span>就只能拷贝字符串了，它遇到</span><span>'\0'</span><span>就结束拷贝。</span></p>
<p align=left><span>例：</span><span>char a[100],b[50];strcpy(a,b);</span><span>如用</span><span>strcpy(b,a)</span><span>，要注意</span><span>a</span><span>中的字符串长度（第一个</span><span>&#8216;\<st1:chmetcnv w:st="on" UnitName="&#8217;" SourceValue="0" HasSpace="False" Negative="False" NumberType="1" TCSC="0">0&#8217;</st1:chmetcnv></span><span>之前）是否超过</span><span>50</span><span>位，如超过，则会造成</span><span>b</span><span>的内存地址溢出。</span></p>
<p align=left><br>strcpy<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">用于字符串</span><span lang=EN-US style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">copy,</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">遇到</span><span lang=EN-US style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">&#8216;\<st1:chmetcnv w:st="on" UnitName="&#8217;" SourceValue="0" HasSpace="False" Negative="False" NumberType="1" TCSC="0">0&#8217;</st1:chmetcnv></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">，将结束</span></span></p>
</span>
<img src ="http://www.cppblog.com/Husiwa/aggbug/141839.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-03-15 08:06 <a href="http://www.cppblog.com/Husiwa/archive/2011/03/15/141839.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>又见单例</title><link>http://www.cppblog.com/Husiwa/archive/2011/03/09/141429.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Wed, 09 Mar 2011 08:18:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/03/09/141429.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/141429.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/03/09/141429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/141429.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/141429.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 温故而知新，总结了多种单例模式的写法，考虑上多线程没有非常完美的，各取所需吧//1.//Easy&nbsp;,&lt;&lt;Pattern&nbsp;Design&gt;&gt;//Q://When&nbsp;to&nbsp;free&nbsp;the&nbsp;m_singleton&nbsp;space?//when&nbsp;to&nbsp;execute&nbsp;the&nbsp;...&nbsp;&nbsp;<a href='http://www.cppblog.com/Husiwa/archive/2011/03/09/141429.html'>阅读全文</a><img src ="http://www.cppblog.com/Husiwa/aggbug/141429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-03-09 16:18 <a href="http://www.cppblog.com/Husiwa/archive/2011/03/09/141429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>char* 转化为wchar* </title><link>http://www.cppblog.com/Husiwa/archive/2011/02/28/140779.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Mon, 28 Feb 2011 04:05:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/02/28/140779.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/140779.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/02/28/140779.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/140779.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/140779.html</trackback:ping><description><![CDATA[总用到这个转化，记下来<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"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">wchar_t</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;atow(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;src)<br><img id=Codehighlighter1_25_239_Open_Image onclick="this.style.display='none'; Codehighlighter1_25_239_Open_Text.style.display='none'; Codehighlighter1_25_239_Closed_Image.style.display='inline'; Codehighlighter1_25_239_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_25_239_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_25_239_Closed_Text.style.display='none'; Codehighlighter1_25_239_Open_Image.style.display='inline'; Codehighlighter1_25_239_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_25_239_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_25_239_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;dest_len;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;dest_len&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;MultiByteToWideChar(CP_ACP,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,src,</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,NULL,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;wchar_t&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">dest&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;wchar_t[dest_len];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(dest&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;NULL)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;NULL;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;MultiByteToWideChar(CP_ACP,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,src,</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,dest,dest_len);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;dest;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<img src ="http://www.cppblog.com/Husiwa/aggbug/140779.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-02-28 12:05 <a href="http://www.cppblog.com/Husiwa/archive/2011/02/28/140779.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>匿名空间</title><link>http://www.cppblog.com/Husiwa/archive/2011/02/16/140143.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Wed, 16 Feb 2011 02:12:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/02/16/140143.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/140143.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/02/16/140143.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/140143.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/140143.html</trackback:ping><description><![CDATA[<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="line-height: 21px; font-family: 'Comic Sans MS'; ">当定义一个命名空间时，可以忽略这个命名空间的名称：</span></p><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp; namespce {</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char c;</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double d;</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp; }</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp; 编译器在内部会为这个命名空间生成一个唯一的名字，而且还会为这个匿名的命名空间生成一条using指令。所以上面的代码在效果上等同于：</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp; namespace __UNIQUE_NAME_ {</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char c;</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double d;</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp; using namespace __UNIQUE_NAME_;</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">&nbsp;</div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">&nbsp;&nbsp;&nbsp;&nbsp; 在匿名命名空间中声明的名称也将被编译器转换，与编译器为这个匿名命名空间生成的唯一内部名称(即这里的__UNIQUE_NAME_)绑定在一起。还有一点很重要，就是这些名称具有internal链接属性，这和声明为static的全局名称的链接属性是相同的，即名称的作用域被限制在当前文件中，无法通过在另外的文件中使用extern声明来进行链接。如果不提倡使用全局static声明一个名称拥有internal链接属性，则匿名命名空间可以作为一种更好的达到相同效果的方法。</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">注意:命名空间都是具有external 连接属性的,只是匿名的命名空间产生的__UNIQUE_NAME__在别的文件中无法得到,这个唯一的名字是不可见的.</span></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "></div><div style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="font-size: small; font-family: 'Comic Sans MS'; ">C++ 新的标准中提倡使用匿名命名空间,而不推荐使用static,因为static用在不同的地方,涵义不同,容易造成混淆.另外,static不能修饰class</span></div>
<img src ="http://www.cppblog.com/Husiwa/aggbug/140143.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-02-16 10:12 <a href="http://www.cppblog.com/Husiwa/archive/2011/02/16/140143.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为什么拷贝构造函数必须为引用传递，不能是值传递？</title><link>http://www.cppblog.com/Husiwa/archive/2011/02/14/140053.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Mon, 14 Feb 2011 09:50:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/02/14/140053.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/140053.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/02/14/140053.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/140053.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/140053.html</trackback:ping><description><![CDATA[<div class="postTitle"><br></div>对于拷贝构造函数引用传递，似乎司空见惯，认为理所当然。但是被问起这个问题，的确是一片茫然，为什么呢？<br><br>去网上搜索了一下，的确有很多这方面的知识讲解。<br><br>我们先看一下CSDN上的一个帖子的回答：<br>简单的回答是为了防止递归引用。<br>具体一些可以这么讲：<br>&nbsp;当一个对象需要以值方式传递时，编译器会生成代码调用它的拷贝构造函数以生成一个复本。如果类A的拷贝构造函数是以值方式传递一个类A对象作为参数的话，当需要调用类A的拷贝构造函数时，需要以值方式传进一个A的对象作为实参；&nbsp;而以值方式传递需要调用类A的拷贝构造函数；结果就是调用类A的拷贝构造函数导致又一次调用类A的拷贝构造函数，这就是一个无限递归。<br><br>这个解释还是蛮具体的。<br>利用值传递的话，会导致递归引用。<br><br>还有一片文章也谈到了这个问题， 
我觉得写得也非常好！<br><br><a class="postTitle2" id="AjaxHolder_ctl01_TitleUrl" href="http://www.cnblogs.com/chio/archive/2007/09/14/893299.html"><font color="#6466b3">为什么拷贝构造函数必须为引用传递，不能是值传递？</font></a> <br>链接地址：<a href="http://www.cnblogs.com/chio/archive/2007/09/14/893299.html">http://www.cnblogs.com/chio/archive/2007/09/14/893299.html</a><br><br>其中讲到了3个问题<br><strong>1是拷贝构造函数的作用。<br></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
作用就是用来复制对象的，在使用这个对象的实例来初始化这个对象的一个新的实例。<br><strong>2是参数传递过程到底发生了什么？<br></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
将地址传递和值传递统一起来，归根结底还是传递的是"值"(地址也是值，只不过通过它可以找到另一个值)！<br>i)值传递:<br>&nbsp;&nbsp;&nbsp;&nbsp;对于内置数据类型的传递时，直接赋值拷贝给形参(注意形参是函数内局部变量)；<br>&nbsp;&nbsp;&nbsp; 
对于类类型的传递时，需要首先调用该类的拷贝构造函数来初始化形参(局部对象)；如void foo(class_type obj_local){}, 
如果调用foo(obj);&nbsp; 首先class_type 
obj_local(obj)&nbsp;,这样就定义了局部变量obj_local供函数内部使用<br>ii)引用传递:<br>&nbsp;&nbsp;&nbsp;&nbsp;无论对内置类型还是类类型，传递引用或指针最终都是传递的地址值！而地址总是指针类型(属于简单类型), 
显然参数传递时，按简单类型的赋值拷贝，而不会有拷贝构造函数的调用(对于类类型).<br><strong>3是在类中有指针数据成员时，拷贝构造函数的使用？<br></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
如果不显式声明拷贝构造函数的时候，编译器也会生成一个默认的拷贝构造函数，而且在一般的情况下运行的也很好。但是在遇到类有指针数据成员时就出现问题了：因为默认的拷贝构造函数是按成员拷贝构造，这导致了两个不同的指针(如ptr1=ptr2)指向了相同的内存。当一个实例销毁时，调用析构函数free(ptr1)释放了这段内存，那么剩下的一个实例的指针ptr2就无效了，在被销毁的时候free(ptr2)就会出现错误了, 
这相当于重复释放一块内存两次。这种情况必须显式声明并实现自己的拷贝构造函数，来为新的实例的指针分配新的内存。<br><br>问题1和2回答了为什么拷贝构造函数使用值传递会产生无限递归调用的问题；<br>问题3回答了回答了在类中有指针数据成员时，拷贝构造函数使用值传递等于白显式定义了拷贝构造函数，因为默认的拷贝构造函数就是这么干的
<img src ="http://www.cppblog.com/Husiwa/aggbug/140053.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-02-14 17:50 <a href="http://www.cppblog.com/Husiwa/archive/2011/02/14/140053.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简洁的字符串连接函数</title><link>http://www.cppblog.com/Husiwa/archive/2011/02/14/140036.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Mon, 14 Feb 2011 07:24:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/02/14/140036.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/140036.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/02/14/140036.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/140036.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/140036.html</trackback:ping><description><![CDATA[看到一个简洁的字符串连接函数，颇有启发性<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"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;constr(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;f,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;s)<br><img id=Codehighlighter1_29_90_Open_Image onclick="this.style.display='none'; Codehighlighter1_29_90_Open_Text.style.display='none'; Codehighlighter1_29_90_Closed_Image.style.display='inline'; Codehighlighter1_29_90_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_29_90_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_29_90_Closed_Text.style.display='none'; Codehighlighter1_29_90_Open_Image.style.display='inline'; Codehighlighter1_29_90_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_29_90_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_29_90_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">f</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_46_56_Open_Image onclick="this.style.display='none'; Codehighlighter1_46_56_Open_Text.style.display='none'; Codehighlighter1_46_56_Closed_Image.style.display='inline'; Codehighlighter1_46_56_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_46_56_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_46_56_Closed_Text.style.display='none'; Codehighlighter1_46_56_Open_Image.style.display='inline'; Codehighlighter1_46_56_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_46_56_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_46_56_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">((</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">f</span><span style="COLOR: #000000">++=*</span><span style="COLOR: #000000">s</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_82_86_Open_Image onclick="this.style.display='none'; Codehighlighter1_82_86_Open_Text.style.display='none'; Codehighlighter1_82_86_Closed_Image.style.display='inline'; Codehighlighter1_82_86_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_82_86_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_82_86_Closed_Text.style.display='none'; Codehighlighter1_82_86_Open_Image.style.display='inline'; Codehighlighter1_82_86_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_82_86_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_82_86_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br><img id=Codehighlighter1_103_200_Open_Image onclick="this.style.display='none'; Codehighlighter1_103_200_Open_Text.style.display='none'; Codehighlighter1_103_200_Closed_Image.style.display='inline'; Codehighlighter1_103_200_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_103_200_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_103_200_Closed_Text.style.display='none'; Codehighlighter1_103_200_Open_Image.style.display='inline'; Codehighlighter1_103_200_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_103_200_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_103_200_Open_Text><span style="COLOR: #000000">{<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>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;f[]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;s[]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;constr(f,s);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,f);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;getchar();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<img src ="http://www.cppblog.com/Husiwa/aggbug/140036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-02-14 15:24 <a href="http://www.cppblog.com/Husiwa/archive/2011/02/14/140036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>预编译头文件</title><link>http://www.cppblog.com/Husiwa/archive/2011/02/10/139854.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Thu, 10 Feb 2011 02:12:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/02/10/139854.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/139854.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/02/10/139854.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/139854.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/139854.html</trackback:ping><description><![CDATA[<table>
<tbody>
<tr class="topicHeader"><td class="topicLineColumn"><a name="Topic18"></a><span class="outlineNumberFirst"></span><span class="topicLineFirst">VC++的预编译功能</span> 
<span class="topicIcons"></span></td></tr></tbody></table>
<div class="topicTextNotes">
<div align="left">TAG:<span>预编译和宏定义,VC++,VC++的预编译功能</span><span></span></div>
<div align="left">TEXT:</div>
<div align="left"><span>这里介绍VC6的预编译功能的使用，由于预编译详细使用比较的复杂，这里只介绍几个最重要的预编译指令: /Yu, 
/Yc,/Yx,/Fp。其它的详细资料可以参考： MSDN -&gt; Visual Studio 6.0 Document -&gt; Visual C++ 
6.0 Document -&gt; VC++ Programmer Guider - &gt;Compiler and Linker -&gt; 
Details -&gt; Creating Precompiled Header files</span><span></span></div>
<div align="left"><span>　　 预编译头的概念：</span><span></span></div>
<div align="left"><span>　　 
所谓的预编译头就是把一个工程中的那一部分代码，预先编译好放在一个文件里（通常是以.pch为扩展名的），这个文件就称为预编译头文件这些预先编译好的代码可以是任何的C/C++代码，甚至是inline的函数，但是必须是稳定的，在工程开发的过程中不会被经常改变。如果这些代码被修改，则需要重新编译生成预编译头文件。注意生成预编译头文件是很耗时间的。同时你得注意预编译头文件通常很大，通常有6- 
7M大。注意及时清理那些没有用的预编译头文件。</span><span></span></div>
<div align="left"><span>　　 也许你会问：现在的编译器都有Time 
stamp的功能，编译器在编译整个工程的时候，它只会编译那些经过修改的文件，而不会去编译那些从上次编译过，到现在没有被修改过的文件。那么为什么还要预编译头文件呢？答案在这里，我们知道编译器是以文件为单位编译的，一个文件经过修改后，会重新编译整个文件，当然在这个文件里包含的所有头文件中的东西（.eg 
Macro, Preprocessor ）都要重新处理一遍。 
VC的预编译头文件保存的正是这部分信息。以避免每次都要重新处理这些头文件。</span><span></span></div>
<div align="left"><span>　　 
根据上文介绍，预编译头文件的作用当然就是提高便宜速度了，有了它你没有必要每次都编译那些不需要经常改变的代码。编译性能当然就提高了。</span><span></span></div>
<div align="left"><span>　　 
要使用预编译头，我们必须指定一个头文件，这个头文件包含我们不会经常改变的代码和其他的头文件，然后我们用这个头文件来生成一个预编译头文件（.pch文件）想必大家都知道 
StdAfx.h这个文件。很多人都认为这是VC提供的一个&#8220;系统级别&#8221;的，编译器带的一个头文件。其实不是的，这个文件可以是任何名字的。我们来考察一个典型的由AppWizard生成的MFC 
Dialog 
Based　程序的预编译头文件。（因为AppWizard会为我们指定好如何使用预编译头文件，默认的是StdAfx.h，这是VC起的名字）。我们会发现这个头文件里包含了以下的头文件：</span><span></span></div>
<div align="left">#include &lt;afxwin.h&gt; // MFC core and standard 
components</div>
<div align="left">#include &lt;afxext.h&gt; // MFC extensions</div>
<div align="left">#include &lt;afxdisp.h&gt; // MFC Automation classes</div>
<div align="left">#include &lt;afxdtctl.h&gt; // MFC support for Internet Explorer 
4 Common Controls</div>
<div align="left">#include &lt;afxcmn.h&gt; </div>
<div align="left"><span>　　 
这些正是使用MFC的必须包含的头文件，当然我们不太可能在我们的工程中修改这些头文件的，所以说他们是稳定的。</span><span></span></div>
<div align="left"><span>　　 
那么我们如何指定它来生成预编译头文件。我们知道一个头文件是不能编译的。所以我们还需要一个cpp文件来生成.pch 
文件。这个文件默认的就是StdAfx.cpp。在这个文件里只有一句代码就是：#include&#8220;Stdafx.h&#8221;。原因是理所当然的，我们仅仅是要它能够编译而已―――也就是说，要的只是它的.cpp的扩展名。我们可以用/Yc编译开关来指定StdAfx.cpp来生成一个.pch文件，通过/Fp编译开关来指定生成的pch文件的名字。打开project 
- &gt;Setting-&gt;C/C++ 对话框。把Category指向Precompiled 
Header。在左边的树形视图里选择整个工程，Project Options(右下角的那个白的地方)可以看到 /Fp 
&#8220;debug/PCH.pch&#8221;，这就是指定生成的.pch文件的名字，默认的通常是　&lt;工程名&gt;.pch。然后，在左边的树形视图里选择StdAfx.cpp，这时原来的Project 
Option变成了 Source File Option（原来是工程，现在是一个文件，当然变了）。在这里我们可以看到 
/Yc开关，/Yc的作用就是指定这个文件来创建一个Pch文件。/Yc后面的文件名是那个包含了稳定代码的头文件，一个工程里只能有一个文件的可以有YC开关。VC就根据这个选项把 
StdAfx.cpp编译成一个Obj文件和一个PCH文件。</span><span></span></div>
<div align="left"><span>这样，我们就设置好了预编译头文件。也就是说，我们可以使用预编译头功能了。以下是注意事项：</span><span></span></div>
<div align="left"><span>　　 
1）如果使用了/Yu，就是说使用了预编译，我们在每个.cpp文件的最开头，包含你指定产生pch文件的.h文件（默认是stdafx.h）不然就会有问题。如果你没有包含这个文件，就告诉你Unexpected 
file end. </span><span></span></div>
<div align="left"><span>　　 2）如果你把pch文件不小心丢了，根据以上的分析，你只要让编译器生成一个pch文件就可以了。也就是说把 
stdafx.cpp（即指定/Yc的那个cpp文件）重新编译一遍就可以了。</span><span></span></div></div>
<img src ="http://www.cppblog.com/Husiwa/aggbug/139854.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-02-10 10:12 <a href="http://www.cppblog.com/Husiwa/archive/2011/02/10/139854.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DLL动态链接库和LIB静态链接库</title><link>http://www.cppblog.com/Husiwa/archive/2011/01/17/138652.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Mon, 17 Jan 2011 03:55:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2011/01/17/138652.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/138652.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2011/01/17/138652.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/138652.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/138652.html</trackback:ping><description><![CDATA[


原文地址：http://hi.baidu.com/freedomknightduzhi/blog/item/a0504560d1277555ebf8f8ff.html<div><p>1：神马是Dll和Lib，神马是静态链接和动态链接</p>
<p>大家都懂的，DLL就是动态链接库，LIB是静态链接库。DLL其实就是EXE，只不过没main。</p>
<p>动态链接是相对于静态链接而言的。所谓静态链接就是把函数或过程直接链接到可执行文件中，成为可执行程序中的一部分，当多个程序调用同样的函数时，内存里就会有这个函数的多个拷贝，浪费内存资源。而动态链接则是提供了一个函数的描述信息给可执行文件（并没有内存拷贝），当程序被夹在到内存里开始运行的时候，系统会在底层创建DLL和应用程序之间的连接关系，当执行期间需要调用DLL函数时，系统才会真正根据链接的定位信息去执行DLL中的函数代码。</p>
<p>在WINDOWS32系统底下，每个进程有自己的32位的线性地址空间，若一个DLL被进程使用，则该DLL首先会被调入WIN32系统的全局堆栈，然后通过内存映射文件方式映射到这个DLL的进程地址空间。若一个DLL被多个进程调用，则每个进程都会接收到该DLL的一个映像，而非多份的拷贝。但，在WIN16系统下，每个进程需要拥有自己的一份DLL空间，可以理解为何静态链接没啥区别。</p>
<p>&nbsp;</p>
<p>2：DLL和LIB区别和联系。</p>
<p>DLL是程序在运行阶段才需要的文件。</p>
<p>LIB是程序编译时需要链接的文件。</p>
<p>DLL只有一种，其中一定是函数和过程的实现。</p>
<p>LIB是有两种。若只生成LIB的话，则这个LIB是静态编译出来的，它内部包含了函数索引以及实现，这个LIB会比较大。若生成DLL的话，则也会生成一个LIB，这个LIB和刚才那个LIB不同，它是只有函数索引，没有实现的，它很小。但是这俩LIB依然遵循上个原则，是在编译时候是需要被链接的。若不链接第一个LIB的话，在程序运行时会无法找到函数实现，当掉。若不链接第二个LIB的话，在程序运行时依然会无法找到函数实现。但第二种LIB有一种替代方式，就是在程序里，使用LoadLibrary,GetProcAddress替代第二个LIB的功能。第一种LIB生成的EXE文件会很大，因为LIB所有信息被静态链接进EXE里了。第二种LIB生成的EXE文件会比较小，因为函数过程实现依旧在DLL内。</p>
<p>（啰嗦了一堆，某志希望大家能够明白两个LIB的区别。要再不行的话，我们可以将静态编译的LIB称为 静态链接库。但动态编译的LIB称为 
引入库。可能会比较好一些。）</p>
<p>静态链接LIB的优点是免除挂接动态链接库，缺点是EXE大，版本控制麻烦些。</p>
<p>动态链接DLL的优点是文件小，版本更换时换DLL就好了，缺点是多了点文件。动态链接若是被多个进程使用，会更加方便和节省内存。</p>
<p>&nbsp;</p>
<p>3：为什么编译DLL时总会同时生成一个LIB？这个LIB有用吗？</p>
<p>若我们不是用静态链接，而使用DLL，那么我们也需要一个LIB，这个LIB的作用是被链接到程序里，在程序运行时告诉系统你需要什么DLL文件。这个LIB里保存的是DLL的名字和输出函数入口的顺序表。它是有意义的。</p>
<p>当然，若我们的应用程序里不链接这个LIB，则可以使用LoadLibrary,GetProcAddress来告诉系统我们在运行时需要怎么着DLL以及其内的函数。</p>
<p>&nbsp;</p>
<p>4：DLL意义。</p>
<p>1：DLL真正实现了跨语言。各种语言都可以生成DLL，而对系统以及应用程序来说，哪种语言生成的DLL是没有区别的。</p>
<p>2：DLL有足够的封装性，对于版本更新有很大好处。因为DLL是运行期间才会使用，所以，即使DLL内函数实现有变化（只要参数和返回值不发生变化），程序是不需要进行编译的。大大提高了软件开发和维护的效率。</p>
<p>3：DLL被多个进程使用，因为有内存映射机制，无需占用更多内存。</p>
<p>&nbsp;</p>
<p>5：创建DLL。（注意：某志就不再讲解使用MFC AppWizard[dll] 方式创建DLL了。有兴趣的自己去百度。这里创建DLL只指使用Win32 
Dynamic-link Library创建Non-MFC DLL。呃，DLL的三种类型就不解释了，依旧那句话：百度一下你就知道。）</p>
<p>每个应用程序必须有一个main或者winmain函数作为入口，DLL一样，有自己的缺省的入口函数，就是DllMain。函数如下</p>
<p>BOOL APIENTRY DllMain( HMODULE hModule,&nbsp;DWORD&nbsp; ul_reason_for_call,&nbsp;LPVOID 
lpReserved)<br>{<br>&nbsp;switch (ul_reason_for_call)<br>&nbsp;{<br>&nbsp;case 
DLL_PROCESS_ATTACH:&nbsp;&nbsp; // 进程被调用<br>&nbsp;case DLL_THREAD_ATTACH:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 线程被调用<br>&nbsp;case 
DLL_THREAD_DETACH:&nbsp;&nbsp; // 线程被停止<br>&nbsp;case DLL_PROCESS_DETACH:&nbsp; 
//&nbsp;进程被停止<br>&nbsp;&nbsp;break;<br>&nbsp;}<br>&nbsp;return TRUE;<br>}</p>
<p>一般情况下，我们不需要对这个缺省的入口函数进行什么修改，它就会使动态链接库得到正确的初始化。但是，当我们的DLL需要额外分配内存或者资源的时候，或者，DLL希望对调用自己的进程或线程进行初始化或清除的额外操作时，可以在上述代码case中加一些自己感冒的东东。（懒&#8230;&#8230;不想细写了- 
-Orz，现在是晚上2点了，明天还一堆的事情）</p>
<p>DLL对于导出类和导出函数没啥不同。只要加上 __declspec( dllexport ) 修饰函数或者类就好了。</p>
<p>但是有查看过DLL代码的人员都会经常见到这么一段代码</p>
<p>#ifdef FK_DLL_EXPORTS</p>
<p>#define FK_DLL __declspec( dllexport ) </p>
<p>#else</p>
<p>#define FK_DLL __declspec( dllimport )</p>
<p>#endif</p>
<p>意义很明显，但是，问题是&nbsp; FK_DLL_EXPORTS 这个宏是应该在哪儿定义呢？在DLL项目内，还是在使用DLL的应用程序内？</p>
<p>这点某志曾迷糊很久，呵呵~其实后来想想，还是蛮明确的。export是导出。import是导入。对于DLL来说，是要导出这些函数给其他应用程序使用的，所以应当定义 
FK_DLL_EXPORTS 宏。对于使用DLL的应用程序来说，是导入，是无需定义的。</p>
<p>使用时候也很简单。</p>
<p>class FK_DLL CMyDllClass{}&nbsp;;</p>
<p>则整个类被导出。</p>
<p>FK_DLL void MyTestFun( int a );</p>
<p>则该函数被导出。</p>
<p>但是有时我们可以见到这样的代码</p>
<p>extern "C" FK_DLL void MyTestFun2( float b );</p>
<p>其中extern "C"的原理就是标示该函数要求以C形式去进行编译，不要以C++形式去编译。具体的编译原理就不罗嗦了，简而言之，被extern 
"C"定义函数，可以被C以及其他语言进行DLL调用，而未被extern "C"定义的函数，C是无法访问DLL中这个函数的。</p>
<p>&nbsp;</p>
<p>在VS中开发DLL还有一种方式，使用.def文件。</p>
<p>新建个文本文档，改后缀为FKDll.def，加入到工程里。</p>
<p>FKDll.def里加入以下代码</p>
<p>LIBRARY FKDll</p>
<p>EXPORTS</p>
<p><a href="mailto:MyTestFun@1">MyTestFun@1</a></p>
<p><a href="mailto:MyTestFun2@2">MyTestFun2@2</a></p>
<p>就可以了。其中，LIBRARY语句是说明.def文件是属于FKDll这个Dll的。EXPORTS下面是我们需要导出的函数名。后面加的@+数字，是表示导出函数的顺序编号。这样就足够了。（详细的自己百度，好困，zzzZZZ）</p>
<p>&nbsp;</p>
<p>6：使用DLL</p>
<p>使用DLL有两种方式。显式链接和隐式链接。</p>
<p>隐式链接很容易。直接#progam comment(lib, "FKDll.lib") 
就可以。当然，也可以在项目工程-&gt;属性-&gt;链接库里加上库和路径（相对路径和绝对路径都可以）。</p>
<p>显式链接则麻烦些。在程序中使用LoadLibrary加载DLL，再GetProcAddress获取函数实现，在程序退出之前，调用FreeLibrary来动态释放掉链接库。</p>
<p>&#8205;例如：</p>
<p>void Main()</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; typedef void (*FKDllFun1)(int a);</p>
<p>&nbsp;&nbsp;&nbsp; FKDllFun1 pFun1;</p>
<p>&nbsp;&nbsp;&nbsp; HINSTANCE hDLL&nbsp; = LoadLibrary("FKDll.dll");&nbsp;&nbsp; // 若hDll为空则读取Dll失败。</p>
<p>&nbsp;&nbsp;&nbsp; pFun1 = (pFun1)GetProcAddress(hDll, "MyTestFun1" );&nbsp;&nbsp; // 
从应用程序中的DLL镜像中获取名为 MyTestFun1 的函数指针</p>
<p>&nbsp;&nbsp;&nbsp; pFun1( 100 );</p>
<p>&nbsp;&nbsp;&nbsp; FreeLibrary(hDll);</p>
<p>}</p>
<p>当然，我们刚才.def里面还指定了导出函数的导出顺序，那么我们可以修改里面获取函数指针那一段为</p>
<p>&#8205;pFun1 = (pFun1)GetProcAddress(hDll, MAKEINTERSOURCE(1) );&nbsp;&nbsp;// 1 
是刚才指定的MyTestFun1函数导出顺序编号。</p>
<p>这样可以更快，但是别将编号记混了，会导致诡异的错误。</p>
<p>&nbsp;</p>
<p>7：比较显式链接和隐式链接。</p>
<p>可能的话，尽量使用显式链接。</p>
<p>显式链接可以在程序执行时动态的加载DLL和卸载DLL文件，隐式链接是做不到的。</p>
<p>显式链接LoadLibrary，GetProcAddress时能获知是否加载失败，我们可以对其进行检查错误处理。而显式链接可能是一个很恶劣的提示或是程序崩溃的结果。</p>
<p>对于有些Ex类型的加强函数，显式链接可以允许我们找到替代方案。也包括选择D3d9.dll和OpenGL.dll时也可采用同样处理。</p>
<p>例如：</p>
<p>if( GetProcAddress( hDll, "FKDllFunEx") == NULL )</p>
<p>{</p>
<p>&#8205;&nbsp;&nbsp;&nbsp; pFun = GetProcAddress( hDll, "FKDllFun");&nbsp;&nbsp;&nbsp; // 然后使用pFun进行处理</p>
<p>}</p>
<p>&nbsp;</p>
<p>8：导出类和导出函数</p>
<p>类和函数的导出方式上面给出了说明，原本极其类似的。</p>
<p>我们说下使用导出类。</p>
<p>若我们隐式的使用了一个导出类，则我们在应用程序里继承它的时候，就如同该类就在应用程序代码里一样，无需任何处理。</p>
<p>例如：</p>
<p>class FK_DLL CMyDllClass{}&nbsp;;&nbsp;&nbsp;&nbsp; // Dll文件内的代码</p>
<p>-----------------------</p>
<p>class CAppClass : public CMyDllClass&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 应用程序内代码，无需做任何处理。</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .... </p>
<p>}</p>
<p>也可以直接使用DLL导出类</p>
<p>void main</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; CMyDllClass* pClass&nbsp;= new CMyDllClass&nbsp;();</p>
<p>}</p>
<p>但是，若应用程序声明或者分类一个DLL中导出类的对象时会存在一个很讨厌的问题：这个操作会使内存跟踪系统失效，使其错误的报告内存分配和释放情况。</p>
<p>为解决这个问题，我们可以给出两个接口函数对DLL导出类进行创建销毁支持，就可以使内存跟踪系统正常了。例如</p>
<p>class FK_DLL CMyDllClass{}&nbsp;;&nbsp;</p>
<p>额外增加俩函数</p>
<p>FK_DLL CMyDllClass* CreateMyDllClass(){ return new CMyDllClass(); }</p>
<p>FK_DLL void DestoryMyDllClass( CMyDllClass* p_pClass ){ delete p_pClass; 
}</p>
<p>-----------------------------------------------</p>
<p>上面的方法可以正确进行内存跟踪了，但是，因为DLL导出类CMyDllClass依旧是导出的状态，用户同样可以跳过我们提供的接口直接使用。那么怎么办呢。方法是不再对类进行DLL导出，而对类内的函数全部进行DLL导出即可，</p>
<p>-----------------------------------------------</p>
<p>但是若仅仅提供上面两个接口函数以及类内全部函数，的确功能可以实现，却无法进行类继承了。若这个类继承很重要，必须开放，那么就需要使用新的内存跟踪程序替换应用程序内的原有内存跟踪程序。或者使用下面的一个方法。（见模块9：复杂问题）</p>
<p>-----------------------------------------------</p>
<p>同样，我们也可以发现，在不导出DLL类本身，而只导出DLL类内函数也有一些好处，一些我们不希望外界知道的函数可以不设置导出标记，这进一步保护了DLL内函数的安全性。</p>
<p>&nbsp;</p>
<p>9：复杂问题。</p>
<p>若我们使用LoadLibrary显式加载一个DLL，并尝试在应用程序中调用一个类内成员函数的话，无论该函数是否在头文件中有声明，VS会给出一个"unresolved 
external symbol（未解析的外部符号）"的错误。我们此时可以将项目属性中的内联函数扩展选项修改为"Only __inline"或"Any 
Suitable"即可。但，我们可能在调试连编的时候期望关闭内联函数扩展，那么另一种解决方案是，将希望导出的函数声明为虚函数，例如</p>
<p>class CMyDllClass</p>
<p>{</p>
<p>&nbsp;&nbsp; FK_DLL virtual void MyTestFun( int a ){&nbsp; dosth(); }&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp; // 用上面代码替换 FK_DLL&nbsp;void MyTestFun( int a ){&nbsp; dosth(); }&nbsp;&nbsp; </p>
<p>}</p>
<p>这样做还有一个额外的好处。将导出的类成员函数设置为虚函数之后，该虚函数所在的类在应用程序中也如同被声明一样，可以接受继承。</p>
<p>例如若是上面的做法，应用程序就可以进行顺利继承，而不必要求CMyDllClass&nbsp;被标示为导出。（原理不知，希望精通底层的高手协助解释。）</p>
<p>class CAppClass : public CMyDllClass&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 应用程序内代码，无需做任何处理。</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .... </p>
<p>}</p></div><div><br></div><img src ="http://www.cppblog.com/Husiwa/aggbug/138652.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-01-17 11:55 <a href="http://www.cppblog.com/Husiwa/archive/2011/01/17/138652.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>宏中"#"和"##"的用法</title><link>http://www.cppblog.com/Husiwa/archive/2010/12/17/136735.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Fri, 17 Dec 2010 06:34:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2010/12/17/136735.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/136735.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2010/12/17/136735.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/136735.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/136735.html</trackback:ping><description><![CDATA[<div>
<p>&nbsp;</p>
<p><span><font face="Times New Roman" size=3>&nbsp;见到这两个符号的很多不同的用法，整理在一起</font></span></p>
<p><font size=3><span>宏中</span><span><font face="Times New Roman">"#"</font></span><span>和</span><span><font face="Times New Roman">"##"</font></span><span>的用法</span><span><font face="Times New Roman"> </font></span></font></p>
<p><font size=3><span>一、一般用法</span><span><font face="Times New Roman"> </font></span></font></p>
<p><font size=3><span>我们使用</span><span><font face="Times New Roman">#</font></span><span>把宏参数变为一个字符串</span><span><font face="Times New Roman">,</font></span><span>用</span><span><font face="Times New Roman">##</font></span><span>把两个宏参数贴合在一起</span><span><font face="Times New Roman">. </font></span></font></p>
<p><font size=3><span>用法</span><span><font face="Times New Roman">: </font></span></font></p>
<p><span><font face="Times New Roman" size=3>#include&lt;cstdio&gt; </font></span></p>
<p><span><font face="Times New Roman" size=3>#include&lt;climits&gt; </font></span></p>
<p><span><font face="Times New Roman" size=3>using namespace std; </font></span></p>
<p><span><font face="Times New Roman" size=3>#define STR(s)<span>&nbsp;&nbsp; </span>#s </font></span></p>
<p><span><font face="Times New Roman" size=3>#define CONS(a,b) int(a##e##b) </font></span></p>
<p><span><font face="Times New Roman" size=3>int main() </font></span></p>
<p><span><font face="Times New Roman" size=3>{ </font></span></p>
<p><font size=3><span><font face="Times New Roman">&nbsp;printf(STR(vck));<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// </font></span><span>输出字符串</span><span><font face="Times New Roman">"vck" </font></span></font></p>
<p><font size=3><span><font face="Times New Roman">&nbsp;printf("%d\n", CONS(2,3)); // 2e3 </font></span><span>输出</span><span><font face="Times New Roman">:2000 </font></span></font></p>
<p><span><font face="Times New Roman"><font size=3>&nbsp;return 0; </font></font></span></p>
<p><span><font face="Times New Roman" size=3>} </font></span></p>
<p><span><font face="Times New Roman" size=3>&nbsp;</font></span></p>
<p><font size=3><span>二、当宏参数是另一个宏的时候</span><span><font face="Times New Roman"> </font></span></font></p>
<p><font size=3><span>需要注意的是凡宏定义里有用</span><span><font face="Times New Roman">'#'</font></span><span>或</span><span><font face="Times New Roman">'##'</font></span><span>的地方宏参数是不会再展开</span><span><font face="Times New Roman">. </font></span></font></p>
<p><font size=3><span><font face="Times New Roman">1, </font></span><span>非</span><span><font face="Times New Roman">'#'</font></span><span>和</span><span><font face="Times New Roman">'##'</font></span><span>的情况</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>#define TOW<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>(2) </font></span></p>
<p><span><font face="Times New Roman" size=3>#define MUL(a,b) (a*b) </font></span></p>
<p><span><font face="Times New Roman" size=3>printf("%d*%d=%d\n", TOW, TOW, MUL(TOW,TOW)); </font></span></p>
<p><font size=3><span>这行的宏会被展开为：</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>printf("%d*%d=%d\n", (2), (2), ((2)*(2))); </font></span></p>
<p><font size=3><span><font face="Times New Roman">MUL</font></span><span>里的参数</span><span><font face="Times New Roman">TOW</font></span><span>会被展开为</span><span><font face="Times New Roman">(2). </font></span></font></p>
<p><font size=3><span><font face="Times New Roman">2, </font></span><span>当有</span><span><font face="Times New Roman">'#'</font></span><span>或</span><span><font face="Times New Roman">'##'</font></span><span>的时候</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>#define A<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(2) </font></span></p>
<p><span><font face="Times New Roman" size=3>#define STR(s)<span>&nbsp;&nbsp; </span>#s </font></span></p>
<p><span><font face="Times New Roman" size=3>#define CONS(a,b) int(a##e##b) </font></span></p>
<p><span><font face="Times New Roman" size=3>printf("int max: %s\n", STR(INT_MAX));<span>&nbsp;&nbsp; </span>// INT_MAX #include&lt;climits&gt; </font></span></p>
<p><font size=3><span>这行会被展开为：</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>printf("int max: %s\n", "INT_MAX"); </font></span></p>
<p><span><font face="Times New Roman" size=3>printf("%s\n", CONS(A, A));<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// compile error </font></span></p>
<p><font size=3><span>这一行则是：</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>printf("%s\n", int(AeA)); </font></span></p>
<p><font size=3><span><font face="Times New Roman">A</font></span><span>不会再被展开</span><span><font face="Times New Roman">, </font></span><span>然而解决这个问题的方法很简单</span><span><font face="Times New Roman">. </font></span><span>加多一层中间转换宏</span><span><font face="Times New Roman">. </font></span></font></p>
<p><font size=3><span>加这层宏的用意是把所有宏的参数在这层里全部展开</span><span><font face="Times New Roman">, </font></span><span>那么在转换宏里的那一个宏</span><span><font face="Times New Roman">(_STR)</font></span><span>就能得到正确的宏参数</span><span><font face="Times New Roman">. </font></span></font></p>
<p><span><font face="Times New Roman" size=3>#define A<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;(2) </font></span></p>
<p><span><font face="Times New Roman" size=3>#define _STR(s)<span>&nbsp;&nbsp; </span>#s </font></span></p>
<p><font size=3><span><font face="Times New Roman">#define STR(s)<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>_STR(s)<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// </font></span><span>转换宏</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>#define _CONS(a,b) int(a##e##b) </font></span></p>
<p><font size=3><span><font face="Times New Roman">#define CONS(a,b)<span>&nbsp;&nbsp; </span>_CONS(a,b)<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>// </font></span><span>转换宏</span><span><font face="Times New Roman"> </font></span></font></p>
<p><font size=3><span><font face="Times New Roman">printf("int max: %s\n", STR(INT_MAX));<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// INT_MAX,int</font></span><span>型的最大值，为一个变量</span><span><font face="Times New Roman"> #include&lt;climits&gt; </font></span></font></p>
<p><font size=3><span>输出为</span><span><font face="Times New Roman">: int max: 0x7fffffff </font></span></font></p>
<p><font size=3><span><font face="Times New Roman">STR(INT_MAX) --&gt; _STR(0x7fffffff) </font></span><span>然后再转换成字符串；</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>printf("%d\n", CONS(A, A)); </font></span></p>
<p><font size=3><span>输出为：</span><span><font face="Times New Roman">200 </font></span></font></p>
<p><span><font face="Times New Roman" size=3>CONS(A, A) --&gt; _CONS((2), (2)) --&gt; int((2)e(2)) </font></span></p>
<p><font size=3><span>三、</span><span><font face="Times New Roman">'#'</font></span><span>和</span><span><font face="Times New Roman">'##'</font></span><span>的一些应用特例</span><span><font face="Times New Roman"> </font></span></font></p>
<p><font size=3><span><font face="Times New Roman">1</font></span><span>、合并匿名变量名</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>#define ___ANONYMOUS1(type, var, line) type var##line </font></span></p>
<p><span><font face="Times New Roman" size=3>#define __ANONYMOUS0(type, line) ___ANONYMOUS1(type, _anonymous, line) </font></span></p>
<p><span><font face="Times New Roman" size=3>#define ANONYMOUS(type) __ANONYMOUS0(type, __LINE__) </font></span></p>
<p><font size=3><span>例：</span><span><font face="Times New Roman">ANONYMOUS(static int); </font></span><span>即</span><span><font face="Times New Roman">: static int _anonymous70; 70</font></span><span>表示该行行号；</span><span><font face="Times New Roman"> </font></span></font></p>
<p><font size=3><span>第一层：</span><span><font face="Times New Roman">ANONYMOUS(static int); --&gt; __ANONYMOUS0(static int, __LINE__); </font></span></font></p>
<p><font size=3><span>第二层：</span><span><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--&gt; ___ANONYMOUS1(static int, _anonymous, 70); </font></span></font></p>
<p><font size=3><span>第三层：</span><span><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--&gt; static int _anonymous70; </font></span></font></p>
<p><font size=3><span>即每次只能解开当前层的宏，所以</span><span><font face="Times New Roman">__LINE__</font></span><span>在第二层才能被解开；</span><span><font face="Times New Roman"> </font></span></font></p>
<p><font size=3><span><font face="Times New Roman">2</font></span><span>、填充结构</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>#define FILL(a)<span>&nbsp;&nbsp; </span>{a, #a} </font></span></p>
<p><span><font face="Times New Roman" size=3>enum IDD{OPEN, CLOSE}; </font></span></p>
<p><span><font face="Times New Roman" size=3>typedef struct MSG{ </font></span></p>
<p><span><font face="Times New Roman" size=3>IDD id; </font></span></p>
<p><span><font face="Times New Roman" size=3>const char * msg; </font></span></p>
<p><span><font face="Times New Roman" size=3>}MSG; </font></span></p>
<p><span><font face="Times New Roman" size=3>MSG _msg[] = {FILL(OPEN), FILL(CLOSE)}; </font></span></p>
<p><font size=3><span>相当于：</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>MSG _msg[] = {{OPEN, "OPEN"}, </font></span></p>
<p><span><font face="Times New Roman"><font size=3><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{CLOSE, "CLOSE"}}; </font></font></span></p>
<p><font size=3><span><font face="Times New Roman">3</font></span><span>、记录文件名</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>#define _GET_FILE_NAME(f)<span>&nbsp;&nbsp; </span>#f </font></span></p>
<p><span><font face="Times New Roman" size=3>#define GET_FILE_NAME(f)<span>&nbsp;&nbsp; </span>_GET_FILE_NAME(f) </font></span></p>
<p><span><font face="Times New Roman" size=3>static char FILE_NAME[] = GET_FILE_NAME(__FILE__); </font></span></p>
<p><font size=3><span><font face="Times New Roman">4</font></span><span>、得到一个数值类型所对应的字符串缓冲大小</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>#define _TYPE_BUF_SIZE(type) sizeof #type </font></span></p>
<p><span><font face="Times New Roman" size=3>#define TYPE_BUF_SIZE(type)<span>&nbsp;&nbsp; </span>_TYPE_BUF_SIZE(type) </font></span></p>
<p><span><font face="Times New Roman" size=3>char buf[TYPE_BUF_SIZE(INT_MAX)]; </font></span></p>
<p><span><font face="Times New Roman"><font size=3>&nbsp;--&gt; char buf[_TYPE_BUF_SIZE(0x7fffffff)]; </font></font></span></p>
<p><span><font face="Times New Roman"><font size=3>&nbsp;--&gt; char buf[sizeof "0x7fffffff"]; </font></font></span></p>
<p><font size=3><span>这里相当于：</span><span><font face="Times New Roman"> </font></span></font></p>
<p><span><font face="Times New Roman" size=3>char buf[11];</font></span></p>
</div>
<img src ="http://www.cppblog.com/Husiwa/aggbug/136735.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2010-12-17 14:34 <a href="http://www.cppblog.com/Husiwa/archive/2010/12/17/136735.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>指令寄存器</title><link>http://www.cppblog.com/Husiwa/archive/2010/12/15/136470.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Wed, 15 Dec 2010 03:17:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2010/12/15/136470.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/136470.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2010/12/15/136470.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/136470.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/136470.html</trackback:ping><description><![CDATA[ebp和esp是32位的SP，BP&nbsp; <br>esp是堆栈指针&nbsp;&nbsp;&nbsp;&nbsp; <br>ebp是基址指针&nbsp; <br>ESP与SP的关系就象AX与AL，AH的关系.<br><br>32位CPU所含有的寄存器有：<br><br>4个数据寄存器(EAX、EBX、ECX和EDX)<br>2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP)<br>6个段寄存器(ES、CS、SS、DS、FS和GS)<br>1个指令指针寄存器(EIP) 1个标志寄存器(EFlags)<br><br>1、数据寄存器<br><br>数据寄存器主要用来保存操作数和运算结果等信息，从而节省读取操作数所需占用总线和访问存储器的时间。<br><br>32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。对低16位数据的存取，不会影响高16位的数据。这些<br>低16位寄存器分别命名为：AX、BX、CX和DX，它和先前的CPU中的寄存器相一致。<br><br>4个16位寄存器又可分割成8个独立的8位寄存器(AX：AH-AL、BX：BH-BL、CX：CH-CL、DX：DH-DL)，每个寄<br>存器都有自己的名称，可独立存取。程序员可利用数据寄存器的这种&#8220;可分可合&#8221;的特性，灵活地处理字/字<br>节的信息。<br><br>寄存器AX和AL通常称为累加器(Accumulator)，用累加器进行的操作可能需要更少时间。累加器可用于乘、<br>除、输入/输出等操作，它们的使用频率很高；<br>寄存器BX称为基地址寄存器(Base Register)。它可作为存储器指针来使用； <br>寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时，要用它来控制循环次数；在位操作<br>中，当移多位时，要用CL来指明移位的位数；<br>寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时，它可作为默认的操作数参与运算，也<br>可用于存放I/O的端口地址。<br><br><br>在16位CPU中，AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址，但在32位CPU中，其32位<br>寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果，而且也可作为指针寄存器，<br>所以，这些32位寄存器更具有通用性。<br><br>2、变址寄存器<br><br>32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI，对低16位数据的存取，不影响<br>高16位的数据。<br><br>寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register)，它们主要用于存放存储单元在段内的偏移量，<br>用它们可实现多种存储器操作数的寻址方式，为以不同的地址形式访问存储单元提供方便。<br><br>变址寄存器不可分割成8位寄存器。作为通用寄存器，也可存储算术逻辑运算的操作数和运算结果。<br><br>它们可作一般的存储器指针使用。在字符串操作指令的执行过程中，对它们有特定的要求，而且还具有特<br>殊的功能。<br><br>3、指针寄存器<br><br>32位CPU有2个32位通用寄存器EBP和ESP。其低16位对应先前CPU中的SBP和SP，对低16位数据的存取，不影<br>响高16位的数据。<br><br>寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register)，主要用于存放堆栈内存储单元的偏移量，<br>用它们可实现多种存储器操作数的寻址方式，为以不同的地址形式访问存储单元提供方便。<br><br>指针寄存器不可分割成8位寄存器。作为通用寄存器，也可存储算术逻辑运算的操作数和运算结果。<br><br>它们主要用于访问堆栈内的存储单元，并且规定：<br><br>BP为基指针(Base Pointer)寄存器，用它可直接存取堆栈中的数据；<br>SP为堆栈指针(Stack Pointer)寄存器，用它只可访问栈顶。<br><br>4、段寄存器<br><br>段寄存器是根据内存分段的管理模式而设置的。内存单元的物理地址由段寄存器的值和一个偏移量组合而成<br>的，这样可用两个较少位数的值组合成一个可访问较大物理空间的内存地址。<br><br>CPU内部的段寄存器：<br><br>CS——代码段寄存器(Code Segment Register)，其值为代码段的段值；<br>DS——数据段寄存器(Data Segment Register)，其值为数据段的段值；<br>ES——附加段寄存器(Extra Segment Register)，其值为附加数据段的段值；<br>SS——堆栈段寄存器(Stack Segment Register)，其值为堆栈段的段值；<br>FS——附加段寄存器(Extra Segment Register)，其值为附加数据段的段值；<br>GS——附加段寄存器(Extra Segment Register)，其值为附加数据段的段值。<br><br>在16位CPU系统中，它只有4个段寄存器，所以，程序在任何时刻至多有4个正在使用的段可直接访问；在32位<br>微机系统中，它有6个段寄存器，所以，在此环境下开发的程序最多可同时访问6个段。<br><br>32位CPU有两个不同的工作方式：实方式和保护方式。在每种方式下，段寄存器的作用是不同的。有关规定简<br>单描述如下：<br><br>实方式： 前4个段寄存器CS、DS、ES和SS与先前CPU中的所对应的段寄存器的含义完全一致，内存单元的逻辑<br>地址仍为&#8220;段值：偏移量&#8221;的形式。为访问某内存段内的数据，必须使用该段寄存器和存储单元的偏移量。<br>保护方式： 在此方式下，情况要复杂得多，装入段寄存器的不再是段值，而是称为&#8220;选择子&#8221;(Selector)的某个值。。<br><br>5、指令指针寄存器<br><br>32位CPU把指令指针扩展到32位，并记作EIP，EIP的低16位与先前CPU中的IP作用相同。<br><br>指令指针EIP、IP(Instruction Pointer)是存放下次将要执行的指令在代码段的偏移量。在具有预取指令功<br>能的系统中，下次要执行的指令通常已被预取到指令队列中，除非发生转移情况。所以，在理解它们的功能<br>时，不考虑存在指令队列的情况。<br><br>在实方式下，由于每个段的最大范围为64K，所以，EIP中的高16位肯定都为0，此时，相当于只用其低16位<br>的IP来反映程序中指令的执行次序。<br><br>6、标志寄存器<br><br>一、运算结果标志位<br>1、进位标志CF(Carry Flag)<br>进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位，那么，其值为1，否则其值为0。<br><br>使用该标志位的情况有：多字(字节)数的加减运算，无符号数的大小比较运算，移位操作，字(字节)之间移位，专门改变CF值的指令等。<br><br>2、奇偶标志PF(Parity Flag)<br>奇偶标志PF用于反映运算结果中&#8220;1&#8221;的个数的奇偶性。如果&#8220;1&#8221;的个数为偶数，则PF的值为1，否则其值为0。<br><br>利用PF可进行奇偶校验检查，或产生奇偶校验位。在数据传送过程中，为了提供传送的可靠性，如果采用奇偶校验的方法，就可使用该标志位。<br><br>3、辅助进位标志AF(Auxiliary Carry Flag)<br>在发生下列情况时，辅助进位标志AF的值被置为1，否则其值为0：<br><br>(1)、在字操作时，发生低字节向高字节进位或借位时；<br>(2)、在字节操作时，发生低4位向高4位进位或借位时。<br><br>对以上6个运算结果标志位，在一般编程情况下，标志位CF、ZF、SF和OF的使用频率较高，而标志位PF和AF的使用频率较低。<br><br>4、零标志ZF(Zero Flag)<br>零标志ZF用来反映运算结果是否为0。如果运算结果为0，则其值为1，否则其值为0。在判断运算结果是否为0时，可使用此标志位。<br><br>5、符号标志SF(Sign Flag)<br>符号标志SF用来反映运算结果的符号位，它与运算结果的最高位相同。在微机系统中，有符号数采用补码表示法，所以，SF也就反映运算结果的正负号。运算结果为正数时，SF的值为0，否则其值为1。<br><br>6、溢出标志OF(Overflow Flag)<br>溢出标志OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围，则称为溢出，OF的值被置为1，否则，OF的值被清为0。<br><br>&#8220;溢出&#8221;和&#8220;进位&#8221;是两个不同含义的概念，不要混淆。如果不太清楚的话，请查阅《计算机组成原理》课程中的有关章节。<br><br>二、状态控制标志位<br>状态控制标志位是用来控制CPU操作的，它们要通过专门的指令才能使之发生改变。<br><br>1、追踪标志TF(Trap Flag)<br>当追踪标志TF被置为1时，CPU进入单步执行方式，即每执行一条指令，产生一个单步中断请求。这种方式主要用于程序的调试。<br><br>指令系统中没有专门的指令来改变标志位TF的值，但程序员可用其它办法来改变其值。<br><br>2、中断允许标志IF(Interrupt-enable Flag)<br>中断允许标志IF是用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。但不管该标志为何值，CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求，以及CPU内部产生的中断请求。具体规定如下：<br><br>(1)、当IF=1时，CPU可以响应CPU外部的可屏蔽中断发出的中断请求；<br><br>(2)、当IF=0时，CPU不响应CPU外部的可屏蔽中断发出的中断请求。<br><br>CPU的指令系统中也有专门的指令来改变标志位IF的值。<br><br>3、方向标志DF(Direction Flag)<br>方向标志DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向。具体规定在第5.2.11节——字符串操作指令——中给出。在微机的指令系统中，还提供了专门的指令来改变标志位DF的值。<br><br>三、32位标志寄存器增加的标志位<br>1、I/O特权标志IOPL(I/O Privilege Level)<br>I/O特权标志用两位二进制位来表示，也称为I/O特权级字段。该字段指定了要求执行I/O指令的特权级。如果当前的特权级别在数值上小于等于IOPL的值，那么，该I/O指令可执行，否则将发生一个保护异常。<br><br>2、嵌套任务标志NT(Nested Task)<br>嵌套任务标志NT用来控制中断返回指令IRET的执行。具体规定如下：<br><br>(1)、当NT=0，用堆栈中保存的值恢复EFLAGS、CS和EIP，执行常规的中断返回操作；<br><br>(2)、当NT=1，通过任务转换实现中断返回。<br><br>3、重启动标志RF(Restart Flag)<br>重启动标志RF用来控制是否接受调试故障。规定：RF=0时，表示&#8220;接受&#8221;调试故障，否则拒绝之。在成功执行完一条指令后，处理机把RF置为0，当接受到一个非调试故障时，处理机就把它置为1。<br><br>4、虚拟8086方式标志VM(Virtual 8086 Mode)<br>如果该标志的值为1，则表示处理机处于虚拟的8086方式下的工作状态，否则，处理机处于一般保护方式下的工作状态
<img src ="http://www.cppblog.com/Husiwa/aggbug/136470.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2010-12-15 11:17 <a href="http://www.cppblog.com/Husiwa/archive/2010/12/15/136470.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>汇编指令集合 </title><link>http://www.cppblog.com/Husiwa/archive/2010/12/15/136467.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Wed, 15 Dec 2010 03:01:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2010/12/15/136467.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/136467.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2010/12/15/136467.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/136467.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/136467.html</trackback:ping><description><![CDATA[<strong><span>
<p></span></strong></p>
<p><strong><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>一、常用指令</span></strong><strong><span>&nbsp;
<p></span></strong></p>
<p><strong><span>1. </span></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>通用数据传送指令</span></em><span>.&nbsp;
<p></span></strong></p>
<p><span><span>&nbsp;&nbsp; </span><strong>MOV</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送字或字节</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>MOVSX</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>先符号扩展</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>再传送</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>MOVZX</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>先零扩展</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>再传送</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>PUSH</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把字压入堆栈</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>POP</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把字弹出堆栈</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>PUSHA</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>AX,CX,DX,BX,SP,BP,SI,DI</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>依次压入堆栈</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>POPA</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>DI,SI,BP,SP,BX,DX,CX,AX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>依次弹出堆栈</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>PUSHAD</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>依次压入堆栈</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>POPAD</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>依次弹出堆栈</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>BSWAP</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>交换</span><span>32</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>位寄存器里字节的顺序</span><span>&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>XCHG</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>交换字或字节</span><span>.( </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>至少有一个操作数为寄存器</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>段寄存器不可作为操作数</span><span>)&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>CMPXCHG</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>比较并交换操作数</span><span>.( </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>第二个操作数必须为累加器</span><span>AL/AX/EAX )&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>XADD</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>先交换再累加</span><span>.( </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>结果在第一个操作数里</span><span> )&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>XLAT</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字节查表转换</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>BX</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>指向一张</span><span> 256 </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字节的表的起点</span><span>, AL </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>为表的索引值</span><span> (0-255,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>即</span><span> 0-FFH); </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>返回</span><span> AL </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>为查表结果</span><span>. ( [BX+AL]-&gt;
<place w:st="on"><state w:st="on">AL</state></place>
)&nbsp;</span></p>
<p><strong><span>2. </span></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>输入输出端口传送指令</span></em><span>.&nbsp;
<p></span></strong></p>
<p><span><span>&nbsp;&nbsp; </span><strong>IN</strong> I/O</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>端口输入</span><span>. ( </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>语法</span><span>: IN </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>累加器</span><span>, {</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>端口号│</span><span>DX} )&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>OUT</strong> I/O</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>端口输出</span><span>. ( </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>语法</span><span>: OUT {</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>端口号│</span><span>DX},</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>累加器</span><span> )&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>输入输出端口由立即方式指定时</span><span>, </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>其范围是</span><span> 0-255; </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>由寄存器</span><span> DX </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>指定时</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>其范围是</span><span> 0-65535.&nbsp;</span></p>
<p><strong><span>3. </span></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>目的地址传送指令</span></em><span>.&nbsp;
<p></span></strong></p>
<p><span><span>&nbsp;&nbsp; </span><strong>LEA</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>装入有效地址</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>例</span><span>: LEA DX,string ;</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把偏移地址存到</span><span>DX.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>LDS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送目标指针</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把指针内容装入</span><span>DS.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>例</span><span>: LDS SI,string ;</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把段地址</span><span>:</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>偏移地址存到</span><span>DS:SI.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>LES</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送目标指针</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把指针内容装入</span><span>ES.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>例</span><span>: LES DI,string ;</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把段地址</span><span>:</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>偏移地址存到</span><span>ESDI.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>LFS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送目标指针</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把指针内容装入</span><span>FS.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>例</span><span>: LFS DI,string ;</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把段地址</span><span>:</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>偏移地址存到</span><span>FSD.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>LGS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送目标指针</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把指针内容装入</span><span>GS.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>例</span><span>: LGS DI,string ;</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把段地址</span><span>:</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>偏移地址存到</span><span>GSDI.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>LSS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送目标指针</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把指针内容装入</span><span>SS.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>例</span><span>: LSS DI,string ;</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把段地址</span><span>:</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>偏移地址存到</span><span>SSDI.&nbsp;</span></p>
<p><strong><span>4. </span></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>标志传送指令</span></em><span>.&nbsp;
<p></span></strong></p>
<p><span><span>&nbsp;&nbsp; </span><strong>LAHF</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>标志寄存器传送</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把标志装入</span><span>AH.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>SAHF</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>标志寄存器传送</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>AH</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>内容装入标志寄存器</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>PUSHF</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>标志入栈</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>POPF</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>标志出栈</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>PUSHD</strong> 32</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>位标志入栈</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>POPD</strong> 32</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>位标志出栈</span><span>.&nbsp;</span></p>
<p><strong><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>二、算术运算指令</span></strong><strong><span>&nbsp;
<p></span></strong></p>
<p><span><span>&nbsp;&nbsp; </span><strong>ADD</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>加法</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>ADC</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>带进位加法</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>INC</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>加</span><span> 1.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>AAA</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>加法的</span><span>ASCII</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>码调整</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>DAA</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>加法的十进制调整</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>SUB</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>减法</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>SBB</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>带借位减法</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>DEC</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>减</span><span> 1.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>NEC</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>求反</span><span>(</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>以</span><span> 0 </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>减之</span><span>).&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>CMP</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>比较</span><span>.(</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>两操作数作减法</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>仅修改标志位</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>不回送结果</span><span>).&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>AAS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>减法的</span><span>ASCII</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>码调整</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>DAS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>减法的十进制调整</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>MUL</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>无符号乘法</span><span>.&nbsp;</span></p>
<p><span>&nbsp;&nbsp;<strong>IMUL</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>整数乘法</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>以上两条</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>结果回送</span><span>AH</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>和</span><span>AL(</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字节运算</span><span>),</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>或</span><span>DX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>和</span><span>AX(</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字运算</span><span>),&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>AAM</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>乘法的</span><span>ASCII</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>码调整</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>DIV</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>无符号除法</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>IDIV</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>整数除法</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>以上两条</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>结果回送</span><span>:&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>商回送</span><span>AL,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>余数回送</span><span>AH, (</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字节运算</span><span>);&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>或</span> <span Times Roman?; mso-hansi-font-family: ?Times New Roman??>商回送</span><span>AX,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>余数回送</span><span>DX, (</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字运算</span><span>).&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>AAD</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>除法的</span><span>ASCII</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>码调整</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>CBW</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字节转换为字</span><span>. (</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>AL</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中字节的符号扩展到</span><span>AH</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中去</span><span>)&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>CWD</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字转换为双字</span><span>. (</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>AX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中的字的符号扩展到</span><span>DX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中去</span><span>)&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>CWDE</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字转换为双字</span><span>. (</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>AX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中的字符号扩展到</span><span>EAX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中去</span><span>)&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>CDQ</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>双字扩展</span><span>. (</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>EAX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中的字的符号扩展到</span><span>EDX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中去</span><span>)&nbsp;</span></p>
<p><strong><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>三、逻辑运算指令</span></strong><strong><span>&nbsp;
<p></span></strong></p>
<p><span><span>&nbsp;&nbsp; </span><strong>AND</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>与运算</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>OR</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>或运算</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>XOR</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>异或运算</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>NOT</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>取反</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>TEST</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>测试</span><span>.(</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>两操作数作与运算</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>仅修改标志位</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>不回送结果</span><span>).&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>SHL</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>逻辑左移</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>SAL</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>算术左移</span><span>.(=SHL)&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>SHR</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>逻辑右移</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>SAR</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>算术右移</span><span>.(=SHR)&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>ROL</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>循环左移</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>ROR</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>循环右移</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>RCL</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>通过进位的循环左移</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>RCR</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>通过进位的循环右移</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>以上八种移位指令</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>其移位次数可达</span><span>255</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>次</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>移位一次时</span><span>, </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>可直接用操作码</span><span>. </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>如</span><span> SHL AX,1.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>移位</span><span>&gt;1</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>次时</span><span>, </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>则由寄存器</span><span>CL</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>给出移位次数</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>如</span><span> MOV CL,04&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SHL AX,CL&nbsp;</span></p>
<p><strong><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>四、串指令</span></strong><strong><span>&nbsp;
<p></span></strong></p>
<p><span><span>&nbsp;&nbsp; </span><strong>DS:SI</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>源串段寄存器</span><span> :</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>源串变址</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>ES</strong> I </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>目标串段寄存器</span><span>:</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>目标串变址</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>CX</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>重复次数计数器</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>AL/AX</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>扫描值</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span>D</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>标志</span><span> 0</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>表示重复操作中</span><span>SI</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>和</span><span>DI</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>应自动增量</span><span>; 1</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>表示应自动减量</span><span>.&nbsp;</span></p>
<p><span>Z</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>标志</span> <span Times Roman?; mso-hansi-font-family: ?Times New Roman??>用来控制扫描或比较操作的结束</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>MOVS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>串传送</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span>( MOVSB </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送字符</span><span>. MOVSW </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送字</span><span>. MOVSD </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送双字</span><span>. )&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>CMPS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>串比较</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span>( CMPSB </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>比较字符</span><span>. CMPSW </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>比较字</span><span>. )&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>SCAS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>串扫描</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把</span><span>AL</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>或</span><span>AX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>的内容与目标串作比较</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>比较结果反映在标志位</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>LODS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>装入串</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>把源串中的元素</span><span>(</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>字或字节</span><span>)</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>逐一装入</span><span>AL</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>或</span><span>AX</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span>( LODSB </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送字符</span><span>. LODSW </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送字</span><span>. LODSD </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>传送双字</span><span>. )&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>STOS</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>保存串</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>是</span><span>LODS</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>的逆过程</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>REP</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>当</span><span>CX/ECX&lt;&gt;0</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>时重复</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>REPE/REPZ</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>当</span><span>ZF=1</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>或比较结果相等</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>且</span><span>CX/ECX&lt;&gt;0</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>时重复</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>REPNE/REPNZ</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>当</span><span>ZF=0</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>或比较结果不相等</span><span>,</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>且</span><span>CX/ECX&lt;&gt;0</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>时重复</span><span>.&nbsp;</span></p>
<p><span>&nbsp;&nbsp;<strong>REPC</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>当</span><span>CF=1</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>且</span><span>CX/ECX&lt;&gt;0</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>时重复</span><span>.&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>REPNC</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>当</span><span>CF=0</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>且</span><span>CX/ECX&lt;&gt;0</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>时重复</span><span>.&nbsp;</span></p>
<p><strong><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>五、程序转移指令</span></strong><strong><span>&nbsp;
<p></span></strong></p>
<p><strong><em><span>1&gt;</span></em></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>无条件转移指令</span><span> (</span></em></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>长转移</span><span>)&nbsp;
<p></span></em></strong></p>
<p><span><span>&nbsp;&nbsp; </span><strong>JMP</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>无条件转移指令</span><span>&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>CALL</strong> </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>过程调用</span><span>&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>RET/RETF</strong></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>过程返回</span><span>.&nbsp;</span></p>
<p><strong><em><span>2&gt;</span></em></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>条件转移指令</span><span> (</span></em></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>短转移</span><span>,-128</span></em></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>到</span><span>+127</span></em></strong><strong><em><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>的距离内</span><span>)&nbsp;
<p></span></em></strong></p>
<p><span><span>&nbsp;&nbsp; </span>( </span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>当且仅当</span><span>(SF XOR OF)=1</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>时</span><span>,OP1&lt;OP2 )&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp; </span><strong>JA/JNBE</strong> &lt;</span></p>
<img src ="http://www.cppblog.com/Husiwa/aggbug/136467.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2010-12-15 11:01 <a href="http://www.cppblog.com/Husiwa/archive/2010/12/15/136467.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模板类静态变量初始化</title><link>http://www.cppblog.com/Husiwa/archive/2010/11/26/134698.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Fri, 26 Nov 2010 01:30:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2010/11/26/134698.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/134698.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2010/11/26/134698.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/134698.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/134698.html</trackback:ping><description><![CDATA[看如下代码：<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"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;I</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Test<br><img id=Codehighlighter1_28_163_Open_Image onclick="this.style.display='none'; Codehighlighter1_28_163_Open_Text.style.display='none'; Codehighlighter1_28_163_Closed_Image.style.display='inline'; Codehighlighter1_28_163_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_28_163_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_28_163_Closed_Text.style.display='none'; Codehighlighter1_28_163_Open_Image.style.display='inline'; Codehighlighter1_28_163_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_28_163_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_28_163_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;Obj<br><img id=Codehighlighter1_48_101_Open_Image onclick="this.style.display='none'; Codehighlighter1_48_101_Open_Text.style.display='none'; Codehighlighter1_48_101_Closed_Image.style.display='inline'; Codehighlighter1_48_101_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_48_101_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_48_101_Closed_Text.style.display='none'; Codehighlighter1_48_101_Open_Image.style.display='inline'; Codehighlighter1_48_101_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_48_101_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_48_101_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;Obj&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">next;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;data[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">;<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>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;Obj</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;freeList[</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;ms_singleton;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;</span></div>
<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"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Class&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;Test</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::ms_singleton</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;</span></div>
<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"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_63_65_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_65_Open_Text.style.display='none'; Codehighlighter1_63_65_Closed_Image.style.display='inline'; Codehighlighter1_63_65_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_63_65_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_65_Closed_Text.style.display='none'; Codehighlighter1_63_65_Open_Image.style.display='inline'; Codehighlighter1_63_65_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>typename&nbsp;Test</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::Obj</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;Test</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::freeList[</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=</span><span id=Codehighlighter1_63_65_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_63_65_Open_Text><span style="COLOR: #000000">{</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">;</span></div>
<br>用typename关键字来告诉编译器Obj是个类型。 
<img src ="http://www.cppblog.com/Husiwa/aggbug/134698.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2010-11-26 09:30 <a href="http://www.cppblog.com/Husiwa/archive/2010/11/26/134698.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#与C++的几个对应的变量</title><link>http://www.cppblog.com/Husiwa/archive/2010/11/24/134467.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Wed, 24 Nov 2010 01:38:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2010/11/24/134467.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/134467.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2010/11/24/134467.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/134467.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/134467.html</trackback:ping><description><![CDATA[1.c++ unsigned char <br>C#中的char是16bits的Unicode字符，而一般C++中的字符则是8位的，所以C++中的&#8220;unsigned &nbsp; char&#8221;在C#中要么转换成char,要么使用Byte类型来代替，前者适用于存放字符型的unsigned &nbsp; char，后者适用于整数型的unsigned &nbsp; char。<br>2.<br>unsigned int&nbsp;&nbsp;&nbsp; == nint32<br>unsigned short== nint16<br>
<img src ="http://www.cppblog.com/Husiwa/aggbug/134467.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2010-11-24 09:38 <a href="http://www.cppblog.com/Husiwa/archive/2010/11/24/134467.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zip、rar文件格式</title><link>http://www.cppblog.com/Husiwa/archive/2010/11/16/133759.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Tue, 16 Nov 2010 01:38:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2010/11/16/133759.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/133759.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2010/11/16/133759.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/133759.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/133759.html</trackback:ping><description><![CDATA[原文地址：<a href="http://www.comicer.com/stronghorse/water/software/ZipRar.htm">http://www.comicer.com/stronghorse/water/software/ZipRar.htm</a><br><br><br><br>
<p><font color=#ff0000><a name=目录表（TOC）与分卷（Volume）>一、目录表（TOC）与分卷（Volume）</a></font></p>
<p>抛开压缩算法不谈，我认为zip、rar在文件格式上最大的差异就在目录表（Table of Contents，TOC）：zip有TOC，而rar没有。</p>
<p>TOC这个词其实是从出版界借用过来的，指的就是每一本书正文前面的&#8220;目录&#8221;，它的作用地球人都知道：如果想快速找到书中某一内容，可以先查TOC，然后按照TOC指明的页码直接翻即可。</p>
<p>在纸质书里TOC是印刷出来的一张表，而在电子文件里则是由结构化数据构成的一张表，它的目的同样是为了快速定位：如果想找文件中的某一内容，可以先查TOC，知道感兴趣的内容在文件的什么位置，直接跳过去就行了。最常见的运用就是avi、rm等多媒体文件：播放的时候经常有人在播放条上点来点去跳着看（即&#8220;随机访问&#8221;），如果没有TOC，在长达几百兆的文件里来回定位会慢死。</p>
<p>具体到zip文件里，TOC是放在文件尾部的一张表，里面列出了zip包中每一个文件的属性（文件名、长度等）和在zip包中的存放位置。如果需要随机访问zip包中的某一个文件，只需在TOC里找到这个文件的存放位置，直接跳过去即可。</p>
<p>而RAR文件里则没有TOC，在文件头之后所有文件按顺序连续存放。</p>
<p>这种差异造成的结果就是：随机访问时zip比rar快，而顺序访问时rar比zip快。</p>
<p>所谓随机访问，就是前面说过的随机访问压缩包中某个指定的文件。举一个简单的例子：一本反编译或下载到的网页电子书，有大量HTML、图像、css、js，然后打成压缩包。现在要求在不解包的情况下访问其中的页面：可以想象，打开每个HTML页面的时候，它所附带的图像、css、js等文件可能随机分布在整个压缩包里，如果没有TOC，查找每个文件的时候都要从头开始找，将会有多慢。 所以各位可以理解为什么jar包就是标准zip包，而我也只用zip格式保存反编译出来的电子书、漫画、PDG书等一切可能需要随机访问的东西。</p>
<p>所谓顺序访问，就是将整个压缩包从头解到尾。在这方面RAR具有天然的优势。而且为了节省WinRAR列文件的时间，对于单个RAR我一般都直接通过右键菜单解压缩，很少双击压缩包打开再解压。解多个RAR时当然都用BatchUnRar。</p>
<p>由于rar的原作者已经去世，造成这种差异的确切原因我相信已不可考，但我个人猜测可能与DOS时代的备份软件之争有关：在DOS时代，电脑硬盘不像现在这样奢侈，20MB就算很大了。这样的容量用两盒软盘 即可备份，备份成本相对数据本身的价值来说非常低廉。因此在DOS时代，很多公司和机构都制定有定期硬盘备份政策，以免因为人为或非人为的因素 （早期硬盘可没有如今可靠）而造成不可挽回的数据损失。在备份软件方面，虽然微软已经随DOS提供了Backup/Restore工具，但是他们基本不具备数据压缩能力，因此在压缩软件中提供备份功能，就成为DOS时代的一个时尚。由于DOS时代的备份介质多为软盘，因此压缩 软件的备份功能其实就转化成如今很常见的一个功能：分卷压缩功能，即按照软盘容量进行分卷压缩，然后将分卷压缩文件备份（Backup）到软盘，需要的时候再解压，或恢复（Restore）到硬盘。</p>
<p>DOS时代最有名的zip工具是pkzip，出现得比DOS版的RAR早。在分卷压缩时，pkzip按照zip文件规范，将TOC存放在最后，即存储在最后一卷，由此带来如下问题：</p>
<p>1、恢复时，每解压一张盘，都要先将最后一张盘插进去一次，读一次TOC。<br>2、只要最后一张盘上的TOC坏了，就算其它盘都是好的，也不能正常解压。</p>
<p>这两个缺点，尤其是第一个缺点实在是太臭名昭著了，因此当时出现了非常强烈的改革呼声。在这个关键时刻，DOS版的RAR出现了：不仅压缩率比pkzip高（这点在DOS时代非常重要，毕竟软盘又贵容量又小），而且由于吸取了当时对zip格式的批评，取消了TOC，因此：</p>
<p>1、在恢复分卷压缩的备份文件时，不需要频繁插入带有TOC的分卷，按顺序换盘即可。<br>2、即使某个分卷损坏，也可以跳过，从完好的分卷再开始解压。</p>
<p>由于这些原因（当然还有其它原因），RAR推出后迅速取得了成功，pkzip在DOS时代就开始流失用户，到Windows时代基本消声匿迹。在Windows时代推出的Winzip，则彻底放弃了分卷压缩功能（zip格式永远的痛？）。 而从我看到的源自WinRAR的<a href="http://www.rarlab.com/" target=_blank><u><font color=#0000ff>UnRAR源代码</font></u></a>来看，现在WinRAR的解压思路明显还是把文件按顺序从头解到尾，看来当年备份/恢复工具之争的影响，还真是深远。</p>
<p><font color=#ff0000><a name=固实（solid）压缩方式>二、固实（solid）压缩方式</a></font></p>
<p>在压缩算法方面，我觉得rar格式最特色的是固实（solid）压缩方式。WinRAR v3.42的帮助文件中对固实压缩的说明如下：<br><br><strong>固实压缩文件是 RAR 的一种特殊压缩方式存储的压缩文件，它把压缩文件中的全部文件都当成一个连续数据流来看待。</strong><br><br>这段说明其实揭示了固实压缩格式能够提高压缩比的奥秘：数据压缩的基础是&#8220;重复&#8221;，例如aaaabbb这个字符串，里面就有重复，如果表示为a4b3，看起来是不是变短了？这就是&#8220;数据压缩&#8221;。&#8220;重复&#8221;是一个具有相对意义的概念，在某一范围内看起来没有重复，或重复不多的数据，把范围扩大，说不定就能找到更多重复的数据了，这就是固实压缩的奥秘。</p>
<p>举一个简单的例子：用zip和普通rar压缩一堆jpg文件，很难压下去，但是用固实压缩方式的rar就可以，其原因就在于：jpg文件本身已经是压缩格式了，单个jpg文件里很难再 找到可利用的重复数据，因此不论是用zip还是普通的rar都很难再压缩，因为他们都将需要压缩的文件分隔开来一个一个处理。但是对于固实rar来说，是将 所有需要压缩的jpg文件当作一个整体来压缩，这些jpg之间就存在重复的数据，如他们都有相同的文件头（其中包括各种数据表）等，这就出现了可压缩的空间。从我看到的资料来看，Flash文件也采用了类似的技术对jpg进行压缩：如果在Flash文件中使用了多个jpg文件，它们可以共用一个文件头。<br><br>当然天下不会有白吃的午餐，固实压缩方式在提高压缩比的同时，也有一些限制，在WinRAR v3.42帮助文件中的说法是：</p>
<p><strong>固实压缩可增加压缩性能，特别是在添加大量的小文件的时候，但它也有一些重要的不利因素:</strong></p>
<ul>
    <li><strong>对已存在的固实压缩文件更新时较慢；</strong>
    <li><strong>要从固实的压缩文件解压单个文件时，它之前的文件都需先经过分析。这造成当从固实的压缩文件内取出文件时会比一般压缩文件取出文件慢一些。但是，当从固实的压缩文件解压全部的文件时，解压速度并没有影响。</strong>
    <li><strong>如果在固实压缩文件中的任何文件损坏了，要从损坏的范围中解压全部的文件是不可能的。因此，如果固实压缩文件是保存在例如软盘等媒介时，推荐你在制作时使用&#8220;恢复记录&#8221;。</strong> </li>
</ul>
<p><strong>固实压缩的适用场合为:</strong></p>
<ul>
    <li><strong>压缩文件很少更新的时候;</strong>
    <li><strong>不需要经常从压缩文件中解压一个文件或是部分文件的时候;</strong>
    <li><strong>压缩效率比压缩速度更为重要的时候。</strong> </li>
</ul>
<p>与前面说的&#8220;随机访问&#8221;对应，固实压缩的RAR文件可能是世界上最不适合随机访问的：如果需要访问固实RAR包中的某个文件，就要从文件头开始解压，一直解到这个文件。</p>
<p><font color=#ff0000><a name=安全性>三、安全性</a></font></p>
<p>这里的安全性包含几个方面的含义：文件系统安全性、密码保护安全性和文件数据安全性。</p>
<p>由于制订zip格式规范的时候操作系统本身的文件安全性还没有引起足够的重视，因此zip格式只记录最基本的文件属性，包括只读属性等，没有其它附加的安全属性。</p>
<p>rar格式刚推出的时候，文件系统的安全性只能参照DOS，和zip差不多。但是rar毕竟是一种封闭的格式，想怎么改作者一个人说了就算，因此当Windows中出现NTFS，并且引入扩展的文件系统安全属性时，rar也积极跟进，所以现在应该说rar格式在这方面比zip强 。</p>
<p>在zip和rar格式中均提供了密码保护功能，但是密码保护的安全强度不同。</p>
<p>zip由于格式开放、代码开源，因此zip密码破解软件出现得比较早，也比较多。初期以暴力破解为主，威胁不大，真正对zip密码安全的致命一击是known plain text（已知明文）攻击法：如果知道加密zip文件中某段内容（密文，ciphertext）解密后的真正内容（明文，plain text），就可以反推出zip加密口令。在这种攻击方法的威胁，及某些国家的法律对密码技术的限制下， 著名开源组织<a href="http://www.zlib.net/" target=_blank><u><font color=#800080>zlib</font></u></a>宣布永久放弃对加密zip的支持，详见<a href="http://www.zlib.net/" target=_blank><u><font color=#800080>zlib</font></u></a>网站上的相关说明（不过在<a href="http://www.zlib.net/" target=_blank><u><font color=#800080>zlib</font></u></a>发行的源代码里仔细找找，还是能找到原来的加/解密相关代码）。</p>
<p>记得rar刚推出的时候也和zip一样，虽然不能列出加密文件中的文件内容，但可以列出加密文件中的文件名。后来大概也是被known plain text攻击法吓到了，增加了一个&#8220;加密文件名&#8221;选项，干脆连加密rar文件里有哪些文件都看不见，让攻击者想猜明文都无从猜起。</p>
<p>rar格式比zip晚推出，在安全方面吸取了足够的教训，因此采用的是美国国家标准与技术局（National Institute of Standard and Technology, NIST）推荐的、目前公认安全程度比较高的AES对称加密算法 ，密钥长度128位。在ASE被攻破以前（NIST认为30年内无法攻破），大家都只能在暴力法上兜圈子，所以密码安全性应该说比zip高。对此WinRAR 3.42的帮助文件是这样描述的：</p>
<p><strong>ZIP 格式使用私有加密算法。 RAR 压缩文件使用更强大的 AES-128 标准加密。如果你需要加密重要的信息，选择 RAR 压缩文件格式会比较好一些。为了确实的安全性，密码长度请最少要 8 个字符。不要使用任何语言的单词作为密码，最好是任意的随机组合字符和数字，并且要注意密码的大小写。请记住，如果你遗失你的密码，你将无法取出加密的文件，就算是 WinRAR 的作者本身也无法解压加密过的文件。</strong></p>
<p>在数据安全性方面，RAR格式本身支持一种特殊的附加信息类型，叫做&#8220;恢复记录&#8221;。如果RAR文件有恢复记录，在介质物理损坏或其它原因造成数据丢失时，WinRAR可以按照&#8220;恢复记录&#8221;尝试对数据进行修复。而zip格式无恢复记录，因此在数据安全性方面应该说比RAR弱。</p>
<p>虽然RAR文件本身支持恢复记录，但是在WinRAR里此选项缺省是关闭的，而打开后会导致压缩出来的RAR文件体积增加（增加的百分比与设置有关），可能会令某些人感到不习惯（我就亲眼见到有人在论坛上抱怨为什么压出来的RAR文件会如此庞大），所以这个功能基本上形同虚设。</p>
<p><font color=#ff0000><a name=开放性>四、开放性</a></font></p>
<p>开放性的对比很明显：zip格式不仅文件格式完全公开，而且有专门的开源组织提供操作源代码，跨平台使用也没有多大限制；rar格式完全保密，作者只提供解压所需源代码，不提供压缩所需源代码 ，跨平台使用有点麻烦。</p>
<p>zip开源组织中，最出名的是<a href="http://www.zlib.net/" target=_blank><u><font color=#800080>zlib</font></u></a>和<a href="http://www.info-zip.org/pub/infozip/" target=_blank><u><font color=#0000ff>InfoZip</font></u></a>，二者各有侧重：zlib偏重对内存缓冲区的压缩，因此被<a href="http://www.libpng.org/" target=_blank><u><font color=#0000ff>png</font></u></a>等开源组织用做内部压缩算法，连java的jar程序内核都来自zlib，打出来的jar包自然也是一个标准的zip文件；InfoZip偏重对文件的操作 （包括口令保护），应用似乎不如zlib广泛，但我个人觉得其实它还是满好用的，前提是需要对它的源代码进行一些必要的修改。</p>
<p>在<a href="http://www.libpng.org/" target=_blank><u><font color=#0000ff>png组织</font></u></a>的网页中有说到png格式的来历，我觉得也很有意思：做png的一班人，其实原来都是做gif格式的，但是由于Unisys公司开始对gif格式的核心——LZW压缩算法征收专利费，这帮人怒了，干脆提出png格式：大结构方面还是采用分段结构，但是核心压缩算法采用开源的zlib，压缩 效果在多数情况下比gif的LZW更强。由于没有版权限制，在静态图形领域png得到广泛应用，如果不是及时提出动画支持并因此在web上大行其道，我估计gif早就死掉了。</p>
<p>RAR的解压源代码在其官方网站<a href="http://www.rarlab.com/"><u><font color=#0000ff>www.rarlab.com</font></u></a>上提供，通常比WinRAR的正式版本晚一点，不过据说是直接从WinRAR的源代码中抠出来的，所以兼容性应该没有什么问题。</p>
<p><font color=#ff0000><a name=结论>五、结论</a></font></p>
<p>以下观点纯属个人观点，仅供参考，不具有如何指导意义：</p>
<ul>
    <li>如果经常需要对压缩包进行随机访问，应该选zip而不是rar。虽然将下载到的rar重新压缩成zip会麻烦一次，但是以后会减少无数的麻烦。
    <li>如果需要分卷压缩（如某些网站对上传文件大小有限制），则只能用rar。事实上，这也是我唯一会使用rar格式的场合，其它时候一律zip没商量。</li>
</ul>
<img src ="http://www.cppblog.com/Husiwa/aggbug/133759.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2010-11-16 09:38 <a href="http://www.cppblog.com/Husiwa/archive/2010/11/16/133759.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>getchar() 和EOF总结</title><link>http://www.cppblog.com/Husiwa/archive/2010/11/01/131998.html</link><dc:creator>IT菜鸟</dc:creator><author>IT菜鸟</author><pubDate>Mon, 01 Nov 2010 08:07:00 GMT</pubDate><guid>http://www.cppblog.com/Husiwa/archive/2010/11/01/131998.html</guid><wfw:comment>http://www.cppblog.com/Husiwa/comments/131998.html</wfw:comment><comments>http://www.cppblog.com/Husiwa/archive/2010/11/01/131998.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Husiwa/comments/commentRss/131998.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Husiwa/services/trackbacks/131998.html</trackback:ping><description><![CDATA[<p>一getchar()<br><br>1.<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"><span style="COLOR: #008080">1</span><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">c;<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img id=Codehighlighter1_38_56_Open_Image onclick="this.style.display='none'; Codehighlighter1_38_56_Open_Text.style.display='none'; Codehighlighter1_38_56_Closed_Image.style.display='inline'; Codehighlighter1_38_56_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_38_56_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_38_56_Closed_Text.style.display='none'; Codehighlighter1_38_56_Open_Image.style.display='inline'; Codehighlighter1_38_56_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">((c&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;getchar())&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;EOF)</span><span id=Codehighlighter1_38_56_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_38_56_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;putchar(c);<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>输入值：abc后面跟个回车<br>本以为屏幕应该显示<br>a<br>a<br>b<br>b<br>c<br>c<br><br>实际上是:<br>abc<br>abc<br><br>这是因为只有当输入回车时，系统才认为是输入完毕<br><br>2.上面的代码还有一个问题<br>因为EOF是-1，所以c=getchar()这一句会出现问题<br>所以c应该是int c<br><br>二、EOF<br><br>只有在新的一行输入的时候输入EOF才算是文件结束符<br>假设输入：<br>abc^zqwer<br>输出为：<br>abc<br></p>
<img src ="http://www.cppblog.com/Husiwa/aggbug/131998.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Husiwa/" target="_blank">IT菜鸟</a> 2010-11-01 16:07 <a href="http://www.cppblog.com/Husiwa/archive/2010/11/01/131998.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>