﻿<?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++博客-LIBERTINE FreeSky</title><link>http://www.cppblog.com/LiBerTine/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 05 Apr 2026 18:45:21 GMT</lastBuildDate><pubDate>Sun, 05 Apr 2026 18:45:21 GMT</pubDate><ttl>60</ttl><item><title>STLport &amp; boost</title><link>http://www.cppblog.com/LiBerTine/archive/2011/01/30/139613.html</link><dc:creator>自由人</dc:creator><author>自由人</author><pubDate>Sun, 30 Jan 2011 04:51:00 GMT</pubDate><guid>http://www.cppblog.com/LiBerTine/archive/2011/01/30/139613.html</guid><wfw:comment>http://www.cppblog.com/LiBerTine/comments/139613.html</wfw:comment><comments>http://www.cppblog.com/LiBerTine/archive/2011/01/30/139613.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LiBerTine/comments/commentRss/139613.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LiBerTine/services/trackbacks/139613.html</trackback:ping><description><![CDATA[<p>STLport:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下载：<a href="http://www.stlport.org/">ww.stlport.org</a>&nbsp; download STLport-5.2.1.tar.bz2；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;编译：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;&nbsp;将STLport减压到d盘，d:\STLport；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;&nbsp;打开VS2005的命令行窗口，进入stl目录d:\STLport；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.&nbsp;&nbsp;执行命令configure msvc8&nbsp; 配置编译环境；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.&nbsp;&nbsp;打开目录d:\STLport\build\lib；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.&nbsp;&nbsp;执行命令 nmake -f msvc.mak clean install；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6.&nbsp;&nbsp;编译完成后，*.dll，*.lib文件将被自动复制到STLport\bin和STLport\lib目录下。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug模式下使用STLport，需定义宏__STL_DEBUG<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug模式下与boost配合使用，需定义宏__STLP_DEBUG<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 与MFC配合使用，需定义宏__STLP_USE_MFC</p>
<img src ="http://www.cppblog.com/LiBerTine/aggbug/139613.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LiBerTine/" target="_blank">自由人</a> 2011-01-30 12:51 <a href="http://www.cppblog.com/LiBerTine/archive/2011/01/30/139613.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Qt 翻译</title><link>http://www.cppblog.com/LiBerTine/archive/2010/12/09/135872.html</link><dc:creator>自由人</dc:creator><author>自由人</author><pubDate>Thu, 09 Dec 2010 01:57:00 GMT</pubDate><guid>http://www.cppblog.com/LiBerTine/archive/2010/12/09/135872.html</guid><wfw:comment>http://www.cppblog.com/LiBerTine/comments/135872.html</wfw:comment><comments>http://www.cppblog.com/LiBerTine/archive/2010/12/09/135872.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LiBerTine/comments/commentRss/135872.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LiBerTine/services/trackbacks/135872.html</trackback:ping><description><![CDATA[<div class=tit>Qt中translate、tr关系 与中文问题</div>
<div class=date>2010-09-22 00:15</div>
<table style="WIDTH: 100%; TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div id=blog_text class=cnt><span class=Apple-style-span>
            <p class=line867><strong>题外话：何时使用 tr ？</strong></p>
            <p class=line874>在论坛中漂，经常遇到有人遇到tr相关的问题。用tr的有两类人：</p>
            <ul>
                <li>(1)因为发现中文老出问题，然后搜索，发现很多人用tr，于是他也开始用tr
                <li>(2)另一类人，确实是出于国际化的需要，将需要在界面上显示的文件都用tr包起来，这有分两种：
                <ul>
                    <li>(2a) 用tr包住英文(最最推荐的用法，源码英文，然后提供英文到其他语言的翻译包)
                    <li>(2b) 用tr包住中文(源码用中文，然后提供中文到其他语言的翻译包) </li>
                </ul>
                </li>
            </ul>
            <p class=line874>注意哦，如果你正在用tr包裹中文字符，却不属于(2b)，那么，这是个信号：</p>
            <ul>
                <li>你在误用tr
                <li>你需要的是QString，而不是tr </li>
            </ul>
            <p class=line867><strong>tr 是做什么的？下面二者的区别是什么？</strong></p>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt solid; BORDER-LEFT: rgb(192,192,192) 1pt solid; PADDING-BOTTOM: 0.5em; BACKGROUND-COLOR: rgb(240,236,230); PADDING-LEFT: 0.5em; PADDING-RIGHT: 0.5em; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt solid; BORDER-RIGHT: rgb(192,192,192) 1pt solid; PADDING-TOP: 0.5em">QString text1 = QObject::tr("hello");<br> QString text2 = QString("hello");</pre>
            <p class=line874>tr是用来实现国际化，如果你为这个程序提供了中文翻译包(其中hello被翻译成中文"你好")，那么text1的内容将是中文"你好"；如果你为程序提供且使用日文翻译包，那么text1的内容将是日文。</p>
            <p class=line874>tr是经过多级函数调用才实现了翻译操作，是有代价的，所以不该用的时候最好不要用。</p>
            <h2 style="BORDER-BOTTOM: maroon 3px solid; PADDING-BOTTOM: 0.3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">关注的对象</h2>
            <p class=line874>本文关注的是tr或translate中包含中文字符串的情况：</p>
            <ul>
                <li>
                <p style="MARGIN: 0.25em 0px" class=line891><tt>QObject::tr()</tt></p>
                <li>
                <p style="MARGIN: 0.25em 0px" class=line891><tt>QCoreApplication::translate()</tt></p>
                <li>
                <p style="MARGIN: 0.25em 0px" class=line891><tt>QTextCodec::setCodecForTr</tt></p>
                </li>
            </ul>
            <p class=line862>这个问题本多少可说的。因为涉及到的编码问题和<a style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; COLOR: maroon; BORDER-LEFT-WIDTH: 0px" href="http://hi.baidu.com/cyclone/blog/item/9d7293130e5a498d6538dbf1.html" target=_blank><u>QString 与中文问题</u></a>中是完全一样的，只不过一个是用的setCodecForCStrings一个用的是setCodecForTr。</p>
            <h3 style="BORDER-BOTTOM: maroon 3px solid; PADDING-BOTTOM: 0.3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">简单回顾QString的中文问题</h3>
            <ul>
                <li>QString 采用的unicode，在中文支持上不存在任何问题
                <li>
                <p style="MARGIN: 0.25em 0px" class=line891><tt>"我是中文"</tt><span class=Apple-converted-space>&nbsp;</span>这是传统的<span class=Apple-converted-space>&nbsp;</span><tt>const&nbsp;char&nbsp;*</tt><span class=Apple-converted-space>&nbsp;</span>的窄字符串</p>
                <li>当将窄字符串赋值到QString时，我们需要告诉它我们的窄串采用的何种编码(gbk?、utf-8?)
                <li>究竟何种编码主要取决于我们的源代码文件的编码(windows上一般是gbk，其他平台一般utf-8) </li>
            </ul>
            <p class=line874>例子：</p>
            <div class="highlight cpp">
            <div style="BORDER-BOTTOM: rgb(174,189,204) 1pt solid; BORDER-LEFT: rgb(174,189,204) 1pt solid; PADDING-BOTTOM: 0px; BACKGROUND-COLOR: rgb(243,245,247); MARGIN: 0.5em 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: black; BORDER-TOP: rgb(174,189,204) 1pt solid; BORDER-RIGHT: rgb(174,189,204) 1pt solid; PADDING-TOP: 0px" dir=ltr class=codearea>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt; BORDER-LEFT: rgb(192,192,192) 1pt; PADDING-BOTTOM: 10pt; BACKGROUND-COLOR: rgb(240,236,230); MARGIN: 0px; PADDING-LEFT: 10pt; PADDING-RIGHT: 10pt; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt; BORDER-RIGHT: rgb(192,192,192) 1pt; PADDING-TOP: 10pt" dir=ltr><span class=line><span style="COLOR: rgb(0,0,0)" class=ID>QString</span> <span style="COLOR: rgb(0,0,0)" class=ID>s1</span> = <span style="COLOR: rgb(0,64,128)" class=String>"</span><span style="COLOR: rgb(0,64,128)" class=String>我是中文</span><span style="COLOR: rgb(0,64,128)" class=String>"</span>;</span><br><span class=line><span style="COLOR: rgb(0,0,0)" class=ID>QString</span> <span style="COLOR: rgb(0,0,0)" class=ID>s2</span>(<span style="COLOR: rgb(0,64,128)" class=String>"</span><span style="COLOR: rgb(0,64,128)" class=String>我是中文</span><span style="COLOR: rgb(0,64,128)" class=String>"</span>);</span><br><span class=line><span style="COLOR: rgb(0,0,0)" class=ID>QString</span> <span style="COLOR: rgb(0,0,0)" class=ID>s3</span>;</span><br><span class=line><span style="COLOR: rgb(0,0,0)" class=ID>s3</span> = <span style="COLOR: rgb(0,64,128)" class=String>"</span><span style="COLOR: rgb(0,64,128)" class=String>我是中文</span><span style="COLOR: rgb(0,64,128)" class=String>"</span></span></pre>
            </div>
            </div>
            <ul>
                <li>
                <p style="MARGIN: 0.25em 0px" class=line862>s1、s2 用的是QString的构造函数<tt>QString&nbsp;(&nbsp;const&nbsp;char&nbsp;*&nbsp;str&nbsp;)</tt></p>
                <li>
                <p style="MARGIN: 0.25em 0px" class=line862>s3 用的是QString的赋值操作符<span class=Apple-converted-space>&nbsp;</span><tt>QString&nbsp;&amp;&nbsp;operator=&nbsp;(&nbsp;const&nbsp;char&nbsp;*&nbsp;str)</tt></p>
                </li>
            </ul>
            <p class=line862>如果不指定编码，s1,s2,s3将全部都是(国内大多数人所称的)乱码。因为QString将这些<tt>const&nbsp;char&nbsp;*</tt>按照latin1来解释的，而不是用户期待的gbk或utf8。</p>
            <div class="highlight cpp">
            <div style="BORDER-BOTTOM: rgb(174,189,204) 1pt solid; BORDER-LEFT: rgb(174,189,204) 1pt solid; PADDING-BOTTOM: 0px; BACKGROUND-COLOR: rgb(243,245,247); MARGIN: 0.5em 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: black; BORDER-TOP: rgb(174,189,204) 1pt solid; BORDER-RIGHT: rgb(174,189,204) 1pt solid; PADDING-TOP: 0px" dir=ltr class=codearea>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt; BORDER-LEFT: rgb(192,192,192) 1pt; PADDING-BOTTOM: 10pt; BACKGROUND-COLOR: rgb(240,236,230); MARGIN: 0px; PADDING-LEFT: 10pt; PADDING-RIGHT: 10pt; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt; BORDER-RIGHT: rgb(192,192,192) 1pt; PADDING-TOP: 10pt" dir=ltr><span class=line><span style="COLOR: rgb(0,0,0)" class=ID>QTextCodec</span>::<span style="COLOR: rgb(0,0,0)" class=ID>setCodecForCStrings</span>(<span style="COLOR: rgb(0,0,0)" class=ID>QTextCodec</span>::<span style="COLOR: rgb(0,0,0)" class=ID>codecForName</span>(<span style="COLOR: rgb(0,64,128)" class=String>"</span><span style="COLOR: rgb(0,64,128)" class=String>GB2312</span><span style="COLOR: rgb(0,64,128)" class=String>"</span>));</span><br><span class=line><span style="COLOR: rgb(0,0,0)" class=ID>QTextCodec</span>::<span style="COLOR: rgb(0,0,0)" class=ID>setCodecForCStrings</span>(<span style="COLOR: rgb(0,0,0)" class=ID>QTextCodec</span>::<span style="COLOR: rgb(0,0,0)" class=ID>codecForName</span>(<span style="COLOR: rgb(0,64,128)" class=String>"</span><span style="COLOR: rgb(0,64,128)" class=String>UTF-8</span><span style="COLOR: rgb(0,64,128)" class=String>"</span>))</span></pre>
            </div>
            </div>
            <p class=line874>这两条语句中的一条可以解决问题，至于如何选择，此处不再重复。</p>
            <h2 style="BORDER-BOTTOM: maroon 3px solid; PADDING-BOTTOM: 0.3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">QObject::tr</h2>
            <p class=line874>说实话，在tr中使用中文不是个好主意。不过既然总有人用（无论是(1)还是(2b)），而且总有人遇到问题，所以还是简单整理一下吧。</p>
            <p class=line862>相比<tt>QCoreApplication::translate</tt>，大家用tr应该用的很多了，尽管不少人不清楚tr究竟是做什么的<tt>^_^</tt></p>
            </span><span class=Apple-style-span>
            <p class=line862><span class=Apple-style-span>
            <p class=line874><span class=Apple-style-span></p>
            <div class="highlight text">
            <div style="BORDER-BOTTOM: rgb(174,189,204) 1pt solid; BORDER-LEFT: rgb(174,189,204) 1pt solid; PADDING-BOTTOM: 0px; BACKGROUND-COLOR: rgb(243,245,247); MARGIN: 0.5em 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: black; BORDER-TOP: rgb(174,189,204) 1pt solid; BORDER-RIGHT: rgb(174,189,204) 1pt solid; PADDING-TOP: 0px" dir=ltr class=codearea>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt; BORDER-LEFT: rgb(192,192,192) 1pt; PADDING-BOTTOM: 10pt; BACKGROUND-COLOR: rgb(240,236,230); MARGIN: 0px; PADDING-LEFT: 10pt; PADDING-RIGHT: 10pt; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt; BORDER-RIGHT: rgb(192,192,192) 1pt; PADDING-TOP: 10pt" dir=ltr><span class=line>tr("我是中文");</span></pre>
            </div>
            </div>
            <p class=line874>这调用的是下面这个函数(至少我们可这么认为是)。</p>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt solid; BORDER-LEFT: rgb(192,192,192) 1pt solid; PADDING-BOTTOM: 0.5em; BACKGROUND-COLOR: rgb(240,236,230); PADDING-LEFT: 0.5em; PADDING-RIGHT: 0.5em; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt solid; BORDER-RIGHT: rgb(192,192,192) 1pt solid; PADDING-TOP: 0.5em">QString QObject::tr ( const char * sourceText, const char * disambiguation = 0, int n = -1 )</pre>
            <p class=line874>与QString("我是中文")完全一样，你必须告诉tr这个窄字符串是何种编码？你不告诉它，它就用latin1。于是所谓的乱码问题就出来了。</p>
            <p class=line874>如何告诉tr你写的这几个汉字在磁盘中保存的是何种编码呢？这正是</p>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt solid; BORDER-LEFT: rgb(192,192,192) 1pt solid; PADDING-BOTTOM: 0.5em; BACKGROUND-COLOR: rgb(240,236,230); PADDING-LEFT: 0.5em; PADDING-RIGHT: 0.5em; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt solid; BORDER-RIGHT: rgb(192,192,192) 1pt solid; PADDING-TOP: 0.5em">QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312")); <br>QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));</pre>
            <p class=line874>所做的。这两个选择的原则，由于和前文完全一样，此处也不再重复。</p>
            <p class=line874>如果你的编码采用的utf8，可以直接使用trUtf8而不必设置setCodecForTr。</p>
            <p class=line874>如果你只关心乱码问题，到此为止就可以了(下面不再关注编码)。如果想对tr进一步了解，不妨。。继续。。</p>
            <p class=line874><span class=Apple-style-span>
            <h2 style="BORDER-BOTTOM: maroon 3px solid; PADDING-BOTTOM: 0.3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">QCoreApplication::translate</h2>
            <p class=line874>我们知道tr是用于实现程序的国际化(或者说多语言翻译)，看Qt相关资料的话，我们知道实现该功能的还有下面这个函数：</p>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt solid; BORDER-LEFT: rgb(192,192,192) 1pt solid; PADDING-BOTTOM: 0.5em; BACKGROUND-COLOR: rgb(240,236,230); PADDING-LEFT: 0.5em; PADDING-RIGHT: 0.5em; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt solid; BORDER-RIGHT: rgb(192,192,192) 1pt solid; PADDING-TOP: 0.5em">QString QCoreApplication::translate ( const char * context, const char * sourceText, const char * disambiguation, Encoding encoding, int n )</pre>
            <p class=line874>其实，这个才是真正进行翻译操作的函数，前面我们提到的tr最终是通过调用该函数来实现翻译功能的(稍后我们会看tr是如何调用translate的)。</p>
            <p class=line874>对tr和这个函数，manual中都有比较详尽的解释。我们这儿简单看一下它的这几个参数：</p>
            <ul>
                <li>context 上下文，一般就是需要翻译的字符串所在的类的名字
                <li>sourceText 需要翻译的字符串。(我们关注的编码其实就是它的编码)
                <li>disambiguation 消除歧义用的。(比如我们的类内出现两处"close"，一处含义是关闭，另一处含义是亲密的。显然需要让翻译人员知道这点区别)
                <li>encoding 指定编码。它有两个值
                <ul>
                    <li>
                    <p style="MARGIN: 0.25em 0px" class=line891>CodecForTr<span class=Apple-converted-space>&nbsp;</span>使用setCodecForTr()设置的编码来解释 sourceText</p>
                    <li>UnicodeUTF8 使用utf8编码来解释 sourceText
                    <li>其实这两个分别对应tr和trUtf8 </li>
                </ul>
                <li>n 处理单复数(对中文来说，不存在这个问题) </li>
            </ul>
            <span class=Apple-style-span>
            <h2 style="BORDER-BOTTOM: maroon 3px solid; PADDING-BOTTOM: 0.3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">tr与translate</h2>
            <p class=line874>这两个函数的说明，一个在QObject的manual，另一个在QCoreApplication的manual中。</p>
            <p class=line874>介绍一下tr与translate的关系。前面提到了，tr调用的是translate。如果仅仅这样一说，没有证据，还真难以让大家相信。好吧，继续</p>
            <h3 style="BORDER-BOTTOM: maroon 3px solid; PADDING-BOTTOM: 0.3em; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">tr 在何处定义</h3>
            <p class=line874>你可能说：这不废话吗，manual中写得明白的，它是QObject的静态成员函数。而且还有源码为证：</p>
            <div class="highlight cpp">
            <div style="BORDER-BOTTOM: rgb(174,189,204) 1pt solid; BORDER-LEFT: rgb(174,189,204) 1pt solid; PADDING-BOTTOM: 0px; BACKGROUND-COLOR: rgb(243,245,247); MARGIN: 0.5em 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: black; BORDER-TOP: rgb(174,189,204) 1pt solid; BORDER-RIGHT: rgb(174,189,204) 1pt solid; PADDING-TOP: 0px" dir=ltr class=codearea>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt; BORDER-LEFT: rgb(192,192,192) 1pt; PADDING-BOTTOM: 10pt; BACKGROUND-COLOR: rgb(240,236,230); MARGIN: 0px; PADDING-LEFT: 10pt; PADDING-RIGHT: 10pt; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt; BORDER-RIGHT: rgb(192,192,192) 1pt; PADDING-TOP: 10pt" dir=ltr><span class=line><span style="COLOR: rgb(0,128,0)" class=Comment>//来自 src/corelib/kernel/qobject.h</span></span> <br><span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>#</span><span style="COLOR: rgb(128,57,153)" class=Preprc>ifdef qdoc</span></span> <span class=line><span style="COLOR: rgb(160,0,0)" class=ResWord><br>static</span> <span style="COLOR: rgb(0,0,0)" class=ID>QString</span> <span style="COLOR: rgb(0,0,0)" class=ID>tr</span>(<span style="COLOR: rgb(160,0,0)" class=ResWord>const</span> <span style="COLOR: rgb(160,0,0)" class=ResWord>char</span> *<span style="COLOR: rgb(0,0,0)" class=ID>sourceText</span>, <span style="COLOR: rgb(160,0,0)" class=ResWord>const</span> <span style="COLOR: rgb(160,0,0)" class=ResWord>char</span> *<span style="COLOR: rgb(0,0,0)" class=ID>comment</span> = <span style="COLOR: rgb(0,128,192)" class=Number>0</span>, <span style="COLOR: rgb(160,0,0)" class=ResWord>int</span> <span style="COLOR: rgb(0,0,0)" class=ID>n</span> = -<span style="COLOR: rgb(0,128,192)" class=Number>1</span>);</span><br><span class=line><span style="COLOR: rgb(160,0,0)" class=ResWord>static</span> <span style="COLOR: rgb(0,0,0)" class=ID>QString</span> <span style="COLOR: rgb(0,0,0)" class=ID>trUtf8</span>(<span style="COLOR: rgb(160,0,0)" class=ResWord>const</span> <span style="COLOR: rgb(160,0,0)" class=ResWord>char</span> *<span style="COLOR: rgb(0,0,0)" class=ID>sourceText</span>, <span style="COLOR: rgb(160,0,0)" class=ResWord>const</span> <span style="COLOR: rgb(160,0,0)" class=ResWord>char</span> *<span style="COLOR: rgb(0,0,0)" class=ID>comment</span> = <span style="COLOR: rgb(0,128,192)" class=Number>0</span>, <span style="COLOR: rgb(160,0,0)" class=ResWord>int</span> <span style="COLOR: rgb(0,0,0)" class=ID>n</span> = -<span style="COLOR: rgb(0,128,192)" class=Number>1</span>);</span><br><span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>#</span><span style="COLOR: rgb(128,57,153)" class=Preprc>endif</span></span></pre>
            </div>
            </div>
            <p class=line874>嘿嘿，差点就被骗了，发现没：它们被预处理语句包住了。</p>
            <p class=line862>这说明了什么呢？说明了这段代码<strong>仅仅是</strong>用来生成Qt那漂亮的文档的(qdoc3从代码中抽取信息，生成一系列的html格式的manual)。</p>
            <p class=line874>啊，也就是说，这是假的。那么真正的定义呢？？在一个大家都很熟悉的地方,猜猜看？</p>
            <p class=line874>这就是</p>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt solid; BORDER-LEFT: rgb(192,192,192) 1pt solid; PADDING-BOTTOM: 0.5em; BACKGROUND-COLOR: rgb(240,236,230); PADDING-LEFT: 0.5em; PADDING-RIGHT: 0.5em; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt solid; BORDER-RIGHT: rgb(192,192,192) 1pt solid; PADDING-TOP: 0.5em">Q_OBJECT</pre>
            <p class=line874>该宏的定义在src/corelib/kernel/qobjectdefs.h中</p>
            </span></span><span class=Apple-style-span>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt; BORDER-LEFT: rgb(192,192,192) 1pt; PADDING-BOTTOM: 10pt; BACKGROUND-COLOR: rgb(240,236,230); MARGIN: 0px; PADDING-LEFT: 10pt; PADDING-RIGHT: 10pt; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt; BORDER-RIGHT: rgb(192,192,192) 1pt; PADDING-TOP: 10pt" dir=ltr><span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>#</span><span style="COLOR: rgb(128,57,153)" class=Preprc>define Q_OBJECT \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>public: \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>Q_OBJECT_CHECK \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>static const QMetaObject staticMetaObject; \<br></span></span>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>Q_OBJECT_GETSTATICMETAOBJECT \<br></span></span>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>virtual const QMetaObject *metaObject() const; \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>virtual void *qt_metacast(const char *); \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>QT_TR_FUNCTIONS \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>virtual int qt_metacall(QMetaObject::Call, int, void **); \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>private:</span></span></pre>
            </span><br class=Apple-interchange-newline><span class=Apple-style-span><span class=Apple-style-span>
            <p class=line874>其中的宏QT_TR_FUNCTIONS</p>
            </span></span><span class=Apple-style-span>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt; BORDER-LEFT: rgb(192,192,192) 1pt; PADDING-BOTTOM: 10pt; BACKGROUND-COLOR: rgb(240,236,230); MARGIN: 0px; PADDING-LEFT: 10pt; PADDING-RIGHT: 10pt; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt; BORDER-RIGHT: rgb(192,192,192) 1pt; PADDING-TOP: 10pt" dir=ltr><span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>#</span><span style="COLOR: rgb(128,57,153)" class=Preprc>  define QT_TR_FUNCTIONS \<br></span></span>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>static inline QString tr(const char *s, const char *c = 0) \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>{ return staticMetaObject.tr(s, c); } \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>static inline QString trUtf8(const char *s, const char *c = 0) \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>{ return staticMetaObject.trUtf8(s, c); } \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>static inline QString tr(const char *s, const char *c, int n) \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>{ return staticMetaObject.tr(s, c, n); } \</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>static inline QString trUtf8(const char *s, const char *c, int n) \<br></span></span>&nbsp;<span class=line><span style="COLOR: rgb(128,57,153)" class=Preprc>{ return staticMetaObject.trUtf8(s, c, n); }</span></span></pre>
            </span><span class=Apple-style-span><span class=Apple-style-span>
            <p class=line874>现在看到：tr调用的是 staticMetaObject对象的tr函数，staticMetaObject 的定义在moc生成的 xxx.moc 或 moc_xxx.cpp 文件内(你随时可以验证的)。</p>
            <p class=line874>staticMetaObject 是一个 QMetaObject 类的实例，我们继续看一下该类的源码：</p>
            </span></span><span class=Apple-style-span>
            <pre style="BORDER-BOTTOM: rgb(192,192,192) 1pt; BORDER-LEFT: rgb(192,192,192) 1pt; PADDING-BOTTOM: 10pt; BACKGROUND-COLOR: rgb(240,236,230); MARGIN: 0px; PADDING-LEFT: 10pt; PADDING-RIGHT: 10pt; WORD-WRAP: break-word; WHITE-SPACE: pre-wrap; BORDER-TOP: rgb(192,192,192) 1pt; BORDER-RIGHT: rgb(192,192,192) 1pt; PADDING-TOP: 10pt" dir=ltr><span class=line><span style="COLOR: rgb(0,128,0)" class=Comment>/*!</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(0,128,0)" class=Comment>\internal</span></span> <span class=line><span style="COLOR: rgb(0,128,0)" class=Comment><br>*/</span></span><br>&nbsp;<span class=line><span style="COLOR: rgb(0,0,0)" class=ID>QString</span> <span style="COLOR: rgb(0,0,0)" class=ID>QMetaObject</span>::<span style="COLOR: rgb(0,0,0)" class=ID>tr</span>(<span style="COLOR: rgb(160,0,0)" class=ResWord>const</span> <span style="COLOR: rgb(160,0,0)" class=ResWord>char</span> *<span style="COLOR: rgb(0,0,0)" class=ID>s</span>, <span style="COLOR: rgb(160,0,0)" class=ResWord>const</span> <span style="COLOR: rgb(160,0,0)" class=ResWord>char</span> *<span style="COLOR: rgb(0,0,0)" class=ID>c</span>) <span style="COLOR: rgb(160,0,0)" class=ResWord>const</span></span><br>&nbsp;<span class=line>{</span><br>&nbsp;<span class=line><span style="COLOR: rgb(160,0,0)" class=ResWord>return</span> <span style="COLOR: rgb(0,0,0)" class=ID>QCoreApplication</span>::<span style="COLOR: rgb(0,0,0)" class=ID>translate</span>(<span style="COLOR: rgb(0,0,0)" class=ID>d</span>.<span style="COLOR: rgb(0,0,0)" class=ID>stringdata</span>, <span style="COLOR: rgb(0,0,0)" class=ID>s</span>, <span style="COLOR: rgb(0,0,0)" class=ID>c</span>, <span style="COLOR: rgb(0,0,0)" class=ID>QCoreApplication</span>::<span style="COLOR: rgb(0,0,0)" class=ID>CodecForTr</span>);<br></span>&nbsp;<span class=line>}<br></span>&nbsp;<span class=line><span style="COLOR: rgb(0,128,0)" class=Comment>/*!<br></span></span>&nbsp;<span class=line><span style="COLOR: rgb(0,128,0)" class=Comment>\internal</span></span> <br><span class=line><span style="COLOR: rgb(0,128,0)" class=Comment>*/</span></span> <br><span class=line><span style="COLOR: rgb(0,0,0)" class=ID>QString</span> <span style="COLOR: rgb(0,0,0)" class=ID>QMetaObject</span>::<span style="COLOR: rgb(0,0,0)" class=ID>trUtf8</span>(<span style="COLOR: rgb(160,0,0)" class=ResWord>const</span> <span style="COLOR: rgb(160,0,0)" class=ResWord>char</span> *<span style="COLOR: rgb(0,0,0)" class=ID>s</span>, <span style="COLOR: rgb(160,0,0)" class=ResWord>const</span> <span style="COLOR: rgb(160,0,0)" class=ResWord>char</span> *<span style="COLOR: rgb(0,0,0)" class=ID>c</span>) <span style="COLOR: rgb(160,0,0)" class=ResWord>const</span></span> <span class=line><br>{</span> <span class=line>    <br><span style="COLOR: rgb(160,0,0)" class=ResWord>return</span> <span style="COLOR: rgb(0,0,0)" class=ID>QCoreApplication</span>::<span style="COLOR: rgb(0,0,0)" class=ID>translate</span>(<span style="COLOR: rgb(0,0,0)" class=ID>d</span>.<span style="COLOR: rgb(0,0,0)" class=ID>stringdata</span>, <span style="COLOR: rgb(0,0,0)" class=ID>s</span>, <span style="COLOR: rgb(0,0,0)" class=ID>c</span>, <span style="COLOR: rgb(0,0,0)" class=ID>QCoreApplication</span>::<span style="COLOR: rgb(0,0,0)" class=ID>UnicodeUTF8</span>);</span> <span class=line><br>}</span></pre>
            </span><span class=Apple-style-span><span class=Apple-style-span>
            <p class=line874>至此，我们应该都看清楚了。我们的 Q_OBJECT 宏展开后为生成 tr ，tr调用QCoreApplication的translate函数。而该函数需要指定编码。</p>
            </span>
            <ul></ul>
                </span>
                <p>&nbsp;</p>
                </span>
                <p>&nbsp;</p>
                </span>
                <p>&nbsp;</p>
                </span></div>
                </td>
            </tr>
        </tbody>
    </table>
<img src ="http://www.cppblog.com/LiBerTine/aggbug/135872.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LiBerTine/" target="_blank">自由人</a> 2010-12-09 09:57 <a href="http://www.cppblog.com/LiBerTine/archive/2010/12/09/135872.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC中如何调用DLL中的函数</title><link>http://www.cppblog.com/LiBerTine/archive/2009/03/08/75890.html</link><dc:creator>自由人</dc:creator><author>自由人</author><pubDate>Sun, 08 Mar 2009 04:57:00 GMT</pubDate><guid>http://www.cppblog.com/LiBerTine/archive/2009/03/08/75890.html</guid><wfw:comment>http://www.cppblog.com/LiBerTine/comments/75890.html</wfw:comment><comments>http://www.cppblog.com/LiBerTine/archive/2009/03/08/75890.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/LiBerTine/comments/commentRss/75890.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LiBerTine/services/trackbacks/75890.html</trackback:ping><description><![CDATA[<div>调用DLL有两种方法：静态调用和动态调用.<br>(一).静态调用其步骤如下:<br>1.把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下;<br>2.把你的youApp.lib拷到你目标工程(需调用youApp.DLL的工程)目录下;<br>3.把你的youApp.h(包含输出函数的定义)拷到你目标工程(需调用youApp.DLL的工程)目<br>录下;<br>4.打开你的目标工程选中工程,选择Visual C++的Project主菜单的Settings菜单;<br>5.执行第4步后，VC将会弹出一个对话框，在对话框的多页显示控件中选择Link页。然<br>后在Object/library modules输入框中输入:youApp.lib<br>6.选择你的目标工程Head Files加入：youApp.h文件;<br>7.最后在你目标工程(*.cpp,需要调用DLL中的函数)中包含你的:#include "youApp.h"<br>注：youApp是你DLL的工程名。<br>2.动态调用其程序如下:<br>动态调用时只需做静态调用步骤1.<br>{<br>HINSTANCE hDllInst = LoadLibrary("youApp.DLL");<br>if(hDllInst)<br>{<br>typedef DWORD (WINAPI *MYFUNC)(DWORD,DWORD);<br>MYFUNC youFuntionNameAlias = NULL; // youFuntionNameAlias 函数别名<br>youFuntionNameAlias = (MYFUNC)GetProcAddress<br>(hDllInst,"youFuntionName");<br>// youFuntionName 在DLL中声明的函数名<br>if(youFuntionNameAlias)<br>{<br>youFuntionNameAlias(param1,param2);<br>}<br>FreeLibrary(hDllInst);<br>}<br>}<br>显式（静态）调用：<br>LIB + DLL + .H，注意.H中dllexport改为dllimport</div>
<div>隐式（动态）调用：<br>DLL + 函数原型声明，先LoadLibrary，再GetProcAddress（即找到DLL中函数的地址），不用后FreeLibrary</div>
<img src ="http://www.cppblog.com/LiBerTine/aggbug/75890.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LiBerTine/" target="_blank">自由人</a> 2009-03-08 12:57 <a href="http://www.cppblog.com/LiBerTine/archive/2009/03/08/75890.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>面向对象的三个基本特征（讲解） </title><link>http://www.cppblog.com/LiBerTine/archive/2009/02/16/73956.html</link><dc:creator>自由人</dc:creator><author>自由人</author><pubDate>Mon, 16 Feb 2009 09:47:00 GMT</pubDate><guid>http://www.cppblog.com/LiBerTine/archive/2009/02/16/73956.html</guid><wfw:comment>http://www.cppblog.com/LiBerTine/comments/73956.html</wfw:comment><comments>http://www.cppblog.com/LiBerTine/archive/2009/02/16/73956.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LiBerTine/comments/commentRss/73956.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LiBerTine/services/trackbacks/73956.html</trackback:ping><description><![CDATA[<h1 align=center><span>面向对象的三个基本特征（讲解）</span></h1>
<p><span>面向对象的三个基本特征是：封装、继承、多态。</span></p>
<p align=center><span><img height=276 alt=o_OOBase.gif src="http://www.cnitblog.com/images/cnitblog_com/lily/1972/o_OOBase.gif" width=365 border=0></span></p>
<h2><span>封装</span></h2>
<p><span>封装最好理解了。封装是面向对象的特征之一，是对象和类概念的主要特性。</span></p>
<p><span>封装，也就是把客观事物封装成抽象的类，并且类可以把自己的数据和方法只让可信的类或者对象操作，对不可信的进行信息隐藏。</span></p>
<h2><span>继承</span></h2>
<p><span>面向对象编程</span><span> (OOP) </span><span>语言的一个主要功能就是</span><span>&#8220;</span><span>继承</span><span>&#8221;</span><span>。继承是指这样一种能力：它可以使用现有类的所有功能，并在无需重新编写原来的类的情况下对这些功能进行扩展。</span></p>
<p><span>通过继承创建的新类称为&#8220;子类&#8221;或&#8220;派生类&#8221;。</span></p>
<p><span>被继承的类称为</span><span>&#8220;</span><span>基类</span><span>&#8221;</span><span>、</span><span>&#8220;</span><span>父类</span><span>&#8221;</span><span>或</span><span>&#8220;</span><span>超类</span><span>&#8221;</span><span>。</span></p>
<p><span>继承的过程，就是从一般到特殊的过程。</span></p>
<p><span>要实现继承，可以通过</span><span>&#8220;</span><span>继承</span><span>&#8221;</span><span>（</span><span>Inheritance</span><span>）和</span><span>&#8220;</span><span>组合</span><span>&#8221;</span><span>（</span><span>Composition</span><span>）来实现。</span></p>
<p><span>在某些</span><span> OOP </span><span>语言中，一个子类可以继承多个基类。但是一般情况下，一个子类只能有一个基类，要实现多重继承，可以通过多级继承来实现。</span></p>
<p>&nbsp;</p>
<p><span>继承概念的实现方式有三类：实现继承、接口继承和可视继承。</span></p>
<p><span><span>&#216;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>实现继承是指使用基类的属性和方法而无需额外编码的能力；</span></p>
<p><span><span>&#216;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力；</span></p>
<p><span><span>&#216;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>可视继承是指子窗体（类）使用基窗体（类）的外观和实现代码的能力。</span></p>
<p><span>在考虑使用继承时，有一点需要注意，那就是两个类之间的关系应该是</span><span>&#8220;</span><span>属于</span><span>&#8221;</span><span>关系。例如，</span><span>Employee </span><span>是一个人，</span><span>Manager </span><span>也是一个人，因此这两个类都可以继承</span><span> Person </span><span>类。但是</span><span> Leg </span><span>类却不能继承</span><span> Person </span><span>类，因为腿并不是一个人。</span></p>
<p><span>抽象类仅定义将由子类创建的一般属性和方法，创建抽象类时，请使用关键字</span><span> <span>Interface </span></span><span>而不是</span><span> <span>Class</span></span><span>。</span></p>
<p><span>OO</span><span>开发范式大致为：划分对象</span><span>&#8594;</span><span>抽象类</span><span>&#8594;</span><span>将类组织成为层次化结构</span><span>(</span><span>继承和合成</span><span>) &#8594;</span><span>用类与实例进行设计和实现几个阶段。</span></p>
<p>&nbsp;</p>
<h2><span>多态</span></h2>
<p><span>多态性（</span><span>polymorphisn</span><span>）是允许你将父对象设置成为和一个或更多的他的子对象相等的技术，赋值之后，父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说，就是一句话：允许将子类类型的指针赋值给父类类型的指针。</span></p>
<p><span>实现多态，有二种方式，覆盖，重载。</span></p>
<p><span>覆盖，是指子类重新定义父类的虚函数的做法。</span></p>
<p><span>重载，是指允许存在多个同名函数，而这些函数的参数表不同（或许参数个数不同，或许参数类型不同，或许两者都不同）。</span></p>
<p><span>其实，重载的概念并不属于</span><span>&#8220;</span><span>面向对象编程</span><span>&#8221;</span><span>，重载的实现是：编译器根据函数不同的参数表，对同名函数的名称做修饰，然后这些同名函数就成了不同的函数（至少对于编译器来说是这样的）。如，有两个同名函数：</span><span>function func(p:integer):integer;</span><span>和</span><span>function func(p:string):integer;</span><span>。那么编译器做过修饰后的函数名称可能是这样的：</span><span>int_func</span><span>、</span><span>str_func</span><span>。对于这两个函数的调用，在编译器间就已经确定了，是静态的（记住：是静态）。也就是说，它们的地址在编译期就绑定了（早绑定），因此，重载和多态无关！真正和多态相关的是</span><span>&#8220;</span><span>覆盖</span><span>&#8221;</span><span>。当子类重新定义了父类的虚函数后，父类指针根据赋给它的不同的子类指针，动态（记住：是动态！）的调用属于子类的该函数，这样的函数调用在编译期间是无法确定的（调用的子类的虚函数的地址无法给出）。因此，这样的函数地址是在运行期绑定的（晚邦定）。结论就是：重载只是一种语言特性，与多态无关，与面向对象也无关！引用一句</span><span>Bruce Eckel</span><span>的话：</span><span>&#8220;</span><span>不要犯傻，如果它不是晚邦定，它就不是多态。</span><span>&#8221;</span></p>
<p><span>那么，多态的作用是什么呢？我们知道，封装可以隐藏实现细节，使得代码模块化；继承可以扩展已存在的代码模块（类）；它们的目的都是为了</span><span>——</span><span>代码重用。而多态则是为了实现另一个目的</span><span>——</span><span>接口重用！多态的作用，就是为了类在继承和派生的时候，保证使用</span><span>&#8220;</span><span>家谱</span><span>&#8221;</span><span>中任一类的实例的某一属性时的正确调用。</span></p>
<p>&nbsp;</p>
<h2><span>概念讲解</span></h2>
<p><span>泛化（</span><span>Generalization</span><span>）</span></p>
<p align=center><span><img height=161 alt=o_Generalization.gif src="http://www.cnitblog.com/images/cnitblog_com/lily/1972/o_Generalization.gif" width=297 border=0></span></p>
<p align=center><font size=2><span>图表</span><font face=Arial> <span><span>1</span></span><span> </span></font><span>泛化</span></font></p>
<p><span>在上图中，空心的三角表示继承关系（类继承），在</span><span>UML</span><span>的术语中，这种关系被称为泛化（</span><span>Generalization</span><span>）。</span><span>Person(</span><span>人</span><span>)</span><span>是基类，</span><span>Teacher(</span><span>教师</span><span>)</span><span>、</span><span>Student(</span><span>学生</span><span>)</span><span>、</span><span>Guest(</span><span>来宾</span><span>)</span><span>是子类。</span></p>
<p><span>若在逻辑上</span><span>B</span><span>是</span><span>A</span><span>的&#8220;一种&#8221;，并且</span><span>A</span><span>的所有功能和属性对</span><span>B</span><span>而言都有意义，则允许</span><span>B</span><span>继承</span><span>A</span><span>的功能和属性。</span></p>
<p><span>例如，</span><span>教师是人，</span><span>Teacher </span><span>是</span><span>Person</span><span>的&#8220;一种&#8221;（</span><span>a kind of </span><span>）。</span><span>那么类</span><span>Teacher</span><span>可以从类</span><span>Person</span><span>派生（继承）。</span></p>
<p><span>如果</span><span>A</span><span>是基类，</span><span>B</span><span>是</span><span>A</span><span>的派生类，那么</span><span>B</span><span>将继承</span><span>A</span><span>的数据和函数。</span></p>
<p><span>如果类</span><span>A</span><span>和类</span><span>B</span><span>毫不相关，不可以为了使</span><span>B</span><span>的功能更多些而让</span><span>B</span><span>继承</span><span>A</span><span>的功能和属性。</span></p>
<p><span>若在逻辑上</span><span>B</span><span>是</span><span>A</span><span>的&#8220;一种&#8221;（</span><span>a kind of </span><span>），则允许</span><span>B</span><span>继承</span><span>A</span><span>的功能和属性。</span></p>
<p>&nbsp;</p>
<p><span>聚合（组合）</span></p>
<p align=center><span><img height=145 alt=o_aggregationBase.gif src="http://www.cnitblog.com/images/cnitblog_com/lily/1972/o_aggregationBase.gif" width=376 border=0></span></p>
<p align=center><font size=2><span>图表</span><font face=Arial> <span><span>2</span></span><span> </span></font><span>组合</span></font></p>
<p><span>若在逻辑上</span><span>A</span><span>是</span><span>B</span><span>的&#8220;一部分&#8221;（</span><span>a part of</span><span>），则不允许</span><span>B</span><span>从</span><span>A</span><span>派生，而是要用</span><span>A</span><span>和其它东西组合出</span><span>B</span><span>。</span></p>
<p><span>例如，眼（</span><span>Eye</span><span>）、鼻（</span><span>Nose</span><span>）、口（</span><span>Mouth</span><span>）、耳（</span><span>Ear</span><span>）是头（</span><span>Head</span><span>）的一部分，所以类</span><span>Head</span><span>应该由类</span><span>Eye</span><span>、</span><span>Nose</span><span>、</span><span>Mouth</span><span>、</span><span>Ear</span><span>组合而成，不是派生（继承）而成。</span></p>
<p>&nbsp;</p>
<p><span>聚合的类型分为无、共享</span><span>(</span><span>聚合</span><span>)</span><span>、复合</span><span>(</span><span>组合</span><span>)</span><span>三类。</span></p>
<p>&nbsp;</p>
<p><span>聚合（</span><span>aggregation</span><span>）</span></p>
<p>&nbsp;</p>
<p align=center><span><img height=55 alt=o_aggregation.gif src="http://www.cnitblog.com/images/cnitblog_com/lily/1972/o_aggregation.gif" width=229 border=0></span></p>
<p align=center><font size=2><span>图表</span><font face=Arial> <span><span>3</span></span><span> </span></font><span>共享</span></font></p>
<p><span>上面图中，有一个菱形（空心）表示聚合（</span><span>aggregation</span><span>）（聚合类型为共享），聚合的意义表示</span><span>has-a</span><span>关系。聚合是一种相对松散的关系，聚合类</span><span>B</span><span>不需要对被聚合的类</span><span>A</span><span>负责。</span></p>
<p>&nbsp;</p>
<p><span>组合（</span><span>composition</span><span>）</span></p>
<p align=center><span><img height=55 alt=o_composition.gif src="http://www.cnitblog.com/images/cnitblog_com/lily/1972/o_composition.gif" width=229 border=0></span></p>
<p align=center><font size=2><span>图表</span><font face=Arial> <span><span>4</span></span><span> </span></font><span>复合</span></font></p>
<p><span>这幅图与上面的唯一区别是菱形为实心的，它代表了一种更为坚固的关系</span><span>——</span><span>组合（</span><span>composition</span><span>）（聚合类型为复合）。组合表示的关系也是</span><span>has-a</span><span>，不过在这里，</span><span>A</span><span>的生命期受</span><span>B</span><span>控制。即</span><span>A</span><span>会随着</span><span>B</span><span>的创建而创建，随</span><span>B</span><span>的消亡而消亡。</span></p>
<p>&nbsp;</p>
<p><span>依赖</span><span>(Dependency)</span></p>
<p align=center><span><img height=55 alt=o_Dependency.gif src="http://www.cnitblog.com/images/cnitblog_com/lily/1972/o_Dependency.gif" width=229 border=0></span></p>
<p align=center><font size=2><span>图表</span><font face=Arial> <span><span>5</span></span><span> </span></font><span>依赖</span></font></p>
<p align=right><span>这里</span><span>B</span><span>与</span><span>A</span><span>的关系只是一种依赖</span><span>(Dependency)</span><span>关系，这种关系表明，如果类</span><span>A</span><span>被修改，那么类</span><span>B</span><span>会受到影响。</span></p>
<img src ="http://www.cppblog.com/LiBerTine/aggbug/73956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LiBerTine/" target="_blank">自由人</a> 2009-02-16 17:47 <a href="http://www.cppblog.com/LiBerTine/archive/2009/02/16/73956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vs.net 2005, 没有找到MSVCR80D.dll的解决方案</title><link>http://www.cppblog.com/LiBerTine/archive/2009/02/09/73323.html</link><dc:creator>自由人</dc:creator><author>自由人</author><pubDate>Mon, 09 Feb 2009 10:57:00 GMT</pubDate><guid>http://www.cppblog.com/LiBerTine/archive/2009/02/09/73323.html</guid><wfw:comment>http://www.cppblog.com/LiBerTine/comments/73323.html</wfw:comment><comments>http://www.cppblog.com/LiBerTine/archive/2009/02/09/73323.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/LiBerTine/comments/commentRss/73323.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LiBerTine/services/trackbacks/73323.html</trackback:ping><description><![CDATA[<div>[分享]VC.net&nbsp;2005找不到MSVCR80D.dll的完美解决方案</div>
<div>stevenz - BY - 2007-8-8 16:04:44</div>
<img onclick=javascript:window.open(this.src); src="http://stevenz.dpnet.com.cn/UploadFiles/2007-8/20078828013188280131.jpg" onload="javascript:if(this.width>650){this.resized=true;this.style.width=650;}" src_cetemp="http://stevenz.dpnet.com.cn/UploadFiles/2007-8/20078828013188280131.jpg"><br><br><br><br>&nbsp;<span>问题描述：大部分的</span><span ms shell dlg??>vs.net&nbsp;2005</span><span>的用户在新建</span><span ms shell dlg??>&#8220;win32</span><span>项目－</span><span ms shell dlg??>windows</span><span>应用程序</span><span ms shell dlg??>&#8221;的时候，新建的工程都通不过去，出现如下提示：</span>
<p ms shell dlg??>Solution&nbsp;to&nbsp;&#8220;MSVCR80D.dll&nbsp;not&nbsp;found&#8221;.</p>
<p><span ms shell dlg??>&#8220;</span><span>没有找到</span><span ms shell dlg??>MSVCR80D.dll</span><span>，因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。</span><span ms shell dlg??>&#8221;</span></p>
<p ms shell dlg??>&nbsp;</p>
<p><span>问题所在：由于</span><span ms shell dlg??>vs.net&nbsp;2005&nbsp;</span><span>采用了一种新的</span><span ms shell dlg??>DLL</span><span>方案，搞成一个</span><span ms shell dlg??>exe</span><span>还要配有一个</span><span ms shell dlg??>manifest</span><span>文件（一般在嵌入文件里了，所以看不到，不过也可以不嵌入，这样会生产一个</span><span ms shell dlg??>&lt;</span><span>程序名</span><span ms shell dlg??>&gt;.exe.manifest</span><span>的文件，没它</span><span ms shell dlg??>exe</span><span>自己就转不了了：）这是个新功能，微软弄了个新工具（</span><span ms shell dlg??>mt.exe</span><span>），结果不好用，好像是</span><span ms shell dlg??>fat32</span><span>下时间戳有问题（在</span><span ms shell dlg??>ntfs</span><span>下这个问题就没有了），搞得</span><span ms shell dlg??>manifest</span><span>有时嵌入不到</span><span ms shell dlg??>exe</span><span>中（默认配置是嵌入的，所以就报错找不到</span><span ms shell dlg??>dll</span><span>了。</span></p>
<p>&nbsp;</p>
<p>解决方案：</p>
<p><span ms shell dlg??>1</span><span>．</span><span ms shell dlg??>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>微软对于这个问题应该也有处理，不过感觉不是很人性化。在</span><span ms shell dlg??>&#8220;属性-&gt;</span><span>配置属性</span><span ms shell dlg??>-&gt;</span><span>清单工具</span><span ms shell dlg??>-&gt;</span><span>常规</span><span ms shell dlg??>&#8220;</span><span>下有一个&#8221;使用</span><span>FAT32</span><span>解决办法，把它选成是，就可以了。（注意：一定要先配置这个选项，然后再编译工程，要不然还是不好用：）</span></p>
<p><span ms shell dlg??>2</span><span>．</span><span ms shell dlg??>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>找到你的工程的文件夹，如（</span><span ms shell dlg??>myproject</span><span>），找到其下的</span><span ms shell dlg??>myproject\myproject\Debug\&nbsp;myproject.rec</span><span>，把它删掉（删掉整个</span><span ms shell dlg??>Debug</span><span>目录也可以），重新编译，搞定！</span></p>
<p>&nbsp;</p>
<p><span ms shell dlg??>3</span><span>．</span><span ms shell dlg??>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>本解决方案可以直接再应用向导中配置，严重符合高级人机界面要求：</span></p>
<p><span ms shell dlg??>1</span><span>）</span><span ms shell dlg??>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>首先找到你的</span><span ms shell dlg??>vs.net</span><span>安装目录（如我的是</span><span ms shell dlg??>E:\Program&nbsp;Files\Microsoft&nbsp;Visual&nbsp;Studio&nbsp;8</span><span>），定位到</span><span ms shell dlg??>Microsoft&nbsp;Visual&nbsp;Studio&nbsp;8\VC\VCWizards\AppWiz\Generic\Application</span><span>文件夹，备份这个</span><span ms shell dlg??>Application</span><span>文件夹，不然一会你自己改咂了我可不管啊：）。</span></p>
<p><span ms shell dlg??>2</span><span>）</span><span ms shell dlg??>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>打开</span><span ms shell dlg??>html\2052</span><span>，看到两个文件了吧，就那个</span><span ms shell dlg??>AppSettings.htm</span><span>了，这个管着你的那个配置向导的界面，用</span><span ms shell dlg??>UE(</span><span>不要告诉我你不知道</span><span ms shell dlg??>ue</span><span>啥东西，</span><span ms shell dlg??>baidu&nbsp;it)</span><span>打开，在</span><span ms shell dlg??>266</span><span>行</span><span ms shell dlg??>&#8220;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/SPAN&gt;&#8221;</span><span>后回车，然后插入一下内容：</span></p>
<p ms shell dlg??>&lt;!--&nbsp;this&nbsp;(hua)section&nbsp;is&nbsp;added&nbsp;by&nbsp;HUA.&nbsp;--&gt;</p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p>
<p><span ms shell dlg?; mso-highlight: silver?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span ms shell dlg?; mso-highlight: silver?>SPAN</span><span ms shell dlg?; mso-highlight: silver?>&nbsp;class='itemTextTop'&nbsp;id='FILE_SYSTEM_SPAN'&nbsp;title=''&gt;</span><span>选择你所使用的文件系统</span><span ms shell dlg?; mso-highlight: silver?>:</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;P&nbsp;CLASS='Spacer'&gt;</span><span>&amp;nbsp</span><span>&lt;/P&gt;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;INPUT&nbsp;TYPE='radio'&nbsp;CLASS='Radio'&nbsp;checked&nbsp;onPropertyChange=''&nbsp;NAME='filesystem'&nbsp;ID='FAT32'&nbsp;ACCESSKEY='F'&nbsp;TITLE='FAT32'&gt;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;DIV&nbsp;CLASS='itemTextRadioB'&nbsp;ID='FAT32_DIV'&nbsp;TITLE='FAT32'&gt;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;LABEL&nbsp;FOR='FAT32'&nbsp;ID='FAT32_LABEL'&gt;FAT32(&lt;U&gt;F&lt;/U&gt;)&lt;/LABEL&gt;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/DIV&gt;</span></p>
<p>&nbsp;</p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;BR&gt;</span></p>
<p>&nbsp;</p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;INPUT&nbsp;TYPE='radio'&nbsp;CLASS='Radio'&nbsp;onPropertyChange=''&nbsp;NAME='filesystem'&nbsp;ID='NTFS'&nbsp;ACCESSKEY='N'&nbsp;TITLE='NTFS'&gt;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;DIV&nbsp;CLASS='itemTextRadioB'&nbsp;ID='NTFS_DIV'&nbsp;TITLE='NTFS'&gt;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;LABEL&nbsp;FOR='NTFS'&nbsp;ID='NTFS_LABEL'&gt;NTFS(&lt;U&gt;N&lt;/U&gt;)&lt;/LABEL&gt;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/DIV&gt;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/</span><span>SPAN</span><span>&gt;</span></p>
<p ms shell dlg??>&lt;!--&nbsp;end&nbsp;of&nbsp;(hua)section&nbsp;--&gt;</p>
<p>好，保存关闭，这个改完了，准备下一个。</p>
<p>&nbsp;</p>
<p><span ms shell dlg??>3</span><span>）</span><span ms shell dlg??>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>打开</span><span ms shell dlg??>scripts\2052</span><span>，这里就一个文件，</span><span ms shell dlg??>ue</span><span>打开它，找到</span><span ms shell dlg??>138</span><span>行</span><span ms shell dlg??>&#8220;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;bATL&nbsp;=&nbsp;wizard.FindSymbol('SUPPORT_ATL');&#8221;</span><span>其后回车，插入如下内容：</span></p>
<p ms shell dlg??>//&nbsp;this&nbsp;(hua)section&nbsp;is&nbsp;added&nbsp;by&nbsp;HUA.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>&nbsp;</span><span>var bNTFS = wizard.FindSymbol('FILE_SYSTEM_SPAN');</span></p>
<p ms shell dlg??>//&nbsp;end&nbsp;of&nbsp;(hua)section&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p><span ms shell dlg??>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>好，继续找到</span><span ms shell dlg??>210</span><span>行</span><span ms shell dlg??>(</span><span>源文件的</span><span ms shell dlg??>210</span><span>，你加了上边的语句就不是</span><span ms shell dlg??>210</span><span>了：</span><span ms shell dlg??>)&#8220;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;config&nbsp;=&nbsp;proj.Object.Configurations.Item('Release');&#8221;</span><span>注</span><span>意这次要在这行&#8220;</span><span>前边</span><span>&#8221;加如下内容</span><span ms shell dlg??>：</span></p>
<p ms shell dlg??>//&nbsp;this&nbsp;(hua)section&nbsp;is&nbsp;added&nbsp;by&nbsp;HUA.</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>if(!bNTFS)</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;MFTool&nbsp;=&nbsp;config.Tools('VCManifestTool');</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MFTool.UseFAT32Workaround&nbsp;=&nbsp;true;</span></p>
<p ms shell dlg??><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p ms shell dlg??>//&nbsp;end&nbsp;of&nbsp;(hua)section</p>
<p><span>该段内容解决了</span><span>在向导下不点&#8220;下一步&#8221;而直接点&#8220;完成&#8221;来生成一个win32控制台项目时，则未能自动设置UseFAT32Workaround属性的值为true。</span></p>
<p>&nbsp;</p>
<p><span>修改后新建<font face="MS Shell Dlg">win32</font><span>项目时的向导如图</span></span></p>
<img src ="http://www.cppblog.com/LiBerTine/aggbug/73323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LiBerTine/" target="_blank">自由人</a> 2009-02-09 18:57 <a href="http://www.cppblog.com/LiBerTine/archive/2009/02/09/73323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IPv6名称到地址的转换函数getaddrinfo()详解</title><link>http://www.cppblog.com/LiBerTine/archive/2009/02/08/73219.html</link><dc:creator>自由人</dc:creator><author>自由人</author><pubDate>Sun, 08 Feb 2009 07:35:00 GMT</pubDate><guid>http://www.cppblog.com/LiBerTine/archive/2009/02/08/73219.html</guid><wfw:comment>http://www.cppblog.com/LiBerTine/comments/73219.html</wfw:comment><comments>http://www.cppblog.com/LiBerTine/archive/2009/02/08/73219.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LiBerTine/comments/commentRss/73219.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LiBerTine/services/trackbacks/73219.html</trackback:ping><description><![CDATA[<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPv4</span><span>中使用</span><span>gethostbyname()</span><span>函数完成主机名到地址解析，但是该</span><span>API</span><span>不允许调用者指定所需地址类型的任何信息，返回的结构只包含了用于存储</span><span>IPv4</span><span>地址的空间。为了解决该问题，</span><span>IPv6</span><span>中引入了</span><span>getaddrinfo()</span><span>的新</span><span>API</span><span>，它是<a href="http://net.rdxx.com/Knowledge/Protocol/" target=_blank>协议</a>无关的，既可用于</span><span>IPv4</span><span>也可用于</span><span>IPv6</span><span>。调用该函数会获得一个</span><span>addrinfo</span><span>结构的列表，调用的返回值是</span><span>addrinfo</span><span>的结构（列表）指针。</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>本文结合在</span><span>WinowsXP</span><span>和</span><span>Windows2003 Server</span><span>上使用该函数的经验，对</span><span>getaddrinfo</span><span>函数和</span><span>addrinfo</span><span>数据结构进行介绍，并对其参数的设置加以讨论，主要包括</span><span>nodename</span><span>和</span><span>servname</span><span>的取值对返回值的影响，</span><span>hints</span><span>成员变量的设置对返回值的影响等。</span></p>
<p><span>可能有不完全或不准确的地方，欢迎大家讨论并指出。</span></p>
<h2><span><span><span><font face=Arial>1</font></span></span></span><span><span><span><span>．</span><span><font face=Arial>getaddrinfo</font></span></span></span></span><span><span><span><span>函数</span></span></span></span><span><span><span>原型</span></span></span></h2>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=284>
            <p><strong><span>函数</span></strong><strong></strong></p>
            </td>
            <td vAlign=top width=284>
            <p><strong><span>参数说明</span></strong><strong></strong></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=284>
            <p><span>int getaddrinfo(</span></p>
            <p><span>const char* nodename</span></p>
            <p><span>const char* servname,</span></p>
            <p><span>const struct addrinfo* hints,//</span></p>
            <p><span>struct addrinfo** res</span></p>
            <p><span>);</span></p>
            </td>
            <td vAlign=top width=284>
            <p><span>nodename:</span><span>节点名可以是主机名，也可以是数字地址。（</span><span>IPV4</span><span>的</span><span>10</span><span>进点分，或是</span><span>IPV6</span><span>的</span><span>16</span><span>进制）</span></p>
            <p><span>servname:</span><span>包含十进制数的端口号或服务名如（</span><span>ftp,http</span><span>）</span></p>
            <p><span>hints:</span><span>是一个空指针或指向一个</span><span>addrinfo</span><span>结构的指针，由调用者填写关于它所想返回的信息类型的线索。</span></p>
            <p><span>res:</span><span>存放返回</span><span>addrinfo</span><span>结构链表的指针</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span>Getaddrinfo</span><span>提供独立于协议的名称解析。</span></p>
<p><span>函数的前两个参数分别是节点名和服务名。节点名可以是主机名，也可以是地址串</span><span>(IPv4</span><span>的点分十进制数表示或</span><span>IPv6</span><span>的十六进制数字串</span><span>)</span><span>。服务名可以是十进制的端口号，也可以是已定义的服务名称，如</span><span>ftp</span><span>、</span><span>http</span><span>等。<strong>注意：其中节点名和服务名都是可选项，即节点名或服务名可以为</strong></span><strong><span>NULL</span></strong><strong><span>，此时调用的结果将取缺省设置，后面将详细讨论。</span></strong><strong></strong></p>
<p><span>函数的第三个参数</span><span>hints</span><span>是</span><span>addrinfo</span><span>结构的指针，由调用者填写关于它所想返回的信息类型的线索。函数的返回值是一个指向</span><span>addrinfo</span><span>结构的链表指针</span><span>res</span><span>。</span></p>
<h2><span><span><span><span><font face=Arial>2</font></span></span></span></span><span><span><span><span><span>．</span><span><font face=Arial>addrinfo</font></span></span></span></span></span><span><span><span><span><span>结构</span></span></span></span></span></h2>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=211>
            <p><strong><span>结构</span></strong><strong></strong></p>
            </td>
            <td vAlign=top width=357>
            <p><strong><span>固定的参数</span></strong><strong></strong></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=211 rowSpan=3>
            <p><span>typedef struct addrinfo {&nbsp;</span></p>
            <p><span>int ai_flags;&nbsp;</span></p>
            <p><span>int ai_family;&nbsp;</span></p>
            <p><span>int ai_socktype;&nbsp;</span></p>
            <p><span>int ai_protocol;&nbsp;</span></p>
            <p><span>size_t ai_addrlen;&nbsp;</span></p>
            <p><span>char* ai_canonname;&nbsp;</span></p>
            <p><span>struct sockaddr* ai_addr;&nbsp;</span></p>
            <p><span>struct addrinfo* ai_next;</span></p>
            <p><span>}</span></p>
            </td>
            <td vAlign=top width=357>
            <p><span>ai_addrlen must be zero or a null pointer </span></p>
            <p><span>ai_canonname must be zero or a null pointer </span></p>
            <p><span>ai_addr must be zero or a null pointer </span></p>
            <p><span>ai_next must be zero or a null pointer </span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=357>
            <p><strong><span>可以改动的参数</span></strong><strong></strong></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=357>
            <p><span>ai_flags:AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST</span></p>
            <p><span>ai_family: </span><span>AF_INET,AF_INET6</span></p>
            <p><span>ai_socktype:</span><span>SOCK_STREAM,SOCK_DGRAM</span></p>
            <p><span>ai_protocol:</span><span>IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc.</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h2><span><span><span><span><font face=Arial>3 </font></span></span></span></span><span>参数说明</span></h2>
<p><span>在</span><span>getaddrinfo</span><span>函数之前通常需要对以下</span><span>6</span><span>个参数进行以下设置：</span><span>nodename</span><span>、</span><span>servname</span><span>、</span><span>hints</span><span>的</span><span>ai_flags</span><span>、</span><span>ai_family</span><span>、</span><span>ai_socktype</span><span>、</span><span>ai_protocol</span></p>
<p><span>在</span><span>6</span><span>项参数中，对函数影响最大的是</span><span>nodename</span><span>，</span><span>sername</span><span>和</span><span>hints.ai_flag</span></p>
<p><span>而</span><span>ai_family</span><span>只是有地址为</span><span>v4</span><span>地址或</span><span>v6</span><span>地址的区别。而</span><span>ai_protocol</span><span>一般是为</span><span>0</span><span>不作改动。</span></p>
<p><span>其中</span><span>ai_flags</span><span>、</span><span>ai_family</span><span>、</span><span>ai_socktype</span><span>说明如下：</span></p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=79>
            <p><strong><span>参数</span></strong><strong></strong></p>
            </td>
            <td vAlign=top width=120>
            <p><strong><span>取值</span></strong><strong></strong></p>
            </td>
            <td vAlign=top width=48>
            <p><strong><span>值</span></strong><strong></strong></p>
            </td>
            <td vAlign=top width=321>
            <p><strong><span>说明</span></strong><strong></strong></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=79 rowSpan=3>
            <p><span>ai_family</span></p>
            </td>
            <td vAlign=top width=120>
            <p><span>AF_INET</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>2</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>IPv4</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=120>
            <p><span>AF_INET6</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>23</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>IPv6</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=120>
            <p><span>AF_UNSPEC</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>0</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>协议无关</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=79 rowSpan=5>
            <p><span>ai_protocol</span></p>
            </td>
            <td vAlign=top width=120>
            <p><span>IPPROTO_IP</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>0</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>IP</span><span>协议</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=120>
            <p><span>IPPROTO_IPV4</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>4</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>IPv4</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=120>
            <p><span>IPPROTO_IPV6</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>41</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>IPv6</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=120>
            <p><span>IPPROTO_UDP</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>17</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>UDP</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=120>
            <p><span>IPPROTO_TCP</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>6</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>TCP</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=79 rowSpan=2>
            <p><span>ai_socktype</span></p>
            </td>
            <td vAlign=top width=120>
            <p><span>SOCK_STREAM</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>1</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>流</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=120>
            <p><span>SOCK_DGRAM</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>2</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>数据报</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=79 rowSpan=3>
            <p><span>ai_flags</span></p>
            </td>
            <td vAlign=top width=120>
            <p><span>AI_PASSIVE</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>1</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>被动的，用于</span><span>bind</span><span>，通常用于</span><span>server socket</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=120>
            <p><span>AI_CANONNAME</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>2</span></p>
            </td>
            <td vAlign=top width=321>
            <p>&nbsp;</p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=120>
            <p><span>AI_NUMERICHOST</span></p>
            </td>
            <td vAlign=top width=48>
            <p><span>4</span></p>
            </td>
            <td vAlign=top width=321>
            <p><span>地址为数字串</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>对于</span><span>ai_flags</span><span>值的说明：</span></p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=189>
            <p><span>AI_NUMERICHOST</span></p>
            </td>
            <td vAlign=top width=189>
            <p><span>AI_CANONNAME</span></p>
            </td>
            <td vAlign=top width=189>
            <p><span>AI_PASSIVE</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=189>
            <p><span>0/1</span></p>
            </td>
            <td vAlign=top width=189>
            <p><span>0/1</span></p>
            </td>
            <td vAlign=top width=189>
            <p><span>0/1</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span>如上表所示，</span><span>ai_flagsde</span><span>值范围为</span><span>0~7</span><span>，取决于程序如何设置</span><span>3</span><span>个标志位，比如设置</span><span>ai_flags</span><span>为</span><span>&nbsp;&#8220;AI_PASSIVE|AI_CANONNAME&#8221;</span><span>，</span><span>ai_flags</span><span>值就为</span><span>3</span><span>。三个参数的含义分别为：</span></p>
<p><span>(1)AI_PASSIVE</span><span>当此标志置位时，表示调用者将在</span><span>bind()</span><span>函数调用中使用返回的地址结构。当此标志不置位时，表示将在</span><span>connect()</span><span>函数调用中使用。</span></p>
<p><span>当节点名位</span><span>NULL</span><span>，且此标志置位，则返回的地址将是通配地址。</span></p>
<p><span>如果节点名</span><span>NULL</span><span>，且此标志不置位，则返回的地址将是回环地址。</span></p>
<p><span>(2)AI_CANNONAME</span><span>当此标志置位时，在函数所返回的第一个</span><span>addrinfo</span><span>结构中的</span><span>ai_cannoname</span><span>成员中，应该包含一个以空字符结尾的字符串，字符串的内容是节点名的正规名。</span></p>
<p><span>(3)AI_NUMERICHOST</span><span>当此标志置位时，<span>此标志表示调用中的节点名必须是一个数字地址字符串。</span></span><strong></strong></p>
<h2><span><font face=Arial>4</font></span><span>．实际使用的几种常用设置</span></h2>
<p><span>一般情况下，</span><span>client/server</span><span><a href="http://dev.rdxx.com/" target=_blank>编程</a>中，</span><span>server</span><span>端调用</span><span>bind</span><span>（如果面向连接的还需要</span><span>listen</span><span>），</span><span>client</span><span>则不用掉</span><span>bind</span><span>函数，解析地址后直接</span><span>connect</span><span>（面向连接）或直接发送数据（无连接）。因此，比较常见的情况有</span></p>
<p><span><span>（1）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>通常<a href="http://hw.rdxx.com/Server/" target=_blank>服务器</a>端在调用</span><span>getaddrinfo</span><span>之前，</span><span>ai_flags</span><span>设置</span><span>AI_PASSIVE</span><span>，用于</span><span>bind</span><span>；主机名</span><span>nodename</span><span>通常会设置为</span><span>NULL</span><span>，返回通配地址</span><span>[::]</span><span>。</span></p>
<p><span><span>（2）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>客户端调用</span><span>getaddrinfo</span><span>时，</span><span>ai_flags</span><span>一般不设置</span><span>AI_PASSIVE</span><span>，但是主机名</span><span>nodename</span><span>和服务名</span><span>servname</span><span>（更愿意称之为端口）则应该不为空。</span></p>
<p><span><span>（3）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>当然，即使不设置</span><span>AI_PASSIVE</span><span>，取出的地址也并非不可以被</span><span>bind</span><span>，很多程序中</span><span>ai_flags</span><span>直接设置为</span><span>0</span><span>，即</span><span>3</span><span>个标志位都不设置，这种情况下只要</span><span>hostname</span><span>和</span><span>servname</span><span>设置的没有问题就可以正确</span><span>bind</span><span>。</span></p>
<p>&nbsp;</p>
<p><span>上述情况只是简单的</span><span>client/server</span><span>中的使用，但实际在使用</span><span>getaddrinfo</span><span>和参考国外开源代码的时候，曾遇到一些将</span><span>servname</span><span>（即端口）设为</span><span>NULL</span><span>的情况</span></p>
<p><span>(</span><span>当然，此时</span><span>nodename</span><span>必不为</span><span>NULL</span><span>，否则调用</span><span>getaddrinfo</span><span>会报错</span><span>)</span><span>。以下分情况进行了测试：</span></p>
<p><span><span>（1）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>如果</span><span>nodename</span><span>是字符串型的</span><span>IPv6</span><span>地址，</span><span>bind</span><span>的时候会分配临时端口；</span></p>
<p><span><span>（2）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>如果</span><span>nodename</span><span>是本机名，</span><span>servname</span><span>为</span><span>NULL</span><span>，则根据<a href="http://os.rdxx.com/" target=_blank>操作系统</a>的不同略有不同，本文仅在</span><span><a href="http://os.rdxx.com/WindowsXP/" target=_blank>WinXP</a></span><span>和</span><span><a href="http://os.rdxx.com/Windows2003/" target=_blank>Win2003</a></span><span>上作了测试。</span></p>
<p><span><span>a)<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>WinXP</span><span>系统（</span><span>SP2</span><span>）返回</span><span>loopback</span><span>地址</span><span>[::1]</span></p>
<p><span><span>b)<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Win2003</span><span>则将本机的所有</span><span>IPv6</span><span>地址列表加以返回。因为通常一台</span><span>IPv6</span><span>主机都有可能不止一个</span><span>IPv6</span><span>地址，比如</span><span>fe80::1</span><span>（本机</span><span>loopback</span><span>地址）、</span><span>fe80::***</span><span>的</span><span>Link-Local</span><span>地址、</span><span>3ffe:***</span><span>的全局地址等等。这种情况下调用</span><span>getaddrinfo</span><span>会将这些地址全部返回，调用者应该注意如何使用这些地址。另外要注意的是，对于</span><span>fe80::</span><span>的地址在绑定的时候必须标明接口地址，即使用</span><span>fe80::20d:60ff:fe78:<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="51" UnitName="C">51c</st1:chmetcnv>2<span>%4</span></span><span>或</span><span>fe80::1<span>%1</span></span><span>这样的地址格式，通过</span><span>getaddrinfo</span><span>直接取出</span><span>fe80</span><span>地址好像无法直接</span><span>bind</span><span>。</span></p>
<h2><span><font face=Arial>5</font></span><span>．几句废话</span></h2>
<p><span>在</span><span>Windows</span><span>环境调试</span><span>IPv6</span><span>的程序个人感觉还是使用</span><span>WinXP</span><span>（</span><span>SP2</span><span>）和</span><span>Win2003</span><span>基本上没有太大的区别，使用</span><span>Win2003</span><span>更规范一些。</span></p>
<p><span>用</span><span>VC</span><span>编写和调试</span><span>IPv6</span><span>的程序一定要安装</span><span>Windows</span><span>较新的</span><span>SDK</span><span>，我安装的是</span><span>MS_Platform_SDK_Feb_2003</span><span>，否则库函数和头文件可能都会有问题。</span></p>
<p align=left><strong><span>[</span></strong><strong><span>参考</span></strong><strong><span>]</span></strong></p>
<p align=left><span>[1]MSDN Library &#8211; January 2</span><span>004</span></p>
<p align=left><span>ms-help://MS.MSDNQTR.2004JAN.1033/winsock/winsock/getaddrinfo_2.htm</span></p>
<p align=left><span>ms-help://MS.MSDNQTR.2004JAN.1033/winsock/winsock/addrinfo_2.htm</span></p>
<p align=left><span>[2]</span><span>《理解<span>IPv6</span>》（<span>"Understanding IPv<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="6" UnitName="&#8221;">6&#8221;</st1:chmetcnv></span>）<span>,</span>清华大学出版社</span></p>
<img src ="http://www.cppblog.com/LiBerTine/aggbug/73219.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LiBerTine/" target="_blank">自由人</a> 2009-02-08 15:35 <a href="http://www.cppblog.com/LiBerTine/archive/2009/02/08/73219.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网络编程－错误：（packet32.h）error C2079: 'IPAddress' uses undefined struct 'sockaddr_storage</title><link>http://www.cppblog.com/LiBerTine/archive/2009/01/28/72657.html</link><dc:creator>自由人</dc:creator><author>自由人</author><pubDate>Wed, 28 Jan 2009 09:53:00 GMT</pubDate><guid>http://www.cppblog.com/LiBerTine/archive/2009/01/28/72657.html</guid><wfw:comment>http://www.cppblog.com/LiBerTine/comments/72657.html</wfw:comment><comments>http://www.cppblog.com/LiBerTine/archive/2009/01/28/72657.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LiBerTine/comments/commentRss/72657.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LiBerTine/services/trackbacks/72657.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;
<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class=cnt id=blog_text>解决方法:<br>1.在winpcap库的packet32.h文件里面加入代码（且位于&#8220;struct npf_if_addr&#8221;定义之前）<br>#ifndef _SS_PAD1SIZE<br>struct sockaddr_storage {<br>u_char sa_len;<br>u_char sa_family;<br>u_char padding[128];<br>};<br>#endif <br>2.sockaddr_storage 改成 sockaddr</div>
            </td>
        </tr>
    </tbody>
</table>
<br>
<img src ="http://www.cppblog.com/LiBerTine/aggbug/72657.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LiBerTine/" target="_blank">自由人</a> 2009-01-28 17:53 <a href="http://www.cppblog.com/LiBerTine/archive/2009/01/28/72657.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CFileDialog 异常退出的问题 </title><link>http://www.cppblog.com/LiBerTine/archive/2008/06/21/54228.html</link><dc:creator>自由人</dc:creator><author>自由人</author><pubDate>Sat, 21 Jun 2008 08:32:00 GMT</pubDate><guid>http://www.cppblog.com/LiBerTine/archive/2008/06/21/54228.html</guid><wfw:comment>http://www.cppblog.com/LiBerTine/comments/54228.html</wfw:comment><comments>http://www.cppblog.com/LiBerTine/archive/2008/06/21/54228.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LiBerTine/comments/commentRss/54228.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LiBerTine/services/trackbacks/54228.html</trackback:ping><description><![CDATA[<div class=post>
<h2>&nbsp;</h2>
很多人遇到这个问题，终于找到了原因。<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">CFileDialog&nbsp;dlg(</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;dlg.DoModal();</span></div>
<br>第一次随便选择一个文件，第二次选择桌面的一个.txt文件，当鼠标移动到这个txt文件的时候，程序就挂了。怀疑是 微软的问题？<br><br>换api操作，照样挂。<br><br>换记事本，挂。<br><br>Windbg跟踪，找不到哪个模块，程序最后崩溃在shell32.dll，检查进程的dll模块，最后终于找到是Adobe的pdfshell.dll引起的。删除掉或者regsvr32 /u 卸载就可以了。水平有限，不能跟进那个dll去检查了。<br><br><br>pdf版本7.0.8.0 <br>系统xp sp2
<p class=postfoot>posted on 2008-06-18 11:52 <a href="http://www.cppblog.com/elva/"><u><font color=#0000ff>叶子</font></u></a> 阅读(601) <a href="http://www.cppblog.com/elva/archive/2008/06/18/53834.html#Post"><u><font color=#0000ff>评论(3)</font></u></a> &nbsp;<a href="http://www.cppblog.com/elva/admin/EditPosts.aspx?postid=53834"><u><font color=#0000ff>编辑</font></u></a>&nbsp;<a href="http://www.cppblog.com/elva/AddToFavorite.aspx?id=53834"><u><font color=#0000ff>收藏</font></u></a> <a href="http://www.cppblog.com/elva/services/trackbacks/53834.aspx"><u><font color=#0000ff>引用</font></u></a> 所属分类: <a href="http://www.cppblog.com/elva/category/4268.html"><u><font color=#0000ff>技术研究</font></u></a> </p>
</div>
<img height=1 src="http://www.cppblog.com/elva/aggbug/53834.html?webview=1" width=1> <!--
<rdf:rdf xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:description
rdf:about="http://www.cppblog.com/elva/archive/2008/06/18/53834.html"
dc:identifier="http://www.cppblog.com/elva/archive/2008/06/18/53834.html"
dc:title="CFileDialog 异常退出的问题"
trackback:ping="http://www.cppblog.com/elva/services/trackbacks/53834.aspx" />
</rdf:rdf>
-->
<script type=text/javascript>
//<![cdata[
Sys.WebForms.PageRequestManager._initialize('AjaxHolder$scriptmanager1', document.getElementById('Form1'));
Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tAjaxHolder$UpdatePanel1'], [], [], 90);
//]]&gt;
</script>
<img src ="http://www.cppblog.com/LiBerTine/aggbug/54228.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LiBerTine/" target="_blank">自由人</a> 2008-06-21 16:32 <a href="http://www.cppblog.com/LiBerTine/archive/2008/06/21/54228.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>位运算—TopCoder</title><link>http://www.cppblog.com/LiBerTine/archive/2008/06/16/53589.html</link><dc:creator>自由人</dc:creator><author>自由人</author><pubDate>Mon, 16 Jun 2008 12:27:00 GMT</pubDate><guid>http://www.cppblog.com/LiBerTine/archive/2008/06/16/53589.html</guid><wfw:comment>http://www.cppblog.com/LiBerTine/comments/53589.html</wfw:comment><comments>http://www.cppblog.com/LiBerTine/archive/2008/06/16/53589.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LiBerTine/comments/commentRss/53589.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LiBerTine/services/trackbacks/53589.html</trackback:ping><description><![CDATA[<h5 class=posthead><a id=AjaxHolder_ctl01_TitleUrl href="http://www.cnblogs.com/drizzlecrj/archive/2007/03/13/672576.html"><font color=#006ff7 size=4>A bit of fun: fun with bits[翻译]</font></a> </h5>
<div class=postText>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> A bit of fun: fun with bits<br></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【原文见：<a href="http://www.topcoder.com/tc?module=Static&amp;d1=tutorials&amp;d2=bitManipulation"><font color=#006ff7 size=2>http://www.topcoder.com/tc?module=Static&amp;d1=tutorials&amp;d2=bitManipulation</font></a>】<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 作者&nbsp;By bmerry<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;TopCoder Member<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>I<strong>ntroduction</strong><br>&nbsp;&nbsp;&nbsp; TopCoder比赛中的大部分优化都是高端优化；也就是说，它们影响的是算法而不是实现。尽管如此，使用位运算一个非常有用和高效的低端优化，或者使用一个整数的位来表示一个集合。使用它不仅可以在速度和空间上上产生一个巨大的提高，还能同时简化代码。</p>
<p>&nbsp;&nbsp;&nbsp; 在进入更多高级技巧的讨论之前，我先对基本概念进行一个简要的分类。</p>
<p><strong>The basics</strong><br>&nbsp;&nbsp;&nbsp; 位运算的核心是按位操作 &amp;(and)，|(or),~(not)和^(xor)。你应该熟悉前三者的bool运算形式(&amp;&amp;,||和!)，下面是真值表：<br>
<table class=formFrame cellSpacing=2 cellPadding=6 width=400 align=center>
    <tbody>
        <tr class=sidebarTitle nowrap="nowrap">
            <td align=middle>A</td>
            <td align=middle>B</td>
            <td align=middle>!A</td>
            <td align=middle>A &amp;&amp; B</td>
            <td align=middle>A || B</td>
            <td align=middle>A ^ B</td>
        </tr>
        <tr class=GAtableText>
            <td align=middle>0</td>
            <td align=middle>0</td>
            <td align=middle>1</td>
            <td align=middle>0</td>
            <td align=middle>0</td>
            <td align=middle>0</td>
        </tr>
        <tr class=GAtableText>
            <td align=middle>0</td>
            <td align=middle>1</td>
            <td align=middle>1</td>
            <td align=middle>0</td>
            <td align=middle>1</td>
            <td align=middle>1</td>
        </tr>
        <tr class=GAtableText>
            <td align=middle>1</td>
            <td align=middle>0</td>
            <td align=middle>0</td>
            <td align=middle>0</td>
            <td align=middle>1</td>
            <td align=middle>1</td>
        </tr>
        <tr class=GAtableText>
            <td align=middle>1</td>
            <td align=middle>1</td>
            <td align=middle>0</td>
            <td align=middle>1</td>
            <td align=middle>1</td>
            <td align=middle>0</td>
        </tr>
    </tbody>
</table>
</p>
<p>这些按位运算操作的变形是一样的，除了在解释参数时不使用true或者false而是对参数的每一个位进行运算。因此，如果A是1010，B是1100，那么<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A &amp; B = 1000&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A | B = 1110&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A ^ B = 0110&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~A = 11110101 (1的数目由A的类型决定). </p>
<p>另外两个我们需要的操作符是移位操作符 a &lt;&lt; b 和a &gt;&gt; b。前者将a中所有的位向左移动b个位置；而后者向右进行移动。对于非负值（这是我们仅需要关注的），新出现的位使用0进行填充。你可以考虑将b左移b位看作乘以2^b，将右移看作整数处以2^b。移位经常被使用来访问一个特定的位，例如,1 &lt;&lt; x是一个x位被设置，而其他位被清楚的二进制数字（位通常总是从最靠右边的/最低有效位进行计数，通常用0标注）</p>
<p>一般来说，我们使用一个整数来表示一个拥有32（或者64，使用一个64位的整数）个值的域的集合，用1来代表元素在集合中，而0表示不在其中。下面的操作都相当的直接，这里ALL_BITS是一个与域元素相对应的全1的数字。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;集合并<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A | B<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;集合交<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A &amp; B<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;集合差<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A &amp; ~B<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;集合补集<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ALL_BITS ^ A<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;设置某个位<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A |= 1 &lt;&lt; bit<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;清除某个位<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A &amp;= ~(1 &lt;&lt; bit)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;测试某个位<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(A &amp; 1 &lt;&lt; bit) != 0</p>
<p><strong>Extracting every last bit</strong><br>&nbsp;&nbsp;&nbsp; 在这一小节中，我们考虑这样一个问题，找出一个数的最高和最低的1位。对于将一个集合分散成单个元素有一些基本的运算。<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 通过正确的位运算和算术运算，找出最低位可以非常简单。假设我们想要找到x的最低位(非0位)。如果我们从x中减1，那么这个位就清除了，但是x中其他所有的位都还存在。因此, x &amp; ~(x-1)包含了x的最低设置位。尽管如此，我们得到的仅仅是值，而不是这个位的索引。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 如果我们需要得到最高或者最低位的下标，最明显的方法是遍历位（向前或者向后）直到找到被设置的位。一眼撇过，这看起来很慢，因为它根本没用到位压缩。尽管如此，如果N个元素的域的2^N个子集都算起来，那么这个循环平均使用两个迭代，事实上这个是最快的方法。<br>&nbsp;&nbsp;&nbsp; 386当中引入了用于位扫描的CPU指令： BSF(bit scan forward)和BSR(bit scan reverse)。GCC使用内建的__builtin_ctz (计数末尾的0)</p>
<p>和__builtin_clz (计数前导0)函数来完成这些操作。对于TopCoder中的C++程序员来说，有最方便的找到位索引的方法。警告：参数为0时返回值未定义。</p>
<p>&nbsp;&nbsp;&nbsp; 最后，有一个可移植的在循环解决方案需要很多迭代的情况下运行很好的方法。使用每种类型的4个或者8个字节的整数来索引一张预先定义好的存储每一个字节里面最高（低）设置位的索引的256个条目的表。整数的最高(低)位就是表中条目的最大（最小）条目。这个方法仅仅是为了完整性而提及，在TopCoder比赛中它获得的效率不太可能得到证明。</p>
<p><strong>Counting out the bits</strong><br>&nbsp;&nbsp;&nbsp; 可以很容易的判断一个数是不是2的幂次：清除最低的1位（见上面）并且检查结果是不是0.尽管如此，有的时候需要直到有多少个被设置了，这就相对有点难度了。</p>
<p>&nbsp;&nbsp;&nbsp; GCC有一个叫做__builtin_popcount的内建函数，它可以精确的计算1的个数。尽管如此，不同于__builtin_ctz，它并没有被翻译成一个硬件指令（至少在x86上不是）。相反的，它使用一张类似上面提到的基于表的方法来进行位搜索。这无疑很高效并且非常方便。</p>
<p>&nbsp;&nbsp;&nbsp; 其他语言的使用者没有这个选项（尽管他们可以重新实现这个算法）。如果一个数只有很少的1的位，另外一个方法是重复的获取最低的1位，并且清除它。</p>
<p><strong>All the subsets</strong><br>&nbsp;&nbsp;&nbsp; 位运算的一个大的优点在于它可以很平常的遍历一个N个元素集合的子集：每一个N位的值表示一些子集。更好一点是，如果A是B的子集，</p>
<p>那么表示A的数要比表示B的小，这对于一些动态规划的解决方案很方便。<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 它同样可以遍历一个特殊集合的子集（通过一些位串表示），例如让你以倒序进行访问（如果这个是一个问题的话，可以将它们生成的时</p>
<p>候放到列表中，然后从后向前访问）。这个技巧和找一个数字的最低位是类似的。如果我们从子集中减1，那么最低的集合元素被清除了，并且</p>
<p>每一个更小的元素被设置了。尽管如此，我们只想在超集中设置这些较小的元素。因此迭代步骤就是i = (i - 1) &amp; superset。</p>
<p><strong>Even a bit wrong scores zero</strong><br>&nbsp;&nbsp;&nbsp; 在进行位操作的时候容易犯一些错误。在你的代码中注意以下方面：<br>&nbsp;1. 当执行移位操作，例如a &lt;&lt; b， x86架构仅使用b的底部5个位（对64位元素是6）。这就意味着左移（右）32位等于什么都没做，</p>
<p>而不是清除所有的位。这个行为在Java和C#语言当中也被指定了；C99中说到移位至少值的大小将得到未定义的结果。历史上：8086使用完全的</p>
<p>移位寄存器，行为上的改变通常用来检测新的处理器。</p>
<p>&nbsp;2. &amp;和|的优先级比比较运算符要低。这就意味着x &amp; 3 == 1被解释成了x &amp; (3 == 1)，这不是我们想要的。</p>
<p>&nbsp;3. 如果你想书写可移植的C/C++代码，确保使用无符号的类型，尤其当你想要使用最高位的时候。C99中谈到对一个负值进行移位操作</p>
<p>是未定义的。Java仅有有符号类型： &gt;&gt;将使用扩展类型值(这可能并不是我们想要的),但是Java指定的&gt;&gt;&gt;操作符将使用0进行填充。</p>
<p><strong>Cute tricks<br></strong>&nbsp;&nbsp;&nbsp;&nbsp; 还有一些可以使用微操作进行的技巧。它们可以用来让你的朋友感到惊讶，但是一般来说在实际中并不是值得使用。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 将一个整数的位进行逆转</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">x&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0xaaaaaaaa</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0x55555555</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>x&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0xcccccccc</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0x33333333</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>x&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0xf0f0f0f0</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0x0f0f0f0f</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">);<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>x&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0xff00ff00</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0x00ff00ff</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">);<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>x&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0xffff0000</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;((x&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0x0000ffff</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">);</span></div>
<p>作为一个练习，看看你能否将它应用在取得一个字长里面所有的位的数量，遍历{0,1,...N-1}所有k个元素的子集</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;s&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;k)&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(s&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;N))<br><img id=Codehighlighter1_44_364_Open_Image onclick="this.style.display='none'; Codehighlighter1_44_364_Open_Text.style.display='none'; Codehighlighter1_44_364_Closed_Image.style.display='inline'; Codehighlighter1_44_364_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_44_364_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_44_364_Closed_Text.style.display='none'; Codehighlighter1_44_364_Open_Image.style.display='inline'; Codehighlighter1_44_364_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_44_364_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_44_364_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;do&nbsp;stuff&nbsp;with&nbsp;s</span><span style="COLOR: #008000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;lo&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;s&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">(s&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;lowest&nbsp;one&nbsp;bit</span><span style="COLOR: #008000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;lz&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(s&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;lo)&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">s;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;lowest&nbsp;zero&nbsp;bit&nbsp;above&nbsp;lo</span><span style="COLOR: #008000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;</span><span style="COLOR: #000000">|=</span><span style="COLOR: #000000">&nbsp;lz;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;add&nbsp;lz&nbsp;to&nbsp;the&nbsp;set</span><span style="COLOR: #008000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;</span><span style="COLOR: #000000">&amp;=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">(lz&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;reset&nbsp;bits&nbsp;below&nbsp;lz</span><span style="COLOR: #008000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;</span><span style="COLOR: #000000">|=</span><span style="COLOR: #000000">&nbsp;(lz&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;lo&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;put&nbsp;back&nbsp;right&nbsp;number&nbsp;of&nbsp;bits&nbsp;at&nbsp;end</span><span style="COLOR: #008000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></span><span style="COLOR: #000000">}</span></span></div>
<p>&nbsp;&nbsp;&nbsp; 在C中，最后移行可以写作 s |= (lz &gt;&gt; ffs(lo)) - 1来避免除法。<br>评估x ? y : -y,这里x是0或者1</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">(</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">x</span><span style="COLOR: #000000">^</span><span style="COLOR: #000000">y)&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;x</span></div>
<p>这个可以在二次补码记法的架构上工作（现在你能找到的机器几乎都是这样），这里负数通过将所有变反再加1得到。注意在i686和上面所说的，原始表达式是由于CMOVE(conditional move)指令而变得高效(也就是，没有分支）。</p>
<p><strong>Sample problems</strong><br><strong><a href="http://www.topcoder.com/stat?c=problem_statement&amp;pm=6725&amp;rd=10100"><font color=#006ff7 size=2>TCCC 2006, Round 1B Medium</font></a></strong><br>&nbsp;&nbsp;&nbsp; 对每一个城市，为它相邻的城市保持一个位集。一旦工厂的部分建筑被选中（递归的），将这些位加在一起将给出一个描述所有部分工厂集合的可能位置。如果这个位集合中拥有k个位，那么将有C(m,k)种方法分配集装工厂。</p>
<p><a href="http://www.topcoder.com/stat?c=problem_statement&amp;pm=6095&amp;rd=9917"><strong><font color=#006ff7 size=2>TCO 2006, Round 1 Easy</font></strong></a><br>&nbsp;&nbsp;&nbsp; 节点的数量暗示可以考虑所有可能的子集。对每一个可能的子集，我们考虑两种可能性：要么最小标号的节点根本不进行通讯，在这种情况下我们在原来的集合中排除它，要么它与一些节点交流，在这种情况下，我们将所有的这些节点排除。结果得到的代码相当短：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;dp[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">18</span><span style="COLOR: #000000">];<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;SeparateConnections::howMany(vector&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;mat)<br><img id=Codehighlighter1_79_468_Open_Image onclick="this.style.display='none'; Codehighlighter1_79_468_Open_Text.style.display='none'; Codehighlighter1_79_468_Closed_Image.style.display='inline'; Codehighlighter1_79_468_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_79_468_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_79_468_Closed_Text.style.display='none'; Codehighlighter1_79_468_Open_Image.style.display='inline'; Codehighlighter1_79_468_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_79_468_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_79_468_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;N&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;mat.size();<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;N2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;N;<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;dp[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;N2;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_178_443_Open_Image onclick="this.style.display='none'; Codehighlighter1_178_443_Open_Text.style.display='none'; Codehighlighter1_178_443_Closed_Image.style.display='inline'; Codehighlighter1_178_443_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_178_443_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_178_443_Closed_Text.style.display='none'; Codehighlighter1_178_443_Open_Image.style.display='inline'; Codehighlighter1_178_443_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_178_443_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_178_443_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;bot&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">(i&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;use&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;__builtin_ctz(bot);<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp[i]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;dp[i&nbsp;</span><span style="COLOR: #000000">^</span><span style="COLOR: #000000">&nbsp;bot];<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;use&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;j&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;N;&nbsp;j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;((i&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;j))&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;mat[use][j]&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">Y</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp[i]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;max(dp[i],&nbsp;dp[i&nbsp;</span><span style="COLOR: #000000">^</span><span style="COLOR: #000000">&nbsp;bot&nbsp;</span><span style="COLOR: #000000">^</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;j)]&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;dp[N2&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p><a href="http://www.topcoder.com/stat?c=problem_statement&amp;pm=6475&amp;rd=9988"><strong><font color=#006ff7 size=2>SRM 308, Division 1 Medium</font></strong></a><br>&nbsp;&nbsp;&nbsp; 棋盘上有36个正方形，并且都是不可辨别的，因此所有可能的位置可以编码成一个64位的整数。第一步是枚举所有合法的<br>移动，任何合法的移动可以使用3个位域表示：一个before状态，一个after状态和一个mask。mask定义了before状态的哪一个部分比较重要。</p>
<p>移动可以从当前的状态得到&nbsp; if (current &amp; mask) == before;如果得到了当前状态，那么新的状态是(current &amp; ~mask) | after</p>
<p><a href="http://www.topcoder.com/stat?c=problem_statement&amp;pm=6400&amp;rd=10000"><strong><font color=#006ff7 size=2>SRM 320, Division 1 Hard</font></strong></a><br>&nbsp;&nbsp;&nbsp; 条件告诉我们最多8个列（如果有更多的话，我们可以交换行和列），因此考虑每种方法来放置行是可行的。一旦我们有了这些信息，我们</p>
<p>可以解决这个问题（参考match editorial详情）。我们因此需要一个n位的不具有两个相邻1的整数的列表，并且我们也需要知道在每一行当中</p>
<p>有多少个1位。我的代码如下：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;n);&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_35_132_Open_Image onclick="this.style.display='none'; Codehighlighter1_35_132_Open_Text.style.display='none'; Codehighlighter1_35_132_Closed_Image.style.display='inline'; Codehighlighter1_35_132_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_35_132_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_35_132_Closed_Text.style.display='none'; Codehighlighter1_35_132_Open_Image.style.display='inline'; Codehighlighter1_35_132_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_35_132_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_35_132_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(i&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;(i&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">))&nbsp;</span><span style="COLOR: #0000ff">continue</span><span style="COLOR: #000000">;<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pg.push_back(i);<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pgb.push_back(__builtin_popcount(i));<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<p>&nbsp;</p>
</div>
<img src ="http://www.cppblog.com/LiBerTine/aggbug/53589.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LiBerTine/" target="_blank">自由人</a> 2008-06-16 20:27 <a href="http://www.cppblog.com/LiBerTine/archive/2008/06/16/53589.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>