﻿<?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++博客-雁过无痕-随笔分类-C++</title><link>http://www.cppblog.com/flyinghearts/category/14248.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 15 Jun 2014 08:04:46 GMT</lastBuildDate><pubDate>Sun, 15 Jun 2014 08:04:46 GMT</pubDate><ttl>60</ttl><item><title>SEH异常处理专利到期了</title><link>http://www.cppblog.com/flyinghearts/archive/2014/06/15/207288.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Sun, 15 Jun 2014 02:55:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2014/06/15/207288.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/207288.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2014/06/15/207288.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/207288.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/207288.html</trackback:ping><description><![CDATA[<div>　　<br />　　Borland的那个恶心的SEH异常处理专利（No:5,628,016&nbsp; Filed: June, 15, 1997），终于到期了。希望GCC/CLANG能快点完成win32的C++异常的SEH实现，下一版本的GCC，能让用户不再纠结SJLJ，Dwarf2的选择。<br /><br /></div><img src ="http://www.cppblog.com/flyinghearts/aggbug/207288.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2014-06-15 10:55 <a href="http://www.cppblog.com/flyinghearts/archive/2014/06/15/207288.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mingw gcc的头文件存在结构定义错误！！</title><link>http://www.cppblog.com/flyinghearts/archive/2013/03/21/198694.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Thu, 21 Mar 2013 13:51:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2013/03/21/198694.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/198694.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2013/03/21/198694.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/198694.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/198694.html</trackback:ping><description><![CDATA[&nbsp;<br />准确的讲是mingw所用的sdk &#8212;&#8212;&nbsp; w32api，存在结构定义错误。<br />&nbsp;<br />&nbsp;打开wingdi.h 定位到 tagGCP_RESULTSW 的结构定义位置，<br />&nbsp;<br />&nbsp; typedef struct tagGCP_RESULTSW {<br />&nbsp;&nbsp;&nbsp; DWORD lStructSize;<br />&nbsp;&nbsp;&nbsp; LPWSTR lpOutString;<br />&nbsp;&nbsp;&nbsp; UINT *lpOrder;<br />&nbsp;&nbsp;&nbsp; int *lpDx;<br />&nbsp;&nbsp;&nbsp; int *lpCaretPos;<br />&nbsp;&nbsp;&nbsp; LPWSTR lpClass;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //正确的类型应该是 LPSTR <br />&nbsp;&nbsp;&nbsp; LPWSTR lpGlyphs;<br />&nbsp;&nbsp;&nbsp; UINT nGlyphs;<br />&nbsp;&nbsp;&nbsp; int nMaxFit;<br />&nbsp; } GCP_RESULTSW,*LPGCP_RESULTSW;<br /><br />&nbsp;根据msdn, lpClass的类型应该是 LPSTR， w32api却将其声明为 LPWSTR。<br />&nbsp;<br />&nbsp; 这个bug，在2011年就有人报告了，据说cvs版本也修正了，但是直到现在，官方下载还是2011年发布的那个有bug的版本（w32api-3.17-2-mingw32-dev.tar.lzma）。<br />&nbsp; <br />&nbsp; 另外，mingw-w64（支持生成32位、64位程序）不存在这个问题。 <p>&nbsp;</p><img src ="http://www.cppblog.com/flyinghearts/aggbug/198694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2013-03-21 21:51 <a href="http://www.cppblog.com/flyinghearts/archive/2013/03/21/198694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++11 最反直觉的地方</title><link>http://www.cppblog.com/flyinghearts/archive/2012/11/22/195570.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Thu, 22 Nov 2012 11:49:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2012/11/22/195570.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/195570.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2012/11/22/195570.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/195570.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/195570.html</trackback:ping><description><![CDATA[<div><br />1 auto 会自动把 引用 去除掉<br />&nbsp; <br />&nbsp; int&amp; get();<br />&nbsp; auto k = get();&nbsp;&nbsp;&nbsp;&nbsp; // k的类型是int，而不是int&amp;<br />&nbsp;<br />&nbsp; Derived object;<br />&nbsp; auto&amp;&nbsp;&nbsp;&nbsp; same_object = (Base&amp;)object;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp; auto&nbsp; another_object = (Base&amp;)object;&nbsp; //会重新构造个Base对象 &nbsp;<br />&nbsp; <br />&nbsp;&nbsp; &nbsp;<br />2 decltype 有时会自动把 引用 加上<br /><br />&nbsp; int x;<br />&nbsp; decltype((x)) 和 decltype(*&amp;x) 的类型是int&amp;，而不是int<br />&nbsp; <br />&nbsp; 在宏中使用decltype时，要特别注意别多加了括号。<br />&nbsp; <br />&nbsp; 下面这段代码错在哪里？<br />&nbsp;&nbsp;&nbsp; template&lt;typename T, typename R&gt;<br />&nbsp;&nbsp;&nbsp; auto min(T t, R r) -&gt; decltype(t &lt; r ? t : r)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (t &lt; r ? t : r);<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp; &nbsp;<br />&nbsp; decltype(t &lt; r ? t : r)的类型是T&amp;或R&amp;，而不是所希望的T或R！<br />&nbsp; <br />&nbsp; <br />&nbsp; 标准是这样规定的：<br /><br />The type denoted by decltype(e) is defined as follows:<br />&nbsp; &#8212; if e is an unparenthesized id-expression or an unparenthesized class member<br />&nbsp;&nbsp;&nbsp;&nbsp; access (5.2.5), decltype(e) is the type of the entity named by e. If there<br />&nbsp;&nbsp;&nbsp;&nbsp; is no such entity, or if e names a set of overloaded functions, the program<br />&nbsp;&nbsp;&nbsp;&nbsp; is ill-formed;<br />&nbsp; &#8212; otherwise, if e is an xvalue, decltype(e) is T&amp;&amp;, where T is the type of e;<br />&nbsp; &#8212; otherwise, if e is an lvalue, decltype(e) is T&amp;, where T is the type of e;<br />&nbsp; &#8212; otherwise, decltype(e) is the type of e.<br />&nbsp; <br /><br />3 std::move、std::forward、右值引用<br />&nbsp; <br />&nbsp; C++11 引入 右值引用，可以做到：函数转发、针对临时对象优化<br />&nbsp; move是动词，从字面上理解好像是要移动对象，其实std::move只是简单的将类型转成右值引用而已！！！ 可以理解成 cast_to_rvalue_reference 或 treat_as_temporal_object。<br />&nbsp; <br /><br />&nbsp; void test1(int&amp;&amp;) {}<br />&nbsp; <br />&nbsp; void test2(int&amp;&amp; value)&nbsp; //注意：value的类型是int，而不是int&amp;&amp;<br />&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp; test1(value);&nbsp;&nbsp;&nbsp; //无法编译通过，因为value的类型是int！ 必须转换类型<br />&nbsp;&nbsp;&nbsp;&nbsp; test1(static_cast&lt;int&amp;&amp;&gt;(value));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //或者<br />&nbsp;&nbsp;&nbsp;&nbsp; test1(std::forward&lt;int&gt;(value));<br />&nbsp; }<br />&nbsp; <br />&nbsp; test2函数中，value的类型是int，而不是int&amp;&amp;。<br />&nbsp; 这是一个不得已的选择。如果value的类型是int&amp;&amp;的话，就会有副作用：<br />&nbsp; <br />&nbsp; void increase(int&amp; value) { ++value; }<br />&nbsp; void test3(int&amp;&amp; value) { increase(value); }<br />&nbsp; <br />&nbsp; char ch = 'a';<br />&nbsp; test3(ch);&nbsp; //本意是改变ch值，但实际上ch值不会改变，改变的是临时对像<br />&nbsp; 通过转发函数test3，increase函数可以修改临时对像，<br />&nbsp; 这造成程序员犯的错误（如上面的例子），难以在编译时就被找出来。<br />&nbsp; <br />&nbsp; <br />&nbsp; std::forward&lt;T&gt;(value) 等价于 static_cast&lt;T&amp;&amp;&gt;(value)，感觉后者更容易理解。<br />&nbsp; std::forward 起到的转发作用。如果T类型为 R&amp;、 R&amp;&amp;，经过类型转换后，其类型还是和原来的一样。<br />&nbsp; 在C++11中 <br />&nbsp;&nbsp;&nbsp; R&amp;&nbsp; &amp;&nbsp;&nbsp; 等同于 R&amp;&nbsp;&nbsp; （在c++03中，R&amp; &amp;这种写法是非法的）<br />&nbsp;&nbsp;&nbsp; R&amp;&amp; &amp;&nbsp;&nbsp; 等同于 R&amp;<br />&nbsp;&nbsp;&nbsp; R&amp;&nbsp; &amp;&amp;&nbsp; 等同于 R&amp;<br />&nbsp;&nbsp;&nbsp; R&amp;&amp; &amp;&amp;&nbsp; 等同于 R&amp;&amp;<br />&nbsp;</div><img src ="http://www.cppblog.com/flyinghearts/aggbug/195570.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2012-11-22 19:49 <a href="http://www.cppblog.com/flyinghearts/archive/2012/11/22/195570.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>decltype的小“陷阱”</title><link>http://www.cppblog.com/flyinghearts/archive/2012/08/14/187204.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Tue, 14 Aug 2012 13:19:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2012/08/14/187204.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/187204.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2012/08/14/187204.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/187204.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/187204.html</trackback:ping><description><![CDATA[int x;<br /><div>decltype(x) 和&nbsp; decltype((x))&nbsp; &nbsp; 的类型是不一样的。</div><div>decltype(x) 和&nbsp; decltype(*&amp;x)&nbsp;&nbsp; 的类型是不一样的。<br /><div></div><br /><div>decltype(x)的类型是 int<br />decltype((x)) 和 decltype(*&amp;x)&nbsp; 的类型是 int&amp;<br /><div><br />C++11标准：</div></div></div><div>The type denoted by decltype(e) is defined as follows:<br />&nbsp; &#8212; if e is an unparenthesized id-expression or an unparenthesized class member<br />&nbsp;&nbsp;&nbsp;&nbsp; access (5.2.5), decltype(e) is the type of the entity named by e. If there<br />&nbsp;&nbsp;&nbsp;&nbsp; is no such entity, or if e names a set of overloaded functions, the program<br />&nbsp;&nbsp;&nbsp;&nbsp; is ill-formed;<br />&nbsp; &#8212; otherwise, if e is an xvalue, decltype(e) is T&amp;&amp;, where T is the type of e;<br />&nbsp; &#8212; otherwise, if e is an lvalue, decltype(e) is T&amp;, where T is the type of e;<br />&nbsp; &#8212; otherwise, decltype(e) is the type of e.</div><img src ="http://www.cppblog.com/flyinghearts/aggbug/187204.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2012-08-14 21:19 <a href="http://www.cppblog.com/flyinghearts/archive/2012/08/14/187204.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内嵌汇编实现的函数转发</title><link>http://www.cppblog.com/flyinghearts/archive/2012/08/05/186382.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Sun, 05 Aug 2012 13:02:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2012/08/05/186382.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/186382.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2012/08/05/186382.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/186382.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/186382.html</trackback:ping><description><![CDATA[&nbsp; 弄着玩的。功能是简单的实现函数转发，即<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 调用CALL(func)，转为调用func()，<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 调用CALL(func, arg1, arg2) ，转为调用func(arg1, arg2)</div><br /><div>&nbsp; 代码中，宏CALL/STDCALL分别用来调用&nbsp; __cdecl/__stdcall 调用规定的函数<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsafe_call 两者都可调用，但它不是多线程安全的。<br /><br />&nbsp; 代码只支持x86 32位， 除内嵌汇编部分，尽量符合C++11标准。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>原理：<br />&nbsp;&nbsp;&nbsp;&nbsp; 刚进入函数时，<br />&nbsp;&nbsp;&nbsp;&nbsp; [esp]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 函数返回地址<br />&nbsp;&nbsp;&nbsp;&nbsp; [esp + 4]&nbsp;&nbsp;&nbsp;&nbsp; 第一个参数，即转发函数的地址<br /><div>&nbsp;&nbsp;&nbsp;&nbsp; [esp + 8]&nbsp;&nbsp;&nbsp;&nbsp; 第二个参数，即转发函数的的第一个参数</div>&nbsp; &nbsp;&nbsp; ...&nbsp; <br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 只要写三行汇编指令实现一个c_call函数，就可调用转发函数<br /><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; eax为函数返回地址<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xchg dword ptr[esp], eax&nbsp;&nbsp;&nbsp;&nbsp; ; eax为转发函数的地址，[esp]为函数返回地址<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp eax<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /><div>&nbsp;&nbsp;&nbsp;&nbsp; 当转发函数是__cdecl，即转发函数不会调节栈，由于在c_call，pop eax，使esp多加了4，因而在调用完c_call后应该手动将esp值减4，保证栈平衡。<br />&nbsp;&nbsp;&nbsp; <div>&nbsp;&nbsp;&nbsp; 当转发函数是__stdcall，转发函数会调节栈，调用转发函数完毕后，栈已经保持平衡，因而调用c_call完毕，不应该进行栈指针调节。似乎将c_call的调用改为__stdcall即可，但实际上c_call有变长参数，改成__stdcall没效果，每次调用编译器还是会自动生成调节栈指针代码。因而只能每次调用完毕，编译器给esp加了多少，就手动减多少。（编译器不一定会生成 call&nbsp; xxxx; add esp, xx这样的代码，通过改函数返回地址，忽略后面的add esp, xx指令是很糟糕的做法。）</div></div> </div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><img id="Code_Closed_Image_202018" onclick="this.style.display='none'; Code_Closed_Text_202018.style.display='none'; Code_Open_Image_202018.style.display='inline'; Code_Open_Text_202018.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" height="16" align="top" width="11"><img id="Code_Open_Image_202018" style="display: none" onclick="this.style.display='none'; Code_Open_Text_202018.style.display='none'; Code_Closed_Image_202018.style.display='inline'; Code_Closed_Text_202018.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" height="16" align="top" width="11"><span id="Code_Closed_Text_202018" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">call_redirect</span><span id="Code_Open_Text_202018" style="display: none"><br /><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;&nbsp;1</span>&nbsp;<span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">cstdio</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;&nbsp;2</span>&nbsp;<span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">cstdarg</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;&nbsp;3</span>&nbsp;<span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">windows.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;&nbsp;4</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;&nbsp;5</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;CALL(<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />)&nbsp;&nbsp;&nbsp;&nbsp;c_call(__VA_ARGS__);&nbsp;ASM_SUB_ESP(4);</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;&nbsp;6</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;STDCALL(<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />)&nbsp;c_call(__VA_ARGS__);&nbsp;ASM_SUB_ESP(MACRO_ARGS(__VA_ARGS__)&nbsp;*&nbsp;4);</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;&nbsp;7</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;&nbsp;8</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MACRO_EXPAND(x)&nbsp;x</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;&nbsp;9</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MACRO_NTH_ARG(a0,&nbsp;a1,&nbsp;a2,&nbsp;a3,&nbsp;a4,&nbsp;a5,&nbsp;a6,&nbsp;a7,&nbsp;a8,&nbsp;a9,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />)&nbsp;a9</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;10</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MACRO_ARGS(<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />)&nbsp;\</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;11</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;MACRO_EXPAND(MACRO_NTH_ARG(__VA_ARGS__,&nbsp;</span><span style="color: #000000; ">9</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">8</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">7</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">6</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">5</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">4</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">3</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">2</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">))<br /></span><span style="color: #008080; ">&nbsp;12</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;13</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#if</span><span style="color: #000000; ">&nbsp;&nbsp;__GNUC__</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;14</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;please&nbsp;enable&nbsp;option,&nbsp;-masm=intel</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">&nbsp;15</span>&nbsp;<span style="color: #008000; "></span><span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;ASM_SUB_ESP(x)&nbsp;asm("lea&nbsp;esp,&nbsp;dword&nbsp;ptr[esp&nbsp;-&nbsp;%0]"&nbsp;:&nbsp;:&nbsp;"i"(x))</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;16</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;17</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;c_call(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;pfn,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />)&nbsp;asm(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">c_call</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">&nbsp;18</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;asm(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;19</span>&nbsp;<span style="color: #000000; "></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;c_call:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;20</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop&nbsp;eax;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;21</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xchg&nbsp;dword&nbsp;ptr[esp],&nbsp;eax;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;22</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;eax;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;23</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;24</span>&nbsp;<span style="color: #000000; "></span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;25</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;unsafe_call(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;pfn,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />)&nbsp;&nbsp;asm(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">unsafe_call</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">&nbsp;26</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;asm(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;27</span>&nbsp;<span style="color: #000000; "></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lcomm&nbsp;old_ret_addr,&nbsp;</span><span style="color: #000000; ">4</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;28</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lcomm&nbsp;old_esp_value,</span><span style="color: #000000; ">4</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;29</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;unsafe_call:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;30</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop&nbsp;&nbsp;dword&nbsp;ptr&nbsp;old_ret_addr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;31</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;dword&nbsp;ptr&nbsp;old_esp_value,&nbsp;esp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;32</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;eax,&nbsp;dword&nbsp;ptr[esp];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;33</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;dword&nbsp;ptr[esp],&nbsp;offset&nbsp;last;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;34</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;eax;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;35</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;last:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;36</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;esp,&nbsp;dword&nbsp;ptr&nbsp;old_esp_value;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;37</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;dword&nbsp;ptr&nbsp;old_ret_addr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n\<br /></span><span style="color: #008080; ">&nbsp;38</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;39</span>&nbsp;<span style="color: #000000; "></span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;40</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#elif</span><span style="color: #000000; ">&nbsp;&nbsp;_MSC_VER</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;41</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;ASM_SUB_ESP(x)&nbsp;__asm&nbsp;lea&nbsp;esp,&nbsp;dword&nbsp;ptr&nbsp;[esp&nbsp;-&nbsp;x]</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;42</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;43</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;__declspec(naked)&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;c_call(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;pfn,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />)<br /></span><span style="color: #008080; ">&nbsp;44</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;45</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;46</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop&nbsp;eax;<br /></span><span style="color: #008080; ">&nbsp;47</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xchg&nbsp;dword&nbsp;ptr[esp],&nbsp;eax;<br /></span><span style="color: #008080; ">&nbsp;48</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;eax;<br /></span><span style="color: #008080; ">&nbsp;49</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">&nbsp;50</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">&nbsp;51</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;__declspec(naked)&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;unsafe_call(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;pfn,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />)<br /></span><span style="color: #008080; ">&nbsp;52</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;53</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;old_ret_addr;<br /></span><span style="color: #008080; ">&nbsp;54</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;old_esp_value;<br /></span><span style="color: #008080; ">&nbsp;55</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;56</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop&nbsp;&nbsp;old_ret_addr;<br /></span><span style="color: #008080; ">&nbsp;57</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;old_esp_value,&nbsp;esp;<br /></span><span style="color: #008080; ">&nbsp;58</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;eax,&nbsp;dword&nbsp;ptr[esp];<br /></span><span style="color: #008080; ">&nbsp;59</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;dword&nbsp;ptr[esp],&nbsp;offset&nbsp;last;<br /></span><span style="color: #008080; ">&nbsp;60</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;eax;<br /></span><span style="color: #008080; ">&nbsp;61</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;last:<br /></span><span style="color: #008080; ">&nbsp;62</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;esp,&nbsp;old_esp_value;<br /></span><span style="color: #008080; ">&nbsp;63</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;old_ret_addr;<br /></span><span style="color: #008080; ">&nbsp;64</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">&nbsp;65</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">&nbsp;66</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;67</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#else</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;68</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">#error</span><span style="color: #000000; ">&nbsp;"only&nbsp;gcc&nbsp;and&nbsp;msvc&nbsp;are&nbsp;supported"</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;69</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#endif</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;70</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;71</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;72</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;show(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;format,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />)<br /></span><span style="color: #008080; ">&nbsp;73</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">&nbsp;74</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;va_list&nbsp;args;<br /></span><span style="color: #008080; ">&nbsp;75</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;va_start(args,&nbsp;format);<br /></span><span style="color: #008080; ">&nbsp;76</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;vprintf(format,&nbsp;args);<br /></span><span style="color: #008080; ">&nbsp;77</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;va_end&nbsp;(args);<br /></span><span style="color: #008080; ">&nbsp;78</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">&nbsp;79</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;80</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;mysleep()&nbsp;{&nbsp;Sleep(</span><span style="color: #000000; ">10</span><span style="color: #000000; ">);&nbsp;}<br /></span><span style="color: #008080; ">&nbsp;81</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;82</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;test1()<br /></span><span style="color: #008080; ">&nbsp;83</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">&nbsp;84</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">5</span><span style="color: #000000; ">,&nbsp;b&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">6</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">&nbsp;85</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;show(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;+&nbsp;%d&nbsp;=&nbsp;%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;a,&nbsp;b,&nbsp;a&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;b);<br /></span><span style="color: #008080; ">&nbsp;86</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;CALL((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)printf,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;+&nbsp;%d&nbsp;=&nbsp;%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;a,&nbsp;b,&nbsp;a&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;b);<br /></span><span style="color: #008080; ">&nbsp;87</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;CALL((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)mysleep);<br /></span><span style="color: #008080; ">&nbsp;88</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;CALL((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)show,&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;+&nbsp;%d&nbsp;=&nbsp;%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;a,&nbsp;b,&nbsp;a&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;b);<br /></span><span style="color: #008080; ">&nbsp;89</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">&nbsp;90</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;91</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;test2()<br /></span><span style="color: #008080; ">&nbsp;92</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">&nbsp;93</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;STDCALL((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)MessageBoxA,&nbsp;NULL,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">text1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">caption1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;MB_OK);<br /></span><span style="color: #008080; ">&nbsp;94</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;STDCALL((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)Sleep,&nbsp;</span><span style="color: #000000; ">10</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">&nbsp;95</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;STDCALL((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)MessageBoxA,&nbsp;NULL,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">text2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">caption2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;MB_OK);<br /></span><span style="color: #008080; ">&nbsp;96</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;STDCALL((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)Sleep,&nbsp;</span><span style="color: #000000; ">100</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">&nbsp;97</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">&nbsp;98</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;99</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;test3()<br /></span><span style="color: #008080; ">100</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">101</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">5</span><span style="color: #000000; ">,&nbsp;b&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">6</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">102</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;unsafe_call((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)printf,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;+&nbsp;%d&nbsp;=&nbsp;%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;a,&nbsp;b,&nbsp;a&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;b);<br /></span><span style="color: #008080; ">103</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;unsafe_call((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)mysleep);<br /></span><span style="color: #008080; ">104</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;unsafe_call((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)show,&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;+&nbsp;%d&nbsp;=&nbsp;%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;a,&nbsp;b,&nbsp;a&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;b);<br /></span><span style="color: #008080; ">105</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;unsafe_call((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)MessageBoxA,&nbsp;NULL,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">text1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">caption1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;MB_OK);<br /></span><span style="color: #008080; ">106</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;unsafe_call((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)Sleep,&nbsp;</span><span style="color: #000000; ">10</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">107</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;unsafe_call((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)MessageBoxA,&nbsp;NULL,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">text2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">caption2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;MB_OK);<br /></span><span style="color: #008080; ">108</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;unsafe_call((</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)Sleep,&nbsp;</span><span style="color: #000000; ">100</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">109</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">110</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">111</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br /></span><span style="color: #008080; ">112</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">113</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;test1();<br /></span><span style="color: #008080; ">114</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;test2();<br /></span><span style="color: #008080; ">115</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;test3();<br /></span><span style="color: #008080; ">116</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">117</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">118</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">119</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">120</span> <span style="color: #000000; "></span></span></div><img src ="http://www.cppblog.com/flyinghearts/aggbug/186382.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2012-08-05 21:02 <a href="http://www.cppblog.com/flyinghearts/archive/2012/08/05/186382.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>避免计算过程中出现溢出的一个技巧</title><link>http://www.cppblog.com/flyinghearts/archive/2012/03/18/168267.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Sun, 18 Mar 2012 13:16:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2012/03/18/168267.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/168267.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2012/03/18/168267.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/168267.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/168267.html</trackback:ping><description><![CDATA[<div>    <p>&nbsp;</p>  <p style="text-indent: 21pt;"><span style="font-family: 宋体;">先看一道面试题：</span></p><p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><br /></span></p>    <p style="text-indent:23.6pt;"><strong><span style="font-size:12.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">长度为</span></strong><strong><span style="font-size:12.0pt">n</span></strong><strong><span style="font-size:12.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">的数组，由数字</span></strong><strong><span style="font-size:12.0pt">1</span></strong><strong><span style="font-size:12.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">到</span></strong><strong><span style="font-size:12.0pt">n</span></strong><strong><span style="font-size:12.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">组成，其中数字</span></strong><strong><span style="font-size:12.0pt">a</span></strong><strong><span style="font-size:12.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">不出现，数字</span></strong><strong><span style="font-size:12.0pt">b</span></strong><strong><span style="font-size:12.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">出现两次，其它的数字恰好出现一次。怎样通过只读遍历一次数组，找出数字</span></strong><strong><span style="font-size:12.0pt">a</span></strong><strong><span style="font-size:12.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">和</span></strong><strong><span style="font-size:12.0pt">b</span></strong><strong><span style="font-size:12.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">。</span></strong></p>  <p>&nbsp;</p>  <p>&nbsp;</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">由于只能遍历一次，在遍历数组</span>arr<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">时，算出</span> a<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>b<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的差值，以及</span>a<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>b<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">的平方差，通过解方程，即可求得</span>a<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>b<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。具体做法为：</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">设：</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>s1 = 1 + 2 + ... + n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(= n * (n + 1) / 2)</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>s2 = arr[0] + arr[1] + ... + arr[n - 1]</span></p>  <p><span>&nbsp;&nbsp;&nbsp; </span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>r1 = 1 + 4 + ... + n^2&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(= n * (n + 1) * (2 * n + 1) / 6)</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>r2 = arr[0]^2 + arr[1]^2 + ... + arr[n - 1]^2</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>  <p><span>&nbsp;&nbsp; &nbsp;&nbsp;c = a - b = s1 - s2</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp; d = a^2 - b^2 = r1 - r2</span></p>  <p>&nbsp;<span>&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">显然：</span> <span>&nbsp;a + b = (r1 - r2) / (s1 - s2) </span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">根据</span>a+b<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">的值和</span>a-b<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的值，很容易就可算出</span>a<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>b<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">。</span></p>  <p>&nbsp;</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">算法虽然简单，但实现起来，却有一个很大问题：计算</span> s1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>s2<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>r1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>r2<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这</span>4<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">个数时，计算过程中可能出现溢出，造成结果不准。由于最终目的是为了计算出</span>c<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>d<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，一个改进的方法是：</span></p>  <p><span>&nbsp;c = s1 - s2 = (1 - arr[0]) + (2 - arr[1]) + ... + (n - arr[n - 1])</span></p>  <p><span>&nbsp;d = (1 - arr[0]^2) + (4 - arr[1]^2) + ... + (n^2 - arr[n - 1]^2)</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">但这样的做法，并不能解决问题，</span>n<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">稍微大点，照样存在溢出问题。</span></p>  <p>&nbsp;</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">那么怎样才能避免计算溢出呢？答案很简单，<strong><span style="color:red">用模运算！</span></strong>每进行一次加减运算时，都取结果为原结果除以一个足够大的常数</span>M<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的余数。这样加减运算中，就不会现现溢出问题。最后再由</span> c % M<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>d % M<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，推测出</span>c<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>d<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的具体值。比如说，计算</span>s2<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">改为计算：</span></p>  <p>&nbsp;<span>&nbsp;&nbsp;s2 % M = ((((arr[0] % M) + arr[1]) % M + ...) % M + arr[n - 1]) %M</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">从表面上看，采用模运算后，计算量会增加很多。但实际上，若</span>M<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">取合适的值时，计算量并不会增加！！</span></p>  <p>&nbsp;</p>  <p style="text-indent:21.75pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">先回顾下计算机基本知识：两个各</span>N<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">位（寄存器为</span>N<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">位）的二进制无符号整数</span>a<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>b<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">相加，若结果溢出了，</span>CPU<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">会怎么处理？当然是将溢出的那一位忽略掉（可能还要设置下溢出标志），得到的结果实际上是：</span>(a + b) mod 2^N<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。<strong><span style="color:red">无符号数间的算术运算，本质上就是模运算</span></strong>。现在的</span>CPU<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">都<strong><span style="color:red">采用二补数来表示负整数，本质上也是运用模运算</span></strong>（教科书将二补数表示的负整数简单定义为：对正整数取反后加</span>1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">），这与无符号数间的运算是一致的，在实现上，比用其它方法（比如说一补数）表示负整数，要优美易实现。</span></p>  <p style="text-indent:21.75pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在</span>32<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">位平台下，</span> <span>-x mod 2^32 = 2^32 &#8211; x&nbsp;(x &gt; 0)</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span> </p>  <p style="text-indent:21.75pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">因而</span>-1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的二进制表示就是：</span>0xFFFFFFFF</p>  <p>&nbsp;</p>  <p style="text-indent:21.75pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">了解了这些，就不会奇怪</span>C/C++<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">标准的规定：无符号数间的运算是模运算不会溢出；有符号数转为无符数，采用模运算后的值。（为了兼容没采用二补数的机器，无符号数转为有符号数时，若无符号数的数值超出了有符号数可表示的范围，结果是平台相关的。）</span></p>  <p>&nbsp;</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">因而，在对</span>32<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">位</span>CPU<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">平台，可以先将有符号数转为无符号数，再取</span>M = 2 ^32<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。需要特别注意的是，应该采用多少位的无符号数保存计算中用到的数值，如何避免模运算可能带来的问题：</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">&#9312;　无符号数类型的选择：</span></p>  <p style="margin-left:27.0pt; text-indent:-6.0pt;">a<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>b<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">的取值范围为：</span>[1, n]<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span> </p>  <p style="text-indent:21.0pt;">c % M = (a - b) % M <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的取值范围为：</span>[1, n] (a &gt; b<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">时</span>)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span><span>&nbsp;&nbsp; [M - n, M - 1] (a &lt; b</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">时</span>)</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这两个范围不能重叠，而因</span> n &lt; M - n <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">即</span> 2 * n &lt; M</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">若</span> M<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">取</span>2^32<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的话，且</span><span> n &lt; 2^31</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span> <span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">可以采用</span>32<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">位无符号数表示</span>c<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的值。</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">根据</span>c % M<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">值在哪一个范围，可以确定</span>a &gt; b<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">还是</span>a &lt; b<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">由于运算过程中都是采用无符号数计算，当</span> a &lt; b<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">时，必须进行如下调整：</span></p>  <p><span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c % M </span><span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">调整为</span>&nbsp;(-c) % M</p>  <p><span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d % M </span><span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">调整为</span>&nbsp;(-d) % M</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这样才能保证结果的正确性。</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">&#9313;</span> <span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">用公式计算所有数字的和、平方和时，可能出现的问题：</span></p>  <p><span>&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">模运算满足：</span><span>&nbsp;(a <strong>*</strong> b) % M &nbsp;=&nbsp;((a % M) <strong>*</strong> (b % M)) % M</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">但<strong>不满足</strong>：</span><span>&nbsp;(a<strong> /</strong> b) % M &nbsp;=&nbsp;((a % M) <strong>/</strong> (b % M)) % M</span></p>  <p><span>&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在计算</span>&nbsp;(n * (n + 1) / 2) % M<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">时，</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">不能写成：</span></p>  <p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp; s = ((n * (n + 1)) % M / 2) % M</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span></p>  <p><span>&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">而应该写成：</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp; if &nbsp;(n % 2 == 0)&nbsp;&nbsp; s = ((n / 2) * (n + 1)) % M</span></p>  <p>&nbsp;<span>&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;s = (((n + 1) / 2) * n) % M</span></p>  <p><span>&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">或者：</span><span>s = (INT((n + 1) / 2) * (n + (n + 1) % 2)) % M </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（其中</span>INT(x)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">为取小数</span>x<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">的整数部份）。</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">完整代码：</span></p>  <p style="text-align: left;" align="left">&nbsp;</p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; "><br />#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">climits</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">cassert</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;SMALL_ARRAY&nbsp;0</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Pair&nbsp;{<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;zero;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;twice;<br />};<br /><br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">32位CPU平台，长度n一定小于2^16次方时，表示一个数的平方值，可用32位无符号数类型，效率很高。<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">长度n若在[2^16,&nbsp;2^31]区间，就必须用到64位无符号数类型，效率较高。<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">长度n若在[2^31,&nbsp;2^32)时，表示&nbsp;所有数的和sum，就必须改用64位无符号数类型，效率不高。&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">Pair&nbsp;find_number(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;arr[],&nbsp;unsigned&nbsp;len)<br />{<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned&nbsp;bits&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;CHAR_BIT&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(unsigned);<br /></span><span style="color: #0000FF; ">#if</span><span style="color: #000000; ">&nbsp;SMALL_ARRAY</span><span style="color: #000000; "><br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned&nbsp;max_len&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1u</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;(bits&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">2u</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;typedef&nbsp;unsigned&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">uint</span><span style="color: #000000; ">;<br /></span><span style="color: #0000FF; ">#else</span><span style="color: #000000; "><br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned&nbsp;max_len&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1u</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;(bits&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;typedef&nbsp;unsigned&nbsp;</span><span style="color: #0000FF; ">long</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">long</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">uint</span><span style="color: #000000; ">;<br /></span><span style="color: #0000FF; ">#endif</span><span style="color: #000000; "><br /><br />&nbsp;&nbsp;assert(arr&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;len&nbsp;</span><span style="color: #000000; ">&gt;=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">2</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;len&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;max_len);<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;data&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)arr;<br />&nbsp;&nbsp;unsigned&nbsp;sum&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">uint</span><span style="color: #000000; ">&nbsp;square_sum&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(unsigned&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;len;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned&nbsp;value&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;data[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;value;<br />&nbsp;&nbsp;&nbsp;&nbsp;square_sum&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">uint</span><span style="color: #000000; ">)value&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;value;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">注意两个数的乘积是否会溢出&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">1&nbsp;+&nbsp;2&nbsp;+&nbsp;3&nbsp;+&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;+&nbsp;len&nbsp;=&nbsp;len&nbsp;*&nbsp;(len&nbsp;+&nbsp;1)&nbsp;/&nbsp;2</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">uint</span><span style="color: #000000; ">&nbsp;sum_all&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(len&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">2u</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">uint</span><span style="color: #000000; ">)(len&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;(len&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">%</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">2u</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">1^2&nbsp;+&nbsp;2^2&nbsp;+&nbsp;3^2&nbsp;+&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;+&nbsp;len^2&nbsp;=&nbsp;len&nbsp;*&nbsp;(len&nbsp;+&nbsp;1)&nbsp;*&nbsp;(2&nbsp;*&nbsp;len&nbsp;+&nbsp;1)&nbsp;/&nbsp;6</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned&nbsp;len2&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">2u</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;len&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">uint</span><span style="color: #000000; ">&nbsp;square_sum_all&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;len2&nbsp;</span><span style="color: #000000; ">%</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">3u</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; ">&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;len2&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">3u</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;sum_all&nbsp;:&nbsp;sum_all&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">3u</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;len2;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;unsigned&nbsp;difference&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(unsigned)sum_all&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;sum;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">uint</span><span style="color: #000000; ">&nbsp;square_difference&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;square_sum_all&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;square_sum;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;is_negative&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;difference&nbsp;</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;INT_MAX;<br /><br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(is_negative)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;difference&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">difference;<br />&nbsp;&nbsp;&nbsp;&nbsp;square_difference&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">square_difference;<br />&nbsp;&nbsp;}&nbsp;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;assert(difference&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;square_difference&nbsp;</span><span style="color: #000000; ">%</span><span style="color: #000000; ">&nbsp;difference&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned&nbsp;sum_two&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;square_difference&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;difference;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;assert((sum_two&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;difference)&nbsp;</span><span style="color: #000000; ">%</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">2u</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 />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned&nbsp;larger&nbsp;&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(sum_two&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;difference)&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">2u</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;unsigned&nbsp;smaller&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(sum_two&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;difference)&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">2u</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(is_negative)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;Pair&nbsp;result&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{&nbsp;smaller,&nbsp;larger};<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;result;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;Pair&nbsp;result&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{&nbsp;larger,&nbsp;smaller};<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;result;<br />}<br /><br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br />{<br /><br />}<br /><br /><br /></span></div></div><img src ="http://www.cppblog.com/flyinghearts/aggbug/168267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2012-03-18 21:16 <a href="http://www.cppblog.com/flyinghearts/archive/2012/03/18/168267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC 2010　error D8027，无法执行c1xx.dll的解决方法</title><link>http://www.cppblog.com/flyinghearts/archive/2011/07/19/151417.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Tue, 19 Jul 2011 14:07:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2011/07/19/151417.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/151417.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2011/07/19/151417.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/151417.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/151417.html</trackback:ping><description><![CDATA[<br /><div>　　晚上想跑个程序，结果VC 2010头一次罢工：　<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; cl: 命令行 error D8027 :无法执行&#8220;E:\prog\vc2010\bin\c1xx.dll&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp; 上网搜索了下，也没找到一个解决方法（<a href="http://msdn.microsoft.com/en-us/library/733t42a9.aspx">官方说明</a>）。正郁闷着，突然间想到cl.exe可以正常运行，而c1xx.dll不能正常运行，会不会是c1xx.dll的依赖库出问题了，于是调出dependency一查，果然少了个msvcp100.dll（估计是某个卸载软件造成的），从别处拷贝一个到bin目录，问题解决。<br /></div><img src ="http://www.cppblog.com/flyinghearts/aggbug/151417.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2011-07-19 22:07 <a href="http://www.cppblog.com/flyinghearts/archive/2011/07/19/151417.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用asio传文件</title><link>http://www.cppblog.com/flyinghearts/archive/2011/07/07/150421.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Thu, 07 Jul 2011 15:01:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2011/07/07/150421.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/150421.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2011/07/07/150421.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/150421.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/150421.html</trackback:ping><description><![CDATA[<div><p>&nbsp;&nbsp;&nbsp; 看了几天asio文档，总算可以写点小程序了。有些细节还是没弄明白，同步IO好像还不能设超时？服务器端采用异步IO，客户端则采用同步IO。传送文件，不得不注意到 C/C++ 2G文件限制，好像没通用的解决方法。<br /></p><p>&nbsp;</p><p>先定义下头文件，统一下asio和boost_asio。</p></div><br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;"><br />#ifndef&nbsp;_FILE_INFO_H_<br /></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;_FILE_INFO_H_</span><span style="color: #000000;"><br /><br />&nbsp;&nbsp;</span><span style="color: #0000ff;">#if</span><span style="color: #000000;">&nbsp;USE_ASIO_ALONE</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">asio.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />&nbsp;&nbsp;</span><span style="color: #0000ff;">#else</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">asio.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;asio&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">using</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;boost::asio;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">using</span><span style="color: #000000;">&nbsp;boost::system::error_code;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;File_info&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;unsigned&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;Size_type;<br />&nbsp;&nbsp;&nbsp;&nbsp;Size_type&nbsp;filesize;<br />&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;filename_size;<br />&nbsp;&nbsp;&nbsp;&nbsp;File_info()&nbsp;:&nbsp;filesize(</span><span style="color: #000000;">0</span><span style="color: #000000;">),&nbsp;filename_size(</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{}<br />&nbsp;&nbsp;};<br />&nbsp;&nbsp;<br /></span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br /></span></div><br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><img id="Code_Closed_Image_230019" onclick="this.style.display='none'; Code_Closed_Text_230019.style.display='none'; Code_Open_Image_230019.style.display='inline'; Code_Open_Text_230019.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11"><img id="Code_Open_Image_230019" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_230019.style.display='none'; Code_Closed_Image_230019.style.display='inline'; Code_Closed_Text_230019.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11"><span id="Code_Closed_Text_230019" style="border: 1px solid #808080; background-color: #ffffff;">client_sender</span><span id="Code_Open_Text_230019" style="display: none;"><br /><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;"><br /></span><span style="color: #008000;">//</span><span style="color: #008000;">www.cnblogs.com/flyinghearts</span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br />#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">cstdio</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">cstring</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">shared_ptr.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">file_info.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br /><br /><br /></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;sender(asio::io_service</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;io,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;ip_address,&nbsp;unsigned&nbsp;port,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;filename)<br />{<br />&nbsp;&nbsp;typedef&nbsp;asio::ip::tcp&nbsp;TCP;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;FILE&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">fp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;fopen(filename,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">rb</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(fp&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;NULL)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">cannot&nbsp;open&nbsp;file\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">使用智能指针，防止程序出现异常时，fclose未被调用。</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;boost::shared_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">FILE</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;file_ptr(fp,&nbsp;fclose);<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;clock_t&nbsp;cost_time&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;clock();<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;size_t&nbsp;k_buffer_size&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">32</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1024</span><span style="color: #000000;">;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;buffer[k_buffer_size];<br />&nbsp;&nbsp;File_info&nbsp;file_info;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;filename_size&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;strlen(filename)&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />&nbsp;&nbsp;size_t&nbsp;file_info_size&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(file_info);<br />&nbsp;&nbsp;size_t&nbsp;total_size&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;file_info_size&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;filename_size;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(total_size&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;k_buffer_size)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">File&nbsp;name&nbsp;is&nbsp;too&nbsp;long</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;file_info.filename_size&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;filename_size;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;fseek(fp,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;SEEK_END);<br />&nbsp;&nbsp;file_info.filesize&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;ftell(fp);<br />&nbsp;&nbsp;rewind(fp);<br /><br />&nbsp;&nbsp;memcpy(buffer,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">file_info,&nbsp;file_info_size);<br />&nbsp;&nbsp;memcpy(buffer&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;file_info_size,&nbsp;filename,&nbsp;filename_size);<br /><br />&nbsp;&nbsp;TCP::socket&nbsp;socket(io);<br />&nbsp;&nbsp;socket.connect(TCP::endpoint(asio::ip::address_v4::from_string(ip_address),&nbsp;port));<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Sending&nbsp;file&nbsp;:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;filename&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;size_t&nbsp;len&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;total_size;<br />&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;total_bytes_read&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;socket.send(asio::buffer(buffer,&nbsp;len),&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(feof(fp))&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;fread(buffer,&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;k_buffer_size,&nbsp;fp);<br />&nbsp;&nbsp;&nbsp;&nbsp;total_bytes_read&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;len;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;cost_time&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;clock()&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;cost_time;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(cost_time&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;cost_time&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;speed&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;total_bytes_read&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;(CLOCKS_PER_SEC&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1024.0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1024.0</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;cost_time;<br />&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">cost&nbsp;time:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;cost_time&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">double</span><span style="color: #000000;">)&nbsp;CLOCKS_PER_SEC&nbsp;&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;s&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;&nbsp;transferred_bytes:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;total_bytes_read&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;bytes\n</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">speed:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;&nbsp;speed&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;MB/s\n\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;&nbsp;<br />}<br /><br /></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;args,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argc[])<br />{<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(args&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">3</span><span style="color: #000000;">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Usage:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;argc[</span><span style="color: #000000;">0</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;ip_address&nbsp;&nbsp;filename1&nbsp;filename2&nbsp;<img src="http://www.cppblog.com/Images/dot.gif" alt="" />\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;asio::io_service&nbsp;io;<br />&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;">2</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;args;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{&nbsp;sender(io,&nbsp;argc[</span><span style="color: #000000;">1</span><span style="color: #000000;">],&nbsp;</span><span style="color: #000000;">1345</span><span style="color: #000000;">,&nbsp;argc[i]);&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(std::exception</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;err)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;err.what()&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />}<br /><br /></span></span></div><br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><img id="Code_Closed_Image_230056" onclick="this.style.display='none'; Code_Closed_Text_230056.style.display='none'; Code_Open_Image_230056.style.display='inline'; Code_Open_Text_230056.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11"><img id="Code_Open_Image_230056" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_230056.style.display='none'; Code_Closed_Image_230056.style.display='inline'; Code_Closed_Text_230056.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11"><span id="Code_Closed_Text_230056" style="border: 1px solid #808080; background-color: #ffffff;">server_receiver</span><span id="Code_Open_Text_230056" style="display: none;"><br /><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;"><br /></span><span style="color: #008000;">//</span><span style="color: #008000;">www.cnblogs.com/flyinghearts</span><span style="color: #008000;"><br /></span><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">cstdio</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">bind.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">shared_ptr.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">enable_shared_from_this.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br /><br />#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">file_info.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br /><br /></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Session&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;boost::enable_shared_from_this</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Session</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;{<br /></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br />&nbsp;&nbsp;typedef&nbsp;asio::ip::tcp&nbsp;TCP;<br />&nbsp;&nbsp;typedef&nbsp;asio::error_code&nbsp;Error;&nbsp;<br />&nbsp;&nbsp;typedef&nbsp;boost::shared_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Session</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;Pointer;<br />&nbsp;&nbsp;typedef&nbsp;File_info::Size_type&nbsp;Size_type;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;print_asio_error(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;Error</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;error)&nbsp;{&nbsp;std::cerr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;error.message()&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;Pointer&nbsp;create(asio::io_service</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;io)&nbsp;{&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;Pointer(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Session(io));}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;TCP::socket</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;socket()&nbsp;{&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;socket_;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">Session()&nbsp;<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(fp_)&nbsp;fclose(fp_);<br />&nbsp;&nbsp;&nbsp;&nbsp;clock_&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;clock()&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;clock_;<br />&nbsp;&nbsp;&nbsp;&nbsp;Size_type&nbsp;bytes_writen&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;total_bytes_writen_;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(clock_&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;clock_&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;speed&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;bytes_writen&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;(CLOCKS_PER_SEC&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1024.0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1024.0</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;clock_&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">cost&nbsp;time:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;clock_&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">double</span><span style="color: #000000;">)&nbsp;CLOCKS_PER_SEC&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;s&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">bytes_writen:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;bytes_writen&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;bytes\n</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">speed:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;&nbsp;speed&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;MB/s\n\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;&nbsp;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;start()<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;clock_&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;clock();<br />&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">client:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;socket_.remote_endpoint().address()&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;socket_.async_receive(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;asio::buffer(reinterpret_cast</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*&gt;</span><span style="color: #000000;">(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">file_info_),&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(file_info_)),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::bind(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">Session::handle_header,&nbsp;shared_from_this(),&nbsp;asio::placeholders::error));&nbsp;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br /></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br />&nbsp;&nbsp;Session(asio::io_service</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;io)&nbsp;:&nbsp;socket_(io),&nbsp;fp_(NULL),&nbsp;total_bytes_writen_(</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;handle_header(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;Error</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;error)&nbsp;<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(error)&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;print_asio_error(error);<br />&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;filename_size&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;file_info_.filename_size;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(filename_size&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;k_buffer_size)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Path&nbsp;name&nbsp;is&nbsp;too&nbsp;long!\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">得用async_read,&nbsp;不能用async_read_some，防止路径名超长时，一次接收不完</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;asio::async_read(socket_,&nbsp;asio::buffer(buffer_,&nbsp;file_info_.filename_size),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::bind(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">Session::handle_file,&nbsp;shared_from_this(),&nbsp;asio::placeholders::error));&nbsp;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;handle_file(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;Error</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;error)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(error)&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;print_asio_error(error);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">basename&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;buffer_&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;file_info_.filename_size&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(basename&nbsp;</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">&nbsp;buffer_&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">basename&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">\\</span><span style="color: #000000;">'</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">basename&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">/</span><span style="color: #000000;">'</span><span style="color: #000000;">))&nbsp;</span><span style="color: #000000;">--</span><span style="color: #000000;">basename;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">basename;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Open&nbsp;file:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;basename&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;buffer_&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">)\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;fp_&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;fopen(basename,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">wb</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(fp_&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;NULL)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Failed&nbsp;to&nbsp;open&nbsp;file&nbsp;to&nbsp;write\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;receive_file_content();<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;receive_file_content()<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;socket_.async_receive(asio::buffer(buffer_,&nbsp;k_buffer_size),&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::bind(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">Session::handle_write,&nbsp;shared_from_this(),&nbsp;asio::placeholders::error,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;asio::placeholders::bytes_transferred));&nbsp;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;handle_write(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;Error</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;error,&nbsp;size_t&nbsp;bytes_transferred)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(error)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(error&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;asio::error::eof)&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;print_asio_error(error);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size_type&nbsp;filesize&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;file_info_.filesize;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(total_bytes_writen_&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;filesize)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Filesize&nbsp;not&nbsp;matched!&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;total_bytes_writen_&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">/</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;filesize&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;total_bytes_writen_&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;fwrite(buffer_,&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;bytes_transferred,&nbsp;fp_);<br />&nbsp;&nbsp;&nbsp;&nbsp;receive_file_content();<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;clock_t&nbsp;clock_;<br />&nbsp;&nbsp;TCP::socket&nbsp;socket_;<br />&nbsp;&nbsp;FILE&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">fp_;<br />&nbsp;&nbsp;File_info&nbsp;file_info_;<br />&nbsp;&nbsp;Size_type&nbsp;total_bytes_writen_;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;unsigned&nbsp;k_buffer_size&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1024</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">32</span><span style="color: #000000;">;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;buffer_[k_buffer_size];<br />};<br /><br /></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tcp_server<br />{<br /></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br />&nbsp;&nbsp;typedef&nbsp;asio::ip::tcp&nbsp;TCP;<br />&nbsp;&nbsp;typedef&nbsp;asio::error_code&nbsp;Error;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;Tcp_server(asio::io_service</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;io,&nbsp;unsigned&nbsp;port)&nbsp;:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor_(io,&nbsp;TCP::endpoint(TCP::v4(),&nbsp;port))<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;start_accept();<br />&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;print_asio_error(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;Error</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;error)&nbsp;{&nbsp;std::cerr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;error.message()&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;}<br /><br /></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;start_accept()<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Session::Pointer&nbsp;session&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Session::create(acceptor_.get_io_service());<br />&nbsp;&nbsp;&nbsp;&nbsp;acceptor_.async_accept(session</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">socket(),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::bind(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">Tcp_server::handle_accept,&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">,&nbsp;session,&nbsp;asio::placeholders::error));<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;handle_accept(Session::Pointer&nbsp;session,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;Error</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;error)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(error)&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;print_asio_error(error);<br />&nbsp;&nbsp;&nbsp;&nbsp;session</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">start();<br />&nbsp;&nbsp;&nbsp;&nbsp;start_accept();<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;TCP::acceptor&nbsp;acceptor_;<br />};<br /><br /><br /></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br />{<br />&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Auto&nbsp;receive&nbsp;files&nbsp;and&nbsp;save&nbsp;then&nbsp;in&nbsp;current&nbsp;directory.\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />&nbsp;&nbsp;asio::io_service&nbsp;io;<br />&nbsp;&nbsp;Tcp_server&nbsp;receiver(io,&nbsp;</span><span style="color: #000000;">1345</span><span style="color: #000000;">);&nbsp;&nbsp;<br />&nbsp;&nbsp;io.run();<br />}<br /><br /></span></span></div><img src ="http://www.cppblog.com/flyinghearts/aggbug/150421.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2011-07-07 23:01 <a href="http://www.cppblog.com/flyinghearts/archive/2011/07/07/150421.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数组左旋转k位 —— C++标准算法库中最悲剧的函数：rotate</title><link>http://www.cppblog.com/flyinghearts/archive/2011/05/27/147403.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Fri, 27 May 2011 13:04:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2011/05/27/147403.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/147403.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2011/05/27/147403.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/147403.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/147403.html</trackback:ping><description><![CDATA[<br /><div><p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">要将一个数组的所有元素向左旋转</span>k<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">位，通常有三种算法：</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">算法</span>1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（</span><span style="font-family: 宋体">分组交换）：</span></p>  <p style="text-indent:26.25pt;"><span style="font-family:宋体">若a长度大于b，将ab分成a<sub>0</sub>a<sub>1</sub>b，交换a<sub>0</sub>和b，得ba<sub>1</sub>a<sub>0</sub>，只需再交换a<sub>1 </sub>和a<sub>0</sub>。</span></p>  <p style="text-indent:26.25pt;"><span style="font-family:宋体">若a长度小于b，将ab分成ab<sub>0</sub>b<sub>1</sub>，交换a和b<sub>0</sub>，得b<sub>0</sub>ab<sub>1</sub>，只需再交换a<sub> </sub>和b<sub>1</sub>。</span></p>  <p style="text-indent:26.25pt;"><span style="font-family:宋体">不断将数组划分和交换，直到不能再划分为止。分组过程与求最大公约数很相似。</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体">&nbsp;</span><span style=" font-family:宋体">读写内存各 n到2*n次</span></p>  <p style="text-indent:15.75pt;">&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">算法</span>2 (<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">三次反转</span>)</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体">利用ba=(b<sup>r</sup>)<sup>r</sup>(a<sup>r</sup>)<sup>r</sup>=(a<sup>r</sup>b<sup>r</sup>)<sup>r</sup>，先分别反转a、b，最后再对所有元素进行一次反转。</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体">读写内存各约2*n次</span></p>  <p style="text-indent:21.0pt;">&nbsp;</p>  <p><span style="font-family:宋体">算法3 （使用循环链）</span></p>  <p style="margin-left:21.0pt;"><span style="font-family:宋体">假设 n、k的最大公约数为M，则所有序号为<span> (i + j*k) % n (0&lt;= i &lt; M, 0 &lt;= j &lt; n/M)</span>的元素，构成M个循环链（i值相同的在同一个循环链上）， 每个循环链上的元素移动到前一个元素的元素，就可以交换到最终结果上的位置，因而总共只要读写内存各n次。（比如： 1 2 3 4 5 6，左移2位， 1 3 5 和 2 4 6分别构成两个循环链。）</span></p>  <p>&nbsp;</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">事实上</span>C++<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">标准算法库提供了现成的函数：</span>rotate<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">函数。按理说，几种算法都比较简单，编译器的库函数又是经过时间检验的，效率即使比手写的差，也不会差太多。但如果对</span>rotate<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">函数进行测试的话，可能会发现标准库的版本慢得可不是一点点。</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">对</span>VC 2010<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，运行后面的测试程序，自定义函数（采用算法</span>2<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）要用</span><span style="color:red">99ms</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，而</span>std::rotate<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">却要</span><span style="color:red">1656ms</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。是库的实现者不懂得用这个简单的算法吗？检查下库的源代码，就会发现：标准算法库中，对</span>C++<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的三种迭代器（前向迭代器、双向迭代器，随机访问迭代器），分别采用了上面三种算法。直接调用其内部的实现（</span>std::_Rotat<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">函数），重新测试下，可得到下面结果：</span></p>  <p style="text-indent:21.0pt;">&nbsp;</p>  <div align="center">  <table style="border-collapse:collapse;border:none;" border="1" cellpadding="0" cellspacing="0">  <tbody><tr>   <td style="border:solid windowtext 1.0pt;   padding:0cm 5.4pt 0cm 5.4pt" valign="top">   <p style="text-align:center;text-indent:10.5pt;" align="center"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">迭代器</span></p>   </td>   <td style="border:solid windowtext 1.0pt;border-left:none;   padding:0cm 5.4pt 0cm 5.4pt" valign="top">   <p style="text-align:center" align="center"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">前向（算法</span>1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）</span></p>   </td>   <td style="border:solid windowtext 1.0pt;border-left:none;   padding:0cm 5.4pt 0cm 5.4pt" valign="top">   <p style="text-align:center" align="center"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">双向（算法</span>2<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）</span></p>   </td>   <td style="border:solid windowtext 1.0pt;border-left:none;   padding:0cm 5.4pt 0cm 5.4pt" valign="top">   <p style="text-align:center" align="center"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">随机访问（算法</span>3<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）</span></p>   </td>  </tr>  <tr>   <td style="border:solid windowtext 1.0pt;border-top:none;   padding:0cm 5.4pt 0cm 5.4pt" valign="top">   <p style="text-align:center" align="center"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">时间（</span>ms<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）</span></p>   </td>   <td style="border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;   border-right:solid windowtext 1.0pt;   padding:0cm 5.4pt 0cm 5.4pt" valign="top">   <p style="text-align:center" align="center">46</p>   </td>   <td style="border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;   border-right:solid windowtext 1.0pt;   padding:0cm 5.4pt 0cm 5.4pt" valign="top">   <p style="text-align:center" align="center">99</p>   </td>   <td style="border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;   border-right:solid windowtext 1.0pt;   padding:0cm 5.4pt 0cm 5.4pt" valign="top">   <p style="text-align:center" align="center">1651</p>   </td>  </tr> </tbody></table>  </div>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:7.5pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（使用</span><span style="font-size:7.5pt">GCC</span><span style="font-size:7.5pt; font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的，请用版本号低于</span><span style="font-size:7.5pt">4.5</span><span style="font-size:7.5pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的进行测试）</span></p>  <p>&nbsp;</p>  <p><span>&nbsp;&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">从结果可以看出，效率是：<strong><span style="color:blue">算法</span></strong></span><strong><span style="color:blue">1 &gt; </span></strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:blue">算法</span><span style="color:blue">2 &gt;&gt;&gt; </span></strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:blue">算法</span><span style="color:blue">3</span></strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。</span>&nbsp;</p>  <p>&nbsp;</p>  <p style="text-indent:21.75pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">从理论上讲，算法</span>3<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">只要读写内存各</span>n<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">次，应该是效率最高的算法。这在每次内存读写的开销相差不大时成立。但实际上，由于硬件限制，</span>CPU<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">对内存的访问采用分级缓存机制：一级缓存容量很小但访问速度最快，存放程序的指令和最常用的数据，而二、三级缓存容量较大但访问速度要慢很多。</span>CPU<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">是无法绕过缓存直接访问内存数据（某些特殊指令可以不用一二三级缓存，但它也要用到其它专用缓存），对不在缓存中的数据，必须先载入到缓存中，这个操作是相当昂贵的。对大数组来说，不可能将所有数据都存放在缓存中，而对内存的不连续访问，</span>CPU<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">对内存定位的开销（各级缓存间数据的调整，反复移入或移出数据到缓存）是巨大的，这就造成了算法</span>3<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的性能在该情况下非常差。测试发现，</span>k = 3<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">时，该算法的效率就已经相当差了。对小数组，尽管该算法读写次数少，但由于各种算法所用时间都很小，这种优势很难体现出来。可以说，<strong><span style="color:blue">算法</span></strong></span><strong><span style="color:blue">3</span></strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:blue">在数学上是非常优美的，但是在实际应用中，是一种相当差的算法。</span></strong></p>  <p style="text-indent:21.75pt"><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">对算法的选择，不应该忽视内存因素。</span></strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在对随机访问迭代器版本的</span>roate<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">实现上犯这个错误的，可不仅仅是</span><strong><span style="color:blue">VC</span></strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，还有著名的</span><strong><span style="color:blue">STL Port</span></strong><strong><span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">、</span><span style="color:blue">GCC</span></strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（</span><strong>GCC</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">从</span>4.5</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">开始</span>libstdc++</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">改用算法</span>1</strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，并做了些优化），以及新兴的</span><strong><span style="color:blue">libc++</span></strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。（其它的编译器</span>/<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">库没用过，也就没有测试。）</span></p>  <p>&nbsp;</p>  <p style="text-indent:21.75pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">另外，测试时发现</span><strong><span style="color:blue">VC 2010</span></strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:blue">的一个</span><span style="color:blue">bug</span></strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">：前向迭代器的实现版本，当</span>k = 0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">时，程序直接挂了。</span></p>  <p>&nbsp;</p>  <p>测试代码：</p><p><br /></p>  </div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><img id="Code_Closed_Image_210241" onclick="this.style.display='none'; Code_Closed_Text_210241.style.display='none'; Code_Open_Image_210241.style.display='inline'; Code_Open_Text_210241.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11"><img id="Code_Open_Image_210241" style="display: none" onclick="this.style.display='none'; Code_Open_Text_210241.style.display='none'; Code_Closed_Image_210241.style.display='inline'; Code_Closed_Text_210241.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11"><span id="Code_Closed_Text_210241" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">rotate</span><span id="Code_Open_Text_210241" style="display: none"><br /><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #000000; "></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;www.cnblogs.com/flyinghearts</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #008000; "></span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">vector</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">algorithm</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">iterator</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">ctime</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#if</span><span style="color: #000000; ">&nbsp;__GNUC__</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;ROTATE&nbsp;std::__rotate</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#elif</span><span style="color: #000000; ">&nbsp;_MSC_VER</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;ROTATE&nbsp;std::_Rotate</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">13</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#else</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">#error</span><span style="color: #000000; ">&nbsp;"You&nbsp;should&nbsp;use&nbsp;GCC&nbsp;or&nbsp;VC"</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">#endif</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #000000; ">template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">unsigned&nbsp;Count,&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;Show,&nbsp;typename&nbsp;T,&nbsp;typename&nbsp;Iterator_tag</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;test(T&nbsp;beg,&nbsp;T&nbsp;mid,&nbsp;T&nbsp;end,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;Iterator_tag</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;iterator_tag,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">str&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">""</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">21</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">22</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;unsigned&nbsp;sum&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">23</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(unsigned&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; ">!=</span><span style="color: #000000; ">&nbsp;Count;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br /></span><span style="color: #008080; ">24</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;ta&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;clock();<br /></span><span style="color: #008080; ">25</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;ROTATE(beg,&nbsp;mid,&nbsp;end,&nbsp;iterator_tag);<br /></span><span style="color: #008080; ">26</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;ta&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;clock()&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;ta;<br /></span><span style="color: #008080; ">27</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;ta;<br /></span><span style="color: #008080; ">28</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(Show)&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s&nbsp;&nbsp;%u&nbsp;ms\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;str,&nbsp;ta);<br /></span><span style="color: #008080; ">29</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">30</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(Show)&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">aveg:&nbsp;%u&nbsp;ms\n\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;sum&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;Count);<br /></span><span style="color: #008080; ">31</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;%s&nbsp;&nbsp;total:&nbsp;%u&nbsp;ms\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;str,&nbsp;sum);<br /></span><span style="color: #008080; ">32</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">33</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">34</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">35</span>&nbsp;<span style="color: #000000; ">template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">unsigned&nbsp;Count,&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;is_std,&nbsp;typename&nbsp;T</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">36</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;test2(T&nbsp;beg,&nbsp;T&nbsp;mid,&nbsp;T&nbsp;end,</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">str&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">""</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">37</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">38</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;unsigned&nbsp;sum&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">39</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(unsigned&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; ">!=</span><span style="color: #000000; ">&nbsp;Count;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br /></span><span style="color: #008080; ">40</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;ta&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;clock();<br /></span><span style="color: #008080; ">41</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(is_std)&nbsp;std::rotate(beg,&nbsp;mid,&nbsp;end);<br /></span><span style="color: #008080; ">42</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">&nbsp;{<br /></span><span style="color: #008080; ">43</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::reverse(beg,&nbsp;mid);<br /></span><span style="color: #008080; ">44</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::reverse(mid,&nbsp;end);<br /></span><span style="color: #008080; ">45</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::reverse(beg,&nbsp;end);<br /></span><span style="color: #008080; ">46</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">47</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;ta&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;clock()&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;ta;<br /></span><span style="color: #008080; ">48</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;ta;<br /></span><span style="color: #008080; ">49</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s&nbsp;&nbsp;%u&nbsp;ms\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;str,&nbsp;ta);<br /></span><span style="color: #008080; ">50</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">51</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">aveg:&nbsp;%u&nbsp;ms\n\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;sum&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;Count);<br /></span><span style="color: #008080; ">52</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">53</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">54</span>&nbsp;<span style="color: #000000; ">template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">unsigned&nbsp;Count,&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;Show,&nbsp;typename&nbsp;T</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">55</span>&nbsp;<span style="color: #000000; ">inline&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;test3(T&nbsp;beg,&nbsp;T&nbsp;mid,&nbsp;T&nbsp;end)<br /></span><span style="color: #008080; ">56</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">57</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;test</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Count,&nbsp;Show</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(beg,&nbsp;mid,&nbsp;end,&nbsp;std::forward_iterator_tag(),&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">forward</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">58</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;test</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Count,&nbsp;Show</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(beg,&nbsp;mid,&nbsp;end,&nbsp;std::bidirectional_iterator_tag(),&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">bidirectional</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">59</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;test</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Count,&nbsp;Show</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(beg,&nbsp;mid,&nbsp;end,&nbsp;std::random_access_iterator_tag(),&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">random</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">60</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">61</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">62</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br /></span><span style="color: #008080; ">63</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">64</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;N&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;1e7;<br /></span><span style="color: #008080; ">65</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;M&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1024</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">66</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">const&nbsp;int&nbsp;M&nbsp;=&nbsp;777;</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">67</span>&nbsp;<span style="color: #008000; "></span><span style="color: #000000; ">&nbsp;&nbsp;std::vector</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;vec(N);<br /></span><span style="color: #008080; ">68</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;std::vector</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::iterator&nbsp;beg(vec.begin()),&nbsp;mid(beg&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;M),&nbsp;end(vec.end());<br /></span><span style="color: #008080; ">69</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">70</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">------\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">71</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;test2</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">3</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(beg,&nbsp;mid,&nbsp;end,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;3_reverse</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">72</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;test2</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">3</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(beg,&nbsp;mid,&nbsp;end,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;std::rotate</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">73</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;<br /></span><span style="color: #008080; ">74</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;test3</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">3</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(beg,&nbsp;mid,&nbsp;end);<br /></span><span style="color: #008080; ">75</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;<br /></span><span style="color: #008080; ">76</span>&nbsp;<span style="color: #000000; ">&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;</span><span style="color: #000000; ">5</span><span style="color: #000000; ">;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br /></span><span style="color: #008080; ">77</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;printf&nbsp;(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">\n%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;i);<br /></span><span style="color: #008080; ">78</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;test3</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">3</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(beg,&nbsp;beg&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;i,&nbsp;end);<br /></span><span style="color: #008080; ">79</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">80</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;<br /></span><span style="color: #008080; ">81</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">82</span>&nbsp;<span style="color: #000000; "></span></span></div><img src ="http://www.cppblog.com/flyinghearts/aggbug/147403.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2011-05-27 21:04 <a href="http://www.cppblog.com/flyinghearts/archive/2011/05/27/147403.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从字符串中提取数字并排序输出</title><link>http://www.cppblog.com/flyinghearts/archive/2011/03/31/143167.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Thu, 31 Mar 2011 15:56:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2011/03/31/143167.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/143167.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2011/03/31/143167.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/143167.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/143167.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 看到别人的讨论贴，也做了下。题目很简单，可以直接用标准库函数，也可以自已造轮子。标准库中能用到的只有：atoi / strtol系列，显然得用 strtol（有些库atoi就是用strtol实现的）在用strtol前，先要对不安全的strtol封装下。&nbsp;int str2i(const char str[], const char* &amp;next, int base = ...&nbsp;&nbsp;<a href='http://www.cppblog.com/flyinghearts/archive/2011/03/31/143167.html'>阅读全文</a><img src ="http://www.cppblog.com/flyinghearts/aggbug/143167.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2011-03-31 23:56 <a href="http://www.cppblog.com/flyinghearts/archive/2011/03/31/143167.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《编程之美》读书笔记22：    1.16  24点游戏（补充）</title><link>http://www.cppblog.com/flyinghearts/archive/2010/08/15/123531.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Sun, 15 Aug 2010 15:35:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2010/08/15/123531.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/123531.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2010/08/15/123531.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/123531.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/123531.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 《编程之美》读书笔记22：&nbsp;&nbsp;&nbsp; 1.16&nbsp; 24点游戏（补充）&nbsp;给定n个数，能否只通过加减乘除计算得到24？ 书上给出的最后一种解法，通过使用集合记录中间结果来减少冗余计算。本以为，程序会占用大量的内存，用一个极端的例子（13, 773, 28, 98, 731, 1357,97357246这7个数）测试了一下实现的程序，发现程序竟然...&nbsp;&nbsp;<a href='http://www.cppblog.com/flyinghearts/archive/2010/08/15/123531.html'>阅读全文</a><img src ="http://www.cppblog.com/flyinghearts/aggbug/123531.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2010-08-15 23:35 <a href="http://www.cppblog.com/flyinghearts/archive/2010/08/15/123531.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>N个数计算24点</title><link>http://www.cppblog.com/flyinghearts/archive/2010/08/15/123529.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Sun, 15 Aug 2010 15:20:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2010/08/15/123529.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/123529.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2010/08/15/123529.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/123529.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/123529.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: N个数计算24点问题：&nbsp;&nbsp;&nbsp; N个1到13之间的自然数，找出所有能通过加减乘除计算（每个数有且只能用一次）得到24的组合？&nbsp;计算24点常用的算法有：① 任取两个数，计算后，将结果放回去，再从剩下的数中任取两个，如此反复直到只剩下一个数；② 先构建前缀/后缀表达式，再计算该表达式；③ 用集合保存中间结果，集合间两两进行合并计算得到新集合（或者对...&nbsp;&nbsp;<a href='http://www.cppblog.com/flyinghearts/archive/2010/08/15/123529.html'>阅读全文</a><img src ="http://www.cppblog.com/flyinghearts/aggbug/123529.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2010-08-15 23:20 <a href="http://www.cppblog.com/flyinghearts/archive/2010/08/15/123529.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《编程之美》读书笔记22：    1.16  24点游戏</title><link>http://www.cppblog.com/flyinghearts/archive/2010/08/01/121907.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Sun, 01 Aug 2010 14:50:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2010/08/01/121907.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/121907.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2010/08/01/121907.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/121907.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/121907.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 《编程之美》读书笔记22：&nbsp;&nbsp;&nbsp; 1.16&nbsp; 24点游戏给定4个数，能否只通过加减乘除计算得到24？由于只有4个数，弄个多重循环，就可以。如果要推广到n个数，有两种思路：① 采用前缀/后缀表达式。相当于将n个数用n-1个括号括起来，其数目就是一个catlan数。最多可得到 f(n) = (1/n * (2*n - 2)! / (n-1)! / (...&nbsp;&nbsp;<a href='http://www.cppblog.com/flyinghearts/archive/2010/08/01/121907.html'>阅读全文</a><img src ="http://www.cppblog.com/flyinghearts/aggbug/121907.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2010-08-01 22:50 <a href="http://www.cppblog.com/flyinghearts/archive/2010/08/01/121907.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《编程之美》读书笔记21： 2.4  1的数目</title><link>http://www.cppblog.com/flyinghearts/archive/2010/07/21/120915.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Tue, 20 Jul 2010 16:25:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2010/07/21/120915.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/120915.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2010/07/21/120915.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/120915.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/120915.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;《编程之美》读书笔记21： 2.4 1的数目&nbsp;问题：&nbsp;&nbsp;&nbsp; 给定一个十进制正整数N，写下从1开始，到N的所有整数，&nbsp;&nbsp;&nbsp; 然后数一下其中出现的所有&#8220;1&#8221;的个数。 &nbsp; &nbsp;&nbsp;例如： &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;...&nbsp;&nbsp;<a href='http://www.cppblog.com/flyinghearts/archive/2010/07/21/120915.html'>阅读全文</a><img src ="http://www.cppblog.com/flyinghearts/aggbug/120915.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2010-07-21 00:25 <a href="http://www.cppblog.com/flyinghearts/archive/2010/07/21/120915.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>