??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲一区精品伊人久久伊人,欧美精品乱码99久久蜜桃,欧美日韩中文字幕久久久不卡http://www.shnenglu.com/Husiwa/category/15324.htmlzh-cnMon, 10 Oct 2011 08:14:47 GMTMon, 10 Oct 2011 08:14:47 GMT60EFFECTIVE-STL-1http://www.shnenglu.com/Husiwa/archive/2011/10/10/157956.htmlIT菜鸟IT菜鸟Mon, 10 Oct 2011 05:33:00 GMThttp://www.shnenglu.com/Husiwa/archive/2011/10/10/157956.htmlhttp://www.shnenglu.com/Husiwa/comments/157956.htmlhttp://www.shnenglu.com/Husiwa/archive/2011/10/10/157956.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/157956.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/157956.html*vector<char>可以作ؓstring的替代品
*vector list deque Qvector是一U可以默认用的序列cdQ当很频J的对序列中q行插入和删除的时候应该用listQ大部分发生在尾部的话用dequeq种数据l构
*q箋内存容器和基于节点的容器的区?br />q箋容器vector/string/deque在一个或者多个内存块中保存它们的元素Q如果新元素被插入或者已存元素被删除Q其他在同一个内存块中的元素必须向上或者向下移动来为新元素提供I间或者填充原来被删除的元素所占的I间Q这U移动媄响了效率?br />Z节点的listQ插入或者删除的时候不需要移?br />*序列容器在Q意位|插入一个新元素Q关联容器不可以
*容器中的数据的内存布局需要兼容C吗,如果是,那只能用vector
*查找速度Q散列容器》排序的vector>标准的关联容?br />*需要可靠的插入和删除的能力Q如果是需要用基于节点的容器
*需要P代器、指针、引用的实效ơ数减少到最,如果是,使用介于节点的容器,一般来_在连l容器上的插入和删除会所有指向容器的q代器指针和引用实效

IT菜鸟 2011-10-10 13:33 发表评论
]]>
DEBUG版本有错QRelease版本无错的原?/title><link>http://www.shnenglu.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.shnenglu.com/Husiwa/archive/2011/03/20/142286.html</guid><wfw:comment>http://www.shnenglu.com/Husiwa/comments/142286.html</wfw:comment><comments>http://www.shnenglu.com/Husiwa/archive/2011/03/20/142286.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Husiwa/comments/commentRss/142286.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Husiwa/services/trackbacks/142286.html</trackback:ping><description><![CDATA[ <a >http://blog.163.com/liuyuelin007@126/blog/static/213387692007411151568/</a><br><br><a >http://blog.csdn.net/lychee007/archive/2009/05/31/4227419.aspx</a><br><br><a >http://social.microsoft.com/Forums/es-ES/visualcpluszhchs/thread/ff6ddac2-a69d-4c02-ad20-d73cb4335c24</a><br><br><a >http://hi.baidu.com/237rxd/blog/item/35a51efa18e098859e5146b9.html</a><br><br><a >http://topic.csdn.net/t/20050712/20/4140158.html</a> <img src ="http://www.shnenglu.com/Husiwa/aggbug/142286.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-03-20 18:17 <a href="http://www.shnenglu.com/Husiwa/archive/2011/03/20/142286.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>memcpy memset strcpyhttp://www.shnenglu.com/Husiwa/archive/2011/03/15/141839.htmlIT菜鸟IT菜鸟Tue, 15 Mar 2011 00:06:00 GMThttp://www.shnenglu.com/Husiwa/archive/2011/03/15/141839.htmlhttp://www.shnenglu.com/Husiwa/comments/141839.htmlhttp://www.shnenglu.com/Husiwa/archive/2011/03/15/141839.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/141839.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/141839.html

Memset 用来对一D内存空间全部设|ؓ某个字符Q一般用在对定义的字W串q行初始化ؓ‘ ’?/span>‘\0’Q?br>

主要应用是初始化某个内存I间

?/span>:char a[100];memset(a, '\0', sizeof(a));

memset可以方便的清IZ个结构类型的变量或数l?/span>

如:

struct sample_struct
{
 char   csName[16];
 int    iSeq;
 int    iType;
};

对于变量
struct sample_strcut  stTest;

一般情况下Q清I?/span>stTest的方法:

stTest.csName[0]='\0';
stTest.iSeq=0;
stTest.iType=0;

?/span>memset非常方便:
memset(&stTest,0,sizeof(struct sample_struct));

如果是数l:

 struct sample_struct   TEST[10];
?/span>
memset(TEST,0,sizeof(struct sample_struct)*10);

memcpy 用来做内存拷贝,你可以拿它拷贝Q何数据类型的对象Q可以指定拷贝的数据长度?br>

memcpy是用?/span>copy源空间的数据到目的空间中
例:
char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a)Q会造成b的内存地址溢出?br>

Strcpy   只能拷贝字W串了,它遇?/span>'\0'q束拷贝?/span>

例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a)Q要注意a中的字符串长度(W一?/span>‘\0’之前Q是否超q?/span>50位,如超q,则会造成b的内存地址溢出?/span>


strcpy用于字符?/span>copy,遇到‘\0’Q将l束



IT菜鸟 2011-03-15 08:06 发表评论
]]>
又见单例http://www.shnenglu.com/Husiwa/archive/2011/03/09/141429.htmlIT菜鸟IT菜鸟Wed, 09 Mar 2011 08:18:00 GMThttp://www.shnenglu.com/Husiwa/archive/2011/03/09/141429.htmlhttp://www.shnenglu.com/Husiwa/comments/141429.htmlhttp://www.shnenglu.com/Husiwa/archive/2011/03/09/141429.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/141429.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/141429.html阅读全文

IT菜鸟 2011-03-09 16:18 发表评论
]]>
char* 转化为wchar* http://www.shnenglu.com/Husiwa/archive/2011/02/28/140779.htmlIT菜鸟IT菜鸟Mon, 28 Feb 2011 04:05:00 GMThttp://www.shnenglu.com/Husiwa/archive/2011/02/28/140779.htmlhttp://www.shnenglu.com/Husiwa/comments/140779.htmlhttp://www.shnenglu.com/Husiwa/archive/2011/02/28/140779.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/140779.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/140779.html
wchar_t* atow(char* src)
{
    
int dest_len;
    dest_len 
= MultiByteToWideChar(CP_ACP,0,src,-1,NULL,0);
    wchar_t 
*dest = new wchar_t[dest_len];
    
if(dest == NULL)
        
return NULL;
    MultiByteToWideChar(CP_ACP,
0,src,-1,dest,dest_len);
    
return dest;
}


IT菜鸟 2011-02-28 12:05 发表评论
]]>
匿名I间http://www.shnenglu.com/Husiwa/archive/2011/02/16/140143.htmlIT菜鸟IT菜鸟Wed, 16 Feb 2011 02:12:00 GMThttp://www.shnenglu.com/Husiwa/archive/2011/02/16/140143.htmlhttp://www.shnenglu.com/Husiwa/comments/140143.htmlhttp://www.shnenglu.com/Husiwa/archive/2011/02/16/140143.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/140143.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/140143.html当定义一个命名空间时Q可以忽略这个命名空间的名称Q?/span>

     namespce {
         char c;
         int i;
         double d;
     }
     ~译器在内部会ؓq个命名I间生成一个唯一的名字,而且q会个匿名的命名I间生成一条using指o。所以上面的代码在效果上{同于:
     namespace __UNIQUE_NAME_ {
         char c;
         int i;
         double d;
     }
     using namespace __UNIQUE_NAME_;
 
     在匿名命名空间中声明的名UC被~译器{换,与编译器个匿名命名空间生成的唯一内部名称(卌里的__UNIQUE_NAME_)l定在一赗还有一点很重要Q就是这些名U具有internal链接属性,q和声明为static的全局名称的链接属性是相同的,卛_U的作用域被限制在当前文件中Q无法通过在另外的文g中用extern声明来进行链接。如果不提倡用全局static声明一个名U拥有internal链接属性,则匿名命名空间可以作ZU更好的辑ֈ相同效果的方法?/span>
注意:命名I间都是hexternal q接属性的,只是匿名的命名空间生的__UNIQUE_NAME__在别的文件中无法得到,q个唯一的名字是不可见的.
C++ 新的标准中提倡用匿名命名空?而不推荐使用static,因ؓstatic用在不同的地?涵义不同,Ҏ造成h.另外,static不能修饰class


IT菜鸟 2011-02-16 10:12 发表评论
]]>
Z么拷贝构造函数必Mؓ引用传递,不能是g递?http://www.shnenglu.com/Husiwa/archive/2011/02/14/140053.htmlIT菜鸟IT菜鸟Mon, 14 Feb 2011 09:50:00 GMThttp://www.shnenglu.com/Husiwa/archive/2011/02/14/140053.htmlhttp://www.shnenglu.com/Husiwa/comments/140053.htmlhttp://www.shnenglu.com/Husiwa/archive/2011/02/14/140053.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/140053.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/140053.html
对于拯构造函数引用传递,g司空见惯Q认为理所当然。但是被问vq个问题Q的是一片茫ӞZ么呢Q?br>
ȝ上搜索了一下,的确有很多这斚w的知识讲解?br>
我们先看一下CSDN上的一个帖子的回答Q?br>单的回答是ؓ了防止递归引用?br>具体一些可以这么讲Q?br> 当一个对象需要以值方式传递时Q编译器会生成代码调用它的拷贝构造函C生成一个复本。如果类A的拷贝构造函数是以值方式传递一个类A对象作ؓ参数的话Q当需要调用类A的拷贝构造函数时Q需要以值方式传q一个A的对象作为实参; 而以值方式传递需要调用类A的拷贝构造函敎ͼl果是调用cA的拷贝构造函数导致又一ơ调用类A的拷贝构造函敎ͼq就是一个无限递归?br>
q个解释q是蛮具体的?br>利用g递的话,会导致递归引用?br>
q有一片文章也谈到了这个问题, 我觉得写得也非常好!

Z么拷贝构造函数必Mؓ引用传递,不能是g递?
链接地址Q?a >http://www.cnblogs.com/chio/archive/2007/09/14/893299.html

其中讲到?个问?br>1是拷贝构造函数的作用?br>      作用是用来复制对象的,在用这个对象的实例来初始化q个对象的一个新的实例?br>2是参C递过E到底发生了什么?
      地址传递和g递统一hQ归根结底还是传递的??(地址也是|只不q通过它可以找到另一个?Q?br>i)g?
    对于内置数据cd的传递时Q直接赋值拷贝给形参(注意形参是函数内局部变?Q?br>    对于cȝ型的传递时Q需要首先调用该cȝ拯构造函数来初始化Ş?局部对?Q如void foo(class_type obj_local){}, 如果调用foo(obj);  首先class_type obj_local(obj) ,q样定义了局部变量obj_local供函数内部?br>ii)引用传?
    无论对内|类型还是类cdQ传递引用或指针最l都是传递的地址|而地址L指针cd(属于单类?, 昄参数传递时Q按单类型的赋值拷贝,而不会有拯构造函数的调用(对于cȝ?.
3是在cM有指针数据成员时Q拷贝构造函数的使用Q?br>        如果不显式声明拷贝构造函数的时候,~译器也会生成一个默认的拯构造函敎ͼ而且在一般的情况下运行的也很好。但是在遇到cL指针数据成员时就出现问题了:因ؓ默认的拷贝构造函数是按成员拷贝构造,q导致了两个不同的指?如ptr1=ptr2)指向了相同的内存。当一个实例销毁时Q调用析构函数free(ptr1)释放了这D内存,那么剩下的一个实例的指针ptr2无效了Q在被销毁的时候free(ptr2)׃出现错误? q相当于重复释放一块内存两ơ。这U情况必L式声明ƈ实现自己的拷贝构造函敎ͼ来ؓ新的实例的指针分配新的内存?br>
问题1?回答了ؓ什么拷贝构造函C用g递会产生无限递归调用的问题;
问题3回答了回{了在类中有指针数据成员Ӟ拯构造函C用g递等于白昑ּ定义了拷贝构造函敎ͼ因ؓ默认的拷贝构造函数就是这么干?

IT菜鸟 2011-02-14 17:50 发表评论
]]>
z的字符串连接函?/title><link>http://www.shnenglu.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.shnenglu.com/Husiwa/archive/2011/02/14/140036.html</guid><wfw:comment>http://www.shnenglu.com/Husiwa/comments/140036.html</wfw:comment><comments>http://www.shnenglu.com/Husiwa/archive/2011/02/14/140036.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/Husiwa/comments/commentRss/140036.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Husiwa/services/trackbacks/140036.html</trackback:ping><description><![CDATA[看到一个简z的字符串连接函敎ͼ颇有启发?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.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> constr(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> f,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> 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.shnenglu.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.shnenglu.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.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_29_90_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </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.shnenglu.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.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </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.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_46_56_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        f</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </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.shnenglu.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.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </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.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_82_86_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> 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.shnenglu.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.shnenglu.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.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_103_200_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> 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.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> 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.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    constr(f,s);<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    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.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    getchar();<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div> <img src ="http://www.shnenglu.com/Husiwa/aggbug/140036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Husiwa/" target="_blank">IT菜鸟</a> 2011-02-14 15:24 <a href="http://www.shnenglu.com/Husiwa/archive/2011/02/14/140036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>预编译头文ghttp://www.shnenglu.com/Husiwa/archive/2011/02/10/139854.htmlIT菜鸟IT菜鸟Thu, 10 Feb 2011 02:12:00 GMThttp://www.shnenglu.com/Husiwa/archive/2011/02/10/139854.htmlhttp://www.shnenglu.com/Husiwa/comments/139854.htmlhttp://www.shnenglu.com/Husiwa/archive/2011/02/10/139854.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/139854.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/139854.html VC++的预~译功能
TAG:预编译和宏定?VC++,VC++的预~译功能
TEXT:
q里介绍VC6的预~译功能的用,׃预编译详l用比较的复杂Q这里只介绍几个最重要的预~译指o: /Yu, /Yc,/Yx,/Fp。其它的详细资料可以参考: MSDN -> Visual Studio 6.0 Document -> Visual C++ 6.0 Document -> VC++ Programmer Guider - >Compiler and Linker -> Details -> Creating Precompiled Header files
   预编译头的概念:
   所谓的预编译头是把一个工E中的那一部分代码Q预先编译好攑֜一个文仉Q通常是以.pch为扩展名的)Q这个文件就UCؓ预编译头文gq些预先~译好的代码可以是Q何的C/C++代码Q甚xinline的函敎ͼ但是必须是稳定的Q在工程开发的q程中不会被l常改变。如果这些代码被修改Q则需要重新编译生成预~译头文件。注意生成预~译头文件是很耗时间的。同时你得注意预~译头文仉常很大Q通常?- 7M大。注意及时清理那些没有用的预~译头文件?/span>
   也许你会问:现在的编译器都有Time stamp的功能,~译器在~译整个工程的时候,它只会编译那些经q修改的文gQ而不会去~译那些从上ơ编译过Q到现在没有被修改过的文件。那么ؓ什么还要预~译头文件呢Q答案在q里Q我们知道编译器是以文g为单位编译的Q一个文件经q修改后Q会重新~译整个文gQ当然在q个文g里包含的所有头文g中的东西Q?eg Macro, Preprocessor Q都要重新处理一遍? VC的预~译头文件保存的正是q部分信息。以避免每次都要重新处理q些头文件?/span>
   Ҏ上文介绍Q预~译头文件的作用当然是提高便宜速度了,有了它你没有必要每次都编译那些不需要经常改变的代码。编译性能当然提高了?/span>
   要用预~译_我们必须指定一个头文gQ这个头文g包含我们不会l常改变的代码和其他的头文gQ然后我们用q个头文件来生成一个预~译头文Ӟ.pch文gQ想必大安知道 StdAfx.hq个文g。很多h都认是VC提供的一?#8220;pȝU别”的,~译器带的一个头文g。其实不是的Q这个文件可以是M名字的。我们来考察一个典型的由AppWizard生成的MFC Dialog Based E序的预~译头文件。(因ؓAppWizard会ؓ我们指定好如何用预~译头文Ӟ默认的是StdAfx.hQ这是VCL名字Q。我们会发现q个头文仉包含了以下的头文Ӟ
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#include <afxcmn.h>
   q些正是使用MFC的必d含的头文Ӟ当然我们不太可能在我们的工程中修改这些头文g的,所以说他们是稳定的?/span>
   那么我们如何指定它来生成预编译头文g。我们知道一个头文g是不能编译的。所以我们还需要一个cpp文g来生?pch 文g。这个文仉认的是StdAfx.cpp。在q个文g里只有一句代码就是:#include“Stdafx.h”。原因是理所当然的,我们仅仅是要它能够编译而已―――也是_要的只是它的.cpp的扩展名。我们可以用/Yc~译开x指定StdAfx.cpp来生成一?pch文gQ通过/Fp~译开x指定生成的pch文g的名字。打开project - >Setting->C/C++ 对话框。把Category指向Precompiled Header。在左边的树形视N选择整个工程QProject Options(右下角的那个白的地方)可以看到 /Fp “debug/PCH.pch”Q这是指定生成?pch文g的名字,默认的通常是 <工程?gt;.pch。然后,在左边的树Ş视图里选择StdAfx.cppQ这时原来的Project Option变成?Source File OptionQ原来是工程Q现在是一个文Ӟ当然变了Q。在q里我们可以看到 /Yc开养I/Yc的作用就是指定这个文件来创徏一个Pch文g?Yc后面的文件名是那个包含了E_代码的头文gQ一个工E里只能有一个文件的可以有YC开兟뀂VC根据这个选项? StdAfx.cpp~译成一个Obj文g和一个PCH文g?/span>
q样Q我们就讄好了预编译头文g。也是_我们可以使用预编译头功能了。以下是注意事项Q?/span>
   1Q如果用了/YuQ就是说使用了预~译Q我们在每个.cpp文g的最开_包含你指定生pch文g?h文gQ默认是stdafx.hQ不然就会有问题。如果你没有包含q个文gQ就告诉你Unexpected file end.
   2Q如果你把pch文g不小心丢了,Ҏ以上的分析,你只要让~译器生成一个pch文g可以了。也是说把 stdafx.cppQ即指定/Yc的那个cpp文gQ重新编译一遍就可以了?/span>


IT菜鸟 2011-02-10 10:12 发表评论
]]>
DLL动态链接库和LIB静态链接库http://www.shnenglu.com/Husiwa/archive/2011/01/17/138652.htmlIT菜鸟IT菜鸟Mon, 17 Jan 2011 03:55:00 GMThttp://www.shnenglu.com/Husiwa/archive/2011/01/17/138652.htmlhttp://www.shnenglu.com/Husiwa/comments/138652.htmlhttp://www.shnenglu.com/Husiwa/archive/2011/01/17/138652.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/138652.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/138652.html

1Q神马是Dll和LibQ神马是静态链接和动态链?/p>

大家都懂的,DLL是动态链接库QLIB是静态链接库。DLL其实是EXEQ只不过没main?/p>

动态链接是相对于静态链接而言的。所谓静态链接就是把函数或过E直接链接到可执行文件中Q成为可执行E序中的一部分Q当多个E序调用同样的函数时Q内存里׃有这个函数的多个拯Q浪费内存资源。而动态链接则是提供了一个函数的描述信息l可执行文gQƈ没有内存拯Q,当程序被夹在到内存里开始运行的时候,pȝ会在底层创徏DLL和应用程序之间的q接关系Q当执行期间需要调用DLL函数Ӟpȝ才会真正Ҏ链接的定位信息去执行DLL中的函数代码?/p>

在WINDOWS32pȝ底下Q每个进E有自己?2位的U性地址I间Q若一个DLL被进E用,则该DLL首先会被调入WIN32pȝ的全局堆栈Q然后通过内存映射文g方式映射到这个DLL的进E地址I间。若一个DLL被多个进E调用,则每个进E都会接收到该DLL的一个映像,而非多䆾的拷贝。但Q在WIN16pȝ下,每个q程需要拥有自q一份DLLI间Q可以理解ؓ何静态链接没啥区别?/p>

 

2QDLL和LIB区别和联pR?/p>

DLL是程序在q行阶段才需要的文g?/p>

LIB是程序编译时需要链接的文g?/p>

DLL只有一U,其中一定是函数和过E的实现?/p>

LIB是有两种。若只生成LIB的话Q则q个LIB是静态编译出来的Q它内部包含了函数烦引以及实玎ͼq个LIB会比较大。若生成DLL的话Q则也会生成一个LIBQ这个LIB和刚才那个LIB不同Q它是只有函数烦引,没有实现的,它很。但是这俩LIB依然遵@上个原则Q是在编译时候是需要被链接的。若不链接第一个LIB的话Q在E序q行时会无法扑ֈ函数实现Q当掉。若不链接第二个LIB的话Q在E序q行时依然会无法扑ֈ函数实现。但W二ULIB有一U替代方式,是在程序里Q用LoadLibrary,GetProcAddress替代W二个LIB的功能。第一ULIB生成的EXE文g会很大,因ؓLIB所有信息被静态链接进EXE里了。第二种LIB生成的EXE文g会比较小Q因为函数过E实C旧在DLL内?/p>

Q啰嗦了一堆,某志希望大家能够明白两个LIB的区别。要再不行的话,我们可以静态编译的LIBUCؓ 静态链接库。但动态编译的LIBUCؓ 引入库。可能会比较好一些。)

静态链接LIB的优Ҏ免除挂接动态链接库Q缺ҎEXE大,版本控制ȝ些?/p>

动态链接DLL的优Ҏ文g,版本更换时换DLL好了,~点是多了点文g。动态链接若是被多个q程使用Q会更加方便和节省内存?/p>

 

3Qؓ什么编译DLL时M同时生成一个LIBQ这个LIB有用吗?

若我们不是用静态链接,而用DLLQ那么我们也需要一个LIBQ这个LIB的作用是被链接到E序里,在程序运行时告诉pȝ你需要什么DLL文g。这个LIB里保存的是DLL的名字和输出函数入口的顺序表。它是有意义的?/p>

当然Q若我们的应用程序里不链接这个LIBQ则可以使用LoadLibrary,GetProcAddress来告诉系l我们在q行旉要怎么着DLL以及其内的函数?/p>

 

4QDLL意义?/p>

1QDLL真正实现了跨语言。各U语a都可以生成DLLQ而对pȝ以及应用E序来说Q哪U语a生成的DLL是没有区别的?/p>

2QDLL有够的装性,对于版本更新有很大好处。因为DLL是运行期间才会用,所以,即DLL内函数实现有变化Q只要参数和q回g发生变化Q,E序是不需要进行编译的。大大提高了软g开发和l护的效率?/p>

3QDLL被多个进E用,因ؓ有内存映机Ӟ无需占用更多内存?/p>

 

5Q创建DLL。(注意Q某志就不再讲解使用MFC AppWizard[dll] 方式创徏DLL了。有兴趣的自己去癑ֺ。这里创建DLL只指使用Win32 Dynamic-link Library创徏Non-MFC DLL。呃QDLL的三U类型就不解释了Q依旧那句话Q百度一下你q道。)

每个应用E序必须有一个main或者winmain函数作ؓ入口QDLL一P有自q~省的入口函敎ͼ是DllMain。函数如?/p>

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
 switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:   // q程被调?br> case DLL_THREAD_ATTACH:     // U程被调?br> case DLL_THREAD_DETACH:   // U程被停?br> case DLL_PROCESS_DETACH:  // q程被停?br>  break;
 }
 return TRUE;
}

一般情况下Q我们不需要对q个~省的入口函数进行什么修改,它就会动态链接库得到正确的初始化。但是,当我们的DLL需要额外分配内存或者资源的时候,或者,DLL希望对调用自qq程或线E进行初始化或清除的额外操作Ӟ可以在上qC码case中加一些自己感冒的东东。(?#8230;…不想l写? -OrzQ现在是晚上2点了Q明天还一堆的事情Q?/p>

DLL对于导出cd导出函数没啥不同。只要加?__declspec( dllexport ) 修饰函数或者类好了?/p>

但是有查看过DLL代码的h员都会经常见到这么一D代?/p>

#ifdef FK_DLL_EXPORTS

#define FK_DLL __declspec( dllexport )

#else

#define FK_DLL __declspec( dllimport )

#endif

意义很明显,但是Q问题是  FK_DLL_EXPORTS q个宏是应该在哪儿定义呢Q在DLL目内,q是在用DLL的应用程序内Q?/p>

q点某志曾迷p很久,呵呵~其实后来xQ还是蛮明确的。export是导出。import是导入。对于DLL来说Q是要导些函数给其他应用E序使用的,所以应当定? FK_DLL_EXPORTS 宏。对于用DLL的应用程序来_是导入,是无需定义的?/p>

使用时候也很简单?/p>

class FK_DLL CMyDllClass{} ;

则整个类被导出?/p>

FK_DLL void MyTestFun( int a );

则该函数被导出?/p>

但是有时我们可以见到q样的代?/p>

extern "C" FK_DLL void MyTestFun2( float b );

其中extern "C"的原理就是标C函数要求以C形式去进行编译,不要以C++形式ȝ译。具体的~译原理׃|嗦了,而言之,被extern "C"定义函数Q可以被C以及其他语言q行DLL调用Q而未被extern "C"定义的函敎ͼC是无法访问DLL中这个函数的?/p>

 

在VS中开发DLLq有一U方式,使用.def文g?/p>

新徏个文本文档,改后~为FKDll.defQ加入到工程里?/p>

FKDll.def里加入以下代?/p>

LIBRARY FKDll

EXPORTS

MyTestFun@1

MyTestFun2@2

可以了。其中,LIBRARY语句是说?def文g是属于FKDllq个Dll的。EXPORTS下面是我们需要导出的函数名。后面加的@+数字Q是表示导出函数的顺序编受这样就_了。(详细的自q度,好困QzzzZZZQ?/p>

 

6Q用DLL

使用DLL有两U方式。显式链接和隐式链接?/p>

隐式链接很容易。直?progam comment(lib, "FKDll.lib") 可以。当Ӟ也可以在目工程->属?>链接库里加上库和路径Q相对\径和l对路径都可以)?/p>

昑ּ链接则麻烦些。在E序中用LoadLibrary加蝲DLLQ再GetProcAddress获取函数实现Q在E序退Z前,调用FreeLibrary来动态释放掉链接库?/p>

‍例如Q?/p>

void Main()

{

     typedef void (*FKDllFun1)(int a);

    FKDllFun1 pFun1;

    HINSTANCE hDLL  = LoadLibrary("FKDll.dll");   // 若hDll为空则读取Dllp|?/p>

    pFun1 = (pFun1)GetProcAddress(hDll, "MyTestFun1" );   // 从应用程序中的DLL镜像中获取名?MyTestFun1 的函数指?/p>

    pFun1( 100 );

    FreeLibrary(hDll);

}

当然Q我们刚?def里面q指定了导出函数的导出顺序,那么我们可以修改里面获取函数指针那一Dؓ

‍pFun1 = (pFun1)GetProcAddress(hDll, MAKEINTERSOURCE(1) );  // 1 是刚才指定的MyTestFun1函数导出序~号?/p>

q样可以更快Q但是别编可混了Q会D诡异的错误?/p>

 

7Q比较显式链接和隐式链接?/p>

可能的话Q尽量用显式链接?/p>

昑ּ链接可以在程序执行时动态的加蝲DLL和卸载DLL文gQ隐式链接是做不到的?/p>

昑ּ链接LoadLibraryQGetProcAddress时能L是否加蝲p|Q我们可以对其进行检查错误处理。而显式链接可能是一个很恶劣的提C或是程序崩溃的l果?/p>

对于有些Excd的加强函敎ͼ昑ּ链接可以允许我们扑ֈ替代Ҏ。也包括选择D3d9.dll和OpenGL.dll时也可采用同样处理?/p>

例如Q?/p>

if( GetProcAddress( hDll, "FKDllFunEx") == NULL )

{

‍    pFun = GetProcAddress( hDll, "FKDllFun");    // 然后使用pFunq行处理

}

 

8Q导出类和导出函?/p>

cd函数的导出方式上面给Z说明Q原本极其类似的?/p>

我们说下使用导出cR?/p>

若我们隐式的使用了一个导出类Q则我们在应用程序里l承它的时候,如同该cd在应用程序代码里一P无需M处理?/p>

例如Q?/p>

class FK_DLL CMyDllClass{} ;    // Dll文g内的代码

-----------------------

class CAppClass : public CMyDllClass      // 应用E序内代码,无需做Q何处理?/p>

{

       ....

}

也可以直接用DLL导出c?/p>

void main

{

     CMyDllClass* pClass = new CMyDllClass ();

}

但是Q若应用E序声明或者分cM个DLL中导出类的对象时会存在一个很讨厌的问题:q个操作会内存跟踪pȝ失效Q光误的报告内存分配和释放情c?/p>

册个问题,我们可以l出两个接口函数对DLL导出c进行创建销毁支持,可以内存跟踪pȝ正常了。例?/p>

class FK_DLL CMyDllClass{} ; 

额外增加俩函?/p>

FK_DLL CMyDllClass* CreateMyDllClass(){ return new CMyDllClass(); }

FK_DLL void DestoryMyDllClass( CMyDllClass* p_pClass ){ delete p_pClass; }

-----------------------------------------------

上面的方法可以正进行内存跟t了Q但是,因ؓDLL导出cCMyDllClass依旧是导出的状态,用户同样可以跌我们提供的接口直接用。那么怎么办呢。方法是不再对类q行DLL导出Q而对cd的函数全部进行DLL导出卛_Q?/p>

-----------------------------------------------

但是若仅仅提供上面两个接口函C及类内全部函敎ͼ的确功能可以实现Q却无法q行cȝ承了。若q个cȝ承很重要Q必d放,那么需要用新的内存跟t程序替换应用程序内的原有内存跟t程序。或者用下面的一个方法。(见模?Q复杂问题)

-----------------------------------------------

同样Q我们也可以发现Q在不导出DLLcLw,而只导出DLLcd函数也有一些好处,一些我们不希望外界知道的函数可以不讄导出标记Q这q一步保护了DLL内函数的安全性?/p>

 

9Q复杂问题?/p>

若我们用LoadLibrary昑ּ加蝲一个DLLQƈ试在应用程序中调用一个类内成员函数的话,无论该函数是否在头文件中有声明,VS会给Z?unresolved external symbolQ未解析的外部符P"的错误。我们此时可以将目属性中的内联函数扩展选项修改?Only __inline"?Any Suitable"卛_。但Q我们可能在调试q编的时候期望关闭内联函数扩展,那么另一U解x案是Q将希望导出的函数声明ؓ虚函敎ͼ例如

class CMyDllClass

{

   FK_DLL virtual void MyTestFun( int a ){  dosth(); }  

   // 用上面代码替?FK_DLL void MyTestFun( int a ){  dosth(); }  

}

q样做还有一个额外的好处。将导出的类成员函数讄函数之后Q该虚函数所在的cd应用E序中也如同被声明一P可以接受l承?/p>

例如若是上面的做法,应用E序可以进行顺利承,而不必要求CMyDllClass 被标CZؓ导出。(原理不知Q希望精通底层的高手协助解释。)

class CAppClass : public CMyDllClass      // 应用E序内代码,无需做Q何处理?/p>

{

       ....

}




IT菜鸟 2011-01-17 11:55 发表评论
]]>
宏中"#"?##"的用?/title><link>http://www.shnenglu.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.shnenglu.com/Husiwa/archive/2010/12/17/136735.html</guid><wfw:comment>http://www.shnenglu.com/Husiwa/comments/136735.html</wfw:comment><comments>http://www.shnenglu.com/Husiwa/archive/2010/12/17/136735.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Husiwa/comments/commentRss/136735.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Husiwa/services/trackbacks/136735.html</trackback:ping><description><![CDATA[<div> <p> </p> <p><span><font face="Times New Roman" size=3> 见到q两个符L很多不同的用法,整理在一?/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>把宏参数变ؓ一个字W串</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<cstdio> </font></span></p> <p><span><font face="Times New Roman" size=3>#include<climits> </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>   </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"> printf(STR(vck));<span>       </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"> 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> 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> </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>     </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>q行的宏会被展开为:</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>       </span>(2) </font></span></p> <p><span><font face="Times New Roman" size=3>#define STR(s)<span>   </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>   </span>// INT_MAX #include<climits> </font></span></p> <p><font size=3><span>q行会被展开为:</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>           </span>// compile error </font></span></p> <p><font size=3><span>q一行则是:</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>加这层宏的用意是把所有宏的参数在q层里全部展开</span><span><font face="Times New Roman">, </font></span><span>那么在{换宏里的那一个宏</span><span><font face="Times New Roman">(_STR)</font></span><span>p得到正确的宏参数</span><span><font face="Times New Roman">. </font></span></font></p> <p><span><font face="Times New Roman" size=3>#define A<span>      </span> (2) </font></span></p> <p><span><font face="Times New Roman" size=3>#define _STR(s)<span>   </span>#s </font></span></p> <p><font size=3><span><font face="Times New Roman">#define STR(s)<span>     </span>_STR(s)<span>       </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>   </span>_CONS(a,b)<span>     </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>       </span>// INT_MAX,int</font></span><span>型的最大|Z个变?/span><span><font face="Times New Roman"> #include<climits> </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) --> _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) --> _CONS((2), (2)) --> 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>、合q匿名变量名</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>表示该行行号Q?/span><span><font face="Times New Roman"> </font></span></font></p> <p><font size=3><span>W一层:</span><span><font face="Times New Roman">ANONYMOUS(static int); --> __ANONYMOUS0(static int, __LINE__); </font></span></font></p> <p><font size=3><span>W二层:</span><span><font face="Times New Roman"><span>                 </span>--> ___ANONYMOUS1(static int, _anonymous, 70); </font></span></font></p> <p><font size=3><span>W三层:</span><span><font face="Times New Roman"><span>                 </span>--> static int _anonymous70; </font></span></font></p> <p><font size=3><span>xơ只能解开当前层的宏,所?/span><span><font face="Times New Roman">__LINE__</font></span><span>在第二层才能被解开Q?/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>   </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>        </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>   </span>#f </font></span></p> <p><span><font face="Times New Roman" size=3>#define GET_FILE_NAME(f)<span>   </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>、得C个数值类型所对应的字W串~冲大小</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>   </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> --> char buf[_TYPE_BUF_SIZE(0x7fffffff)]; </font></font></span></p> <p><span><font face="Times New Roman"><font size=3> --> char buf[sizeof "0x7fffffff"]; </font></font></span></p> <p><font size=3><span>q里相当于:</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.shnenglu.com/Husiwa/aggbug/136735.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Husiwa/" target="_blank">IT菜鸟</a> 2010-12-17 14:34 <a href="http://www.shnenglu.com/Husiwa/archive/2010/12/17/136735.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>指o寄存?/title><link>http://www.shnenglu.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.shnenglu.com/Husiwa/archive/2010/12/15/136470.html</guid><wfw:comment>http://www.shnenglu.com/Husiwa/comments/136470.html</wfw:comment><comments>http://www.shnenglu.com/Husiwa/archive/2010/12/15/136470.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Husiwa/comments/commentRss/136470.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Husiwa/services/trackbacks/136470.html</trackback:ping><description><![CDATA[ebp和esp?2位的SPQBP  <br>esp是堆栈指?nbsp;    <br>ebp是基址指针  <br>ESP与SP的关pd象AX与ALQAH的关p?<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>数据寄存器主要用来保存操作数和运结果等信息Q从而节省读取操作数所需占用ȝ和访问存储器的时间?br><br>32位CPU??2位的通用寄存器EAX、EBX、ECX和EDX。对?6位数据的存取Q不会媄响高16位的数据。这?br>?6位寄存器分别命名为:AX、BX、CX和DXQ它和先前的CPU中的寄存器相一致?br><br>4?6位寄存器又可分割?个独立的8位寄存器(AXQAH-AL、BXQBH-BL、CXQCH-CL、DXQDH-DL)Q每个寄<br>存器都有自己的名Uͼ可独立存取。程序员可利用数据寄存器的这U?#8220;可分可合”的特性,灉|地处理字/?br>节的信息?br><br>寄存器AX和AL通常UCؓ累加?Accumulator)Q用累加器进行的操作可能需要更时间。篏加器可用于乘?br>除、输?输出{操作,它们的用频率很高;<br>寄存器BXUCؓ基地址寄存?Base Register)。它可作为存储器指针来用; <br>寄存器CXUCؓ计数寄存?Count Register)。在循环和字W串操作Ӟ要用它来控制循环ơ数Q在位操?br>中,当移多位Ӟ要用CL来指明移位的位数Q?br>寄存器DXUCؓ数据寄存?Data Register)。在q行乘、除q算Ӟ它可作ؓ默认的操作数参与q算Q也<br>可用于存放I/O的端口地址?br><br><br>?6位CPU中,AX、BX、CX和DX不能作ؓ基址和变址寄存器来存放存储单元的地址Q但?2位CPU中,?2?br>寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑q算l果Q而且也可作ؓ指针寄存器,<br>所以,q些32位寄存器更具有通用性?br><br>2、变址寄存?br><br>32位CPU??2位通用寄存器ESI和EDI。其?6位对应先前CPU中的SI和DIQ对?6位数据的存取Q不影响<br>?6位的数据?br><br>寄存器ESI、EDI、SI和DIUCؓ变址寄存?Index Register)Q它们主要用于存攑֭储单元在D内的偏U量Q?br>用它们可实现多种存储器操作数的寻址方式Qؓ以不同的地址形式讉K存储单元提供方便?br><br>变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储术逻辑q算的操作数和运结果?br><br>它们可作一般的存储器指针用。在字符串操作指令的执行q程中,对它们有特定的要求,而且q具有特<br>D的功能?br><br>3、指针寄存器<br><br>32位CPU??2位通用寄存器EBP和ESP。其?6位对应先前CPU中的SBP和SPQ对?6位数据的存取Q不?br>响高16位的数据?br><br>寄存器EBP、ESP、BP和SPUCؓ指针寄存?Pointer Register)Q主要用于存攑֠栈内存储单元的偏U量Q?br>用它们可实现多种存储器操作数的寻址方式Qؓ以不同的地址形式讉K存储单元提供方便?br><br>指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储术逻辑q算的操作数和运结果?br><br>它们主要用于讉K堆栈内的存储单元Qƈ且规定:<br><br>BP为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据;<br>SP为堆栈指?Stack Pointer)寄存器,用它只可讉K栈顶?br><br>4、段寄存?br><br>D寄存器是根据内存分D늚理模式而设|的。内存单元的物理地址由段寄存器的值和一个偏U量l合而成<br>的,q样可用两个较少位数的值组合成一个可讉K较大物理I间的内存地址?br><br>CPU内部的段寄存器:<br><br>CS——代码段寄存?Code Segment Register)Q其gؓ代码D늚D|<br>DS——数据段寄存?Data Segment Register)Q其gؓ数据D늚D|<br>ES——附加段寄存?Extra Segment Register)Q其gؓ附加数据D늚D|<br>SS——堆栈段寄存?Stack Segment Register)Q其gؓ堆栈D늚D|<br>FS——附加段寄存?Extra Segment Register)Q其gؓ附加数据D늚D|<br>GS——附加段寄存?Extra Segment Register)Q其gؓ附加数据D늚D倹{?br><br>?6位CPUpȝ中,它只?个段寄存器,所以,E序在Q何时刻至多有4个正在用的D可直接讉KQ在32?br>微机pȝ中,它有6个段寄存器,所以,在此环境下开发的E序最多可同时讉K6个段?br><br>32位CPU有两个不同的工作方式Q实方式和保护方式。在每种方式下,D寄存器的作用是不同的。有兌定简<br>单描q如下:<br><br>实方式: ?个段寄存器CS、DS、ES和SS与先前CPU中的所对应的段寄存器的含义完全一_内存单元的逻辑<br>地址仍ؓ“D|偏移?#8221;的Ş式。ؓ讉K某内存段内的数据Q必M用该D寄存器和存储单元的偏移量?br>保护方式Q?在此方式下,情况要复杂得多,装入D寄存器的不再是D|而是UCؓ“选择?#8221;(Selector)的某个倹{?br><br>5、指令指针寄存器<br><br>32位CPU把指令指针扩展到32位,q记作EIPQEIP的低16位与先前CPU中的IP作用相同?br><br>指o指针EIP、IP(Instruction Pointer)是存放下ơ将要执行的指o在代码段的偏U量。在h预取指o?br>能的pȝ中,下次要执行的指o通常已被预取到指令队列中Q除非发生{ULc所以,在理解它们的功能<br>Ӟ不考虑存在指o队列的情c?br><br>在实方式下,׃每个D늚最大范围ؓ64KQ所以,EIP中的?6位肯定都?Q此Ӟ相当于只用其?6?br>的IP来反映程序中指o的执行次序?br><br>6、标志寄存器<br><br>一、运结果标志位<br>1、进位标志CF(Carry Flag)<br>q位标志CF主要用来反映q算是否产生q位或借位。如果运结果的最高位产生了一个进位或借位Q那么,其gؓ1Q否则其gؓ0?br><br>使用该标志位的情冉|Q多?字节)数的加减q算Q无W号数的大小比较q算Q移位操作,?字节)之间UMQ专门改变CF值的指o{?br><br>2、奇偶标志PF(Parity Flag)<br>奇偶标志PF用于反映q算l果?#8220;1”的个数的奇偶性。如?#8220;1”的个Cؓ偶数Q则PF的gؓ1Q否则其gؓ0?br><br>利用PF可进行奇偶校验检查,或生奇偶校验位。在数据传送过E中Qؓ了提供传送的可靠性,如果采用奇偶校验的方法,可使用该标志位?br><br>3、辅助进位标志AF(Auxiliary Carry Flag)<br>在发生下列情冉|Q辅助进位标志AF的D|ؓ1Q否则其gؓ0Q?br><br>(1)、在字操作时Q发生低字节向高字节q位或借位Ӟ<br>(2)、在字节操作Ӟ发生?位向?位进位或借位时?br><br>对以?个运结果标志位Q在一般编E情况下Q标志位CF、ZF、SF和OF的用频率较高,而标志位PF和AF的用频率较低?br><br>4、零标志ZF(Zero Flag)<br>零标志ZF用来反映q算l果是否?。如果运结果ؓ0Q则其gؓ1Q否则其gؓ0。在判断q算l果是否?Ӟ可用此标志位?br><br>5、符h志SF(Sign Flag)<br>W号标志SF用来反映q算l果的符号位Q它与运结果的最高位相同。在微机pȝ中,有符h采用补码表示法,所以,SF也就反映q算l果的正负号。运结果ؓ正数ӞSF的gؓ0Q否则其gؓ1?br><br>6、溢出标志OF(Overflow Flag)<br>溢出标志OF用于反映有符h加减q算所得结果是否溢出。如果运结果超q当前运位数所能表C的范围Q则UCؓ溢出QOF的D|ؓ1Q否则,OF的D清ؓ0?br><br>“溢出”?#8220;q位”是两个不同含义的概念Q不要؜淆。如果不太清楚的话,h阅《计机l成原理》课E中的有关章节?br><br>二、状态控制标志位<br>状态控制标志位是用来控制CPU操作的,它们要通过专门的指令才能之发生改变?br><br>1、追t标志TF(Trap Flag)<br>当追t标志TF被置?ӞCPUq入单步执行方式Q即每执行一条指令,产生一个单步中断请求。这U方式主要用于程序的调试?br><br>指opȝ中没有专门的指o来改变标志位TF的|但程序员可用其它办法来改变其倹{?br><br>2、中断允许标志IF(Interrupt-enable Flag)<br>中断允许标志IF是用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。但不管该标志ؓ何|CPU都必d应CPU外部的不可屏蔽中断所发出的中断请求,以及CPU内部产生的中断请求。具体规定如下:<br><br>(1)、当IF=1ӞCPU可以响应CPU外部的可屏蔽中断发出的中断请求;<br><br>(2)、当IF=0ӞCPU不响应CPU外部的可屏蔽中断发出的中断请求?br><br>CPU的指令系l中也有专门的指令来改变标志位IF的倹{?br><br>3、方向标志DF(Direction Flag)<br>方向标志DF用来军_在串操作指o执行时有x针寄存器发生调整的方向。具体规定在W?.2.11节——字W串操作指o——中l出。在微机的指令系l中Q还提供了专门的指o来改变标志位DF的倹{?br><br>三?2位标志寄存器增加的标志位<br>1、I/OҎ标志IOPL(I/O Privilege Level)<br>I/OҎ标志用两位二q制位来表示Q也UCؓI/OҎU字Dc该字段指定了要求执行I/O指o的特权。如果当前的ҎU别在数g于{于IOPL的|那么Q该I/O指o可执行,否则发生一个保护异常?br><br>2、嵌套Q务标志NT(Nested Task)<br>嵌套d标志NT用来控制中断q回指oIRET的执行。具体规定如下:<br><br>(1)、当NT=0Q用堆栈中保存的值恢复EFLAGS、CS和EIPQ执行常规的中断q回操作Q?br><br>(2)、当NT=1Q通过d转换实现中断q回?br><br>3、重启动标志RF(Restart Flag)<br>重启动标志RF用来控制是否接受调试故障。规定:RF=0Ӟ表示“接受”调试故障Q否则拒l之。在成功执行完一条指令后Q处理机把RF|ؓ0Q当接受C个非调试故障Ӟ处理机就把它|ؓ1?br><br>4、虚?086方式标志VM(Virtual 8086 Mode)<br>如果该标志的gؓ1Q则表示处理机处于虚拟的8086方式下的工作状态,否则Q处理机处于一般保护方式下的工作状? <img src ="http://www.shnenglu.com/Husiwa/aggbug/136470.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Husiwa/" target="_blank">IT菜鸟</a> 2010-12-15 11:17 <a href="http://www.shnenglu.com/Husiwa/archive/2010/12/15/136470.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>汇编指o集合 http://www.shnenglu.com/Husiwa/archive/2010/12/15/136467.htmlIT菜鸟IT菜鸟Wed, 15 Dec 2010 03:01:00 GMThttp://www.shnenglu.com/Husiwa/archive/2010/12/15/136467.htmlhttp://www.shnenglu.com/Husiwa/comments/136467.htmlhttp://www.shnenglu.com/Husiwa/archive/2010/12/15/136467.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/136467.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/136467.html

一、常用指?/span> 

1. 通用数据传送指?/span>

   MOV 传送字或字?/span>

   MOVSX 先符h?/span>,再传?/span>

   MOVZX 先零扩展,再传?/span>

   PUSH 把字压入堆栈

   POP 把字弹出堆栈

   PUSHA ?/span>AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈

   POPA ?/span>DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈

   PUSHAD ?/span>EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈

   POPAD ?/span>EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈

   BSWAP 交换32位寄存器里字节的序 

   XCHG 交换字或字节.( 臛_有一个操作数为寄存器,D寄存器不可作ؓ操作?/span>

   CMPXCHG 比较q交换操作数.( W二个操作数必须为篏加器AL/AX/EAX ) 

   XADD 先交换再累加.( l果在第一个操作数?/span>

   XLAT 字节查表转换

   BX 指向一?/span> 256 字节的表的v?/span>, AL 的烦引?/span> (0-255,?/span> 0-FFH); q回 AL 为查表结?/span>. ( [BX+AL]-> AL

2. 输入输出端口传送指?/span>

   IN I/O端口输入. ( 语法: IN 累加?/span>, {端口号│DX} ) 

   OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加?/span>

   输入输出端口qx式指定时, 其范围是 0-255; 由寄存器 DX 指定?/span>,其范围是 0-65535. 

3. 目的地址传送指?/span>

   LEA 装入有效地址

     ?/span>: LEA DX,string ;把偏Ud址存到DX. 

   LDS 传送目标指?/span>,把指针内容装?/span>DS. 

     ?/span>: LDS SI,string ;把段地址:偏移地址存到DS:SI. 

   LES 传送目标指?/span>,把指针内容装?/span>ES. 

     ?/span>: LES DI,string ;把段地址:偏移地址存到ESDI. 

   LFS 传送目标指?/span>,把指针内容装?/span>FS. 

     ?/span>: LFS DI,string ;把段地址:偏移地址存到FSD. 

   LGS 传送目标指?/span>,把指针内容装?/span>GS. 

     ?/span>: LGS DI,string ;把段地址:偏移地址存到GSDI. 

   LSS 传送目标指?/span>,把指针内容装?/span>SS. 

     ?/span>: LSS DI,string ;把段地址:偏移地址存到SSDI. 

4. 标志传送指?/span>

   LAHF 标志寄存器传?/span>,把标志装?/span>AH. 

   SAHF 标志寄存器传?/span>,?/span>AH内容装入标志寄存?/span>

   PUSHF 标志入栈

   POPF 标志出栈

   PUSHD 32位标志入?/span>

   POPD 32位标志出?/span>

二、算术运指?/span> 

   ADD 加法

   ADC 带进位加?/span>

   INC ?/span> 1. 

   AAA 加法?/span>ASCII码调?/span>

   DAA 加法的十q制调整

   SUB 减法

   SBB 带借位减法

   DEC ?/span> 1. 

   NEC 求反(?/span> 0 减之). 

   CMP 比较.(两操作数作减?/span>,仅修Ҏ志位,不回送结?/span>). 

   AAS 减法?/span>ASCII码调?/span>

   DAS 减法的十q制调整

   MUL 无符号乘?/span>

  IMUL 整数乘法

     以上两条,l果回?/span>AH?/span>AL(字节q算),?/span>DX?/span>AX(字运?/span>), 

   AAM 乘法?/span>ASCII码调?/span>

   DIV 无符号除?/span>

   IDIV 整数除法

     以上两条,l果回?/span>

     商回?/span>AL,余数回?/span>AH, (字节q算); 

     ?/span> 商回?/span>AX,余数回?/span>DX, (字运?/span>). 

   AAD 除法?/span>ASCII码调?/span>

   CBW 字节转换为字. (?/span>AL中字节的W号扩展?/span>AH中去

   CWD 字{换ؓ双字. (?/span>AX中的字的W号扩展?/span>DX中去

   CWDE 字{换ؓ双字. (?/span>AX中的字符h展到EAX中去

   CDQ 双字扩展. (?/span>EAX中的字的W号扩展?/span>EDX中去

三、逻辑q算指o 

   AND 与运?/span>

   OR 或运?/span>

   XOR 异或q算

   NOT 取反

   TEST .(两操作数作与q算,仅修Ҏ志位,不回送结?/span>). 

   SHL 逻辑左移

   SAL 术左移.(=SHL) 

   SHR 逻辑右移

   SAR 术右移.(=SHR) 

   ROL 循环左移

   ROR 循环右移

   RCL 通过q位的@环左U?/span>

   RCR 通过q位的@环右U?/span>

     以上八种UM指o,其移位次数可?/span>255?/span>

     UM一ơ时, 可直接用操作?/span>. ?/span> SHL AX,1. 

     UM>1ơ时, 则由寄存?/span>CLl出UMơ数

      ?/span> MOV CL,04 

         SHL AX,CL 

四、串指o 

   DS:SI 源串D寄存器 :源串变址

   ES I 目标串段寄存?/span>:目标串变址

   CX 重复ơ数计数?/span>

   AL/AX 扫描?/span>

   D标志 0表示重复操作?/span>SI?/span>DI应自动增?/span>; 1表示应自动减?/span>

Z标志 用来控制扫描或比较操作的l束

   MOVS 串传?/span>

   ( MOVSB 传送字W?/span>. MOVSW 传送字. MOVSD 传送双?/span>. ) 

   CMPS 串比?/span>

   ( CMPSB 比较字符. CMPSW 比较?/span>. ) 

   SCAS 串扫?/span>

     ?/span>AL?/span>AX的内容与目标串作比较,比较l果反映在标志位

   LODS 装入?/span>

     把源串中的元?/span>(字或字节)逐一装入AL?/span>AX?/span>

   ( LODSB 传送字W?/span>. LODSW 传送字. LODSD 传送双?/span>. ) 

   STOS 保存?/span>

   ?/span>LODS的逆过E?/span>

   REP ?/span>CX/ECX<>0旉?/span>

   REPE/REPZ ?/span>ZF=1或比较结果相{?/span>,?/span>CX/ECX<>0旉?/span>

   REPNE/REPNZ ?/span>ZF=0或比较结果不相等,?/span>CX/ECX<>0旉?/span>

  REPC ?/span>CF=1?/span>CX/ECX<>0旉?/span>

   REPNC ?/span>CF=0?/span>CX/ECX<>0旉?/span>

五、程序{UL?/span> 

1>无条件{UL?/span> (长{U?/span>

   JMP 无条件{UL?/span> 

   CALL q程调用 

   RET/RETFq程q回

2>条g转移指o (短{U?/span>,-128?/span>+127的距d

   ( 当且仅当(SF XOR OF)=1?/span>,OP1<OP2 ) 

   JA/JNBE <



IT菜鸟 2010-12-15 11:01 发表评论
]]>
模板c静态变量初始化http://www.shnenglu.com/Husiwa/archive/2010/11/26/134698.htmlIT菜鸟IT菜鸟Fri, 26 Nov 2010 01:30:00 GMThttp://www.shnenglu.com/Husiwa/archive/2010/11/26/134698.htmlhttp://www.shnenglu.com/Husiwa/comments/134698.htmlhttp://www.shnenglu.com/Husiwa/archive/2010/11/26/134698.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/134698.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/134698.html
template <int I> class Test
{
    union Obj
    
{
        union Obj 
*next;
        
char data[1];
    }
;

    
static Obj* freeList[16];
    
static T* ms_singleton;
}
;

W二个静态变量初始化很容易:
template<Class T>
T
* Test<T>::ms_singleton=0;

W一个呢Q?br>要这P
template<class T>
typename Test
<T>::Obj* Test<T>::freeList[16]={0};

用typename关键字来告诉~译器Obj是个cd?

IT菜鸟 2010-11-26 09:30 发表评论
]]>
C#与C++的几个对应的变量http://www.shnenglu.com/Husiwa/archive/2010/11/24/134467.htmlIT菜鸟IT菜鸟Wed, 24 Nov 2010 01:38:00 GMThttp://www.shnenglu.com/Husiwa/archive/2010/11/24/134467.htmlhttp://www.shnenglu.com/Husiwa/comments/134467.htmlhttp://www.shnenglu.com/Husiwa/archive/2010/11/24/134467.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/134467.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/134467.htmlC#中的char?6bits的Unicode字符Q而一般C++中的字符则是8位的Q所以C++中的“unsigned   char”在C#中要么{换成char,要么使用Bytecd来代替,前者适用于存攑֭W型的unsigned   charQ后者适用于整数型的unsigned   char?br>2.
unsigned int    == nint32
unsigned short== nint16


IT菜鸟 2010-11-24 09:38 发表评论
]]>
zip、rar文g格式http://www.shnenglu.com/Husiwa/archive/2010/11/16/133759.htmlIT菜鸟IT菜鸟Tue, 16 Nov 2010 01:38:00 GMThttp://www.shnenglu.com/Husiwa/archive/2010/11/16/133759.htmlhttp://www.shnenglu.com/Husiwa/comments/133759.htmlhttp://www.shnenglu.com/Husiwa/archive/2010/11/16/133759.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/133759.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/133759.htmlhttp://www.comicer.com/stronghorse/water/software/ZipRar.htm



抛开压羃法不谈Q我认ؓzip、rar在文件格式上最大的差异在目录表(Table of ContentsQTOCQ:zip有TOCQ而rar没有?/p>

TOCq个词其实是从出版界借用q来的,指的是每一本书正文前面?#8220;目录”Q它的作用地球h都知道:如果惛_速找C中某一内容Q可以先查TOCQ然后按照TOC指明的页码直接翻卛_?/p>

在纸质书里TOC是印刷出来的一张表Q而在电子文g里则是由l构化数据构成的一张表Q它的目的同hZ快速定位:如果x文g中的某一内容Q可以先查TOCQ知道感兴趣的内容在文g的什么位|,直接跌d行了。最常见的运用就是avi、rm{多媒体文gQ播攄时候经常有人在播放条上Ҏ点去跳着看(?#8220;随机讉K”Q,如果没有TOCQ在长达几百兆的文g里来回定位会慢死?/p>

具体到zip文g里,TOC是放在文件尾部的一张表Q里面列Zzip包中每一个文件的属性(文g名、长度等Q和在zip包中的存放位|。如果需要随问zip包中的某一个文Ӟ只需在TOC里找到这个文件的存放位置Q直接蟩q去卛_?/p>

而RAR文g里则没有TOCQ在文g头之后所有文件按序q箋存放?/p>

q种差异造成的结果就是:随机讉K时zip比rar快,而顺序访问时rar比zip快?/p>

所谓随问,是前面说过的随问压~包中某个指定的文g。D一个简单的例子Q一本反~译或下载到的网는子书Q有大量HTML、图像、css、jsQ然后打成压~包。现在要求在不解包的情况下访问其中的面Q可以想象,打开每个HTML面的时候,它所附带的图像、css、js{文件可能随机分布在整个压羃包里Q如果没有TOCQ查找每个文件的时候都要从头开始找Q将会有多慢?所以各位可以理解ؓ什么jar包就是标准zip包,而我也只用zip格式保存反编译出来的电子书、O甅RPDG书等一切可能需要随问的东西?/p>

所谓顺序访问,是整个压~包从头解到。在q方面RARh天然的优ѝ而且Z节省WinRAR列文件的旉Q对于单个RAR我一般都直接通过右键菜单解压~,很少双击压羃包打开再解压。解多个RAR时当焉用BatchUnRar?/p>

׃rar的原作者已l去世,造成q种差异的确切原因我怿已不可考,但我个h猜测可能与DOS时代的备份Y件之争有养I在DOS时代Q电脑硬盘不像现在这样奢侈,20MBq很大了。这L定w用两盒Y?卛_备䆾Q备份成本相Ҏ据本w的价值来说非怽廉。因此在DOS时代Q很多公司和机构都制定有定期盘备䆾政策Q以免因Zh为或非h为的因素 Q早期硬盘可没有如今可靠Q而造成不可挽回的数据损失。在备䆾软g斚wQ虽然微软已l随DOS提供了Backup/Restore工具Q但是他们基本不具备数据压羃能力Q因此在压羃软g中提供备份功能,成为DOS时代的一个时。由于DOS时代的备份介质多Y盘,因此压羃 软g的备份功能其实就转化成如今很常见的一个功能:分卷压羃功能Q即按照软盘定wq行分卷压羃Q然后将分卷压羃文g备䆾QBackupQ到软盘Q需要的时候再解压Q或恢复QRestoreQ到盘?/p>

DOS时代最有名的zip工具是pkzipQ出现得比DOS版的RAR早。在分卷压羃Ӟpkzip按照zip文g规范Q将TOC存放在最后,卛_储在最后一P由此带来如下问题Q?/p>

1、恢复时Q每解压一张盘Q都要先最后一张盘插进Mơ,MơTOC?br>2、只要最后一张盘上的TOC坏了Q就其它盘都是好的Q也不能正常解压?/p>

q两个缺点,其是第一个缺点实在是太臭名昭著了Q因此当时出C非常强烈的改革呼声。在q个关键时刻QDOS版的RAR出现了:不仅压羃率比pkzip高(q点在DOS时代非常重要Q毕竟Y盘又贵容量又)Q而且׃吸取了当时对zip格式的批评,取消了TOCQ因此:

1、在恢复分卷压羃的备份文件时Q不需要频J插入带有TOC的分P按顺序换盘即可?br>2、即使某个分h坏,也可以蟩q,从完好的分卷再开始解压?/p>

׃q些原因Q当然还有其它原因)QRAR推出后迅速取得了成功Qpkzip在DOS时代开始流qP到Windows时代基本消声匿迹。在Windows时代推出的WinzipQ则d攑ּ了分卷压~功能(zip格式永远的痛Q)?而从我看到的源自WinRAR?a target=_blank>UnRAR源代?/font>来看Q现在WinRAR的解压思\明显q是把文件按序从头解到,看来当年备䆾/恢复工具之争的媄响,q真是深q?/p>

在压~算法方面,我觉得rar格式最特色的是固实QsolidQ压~方式。WinRAR v3.42的帮助文件中对固实压~的说明如下Q?br>
固实压羃文g?RAR 的一U特D压~方式存储的压羃文gQ它把压~文件中的全部文仉当成一个连l数据流来看待?/strong>

q段说明其实揭示了固实压~格式能够提高压~比的奥U:数据压羃的基?#8220;重复”Q例如aaaabbbq个字符Ԍ里面有重复Q如果表CZؓa4b3Q看h是不是变短了Q这是“数据压羃”?#8220;重复”是一个具有相Ҏ义的概念Q在某一范围内看h没有重复Q或重复不多的数据,把范围扩大,说不定就能找到更多重复的数据了,q就是固实压~的奥秘?/p>

举一个简单的例子Q用zip和普通rar压羃一堆jpg文gQ很隑֎下去Q但是用固实压羃方式的rar可以,其原因就在于Qjpg文g本n已经是压~格式了Q单个jpg文g里很隑ֆ 扑ֈ可利用的重复数据Q因此不论是用zipq是普通的rar都很隑ֆ压羃Q因Z们都需要压~的文g分隔开来一个一个处理。但是对于固实rar来说Q是?所有需要压~的jpg文g当作一个整体来压羃Q这些jpg之间存在重复的数据Q如他们都有相同的文件头Q其中包括各U数据表Q等Q这出C可压~的I间。从我看到的资料来看QFlash文g也采用了cM的技术对jpgq行压羃Q如果在Flash文g中用了多个jpg文gQ它们可以共用一个文件头?br>
当然天下不会有白吃的午餐Q固实压~方式在提高压羃比的同时Q也有一些限Ӟ在WinRAR v3.42帮助文g中的说法是:

固实压羃可增加压~性能Q特别是在添加大量的文件的时候,但它也有一些重要的不利因素:

  • 对已存在的固实压~文件更新时较慢Q?/strong>
  • 要从固实的压~文件解压单个文件时Q它之前的文仉需先经q分析。这造成当从固实的压~文件内取出文g时会比一般压~文件取出文件慢一些。但是,当从固实的压~文件解压全部的文gӞ解压速度q没有媄响?/strong>
  • 如果在固实压~文件中的Q何文件损坏了Q要从损坏的范围中解压全部的文g是不可能的。因此,如果固实压羃文g是保存在例如软盘{媒介时Q推荐你在制作时使用“恢复记录”?/strong>

固实压羃的适用场合?

  • 压羃文g很少更新的时?
  • 不需要经总压羃文g中解压一个文件或是部分文件的时?
  • 压羃效率比压~速度更ؓ重要的时候?/strong>

与前面说?#8220;随机讉K”对应Q固实压~的RAR文g可能是世界上最不适合随机讉K的:如果需要访问固实RAR包中的某个文Ӟp从文件头开始解压,一直解到这个文件?/p>

q里的安全性包含几个方面的含义Q文件系l安全性、密码保护安全性和文g数据安全性?/p>

׃制订zip格式规范的时候操作系l本w的文g安全性还没有引v_的重视,因此zip格式只记录最基本的文件属性,包括只读属性等Q没有其它附加的安全属性?/p>

rar格式刚推出的时候,文gpȝ的安全性只能参照DOSQ和zip差不多。但是rar毕竟是一U封闭的格式Q想怎么改作者一个h说了qQ因此当Windows中出现NTFSQƈ且引入扩展的文gpȝ安全属性时Qrar也积极跟q,所以现在应该说rar格式在这斚w比zip??/p>

在zip和rar格式中均提供了密码保护功能,但是密码保护的安全强度不同?/p>

zip׃格式开放、代码开源,因此zip密码破解软g出现得比较早Q也比较多。初期以暴力破解ZQ威胁不大,真正对zip密码安全的致命一Lknown plain textQ已知明文)d法:如果知道加密zip文g中某D内容(密文QciphertextQ解密后的真正内容(明文Qplain textQ,可以反推出zip加密口o。在q种dҎ的威胁,及某些国家的法律对密码技术的限制下, 著名开源组l?a target=_blank>zlib宣布怹攑ּ对加密zip的支持,详见zlib|站上的相关说明Q不q在zlib发行的源代码里仔l找找,q是能找到原来的?解密相关代码Q?/p>

记得rar刚推出的时候也和zip一P虽然不能列出加密文g中的文g内容Q但可以列出加密文g中的文g名。后来大概也是被known plain textd法吓CQ增加了一?#8220;加密文g?#8221;选项Q干脆连加密rar文g里有哪些文g都看不见Q让d者想猜明文都无从猜v?/p>

rar格式比zip晚推出,在安全方面吸取了_的教训,因此采用的是国国家标准与技术局QNational Institute of Standard and Technology, NISTQ推荐的、目前公认安全程度比较高的AES对称加密法 Q密钥长?28位。在ASE被攻破以前(NIST认ؓ30q内无法ȝQ,大家都只能在暴力法上兜圈子,所以密码安全性应该说比zip高。对此WinRAR 3.42的帮助文件是q样描述的:

ZIP 格式使用U有加密法?RAR 压羃文g使用更强大的 AES-128 标准加密。如果你需要加密重要的信息Q选择 RAR 压羃文g格式会比较好一些。ؓ了确实的安全性,密码长度h要 8 个字W。不要用Q何语a的单词作为密码,最好是L的随机组合字W和数字Qƈ且要注意密码的大写。请CQ如果你遗失你的密码Q你无法取出加密的文gQ就是 WinRAR 的作者本w也无法解压加密q的文g?/strong>

在数据安全性方面,RAR格式本n支持一U特D的附加信息cdQ叫?#8220;恢复记录”。如果RAR文g有恢复记录,在介质物理损坏或其它原因造成数据丢失ӞWinRAR可以按照“恢复记录”试Ҏ据进行修复。而zip格式无恢复记录,因此在数据安全性方面应该说比RAR弱?/p>

虽然RAR文g本n支持恢复记录Q但是在WinRAR里此选项~省是关闭的Q而打开后会D压羃出来的RAR文g体积增加Q增加的癑ֈ比与讄有关Q,可能会o某些人感C习惯Q我׃D到有人在论坛上抱怨ؓ什么压出来的RAR文g会如此庞大)Q所以这个功能基本上形同虚设?/p>

开放性的Ҏ很明显:zip格式不仅文g格式完全公开Q而且有专门的开源组l提供操作源代码Q跨q_使用也没有多大限Ӟrar格式完全保密Q作者只提供解压所需源代码,不提供压~所需源代?Q跨q_使用有点ȝ?/p>

zip开源组l中Q最出名的是zlib?a target=_blank>InfoZipQ二者各有侧重:zlib偏重对内存缓冲区的压~,因此?a target=_blank>png{开源组l用做内部压~算法,qjava的jarE序内核都来自zlibQ打出来的jar包自然也是一个标准的zip文gQInfoZip偏重Ҏ件的操作 Q包括口令保护)Q应用似乎不如zlibq泛Q但我个得其实它q是满好用的Q前提是需要对它的源代码进行一些必要的修改?/p>

?a target=_blank>pngl织的网中有说到png格式的来历,我觉得也很有意思:做png的一班hQ其实原来都是做gif格式的,但是׃Unisys公司开始对gif格式的核心——LZW压羃法征收专利费,q帮人怒了Q干脆提出png格式Q大l构斚wq是采用分段l构Q但是核心压~算法采用开源的zlibQ压~?效果在多数情况下比gif的LZW更强。由于没有版权限Ӟ在静态图形领域png得到q泛应用Q如果不是及时提出动L持ƈ因此在web上大行其道,我估计gif早就L了?/p>

RAR的解压源代码在其官方|站www.rarlab.com上提供,通常比WinRAR的正式版本晚一点,不过据说是直接从WinRAR的源代码中抠出来的,所以兼Ҏ应该没有什么问题?/p>

五、结?/a>

以下观点U属个h观点Q仅供参考,不具有如何指导意义:

  • 如果l常需要对压羃包进行随问,应该选zip而不是rar。虽然将下蝲到的rar重新压羃成zip会麻烦一ơ,但是以后会减无数的ȝ?
  • 如果需要分卷压~(如某些网站对上传文g大小有限ӞQ则只能用rar。事实上Q这也是我唯一会用rar格式的场合,其它时候一律zip没商量?/li>


IT菜鸟 2010-11-16 09:38 发表评论
]]>
getchar() 和EOFȝhttp://www.shnenglu.com/Husiwa/archive/2010/11/01/131998.htmlIT菜鸟IT菜鸟Mon, 01 Nov 2010 08:07:00 GMThttp://www.shnenglu.com/Husiwa/archive/2010/11/01/131998.htmlhttp://www.shnenglu.com/Husiwa/comments/131998.htmlhttp://www.shnenglu.com/Husiwa/archive/2010/11/01/131998.html#Feedback0http://www.shnenglu.com/Husiwa/comments/commentRss/131998.htmlhttp://www.shnenglu.com/Husiwa/services/trackbacks/131998.html一getchar()

1.

1char c;
2while((c = getchar()) != EOF){
3    putchar(c);
4}

5

输入|abc后面跟个回R
本以为屏q应该显C?br>a
a
b
b
c
c

实际上是:
abc
abc

q是因ؓ只有当输入回车时Q系l才认ؓ是输入完?br>
2.上面的代码还有一个问?br>因ؓEOF?1Q所以c=getchar()q一句会出现问题
所以c应该是int c

二、EOF

只有在新的一行输入的时候输入EOF才算是文件结束符
假设输入Q?br>abc^zqwer
输出为:
abc



IT菜鸟 2010-11-01 16:07 发表评论
]]>
Ʒ99þþþƷ| þۺϸϾþúݺݺ97ɫ| þþþþҹӰԺ| ޾þþþþ| þþƷѹۿ| ŷ޹Ʒþ| þƵվ| ĻþþƷAPP| һһþۺϺݺ| þù޾Ʒ鶹| ŷƷרþ| ݺɫۺþö| ʵҶ԰׾ʾþ| ަvþþ| պŷۺϾþӰԺDs | ƷþþþþĻһ | ʵҶ԰׾ʾþ| ˳˳ۺþþ | þۺ϶| ŷþþXXX| þþƷav٤| 99þùۺϾƷ| ˾þ777777| þþþùƷ| 뾫Ʒþþɫ| þþþþùaѹۿ | ƷþþþþþҹƬ| þþþavۺϲҰ| ŷþۺϾɫۺ| þþƷƵ| AVþþþò| 2021ھƷþþþþӰԺ| þۺƵվ| þ¶ݺɫ| þþþþƷ66| 鶹wwwþ| 91Ըߺþþþ| 鶹ƷþþƷɫۺ| þerƵᆱƷ| ƷþþþӰӲ| ɫۺϾþ|