﻿<?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++博客-A Za, A Za, Fighting...-随笔分类-R_找工复习2011</title><link>http://www.cppblog.com/Joe/category/17405.html</link><description>坚信：勤能补拙</description><language>zh-cn</language><lastBuildDate>Thu, 20 Oct 2011 12:24:49 GMT</lastBuildDate><pubDate>Thu, 20 Oct 2011 12:24:49 GMT</pubDate><ttl>60</ttl><item><title>2011知识点 - 多态的C实现</title><link>http://www.cppblog.com/Joe/archive/2011/10/20/158766.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Thu, 20 Oct 2011 09:22:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/10/20/158766.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/158766.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/10/20/158766.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/158766.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/158766.html</trackback:ping><description><![CDATA[示例代码:<br /><br /><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: #008000; ">/*</span><span style="color: #008000; ">&nbsp;how&nbsp;to&nbsp;simulate&nbsp;C++'s&nbsp;polymorphism&nbsp;with&nbsp;C&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;declaration&nbsp;of&nbsp;virtual&nbsp;method&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />typedef&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">Func1)(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">);<br />typedef&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">Func2)(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />typedef&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">Func3)(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">);<br /><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;-------------------&nbsp;Base&nbsp;Class&nbsp;begin&nbsp;------------------</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;func1_base(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">func1_base(void)&nbsp;called\n</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;func2_base(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;item)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">func2_base(%d)&nbsp;called\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;item);<br />}<br /><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vtbl_Base&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Func1&nbsp;f1;<br />&nbsp;&nbsp;&nbsp;&nbsp;Func2&nbsp;f2;<br />};<br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vtbl_Base&nbsp;bvtbl&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">func1_base,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">func2_base};<br /><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Base&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">vptr;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;pointer&nbsp;to&nbsp;VTABLE&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;field_base;<br />};<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;Base_Init(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;value)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">vptr&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">bvtbl;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">field_base&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;value;<br />}<br /><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;-------------------&nbsp;Base&nbsp;Class&nbsp;end&nbsp;------------------</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;-------------------&nbsp;Derived&nbsp;Class&nbsp;begin&nbsp;------------------</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;func1_derived(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">func1_derived(void)&nbsp;called\n</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;func3_derived(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">item)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">func3_derived(%s)&nbsp;called\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;item);<br />}<br /><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vtbl_Derived&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vtbl_Base&nbsp;vtbl_base;<br />&nbsp;&nbsp;&nbsp;&nbsp;Func3&nbsp;f3;<br />};<br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vtbl_Derived&nbsp;dvtbl&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{{</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">func1_derived,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">func2_base},&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">func3_derived};<br /><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Derived&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Base&nbsp;</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;field_derived;<br />};<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;Derived_Init(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Derived&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">derived,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;b,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;d)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;Base_Init((</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)derived,&nbsp;b);<br />&nbsp;&nbsp;&nbsp;&nbsp;derived</span><span style="color: #000000; ">-&gt;</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">.vptr&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">dvtbl;<br />&nbsp;&nbsp;&nbsp;&nbsp;derived</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">field_derived&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;d;<br />}<br /><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;-------------------&nbsp;Derived&nbsp;Class&nbsp;end&nbsp;------------------</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;<br />test_polymorphism(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">obj)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vtbl_Base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)(obj</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">vptr))</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">f1();<br />&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vtbl_Base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)(obj</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">vptr))</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">f2(obj</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">field_base);<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">argv)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Base&nbsp;</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;Base_Init(</span><span style="color: #000000; ">&amp;</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">128</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;test_polymorphism(</span><span style="color: #000000; ">&amp;</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Derived&nbsp;derived;<br />&nbsp;&nbsp;&nbsp;&nbsp;Derived_Init(</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">derived,&nbsp;</span><span style="color: #000000; ">128</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">256</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;test_polymorphism((</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">derived);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vtbl_Derived&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">derived))</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">f3(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">polymorphism</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />}</span></div><img src ="http://www.cppblog.com/Joe/aggbug/158766.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-10-20 17:22 <a href="http://www.cppblog.com/Joe/archive/2011/10/20/158766.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011好题 - Young氏矩阵[zz]</title><link>http://www.cppblog.com/Joe/archive/2011/10/16/158483.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sun, 16 Oct 2011 11:11:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/10/16/158483.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/158483.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/10/16/158483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/158483.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/158483.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; line-height: 22px; background-color: #ffffff; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">转:&nbsp;<br /><div><a href="http://www.binghe.org/2011/05/young-tableau/">http://www.binghe.org/2011/05/young-tableau/</a></div><br />一个 m*n 的 Young 氏矩阵(Young tableau) 是一个 m*n 的矩阵,其中每一行的数据都从左到右排序,每一列的数据都从上到下排序.Young&nbsp;氏矩阵中可能会有一些&nbsp;&nbsp;&#8734; 数据项,表示不存在的元素.所以,Young 氏矩阵可以用来存放 r&lt;= mn 个有限的元素.<br />a).画一个包含{9,16,3,2,4,8,5,14,12} 的4*4 的 Young 氏矩阵.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">b).给出一个在非空 m*n 的 Young&nbsp; 氏矩阵上实现 EXTRACT-MIN 算法,使其运行时间为O(m+n).</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">c).说明如何在O(m+n)时间内,将一个新元素手入到一个未满的 m*n Young 氏矩阵中.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">d).给出一个时间复杂度为 O(n^3) 的对 n*n Young 氏矩阵排序的算法.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">e).给出一个运行时间为O(m+n) 的算法,来决定一个给定的数是否存在于一个给定的 m*n&nbsp;&nbsp;的 Young 氏矩阵当中.<span id="more-545" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; "></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">答</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">a).&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">8&nbsp;&nbsp;&nbsp;&nbsp; 9&nbsp;&nbsp;&nbsp;&nbsp; 12&nbsp;&nbsp;&nbsp; 14</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">16&nbsp;&nbsp;&nbsp; &#8734;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8734;&nbsp;&nbsp;&nbsp;&nbsp; &#8734;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">&#8734;&nbsp;&nbsp;&nbsp;&nbsp; &#8734;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8734;&nbsp;&nbsp;&nbsp;&nbsp; &#8734;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">PS.该矩阵并不是唯一的.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">b). (1)用递归的思想.在 Young 氏矩阵中，通过递归的解决(m-1)*n,或m*(n-1) 的子问题来求解.则有 T(m,n)=T(m-1,n) or T(m,n-1)+&nbsp;O(1),显然,T=O(m+n).伪代码如下:</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; ">EXTRACT_MIN(Young[1...m]&nbsp;[1...n])<br />EXTRACT_MIN=Young[1][1];&nbsp;//类似FORTRAN的写法.函数名即是返回值.<br />Young[1][1]=&nbsp;INFINITY;<br />ADJUST_TO_YOUNG(Young[1...m]&nbsp;[1...n]);<br />END<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; "></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">ADJUST_TO_YOUNG(Young[x...m]&nbsp;[y...n])<br />if(Young[x][y]==&#8734;)<br />return;<br />if(Young[x+1][y]&gt;Young[x][y+1])<br />swap(Young[x][y], Young[x][y+1]);<br />ADJUST_TO_YOUNG(Young[x...m][y+1...n]);<br />else<br />swap(Young[x][y], Young[x+1][y]);<br />ADJUST_TO_YOUNG(Young[x+1...m][y...n]);<br />END</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">(2)类似堆的删除：将Young[1][1]与最右下角元素交换, 然后移动Young[1][1]处的元素至合适位置，即把它与右方或下方元素的比较,并与其中较小的一个交换.反复进行直到它不大于它右方和下方的元素为止.</p></div></div><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">c).&nbsp; 类似堆的插入：先将待插入的元素 K 放在 Young[m][n], 然后比较 K 与它左方或上方元素的大小,并与其中较大的一个交换.反复进行直到 K 不小于它左方和上方的元素为止. 在这里,同样有,T(m,n)=T(m-1,n) or T(m,n-1)+&nbsp;O(1),T=O(m+n).伪代码如下:</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; ">INSERT(k,Young[m][n])<br />if(Young[m][n]&nbsp;&lt;&nbsp;INFINITY)&nbsp;&nbsp;alert:&nbsp;矩阵已满,无法插入!!<br />while(k&lt;Young[m-1][n]&nbsp;or&nbsp;k&lt;Young[m][n-1])<br />if(Young[m-1][n]&nbsp;&gt;Young[m][n-1])<br />swap(k,Young[m-1][n]);<br />m=m-1;<br />else<br />swap(k,Young[m][n-1]);<br />n=n-1;<br />END</div></div><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">d). 调用 n*n 次 EXTRACT_MIN 过程即可.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">e). 总是于最右上角的元素X比较；<br />1）如果==X,结束；<br />2）如果比X小，那么元素只可能在前N-1列中；<br />3）如果比X大，那么元素只可能在后M-1行中；<br />Young 氏矩阵去掉一行或一列还是 Young 氏矩阵；<br />所以每次比较最少去掉一行或一列，这样复杂度就是 O(m+n);</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; "><div></div></div></span><img src ="http://www.cppblog.com/Joe/aggbug/158483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-10-16 19:11 <a href="http://www.cppblog.com/Joe/archive/2011/10/16/158483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011好题 - 寻找俩已排好序数组的中位数</title><link>http://www.cppblog.com/Joe/archive/2011/10/16/158477.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sun, 16 Oct 2011 10:38:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/10/16/158477.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/158477.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/10/16/158477.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/158477.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/158477.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; line-height: 22px; background-color: #ffffff; ">问题:<br />有两个已排好序的数组A和B，长度均为n，找出这两个数组的中间元素。要求时间代价为O(logn)<br /><br />思路:<br />a. 比较自然的思路是归并算法，不过时间复杂度是O(n)，无法满足题目要求<br /><br />b. <br />(&nbsp;<a href="http://www.binghe.org/2011/05/find-median/">http://www.binghe.org/2011/05/find-median/</a>&nbsp;)<br /><br /></span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; line-height: 22px; background-color: #ffffff; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">Say the two arrays are sorted and increasing, namely A and B.<br />It is easy to find the median of each array in O(1) time.<br />Assume the median of array A is m and the median of array B is n.<br />Then,<br />1&#8242; If m=n, then clearly the median after merging is also m, the algorithm holds.<br />2&#8242; If m&lt;n, then reserve the half of sequence A in which all numbers are greater than<br />m, also reserve the half of sequence B in which all numbers are smaller than n.<br />Run the algorithm on the two new arrays.<br />3&#8242; If m&gt;n, then reserve the half of sequence A in which all numbers are smaller than<br />m, also reserve the half of sequence B in which all numbers are larger than n.<br /><br />Run the algorithm on the two new arrays.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; text-align: justify; ">Time complexity: O(logn)</p></span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; line-height: 22px; background-color: #ffffff; "><br /><br /><br /><br /><br /></span><img src ="http://www.cppblog.com/Joe/aggbug/158477.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-10-16 18:38 <a href="http://www.cppblog.com/Joe/archive/2011/10/16/158477.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011面试题 - 循环报数</title><link>http://www.cppblog.com/Joe/archive/2011/10/11/158089.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Tue, 11 Oct 2011 15:08:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/10/11/158089.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/158089.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/10/11/158089.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/158089.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/158089.html</trackback:ping><description><![CDATA[昨天去面试，结果中间还插了一个小时的上机(给个laptop，Windows+VC环境，用惯Vim结果好不习惯^_^)，其中一题如下：<br /><br /><span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; line-height: 16px; background-color: #ffffff; font-size: small; ">有N个人按照1到N编号围成一个圈做游戏<br />从第一个人开始从1<em style="color: #d14836; font-style: normal; ">报数</em>,数到M的人退出游戏,他后面的人接着重新从1开始<em style="color: #d14836; font-style: normal; ">报数，一直持续到所有人都退出</em>．<br />要求输出退出游戏的人的顺序.<br /><br /></span>这题以前看过，记得貌似有些数学规律的，忘了，所以只能当场用模拟的方法来做。<br />当时用的是循环数组来模拟，结果花了半个小时才编译、测试搞定，面试我的人(挺Nice的)看了之后说，答案输出是对的，其实更自然的模拟是用链表。<br />刚才用链表试了下，果然简单好多，大概五分钟就可以搞定。<br /><br /><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; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">assert.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;n,&nbsp;m;<br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Item&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;number;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Item&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">next;<br />};<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "><br />solve(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;n,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;m)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i,&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;assert(n</span><span style="color: #000000; ">&gt;</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;m</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">n);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Item&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">items&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Item&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)malloc(</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Item)&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;n);<br />&nbsp;&nbsp;&nbsp;&nbsp;assert(items&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;init&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">n</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;items[i].number&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;items[i].next&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;items</span><span style="color: #000000; ">+</span><span style="color: #000000; ">i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;items[n</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">].number&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;n;<br />&nbsp;&nbsp;&nbsp;&nbsp;items[n</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">].next&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;items;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;simulate&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Item&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">cur,&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">prev&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;cur&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;items;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(n</span><span style="color: #000000; ">--</span><span style="color: #000000; ">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;m;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(</span><span style="color: #000000; ">--</span><span style="color: #000000; ">j)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;cur;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cur&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;cur</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">next;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;cur</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">number);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">next&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;cur</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">next;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cur&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;cur</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">next;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;free(items);<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">argv)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">n,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">m)&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;EOF)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Result&nbsp;of&nbsp;(N=%d,&nbsp;M=%d)\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;n,&nbsp;m);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;solve(n,&nbsp;m);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}</span></div><img src ="http://www.cppblog.com/Joe/aggbug/158089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-10-11 23:08 <a href="http://www.cppblog.com/Joe/archive/2011/10/11/158089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点 - 文件描述符 dup/dup2</title><link>http://www.cppblog.com/Joe/archive/2011/10/08/157799.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sat, 08 Oct 2011 07:57:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/10/08/157799.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/157799.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/10/08/157799.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/157799.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/157799.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="color: #333333; font-family: Arial; line-height: normal; background-color: #ffffff; "><p class="p0" style="line-height: normal; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-weight: bold; font-size: 12pt; ">文件描述符<font face="Arial Black" style="line-height: normal; ">----</font><font face="宋体" style="line-height: normal; ">文件表</font><font face="Arial Black" style="line-height: normal; ">----v</font><font face="宋体" style="line-height: normal; ">节点结构三者的联系</font></span></p><p class="p0" style="line-height: normal; text-indent: 21pt; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-size: 10.5pt; "><br />&nbsp; &nbsp; &nbsp; &nbsp;既然文件描述符标识特定进程正在访问的文件，那进程跟文件是怎么联系起来的呢？</span></p><p class="p0" style="line-height: normal; margin-left: 21.25pt; text-indent: -21.25pt; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-size: 10.5pt; ">&nbsp; &nbsp; &nbsp; &nbsp;首先我们得知道每运行一个进程，<font face="Arial Black" style="line-height: normal; ">shell</font><font face="宋体" style="line-height: normal; ">就会默认为其打开三个文件描述符</font><font face="Arial Black" style="line-height: normal; ">(0,1,2)</font><font face="宋体" style="line-height: normal; ">，分别与标准输入</font><font face="Arial Black" style="line-height: normal; ">(stdin)</font><font face="宋体" style="line-height: normal; ">，标准输出</font><font face="Arial Black" style="line-height: normal; ">(stdout)</font><font face="宋体" style="line-height: normal; ">和标准错误</font><font face="Arial Black" style="line-height: normal; ">(stderr)</font><font face="宋体" style="line-height: normal; ">对应。</font></span></p><p class="p0" style="line-height: normal; margin-left: 21.25pt; text-indent: -21.25pt; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-size: 10.5pt; ">&nbsp; &nbsp; &nbsp; &nbsp;接下来讲下内核所使用的三种数据结构，正是这三种数据结构才使进程最终跟文件联系起来。</span><span style="line-height: normal; font-size: 10.5pt; ">建议边看图一边看下面的文字描述</span></p><p class="p0" style="line-height: normal; margin-left: 49.6pt; text-indent: -28.35pt; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-size: 10.5pt; ">&nbsp; &nbsp; &nbsp; a.&nbsp;</span><span style="line-height: normal; font-size: 10.5pt; ">每个进程在进程表中都有一个记录项，每个记录项中有一张打开文件描述符表，可将其视为一个矢量，每个描述符占用一项。<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 与每个文件描述符相关联的是：</span><span style="line-height: normal; font-size: 10.5pt; ">(a)&nbsp;</span><span style="line-height: normal; font-size: 10.5pt; ">文件描述符。</span><span style="line-height: normal; font-size: 10.5pt; ">(b)&nbsp;</span><span style="line-height: normal; font-size: 10.5pt; ">指向一个文件表项的指针</span></p><p class="p0" style="line-height: normal; margin-left: 49.6pt; text-indent: -28.35pt; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-size: 10.5pt; ">&nbsp; &nbsp; &nbsp; b. 内核为所有打开文件维持一张文件表。每个文件表项包含：</span><span style="line-height: normal; font-size: 10.5pt; ">(a)&nbsp;</span><span style="line-height: normal; font-size: 10.5pt; ">文件状态标志</span><span style="line-height: normal; font-size: 10.5pt; ">。</span><span style="line-height: normal; font-size: 10.5pt; ">(b)&nbsp;</span><span style="line-height: normal; font-size: 10.5pt; ">当前文件位移量。</span><span style="line-height: normal; font-size: 10.5pt; ">(c)&nbsp;</span><span style="line-height: normal; font-size: 10.5pt; ">指向该文件</span><span style="line-height: normal; font-size: 10.5pt; ">v</span><span style="line-height: normal; font-size: 10.5pt; ">节点表项的指针。</span></p><p class="p0" style="line-height: normal; margin-left: 49.6pt; text-indent: -28.35pt; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-size: 10.5pt; ">&nbsp; &nbsp; &nbsp; c. 每个打开文件（或设备）都有一个</span><span style="line-height: normal; font-size: 10.5pt; ">v</span><span style="line-height: normal; font-size: 10.5pt; ">节点结构。</span><span style="line-height: normal; font-size: 10.5pt; ">是文件的重要信息部分。</span></p></span><span class="Apple-style-span" style="color: #333333; font-family: Arial; line-height: normal; background-color: #ffffff; ">&nbsp; &nbsp; &nbsp; 下图表示以上三个数据结构的关系：<br /></span><span class="Apple-style-span" style="color: #333333; font-family: Arial; line-height: normal; background-color: #ffffff; "><p class="p0" style="line-height: normal; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-size: 10.5pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fd1&nbsp;=&nbsp;open(pathname,&nbsp;oflags);</span></p><p class="p0" style="line-height: normal; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-size: 10.5pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fd2&nbsp;=&nbsp;dup(fd1);</span></p><p class="p0" style="line-height: normal; margin-bottom: 0pt; margin-top: 0pt; "><span style="line-height: normal; font-size: 10.5pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fd3&nbsp;=&nbsp;open(pathname,&nbsp;oflags);</span></p></span><span class="Apple-style-span" style="color: #333333; font-family: Arial; line-height: normal; background-color: #ffffff; "><br /><br /></span><span class="Apple-style-span" style="color: #333333; font-family: Arial; line-height: normal; background-color: #ffffff; "><p class="p0" style="line-height: normal; margin-bottom: 0pt; margin-top: 0pt; text-align: center; "><span style="line-height: normal; "><img border="0" class="blogimg" small="0" src="http://hiphotos.baidu.com/lammy/pic/item/6c44b412d586bde0c3fd7898.jpg" style="line-height: normal; "  alt="" /><br /></span></p><p class="p0" style="line-height: normal; margin-bottom: 0pt; margin-top: 0pt; text-align: center; "><span style="line-height: normal; font-size: 10.5pt; ">图一</span></p></span>&nbsp; &nbsp; &nbsp;&nbsp;<br /><br />&nbsp;dup/dup2<br /><span class="Apple-style-span" style="color: #3398cc; font-family: 'Times New Roman'; font-size: 13px; line-height: 20px; background-color: #ffffff; ">相信大部分在Unix/Linux下编程的程序员手头上都有《Unix环境高级编程》(APUE)这本超级经典巨著。作者在该书中讲解dup/dup2之前曾经讲过&#8220;文件共享&#8221;，这对理解dup/dup2还是很有帮助的。这里做简单摘录以备在后面的分析中使用：<br />Stevens said:<br />(1) 每个进程在进程表中都有一个记录项，每个记录项中有一张打开文件描述符表，可将视为一个矢量，每个描述符占用一项。与每个文件描述符相关联的是：<br />(a) 文件描述符标志。<br />(b) 指向一个文件表项的指针。<br />(2) 内核为所有打开文件维持一张文件表。每个文件表项包含：<br />(a) 文件状态标志(读、写、增写、同步、非阻塞等)。<br />(b) 当前文件位移量。<br />(c) 指向该文件v节点表项的指针。<br />图示：<br />文件描述符表<br />------------<br />fd0 0 | p0 -------------&gt; 文件表0 ---------&gt; vnode0<br />------------<br />fd1 1 | p1 -------------&gt; 文件表1 ---------&gt; vnode1<br />------------<br />fd2 2 | p2&nbsp;<br />------------<br />fd3 3 | p3&nbsp;<br />------------<br />... ...<br />... ...<br />------------<br /><br />一、单个进程内的dup和dup2<br />假设进程A拥有一个已打开的文件描述符fd3，它的状态如下：<br />进程A的文件描述符表(before dup2)<br />------------<br />fd0 0 | p0&nbsp;<br />------------<br />fd1 1 | p1 -------------&gt; 文件表1 ---------&gt; vnode1<br />------------<br />fd2 2 | p2&nbsp;<br />------------<br />fd3 3 | p3 -------------&gt; 文件表2 ---------&gt; vnode2<br />------------<br />... ...<br />... ...<br />------------<br /><br />经下面调用：<br />n_fd = dup2(fd3, STDOUT_FILENO);后进程状态如下：<br /><br />进程A的文件描述符表(after dup2)<br />------------<br />fd0 0 | p0&nbsp;<br />------------<br />n_fd 1 | p1 ------------<br />------------ \<br />fd2 2 | p2 \<br />------------ _\|<br />fd3 3 | p3 -------------&gt; 文件表2 ---------&gt; vnode2<br />------------<br />... ...<br />... ...<br />------------<br />解释如下：<br />n_fd = dup2(fd3, STDOUT_FILENO)表示n_fd与fd3共享一个文件表项(它们的文件表指针指向同一个文件表项)，n_fd在文件描述符表中的位置为 STDOUT_FILENO的位置，而原先的STDOUT_FILENO所指向的文件表项被关闭，我觉得上图应该很清晰的反映出这点。按照上面的解释我们 就可以解释CU中提出的一些问题：<br />(1) "dup2的第一个参数是不是必须为已打开的合法filedes？" -- 答案：必须。<br />(2) "dup2的第二个参数可以是任意合法范围的filedes值么？" -- 答案：可以，在Unix其取值区间为[0,255]。<br /><br />另外感觉理解dup2的一个好方法就是把fd看成一个结构体类型，就如上面图形中画的那样，我们不妨把之定义为：<br />struct fd_t {<br />int index;<br />filelistitem *ptr;<br />};<br />然后dup2匹配index，修改ptr，完成dup2操作。<br /><br />在学习dup2时总是碰到&#8220;重定向&#8221;一词，上图完成的就是一个&#8220;从标准输出到文件的重定向&#8221;，经过dup2后进程A的任何目标为STDOUT_FILENO的I/O操作如printf等，其数据都将流入fd3所对应的文件中。下面是一个例子程序：<br />#define TESTSTR "Hello dup2\n"<br />int main() {<br />int fd3;<br /><br />fd3 = open("testdup2.dat", 0666);<br />if (fd &lt; 0) {<br />printf("open error\n");<br />exit(-1);<br />}<br /><br />if (dup2(fd3, STDOUT_FILENO) &lt; 0) {&nbsp;<br />printf("err in dup2\n");<br />}<br />printf(TESTSTR);<br />return 0;<br />}<br />其结果就是你在testdup2.dat中看到"Hello dup2"。<br /><br />二、重定向后恢复<br />CU上有这样一个帖子，就是如何在重定向后再恢复原来的状态？首先大家都能想到要保存重定向前的文件描述符。那么如何来保存呢，象下面这样行么？<br />int s_fd = STDOUT_FILENO;<br />int n_fd = dup2(fd3, STDOUT_FILENO);<br />还是这样可以呢？<br />int s_fd = dup(STDOUT_FILENO);<br />int n_fd = dup2(fd3, STDOUT_FILENO);<br />这两种方法的区别到底在哪呢？答案是第二种方案才是正确的，分析如下：按照第一种方法，我们仅仅在"表面上"保存了相当于fd_t（按照我前面说的理解方 法）中的index，而在调用dup2之后，ptr所指向的文件表项由于计数值已为零而被关闭了，我们如果再调用dup2(s_fd, fd3)就会出错(出错原因上面有解释)。而第二种方法我们首先做一下复制，复制后的状态如下图所示:<br />进程A的文件描述符表(after dup)<br />------------<br />fd0 0 | p0&nbsp;<br />------------<br />fd1 1 | p1 -------------&gt; 文件表1 ---------&gt; vnode1<br />------------ /|<br />fd2 2 | p2 /<br />------------ /<br />fd3 3 | p3 -------------&gt; 文件表2 ---------&gt; vnode2<br />------------ /<br />s_fd 4 | p4 ------/&nbsp;<br />------------<br />... ...<br />... ...<br />------------<br /><br />调用dup2后状态为：<br />进程A的文件描述符表(after dup2)<br />------------<br />fd0 0 | p0&nbsp;<br />------------<br />n_fd 1 | p1 ------------<br />------------ \<br />fd2 2 | p2 \<br />------------ _\|<br />fd3 3 | p3 -------------&gt; 文件表2 ---------&gt; vnode2<br />------------<br />s_fd 4 | p4 -------------&gt;文件表1 ---------&gt; vnode1&nbsp;<br />------------<br />... ...<br />... ...<br />------------<br />dup(fd)的语意是返回的新的文件描述符与fd共享一个文件表项。就如after dup图中的s_fd和fd1共享文件表1一样。<br /><br />确定第二个方案后重定向后的恢复就很容易了，只需调用dup2(s_fd, n_fd);即可。下面是一个完整的例子程序：<br />#define TESTSTR "Hello dup2\n"<br />#define SIZEOFTESTSTR 11<br /><br />int main() {<br />int fd3;<br />int s_fd;<br />int n_fd;<br /><br />fd3 = open("testdup2.dat", 0666);<br />if (fd3 &lt; 0) {<br />printf("open error\n");<br />exit(-1);<br />}<br /><br />/* 复制标准输出描述符 */<br />s_fd = dup(STDOUT_FILENO);<br />if (s_fd &lt; 0) {<br />printf("err in dup\n");<br />}<br /><br />/* 重定向标准输出到文件 */<br />n_fd = dup2(fd3, STDOUT_FILENO);<br />if (n_fd &lt; 0) {<br />printf("err in dup2\n");<br />}<br />write(STDOUT_FILENO, TESTSTR, SIZEOFTESTSTR); /* 写入testdup2.dat中 */<br /><br />/* 重定向恢复标准输出 */<br />if (dup2(s_fd, n_fd) &lt; 0) {<br />printf("err in dup2\n");<br />}<br />write(STDOUT_FILENO, TESTSTR, SIZEOFTESTSTR); /* 输出到屏幕上 */<br />return 0;<br />}<br />注意这里我在输出数据的时候我是用了不带缓冲的write库函数，如果使用带缓冲区的printf，则最终结果为屏幕上输出两行"Hello dup2"，而文件testdup2.dat中为空，原因就是缓冲区作怪，由于最终的目标是屏幕，所以程序最后将缓冲区的内容都输出到屏幕。<br /><br /><br />三、父子进程间的dup/dup2<br />由fork调用得到的子进程和父进程的相同文件描述符共享同一文件表项，如下图所示：<br />父进程A的文件描述符表<br />------------<br />fd0 0 | p0&nbsp;<br />------------<br />fd1 1 | p1 -------------&gt; 文件表1 ---------&gt; vnode1<br />------------ /|\<br />fd2 2 | p2 |<br />------------ |<br />|<br />子进程B的文件描述符表 |<br />------------ |<br />fd0 0 | p0 |<br />------------ |<br />fd1 1 | p1 ---------------------|<br />------------<br />fd2 2 | p2&nbsp;<br />------------<br />所以恰当的利用dup2和dup可以在父子进程之间建立一条&#8220;沟通的桥梁&#8221;。这里不详述。<br /><br />四、小结<br />灵活的利用dup/dup2可以给你带来很多强大的功能，花了一些时间总结出上面那么多，不知道自己理解的是否透彻，只能在以后的实践中慢慢探索了。<br /></span><br /><br />转载:&nbsp;<a href="http://blog.21ic.com/user1/6406/archives/2011/81684.html">http://blog.21ic.com/user1/6406/archives/2011/81684.html</a><br /><br /><br /> &nbsp; &nbsp; &nbsp; &nbsp;<img src ="http://www.cppblog.com/Joe/aggbug/157799.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-10-08 15:57 <a href="http://www.cppblog.com/Joe/archive/2011/10/08/157799.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点 - overload与override</title><link>http://www.cppblog.com/Joe/archive/2011/10/07/157709.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Fri, 07 Oct 2011 11:11:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/10/07/157709.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/157709.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/10/07/157709.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/157709.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/157709.html</trackback:ping><description><![CDATA[override: 覆盖、重写<br />overload: 重载<br /><br /><span class="Apple-style-span" style="font-family: verdana; line-height: 22px; background-color: #ffffff; "><font size="3"><font color="#000000"><span style="font-family: 宋体; ">虚函数总是在派生类中被改写，这种改写被称为</span><span lang="EN-US">&#8220;override&#8221;</span><span style="font-family: 宋体; ">。我经常混淆</span><span lang="EN-US">&#8220;overload&#8221;</span><span style="font-family: 宋体; ">和</span><span lang="EN-US">&#8220;override&#8221;</span><span style="font-family: 宋体; ">这两个单词。澄清一下：</span></font></font><span lang="EN-US"><br /><font size="3"><font color="#000000"><br />override</font></font></span><font size="3"><font color="#000000"><span style="font-family: 宋体; ">是指派生类重写基类的虚函数，就象我们前面</span><span lang="EN-US">B</span><span style="font-family: 宋体; ">类中重写了</span><span lang="EN-US">A</span><span style="font-family: 宋体; ">类中的</span><span lang="EN-US">foo()</span><span style="font-family: 宋体; ">函数。重写的函数必须有一致的参数表和返回值（</span><span lang="EN-US">C++</span><span style="font-family: 宋体; ">标准允许返回值不同的情况，这个我会在</span><span lang="EN-US">&#8220;</span><span style="font-family: 宋体; ">语法</span><span lang="EN-US">&#8221;</span><span style="font-family: 宋体; ">部分简单介绍，但是很少编译器支持这个</span><span lang="EN-US">feature</span><span style="font-family: 宋体; ">）。这个单词好象一直没有什么合适的中文词汇来对应，有人译为</span><span lang="EN-US">&#8220;</span><span style="font-family: 宋体; ">覆盖</span><span lang="EN-US">&#8221;</span><span style="font-family: 宋体; ">，还贴切一些。</span></font></font><font size="3"><font color="#000000"><span lang="EN-US">&nbsp;<br /><br />overload</span><span style="font-family: 宋体; ">约定成俗的被翻译为</span><span lang="EN-US">&#8220;</span><span style="font-family: 宋体; ">重载</span><span lang="EN-US">&#8221;</span><span style="font-family: 宋体; ">。是指编写一个与已有函数同名但是参数表不同的函数。例如一个函数即可以接受整型数作为参数，也可以接受浮点数作为参数。</span></font></font></span><br /><br /><img src ="http://www.cppblog.com/Joe/aggbug/157709.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-10-07 19:11 <a href="http://www.cppblog.com/Joe/archive/2011/10/07/157709.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点 - 构造函数可以为虚函数吗</title><link>http://www.cppblog.com/Joe/archive/2011/10/07/157708.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Fri, 07 Oct 2011 11:06:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/10/07/157708.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/157708.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/10/07/157708.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/157708.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/157708.html</trackback:ping><description><![CDATA[答案是：不可以<br />原因：<br />概念上，<span class="Apple-style-span" style="font-family: Arial; line-height: 24px; white-space: pre-wrap; background-color: #ffffff; ">虚函数的意图是动态绑定，程序会根据对象的动态类型来选择要调用的方法。然而在构造函数运行的时候，这个对象的动态类型还不完整(可以是基类，也可以是子类)，没有办法确定它到底是什么类型，故构造函数不能动态绑定。<br /><br />实现上，<span style="font-family: 宋体; font-size: 14px; line-height: 16px; background-color: #e8f7e6; ">vptr是构造函数设置的。通过vptr才能找到虚函数。<br />如果构造函数为虚函数，通过构造函数设置的vptr才能找到构造函数，然后调用它设置vptr，这是不可能实现的。&nbsp;<br /><br /><br /></span><br />参考:<br /><div><a href="http://bbs.seu.edu.cn/wForum/disparticle.php?boardName=C_CPlusPlus&amp;ID=17648">http://bbs.seu.edu.cn/wForum/disparticle.php?boardName=C_CPlusPlus&amp;ID=17648</a></div><div><a href="http://www.cppblog.com/guevara/articles/77360.html">http://www.cppblog.com/guevara/articles/77360.html</a></div></span><img src ="http://www.cppblog.com/Joe/aggbug/157708.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-10-07 19:06 <a href="http://www.cppblog.com/Joe/archive/2011/10/07/157708.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点 - 优先级反转</title><link>http://www.cppblog.com/Joe/archive/2011/09/25/156727.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sat, 24 Sep 2011 16:33:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/25/156727.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/156727.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/25/156727.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/156727.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/156727.html</trackback:ping><description><![CDATA[前两天Marvell面试，被问到优先级反转是什么东东，无奈只能表示不会，还好面试官非常地NICE，很耐心地告诉我这是什么，还聊起NASA的火星探测器就因为优先级反转的原因出现过BUG， 我就一直点头，还说回来会GOOGLE学习下<br /><br /><span class="Apple-style-span" style="color: #555555; font-family: Verdana, 'Lucida Grande', Verdana, Helvetica, sans-serif; font-size: 13px; line-height: 20px; background-color: #ffffff; "><p style="margin-top: 1em; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; ">Priority Inversion 优先级反转是嵌入式实时系统里面的一个经典的问题。简单描述一下这个问题：有三个优先级不同的task,A,B,C; A的优先级最高，B次之，C最低。其中A和C有共享的临界区。如果C已进入临界区，那么A在进入进入临界区之前，就会被阻塞。task B有可能打断C而进入运行状态，这样C什么时候从临界区退出，就是一个未知的时间。A只有C从临界区退出后才能被调度，A被阻塞的时间也是未知的。这样，低优先级的B先于高优先级的A被调度，优先级发生了逆转。<br />这个问题在一般的操作系统里面不是一个严重的问题，最多A被多阻塞了一段时间。但是，在实时系统里面，如果一个任务在规定的时间里面没有被调度运行，系统就相当于失败了，可能引发系统崩溃。<br />解决这个问题有两种手段：<br />1：Priority inheritance(优先级继承)，如果一个高优先级的task被阻塞，与它共享临界区的低优先级的task在进入临界区后，优先级就会继承高优先级task的优先级，保证它不会被其他优先级次高的任务打断。从临界区退出后，C的优先级恢复正常。<br />2：A priority ceiling（最高优先级），给临界区分配最高优先级，如果一个task进入临界区，就把临界区的优先级赋给它，已保证它不会被打断。从临界区退出后，task的优先级恢复正常。</p><p style="margin-top: 1em; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; ">实时操作系统的一个特点就是，一个实时任务，会在规定的时间内得到响应，并且在规定的时间内完成任务。所以，一切不可预知的动作都是有害的。</p><p style="margin-top: 1em; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; ">有兴趣可以看看下面两个链接：<br /><a href="http://en.wikipedia.org/wiki/Priority_inversion" title="http://en.wikipedia.org/wiki/Priority_inversion" rel="nofollow" style="color: #467aa7; font-style: normal; text-decoration: none; ">http://en.wikipedia.org/wiki/Priority_inversion</a><br /><a href="http://www.embedded.com/story/OEG20020321S0023" title="http://www.embedded.com/story/OEG20020321S0023" rel="nofollow" style="color: #467aa7; font-style: normal; text-decoration: none; ">http://www.embedded.com/story/OEG20020321S0023</a></p></span><br /><br /><br />来源:&nbsp;<a href="http://www.kernelchina.org/node/210">http://www.kernelchina.org/node/210</a><img src ="http://www.cppblog.com/Joe/aggbug/156727.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-25 00:33 <a href="http://www.cppblog.com/Joe/archive/2011/09/25/156727.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011推理题 - 两个鸡蛋[zz]</title><link>http://www.cppblog.com/Joe/archive/2011/09/25/156726.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sat, 24 Sep 2011 16:13:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/25/156726.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/156726.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/25/156726.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/156726.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/156726.html</trackback:ping><description><![CDATA[<span style="font-family: 'ms shell dlg'; font-size: 14px; line-height: 28px; "><h2><a id="ctl02_TitleUrl" href="http://www.cnblogs.com/Jason_Yao/articles/1425904.html" style="color: #2e9ce9; text-decoration: none; font-size: 14px; ">2 Egg Problem</a></h2><div id="cnblogs_post_body" style="word-wrap: break-word; "><p style="word-wrap: break-word; ">&nbsp;继续我们的推理问题之旅，今天我们要对付的是一个Google的面试题：Two Egg Problem.</p><p style="word-wrap: break-word; ">我们开始吧！&nbsp;</p><p style="word-wrap: break-word; "><span style="font-size: 12pt; line-height: 27px; font-family: 'Times New Roman'; "><strong>No.2 &nbsp;Google Interview Puzzle : 2 Egg Problem</strong></span></p><p style="word-wrap: break-word; margin-left: 21pt; font-size: 13px; line-height: 19px; "><span style="color: #666666; font-family: Verdana; ">* You are given 2 eggs.</span></p><p style="word-wrap: break-word; margin-left: 21pt; font-size: 13px; line-height: 19px; "><span style="color: #666666; font-family: Verdana; ">* You have access to a 100-storey building.</span></p><p style="word-wrap: break-word; margin-left: 21pt; font-size: 13px; line-height: 19px; "><span style="color: #666666; font-family: Verdana; ">* Eggs can be very hard or very fragile means it may break if dropped from the first floor or may not even break if dropped from 100<sup>th</sup>&nbsp;floor. Both eggs are identical.</span></p><p style="word-wrap: break-word; margin-left: 21pt; font-size: 13px; line-height: 19px; "><span style="color: #666666; font-family: Verdana; ">* You need to figure out the highest floor of a 100-storey building an egg can be dropped without breaking.</span></p><p style="word-wrap: break-word; margin-left: 21pt; font-size: 13px; line-height: 19px; "></p><p style="word-wrap: break-word; margin-left: 21pt; text-indent: 5.25pt; font-size: 13px; line-height: 19px; "><span style="color: #666666; font-family: Verdana; ">Now the question is how many drops you need to make. You are allowed to break 2 eggs in the process</span></p><p style="word-wrap: break-word; margin-left: 21pt; text-indent: 5.25pt; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-family: 宋体; "><strong>分析与解答：</strong></span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span>&nbsp;&nbsp;&nbsp;</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; ">题目要求试的最大次数最小。首先，讨论两个比较</span>trivial<span style="font-family: 宋体; ">的方案。</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-family: 宋体; ">&nbsp;&nbsp; 方案</span>1<span style="font-family: 宋体; ">：从第一层开始扔鸡蛋，如果鸡蛋不碎，则上一层再扔。这样，如果鸡蛋在某一层碎的话，该层就是临界的层。这种方案的优点在于省鸡蛋，只会摔破一个鸡蛋。还有一个鸡蛋可以带回家，做个鸡蛋羹，补充营养个</span>!<span>&nbsp;&nbsp;:)&nbsp;</span><span style="font-family: 宋体; ">缺点就是，如果鸡蛋在</span>100<span style="font-family: 宋体; ">层才碎的话，那就要试</span>100<span style="font-family: 宋体; ">次啦。那你等电梯要等死啦，而且还要接受别人的打量的目光，心说这怪咖为什么每次都只坐一层楼啊&#8230;</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-family: 宋体; ">&nbsp; 方案</span>2<span style="font-family: 宋体; ">：</span>&nbsp;<span style="font-family: 宋体; ">想必很多人都会想到这个方案。我只能说，这是中国计算机教育的成功啊。这就是&#8220;二分查找法&#8221;。首先在第</span>50<span style="font-family: 宋体; ">层楼扔鸡蛋，如果鸡蛋不碎的话，就去</span>75<span style="font-family: 宋体; ">楼。如果碎了的话，那么对不起，同志。由于你只剩一个鸡蛋了，所以你得小心地从第一层开始，这样才能保证你在鸡蛋碎完的时候能找到临界楼层。这种方法的优势在于，如果你知道你的鸡蛋比较硬的话，你就采用这个方法吧。临界楼层越高，这个方法尝试的次数越小。但这种优势是用临界楼层比较小时比较大的尝试次数为代价获得的。我们看到，如果临界层数在</span>49<span style="font-family: 宋体; ">层的话，我们要尝试</span>50<span style="font-family: 宋体; ">次，而临界层数为</span>100<span style="font-family: 宋体; ">层的时候，尝试次数只有</span>7<span style="font-family: 宋体; ">次。但是，现在的问题是，全部情况下的最大尝试次数最小。这样，虽然在某些情况下，这种方法的性能很好。但是就最差情况而言，还是要尝试</span>50<span style="font-family: 宋体; ">次，好像还是有点大。这边，我们想起来，&#8220;二分查找法&#8221;的目标是平均性能最佳，并不是最差性能最佳。我们似乎走错了路！！！不过，方案二相比方案一来讲还是有进步的。</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span>&nbsp;&nbsp;</span><span style="font-family: 宋体; ">方案</span>2<span style="font-family: 宋体; ">似乎陷入了&#8220;短板效应&#8221;的泥沼，由于最坏情况下的坏性能制约了总体性能的提高。解决这个问题的总的原则应是：&#8220;一碗水端平&#8221;，尽量做到各种情况下的尝试次数尽量差不多。这正应合</span>GOOGLE<span style="font-family: 宋体; ">的信条</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">Don't be evil</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">，不以别的情况为代价换取另一些情况的指标的提高。做到&#8220;不伤害&#8221;</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">.(</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">呵呵，这是我瞎联想的</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">)</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">。那么，就照着这条路走吧，我假设每种情况下最大的尝试次数为</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">x.</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: Verdana; ">&nbsp;&nbsp;</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">则第一次扔蛋的楼层应为</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">x;</span></p><p style="word-wrap: break-word; text-indent: 21pt; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: 宋体; ">第二次扔蛋的楼层应为</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">&nbsp;x+(x-1);</span></p><p style="word-wrap: break-word; text-indent: 21pt; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: 宋体; ">&#8230;</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: Verdana; ">&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">依次类推。</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: Verdana; ">&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">从上面看到，每次我们增加的楼层都是前一次减</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">1.</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">我们所要保证的就是应该在增加的层数变成</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">0</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">之前到顶楼，所以有：</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: Verdana; ">&nbsp;&nbsp;&nbsp;x+(x-1)+</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">&#8230;</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">+1</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">&#8805;</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">100</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: Verdana; ">&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">这是一个等差数列，整理后有：</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: Verdana; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x<sup>2</sup>+x-200</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">&#8805;</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">0</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: 宋体; ">发现</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">x</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">&#8805;</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">14</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">。</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: 宋体; ">我们总结一下：</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: Verdana; ">&nbsp;&nbsp;</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">第一次在</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">14</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">楼扔，如果碎了的话从一楼再开始扔；</span></p><p style="word-wrap: break-word; text-indent: 10pt; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: 宋体; ">否则在</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">14+13=27</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">层扔，如果碎了的话从</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">15</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">层开始扔；</span></p><p style="word-wrap: break-word; text-indent: 10pt; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: 宋体; ">否则在</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">27+12=39</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">层扔，如果碎了的话从</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">28</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">层开始扔；</span></p><p style="word-wrap: break-word; text-indent: 10pt; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: 宋体; ">&#8230;&#8230;</span></p><p style="word-wrap: break-word; text-indent: 10pt; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: 宋体; ">这样，最大尝试次数为</span><span style="font-size: 10pt; color: black; font-family: Verdana; ">14</span><span style="font-size: 10pt; color: black; font-family: 宋体; ">次就行了。不信你试试。</span></p><p style="word-wrap: break-word; text-indent: 10pt; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="word-wrap: break-word; text-indent: 10pt; font-size: 13px; line-height: 19px; "><span style="font-size: 10pt; color: black; font-family: 宋体; ">最后，为了体现严谨性，给出本题的模型：</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><strong><span style="font-size: 12pt; font-family: 宋体; ">转移方程：</span></strong><strong></strong></p><p style="word-wrap: break-word; text-indent: 10.5pt; font-size: 13px; line-height: 19px; ">minNum[n ] = min(1 + max(i &#8211; 1, minNum[n-i]))&nbsp;<span style="font-family: 宋体; ">，</span>for 1<span style="font-family: 宋体; ">&#8804;</span>i&nbsp;<span style="font-family: 宋体; ">&#8804;</span>n</p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><strong><span style="font-size: 12pt; font-family: 宋体; ">边界条件:</span></strong></p><p style="word-wrap: break-word; text-indent: 15.75pt; font-size: 13px; line-height: 19px; ">minNum[0] = 0; minNum[1] = 1</p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-family: 宋体; ">这里，</span>n<span style="font-family: 宋体; ">为楼层数，</span>i<span style="font-family: 宋体; ">为起始楼层数。</span></p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="word-wrap: break-word; font-size: 13px; line-height: 19px; "><span style="font-family: 宋体; ">据说这是一个动态规划问题，我还没来得及仔细研究。其实，我的感觉是，很多理论最初的来源都是很朴素的真理，只是我们没学懂，所以把它们想复杂了。所以，很好的理论就这样不被大多数人所理解了。</span></p><p style="word-wrap: break-word; text-indent: 15.75pt; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="word-wrap: break-word; text-indent: 15.75pt; font-size: 13px; line-height: 19px; "><span style="font-family: 宋体; ">参考文献：</span></p><p style="word-wrap: break-word; margin-left: 33.75pt; text-indent: -18pt; font-size: 13px; line-height: 19px; "><span>1.<span style="font: normal normal normal 7pt/normal 'Times New Roman'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><a href="http://blog.csdn.net/TravelInHistory/archive/2006/12/07/1434098.aspx" style="color: #2e9ce9; text-decoration: none; ">http://blog.csdn.net/TravelInHistory/archive/2006/12/07/1434098.aspx</a></p><p style="word-wrap: break-word; margin-left: 33.75pt; text-indent: -18pt; font-size: 13px; line-height: 19px; "><span>2.<span style="font: normal normal normal 7pt/normal 'Times New Roman'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><a href="http://classic-puzzles.blogspot.com/2006/12/google-interview-puzzle-2-egg-problem.html" style="color: #2e9ce9; text-decoration: none; ">http://classic-puzzles.blogspot.com/2006/12/google-interview-puzzle-2-egg-problem.html</a></p></div></span><img src ="http://www.cppblog.com/Joe/aggbug/156726.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-25 00:13 <a href="http://www.cppblog.com/Joe/archive/2011/09/25/156726.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011好题收集 - 给C瓜同学吧 [zz]</title><link>http://www.cppblog.com/Joe/archive/2011/09/22/156569.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Thu, 22 Sep 2011 15:36:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/22/156569.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/156569.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/22/156569.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/156569.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/156569.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="color: #333333; font-family: 宋体, 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; background-color: #ffffff; "><h2 style="font-family: 'Trebuchet MS', 'Lucida Grande', Verdana, Arial, sans-serif; font-weight: bold; font-size: 1.5em; color: #999933; margin-bottom: 0px; text-decoration: none; margin-top: 0px; margin-right: 0px; margin-left: 0px; padding-top: 14px; padding-bottom: 2px; ">给C瓜同学吧</h2><div class="entry" style="line-height: 1.5em; "><p style="font-size: 1.05em; ">C瓜同学一直关注这个我这个小地方，下面是一些我面试中或者和同学讨论的一些不错的面试题，备份一下，也希望对你有用。</p><p style="font-size: 1.05em; ">1：C++的多态是如何实现的？如果你用C如何来实现面向对象的多态？<br />解:<br />C++多态的实现主要依赖虚函数表，以及每个对象中指向虚函数表的指针<br />至于如何用C来实现面向对象的多态，我觉得比较靠谱的方法是函数指针，通过赋予函数指针不同的函数(地址)来调用不同的函数，得到不同的结果<br /><br /></p></div></span><span class="Apple-style-span" style="color: #333333; font-family: 宋体, 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; background-color: #ffffff; "><div class="entry" style="line-height: 1.5em; "><p style="font-size: 1.05em; ">2：判断一个有向图中是否有环。上篇文章里面写的那个杯子倒水问题。给一个都是正整数的数组，和一个正整数sum，求是否存在和为sum的子数列。<br />解:<br />【判断一个有向图是否有环】<br /><br /></p></div></span><span class="Apple-style-span" style="color: #333333; font-family: 宋体, 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; background-color: #ffffff; "><div class="entry" style="line-height: 1.5em; "><p style="font-size: 1.05em; ">【杯子倒水问题】<br />把所有可能的操作列出来，宽度优先搜索，从初始状态到结束状态<br /><br /></p></div></span><span class="Apple-style-span" style="color: #333333; font-family: 宋体, 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; font-size: 15px; background-color: #ffffff; ">【给一个都是正整数的数组，和一个正整数sum，求是否存在和为sum的子数列】</span><span class="Apple-style-span" style="color: #333333; font-family: 宋体, 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; background-color: #ffffff; "><div class="entry" style="line-height: 1.5em; "><p style="font-size: 1.05em; ">联想到的问题有：<br />a. 给一个都是正整数的数组，是否存在两个数的和为某个给定的sum? 三个数呢？<br />针对两个数的情况，可以先排序，然后一个指针front指向第一个元素(最小)，一个指针tail指向最后一个元素(最大)，如果*front + *tail &lt; sum, ++front, 如果*front + *tail &gt; sum, --tail;<br />如果三个数，或者N个数，该如何做？<br /><br />动态规划，类似于01背包问题<br />f[i][k]表示前i个元素中任意k个元素的和的集合，那么有:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;f[i][k] = f[i-1][k] + (f[i-1][k-1] + array[i])<br />or:<br />f[i][v]表示前i个元素中是否存在和的v的子数列，那么有:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;f[i][v] = 1, only if f[i-1][v]=1 or f[i-1][v-array[i]]=1<br /><br /></p><p style="font-size: 1.05em; ">3：两个有大量id的集合A和B，数量上亿级，如何求出两个集合的交集，A中有的B中没有的，和B中有的A中没有的集合。<br />涉及海量数据处理: 二分搜索、位图Bitmap、哈希Hash、字典树、分成若干小文件+多路归并...&nbsp;<br /><br /></p><p style="font-size: 1.05em; ">4：设计实现一个管理内存的小模块，接口为void* checkout(size_t size), void checkin(void* ptr)。</p><p style="font-size: 1.05em; ">5： 设计一个数据结构，存储一副象棋子的摆放，尽量压缩空间，使得方便通过传输到另外一台机子上然后恢复棋盘。</p><p style="font-size: 1.05em; ">6：数组的众数问题，最长递增子序列问题。找大量数据中前k个大的数。找大量数据中第k大的数。</p><p style="font-size: 1.05em; ">7：一个平面中有很多点，用最快的算法找出相隔最近的两个点。</p><p style="font-size: 1.05em; ">8：select/poll和epoll，基本互联网公司都会提到这个东西。</p><p style="font-size: 1.05em; ">9：给敏感词列表，和一大段文本，考虑一个敏感词过滤的算法。</p><p style="font-size: 1.05em; ">10：海量数据问题，很多，一般方法就为分治、hash、位图。</p><p style="font-size: 1.05em; ">很多没有标准答案，面试过程中的探讨很重要。找工作不难，找份好工作还是难的，基础知识很重要，数据结构和算法、操作系统、编程语言的掌握，数据库和网络。可以根据自己的喜好，偏向于某个方向。</p></div></span><br />转自:&nbsp;<a href="http://www.moorekang.com/2010/10/27/forc.html">http://www.moorekang.com/2010/10/27/forc.html</a><img src ="http://www.cppblog.com/Joe/aggbug/156569.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-22 23:36 <a href="http://www.cppblog.com/Joe/archive/2011/09/22/156569.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点 - C之const</title><link>http://www.cppblog.com/Joe/archive/2011/09/21/156421.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Wed, 21 Sep 2011 07:00:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/21/156421.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/156421.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/21/156421.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/156421.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/156421.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="font-family: 'Times New Roman'; line-height: 23px; background-color: #f5fafe; "><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">基本解释</strong></p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　const是一个C语言的关键字，它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的健壮性，另外，在观看别人代码的时候，清晰理解const所起的作用，对理解对方的程序也有一些帮助。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　虽然这听起来很简单，但实际上，const的使用也是c语言中一个比较微妙的地方，微妙在何处呢？请看下面几个问题。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">问题：</font>const变量 &amp; 常量</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　为什么我象下面的例子一样用一个const变量来初始化数组，ANSI C的编译器会报告一个错误呢？</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　const int n = 5;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　int a[n];</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">答案与分析:</font></p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　1)、这个问题讨论的是&#8220;常量&#8221;与&#8220;只读变量&#8221;的区别。常量肯定是只读的，例如5， &#8220;abc&#8221;，等，肯定是只读的，因为程序中根本没有地方存放它的值，当然也就不能够去修改它。而&#8220;只读变量&#8221;则是在内存中开辟一个地方来存放它的值，只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符(Qualifier)。上述代码中变量n被修饰为只读变量，可惜再怎么修饰也不是常量。而ANSI C规定数组定义时维度必须是&#8220;常量&#8221;，&#8220;只读变量&#8221;也是不可以的。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　2)、注意：在ANSI C中，这种写法是错误的，因为数组的大小应该是个常量，而const int n,n只是一个变量(常量 != 不可变的变量，但在标准C++中，这样定义的是一个常量，这种写法是对的)，实际上，根据编译过程及内存分配来看，这种用法本来就应该是合理的，只是ANSI C对数组的规定限制了它。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　3)、那么，在ANSI C 语言中用什么来定义常量呢？答案是enum类型和#define宏，这两个都可以用来定义常量。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">　问题：</font>const变量 &amp; const 限定的内容</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　下面的代码编译器会报一个错误，请问，哪一个语句是错误的呢？</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　typedef char * pStr;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　char string[4] = "abc";</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　const char *p1 = string;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　const pStr p2 = string;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　p1++;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　p2++;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">答案与分析：</font></p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　问题出在p2++上。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　1)、const使用的基本形式： const char m;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　限定m不可变。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　2)、替换1式中的m, const char *pm;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　限定*pm不可变，当然pm是可变的，因此问题中p1++是对的。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　3)、替换1式char, const newType m;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　限定m不可变，问题中的charptr就是一种新类型，因此问题中p2不可变，p2++是错误的。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">　问题：</font>const变量 &amp; 字符串常量</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　请问下面的代码有什么问题？</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　char *p = "i'm hungry!";</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　p[0]= 'I';</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">答案与分析：</font></p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　上面的代码可能会造成内存的非法写操作。分析如下， &#8220;i'm hungry&#8221;实质上是字符串常量，而常量往往被编译器放在只读的内存区，不可写。p初始指向这个只读的内存区，而p[0] = 'I'则企图去写这个地方，编译器当然不会答应。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">问题：</font>const变量 &amp; 字符串常量2</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　请问char a[3] = "abc" 合法吗？使用它有什么隐患？</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">答案与分析：</font></p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　在标准C中这是合法的，但是它的生存环境非常狭小；它定义一个大小为3的数组，初始化为&#8220;abc&#8221;，，注意，它没有通常的字符串终止符'\0'，因此这个数组只是看起来像C语言中的字符串，实质上却不是，因此所有对字符串进行处理的函数，比如strcpy、printf等，都不能够被使用在这个假字符串上。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">问题：</font>const &amp; 指针</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　类型声明中const用来修饰一个常量，有如下两种写法，那么，请问，下面分别用const限定不可变的内容是什么?</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　1)、const在前面</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　const int nValue； //nValue是const</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　const char *pContent; //*pContent是const, pContent可变</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　const (char *) pContent;//pContent是const,*pContent可变</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　char* const pContent; //pContent是const,*pContent可变</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　const char* const pContent; //pContent和*pContent都是const</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　2)、const在后面，与上面的声明对等</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　int const nValue； // nValue是const</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　char const * pContent;// *pContent是const, pContent可变</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　(char *) const pContent;//pContent是const,*pContent可变</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　char* const pContent;// pContent是const,*pContent可变</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　char const* const pContent;// pContent和*pContent都是const</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　<font color="#ff0000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">答案与分析：</font></p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　const和指针一起使用是C语言中一个很常见的困惑之处，在实际开发中，特别是在看别人代码的时候，常常会因为这样而不好判断作者的意图，下面讲一下我的判断原则：</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　沿着*号划一条线，const和谁在一边，那么谁就是const，即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义，相信定会一目了然。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　另外，需要注意：对于const (char *) ; 因为char *是一个整体，相当于一个类型(如 char)，因此，这是限定指针是const。</p></span><img src ="http://www.cppblog.com/Joe/aggbug/156421.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-21 15:00 <a href="http://www.cppblog.com/Joe/archive/2011/09/21/156421.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011好题 - C </title><link>http://www.cppblog.com/Joe/archive/2011/09/21/156420.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Wed, 21 Sep 2011 06:57:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/21/156420.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/156420.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/21/156420.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/156420.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/156420.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="color: #333333; font-family: Tahoma, Verdana, STHeiTi, simsun, sans-serif; background-color: #ffffff; "><table border="0" cellpadding="0" width="100%" style="border-collapse: collapse; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><tbody><tr><td style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.5; list-style-type: none; list-style-position: initial; list-style-image: initial; "><span style="color: red; ">1. 用预处理指令#define 声明一个常数，用以表明1年中有多少秒（忽略闰年问题）</span><br /><br />#define SECONDS_PER_YEAR <span style="color: red; ">(60 * 60 * 24 * 365)UL</span><br />我在这想看到几件事情：<br />1). #define 语法的基本知识（例如：不能以分号结束，括号的使用，等等）<br />2). 懂得预<u>处理器</u>将为你计算常数表达式的值，因此，直接写出你是如何计算一年中有多少秒而不是计算出实际的值，是更清晰而没有代价的。<br />3). 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。<br />4). 如果你在你的表达式中用到UL（表示无符号长整型），那么你有了一个好的起点。记住，第一印象很重要。<br /><br />2. 写一个&#8220;标准&#8221;宏MIN，这个宏输入两个参数并返回较小的一个。<br /><br />#define MIN(A,B) ((A) &lt;= (B) ？(A) : (B))<br />这个测试是为下面的目的而设的：<br />1). 标识#define在宏中应用的基本知识。这是很重要的，因为直到嵌入(inline)操作符变为标准C的一部分，宏是方便产生嵌入代码的唯一方法，<br />对于嵌入式系统来说，为了能达到要求的性能，嵌入代码经常是必须的方法。<br />2). 三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码，了解这个用法是很重要的。<br />3). 懂得在宏中小心地把参数用括号括起来<br />4). 我也用这个问题开始讨论宏的副作用，例如：当你写下面的代码时会发生什么事？<br />least = MIN(*p++, b);<br /><br />3. 预处理器标识#error的目的是什么？<br /><br />如果你不知道答案，请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种<br />问题的答案。当然如果你不是在找一个书呆子，那么应试者最好希望自己不要知道答案。<br /><br />死循环（Infinite loops）<br /><br />4. 嵌入式系统中经常要用到无限循环，你怎么样用C编写死循环呢？<br /><br />这个问题用几个解决方案。我首选的方案是：<br />while(1)<br />{<br />}<br />一些程序员更喜欢如下方案：<br />for(;;)<br />{<br />}<br />这个实现方式让我为难，因为这个语法没有确切表达到底怎么回事。如果一个应试者给出这个作为方案，我将用这个作为一个机会去探究他们这样做的<br />基本原理。如果他们的基本答案是：&#8220;我被教着这样做，但从没有想到过为什么。&#8221;这会给我留下一个坏印象。<br />第三个方案是用 goto<br />Loop:<br />...<br />goto Loop;<br />应试者如给出上面的方案，这说明或者他是一个汇编语言程序员（这也许是好事）或者他是一个想进入新领域的BASIC/FORTRAN程序员。<br /><br />数据声明（Data declarations）<br /><br />5. 用变量a给出下面的定义<br />a) 一个整型数（An integer）<br />b) 一个指向整型数的指针（A pointer to an integer）<br />c) 一个指向指针的的指针，它指向的指针是指向一个整型数（A pointer to a pointer to an integer）<br />d) 一个有10个整型数的数组（An array of 10 integers）<br />e) 一个有10个指针的数组，该指针是指向一个整型数的（An array of 10 pointers to integers）<br />f) 一个指向有10个整型数数组的指针（A pointer to an array of 10 integers）<br />g) 一个指向函数的指针，该函数有一个整型参数并返回一个整型数（A pointer to a function that takes an integer as an argument and returns an integer）<br />h) 一个有10个指针的数组，该指针指向一个函数，该函数有一个整型参数并返回一个整型数（ An array of ten pointers to functions that take an integer<br />argument and return an integer ）<br /><br />答案是：<br />a) int a; // An integer<br />b) int *a; // A pointer to an integer<br />c) int **a; // A pointer to a pointer to an integer<br />d) int a[10]; // An array of 10 integers<br />e) int *a[10]; // An array of 10 pointers to integers<br />f) int (*a)[10]; // A pointer to an array of 10 integers<br />g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer<br />h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer<br /><br />人们经常声称这里有几个问题是那种要翻一下书才能回答的问题，我同意这种说法。当我写这篇文章时，为了确定语法的正确性，我的确查了一下书。<br />但是当我被面试的时候，我期望被问到这个问题（或者相近的问题）。因为在被面试的这段时间里，我确定我知道这个问题的答案。应试者如果不知道<br />所有的答案（或至少大部分答案），那么也就没有为这次面试做准备，如果该面试者没有为这次面试做准备，那么他又能为什么出准备呢？<br /><br />Static<br /><br />6. 关键字static的作用是什么？<br /><br />这个简单的问题很少有人能回答完全。在C语言中，关键字static有三个明显的作用：<br />1). 在函数体，一个被声明为静态的变量在这一函数被调用过程中维持其值不变。<br />2). 在模块内（但在函数体外），一个被声明为静态的变量可以被模块内所用函数访问，但不能被模块外其它函数访问。它是一个本地的全局变量。<br />3). 在模块内，一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是，这个函数被限制在声明它的模块的本地范围内使用。<br />大多数应试者能正确回答第一部分，一部分能正确回答第二部分，同是很少的人能懂得第三部分。这是一个应试者的严重的缺点，因为他显然不懂得本地化数<br />据和代码范围的好处和重要性。<br /><br />Const<br /><br /><span style="color: red; ">7．关键字const是什么含意？</span><br />我只要一听到被面试者说：&#8220;const意味着常数&#8221;，我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法，因此ESP(译者：Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章，只要能说出<span style="color: red; ">const意味着&#8220;只读&#8221;</span>就可以了。尽管这个答案不是完全的答案，但我接受它作为一个正确的答案。（如果你想知道更详细的答案，仔细读一下Saks的文章吧。）如果应试者能正确回答这个问题，我将问他一个附加的问题：下面的声明都是什么意思？<br /><br />const int a;<br />int const a;<br />const int *a;<br />int * const a;<br />int const * a const;<br /><br />前两个的作用是一样，a是一个常整型数。第三个意味着a是一个指向常整型数的指针（也就是，整型数是不可修改的，但指针可以）。第四个意思a是一个指向整型数的常指针（也就是说，指针指向的整型数是可以修改的，但指针是不可修改的）。最后一个意味着a是一个指向常整型数的常指针（也就是说，指针指向的整型数是不可修改的，同时指针也是不可修改的）。如果应试者能正确回答这些问题，那么他就给我留下了一个好印象。顺带提一句，也许你可能会问，即使不用关键字 const，也还是能很容易写出功能正确的程序，那么我为什么还要如此看重关键字const呢？我也如下的几下理由：<br />1). 关键字const的作用是为给读你代码的人传达非常有用的信息，实际上，声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾，你就会很快学会感谢这点多余的信息。（当然，懂得用const的程序员很少会留下的垃圾让别人来清理的。）<br />2). 通过给优化器一些附加的信息，使用关键字const也许能产生更紧凑的代码。<br />3). 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数，防止其被无意的代码修改。简而言之，这样可以减少bug的出现。<br /><br />Volatile<br /><br /><span style="color: red; ">8. 关键字volatile有什么含意 并给出三个不同的例子。</span><br /><br />一个定义为volatile的变量是说这变量可能会被意想不到地改变，这样，编译器就不会去假设这个变量的值了。精确地说就是，优化器在用到这个变量时必须每次都小心地重新读取这个变量的值，而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子：<br />1). 并行设备的硬件寄存器（如：状态寄存器）<br />2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)<br />3). 多线程应用中被几个任务共享的变量<br />回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道，所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。<br />假设被面试者正确地回答了这是问题（嗯，怀疑这否会是这样），我将稍微深究一下，看一下这家伙是不是直正懂得volatile完全的重要性。<br />1). 一个参数既可以是const还可以是volatile吗？解释为什么。<br />2). 一个指针可以是volatile 吗？解释为什么。<br />3). 下面的函数有什么错误：<br />int square(volatile int *ptr)<br />{<br />return *ptr * *ptr;<br />}<br />下面是答案：<br />1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。<br />2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。<br />3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方，但是，由于*ptr指向一个volatile型参数，编译器将产生类似下面的代码：<br />int square(volatile int *ptr)<br />{<br />int a,b;<br />a = *ptr;<br />b = *ptr;<br />return a * b;<br />}<br />由于*ptr的值可能被意想不到地该变，因此a和b可能是不同的。结果，这段代码可能返不是你所期望的平方值！正确的代码如下：<br />long square(volatile int *ptr)<br />{<br />int a;<br />a = *ptr;<br />return a * a;<br />}<br /><br />位操作（Bit manipulation）<br /><br />9. 嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a，写两段代码，第一个设置a的bit 3，第二个清除a 的bit 3。在以上两个操作中，要保持其它位不变。<br /><br />对这个问题有三种基本的反应<br />1). 不知道如何下手。该被面者从没做过任何嵌入式系统的工作。<br />2). 用bit fields。Bit fields是被扔到C语言死角的东西，它保证你的代码在不同编译器之间是不可移植的，同时也保证了的你的代码是不可重用的。我最近不幸看到 Infineon为其较复杂的通信芯片写的驱动程序，它用到了bit fields因此完全对我无用，因为我的编译器用其它的方式来实现bit fields的。从道德讲：永远不要让一个非嵌入式的家伙粘实际硬件的边。<br />3). 用 #defines 和 bit masks 操作。这是一个有极高可移植性的方法，是应该被用到的方法。最佳的解决方案如下：<br />#define BIT3 (0x1&lt;&lt;3)<br />static int a;<br />void set_bit3(void)<br />{<br />a |= BIT3;<br />}<br />void clear_bit3(void)<br />{<br />a &amp;= ~BIT3;<br />}<br />一些人喜欢为设置和清除值而定义一个掩码同时定义一些说明常数，这也是可以接受的。我希望看到几个要点：说明常数、|=和&amp;=~操作。<br /><br />访问固定的内存位置（Accessing fixed memory locations）<br /><br />10. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中，要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。<br /><br />这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换（typecast）为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下：<br />int *ptr;<br />ptr = (int *)0x67a9;<br />*ptr = 0xaa55;<br /><br />一个较晦涩的方法是：<br />*(int * const)(0x67a9) = 0xaa55;<br /><br />即使你的品味更接近第二种方案，但我建议你在面试时使用第一种方案。<br /><br />中断（Interrupts）<br /><br />11. 中断是嵌入式系统中重要的组成部分，这导致了很多编译开发商提供一种扩展&#8212;让标准C支持中断。具代表事实是，产生了一个新的关键字 __interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR)，请评论一下这段代码的。<br /><br />__interrupt double compute_area (double radius)<br />{<br />double area = PI * radius * radius;<br />printf(" Area = %f", area);<br />return area;<br />}<br /><br />这个函数有太多的错误了，以至让人不知从何说起了：<br />1). ISR 不能返回一个值。如果你不懂这个，那么你不会被雇用的。<br />2). ISR 不能传递参数。如果你没有看到这一点，你被雇用的机会等同第一项。<br />3). 在许多的处理器/编译器中，浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈，有些处理器/编译器就是不允许在ISR中做浮点运算。此外，ISR应该是短而有效率的，在ISR中做浮点运算是不明智的。<br />4). 与第三点一脉相承，printf()经常有重入和性能上的问题。如果你丢掉了第三和第四点，我不会太为难你的。不用说，如果你能得到后两点，那么你的被雇用前景越来越光明了。<br /><br />代码例子（Code examples）<br /><br />12 . 下面的代码输出是什么，为什么？<br /><br />void foo(void)<br />{<br />unsigned int a = 6;<br />int b = -20;<br />(a+b &gt; 6) puts("&gt; 6") : puts("&lt;= 6");<br />}<br /><br /><br />这个问题测试你是否懂得C语言中的整数自动转换原则，我发现有些开发者懂得极少这些东西。不管如何，这无符号整型问题的答案是输出是&#8220;&gt;6&#8221;。原因是<span style="color: red; ">当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型</span>。因此-20变成了一个非常大的正整数，所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题，你也就到了得不到这份工作的边缘。<br /><br />13. 评价下面的代码片断：<br /><br />unsigned int zero = 0;<br />unsigned int compzero = 0xFFFF;<br />/*1's complement of zero */<br /><br />对于一个int型不是16位的处理器为说，上面的代码是不正确的。应编写如下：<br /><br /><span style="color: red; ">unsigned int compzero = ~0;</span><br /><br />这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的经验里，好的嵌入式程序员非常准确地明白硬件的细节和它的局限，然而PC机程序往往把硬件作为一个无法避免的烦恼。<br />到了这个阶段，应试者或者完全垂头丧气了或者信心满满志在必得。如果显然应试者不是很好，那么这个测试就在这里结束了。但如果显然应试者做得不错，那么我就扔出下面的追加问题，这些问题是比较难的，我想仅仅非常优秀的应试者能做得不错。提出这些问题，我希望更多看到应试者应付问题的方法，而不是答案。不管如何，你就当是这个娱乐吧&#8230;<br /><br />动态内存分配（Dynamic memory allocation）<br /><br />14. 尽管不像非嵌入式计算机那么常见，嵌入式系统还是有从堆（heap）中动态分配内存的过程的。那么嵌入式系统中，动态分配内存可能发生的问题是什么？<br /><br />这里，我期望应试者能提到内存碎片，碎片收集的问题，变量的持行时间等等。这个主题已经在ESP杂志中被广泛地讨论过了（主要是 P.J. Plauger, 他的解释远远超过我这里能提到的任何解释），所有回过头看一下这些杂志吧！让应试者进入一种虚假的安全感觉后，我拿出这么一个小节目：下面的代码片段的输出是什么，为什么？<br /><br />char *ptr;<br />if ((ptr = (char *)malloc(0)) == NULL)<br />puts("Got a null pointer");<br />else<br />puts("Got a valid pointer");<br /><br />这是一个有趣的问题。最近在我的一个同事不经意<span style="color: red; ">把0值传给了函数malloc，得到了一个合法的指针</span>之后，我才想到这个问题。这就是上面的代码，该代码的输出是&#8220;Got a valid pointer&#8221;。我用这个来开始讨论这样的一问题，看看被面试者是否想到库例程这样做是正确。得到正确的答案固然重要，但解决问题的方法和你做决定的基本原理更重要些。<br /><br />Typedef<br /><br />15. Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如，思考一下下面的例子：<br />#define dPS struct s *<br />typedef struct s * tPS;<br /><br />以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢？（如果有的话）为什么？</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.5; list-style-type: none; list-style-position: initial; list-style-image: initial; "><br />这是一个非常微妙的问题，任何人答对这个问题（正当的原因）是应当被恭喜的。答案是：typedef更好。思考下面的例子：<br />dPS p1,p2;<br />tPS p3,p4;<br /><br />第一个扩展为<br />struct s * p1, p2;<br /><br />上面的代码定义p1为一个指向结构的指，p2为一个实际的结构，这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。<br /><br />晦涩的语法<br /><br />16. C语言同意一些令人震惊的结构,下面的结构是合法的吗，如果是它做些什么？<br />int a = 5, b = 7, c;<br />c = a+++b;<br /><br />这个问题将做为这个测验的一个愉快的结尾。不管你相不相信，上面的例子是完全合乎语法的。问题是编译器如何处理它？水平不高的编译作者实际上会争论这个问题，根据最处理原则，编译器应当能处理尽可能所有合法的用法。因此，上面的代码被处理成：<br />c = a++ + b;<br />因此, 这段代码持行后a = 6, b = 7, c = 12。<br />如果你知道答案，或猜出正确答案，做得好。如果你不知道答案，我也不把这个当作问题。我发现这个问题的最大好处是:这是一个关于代码编写风格，代码的可读性，代码的可修改性的好的话题</p></td></tr></tbody></table></span><img src ="http://www.cppblog.com/Joe/aggbug/156420.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-21 14:57 <a href="http://www.cppblog.com/Joe/archive/2011/09/21/156420.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点 - 大端模式与小端模式、网络字节顺序与主机字节顺序 （经典）[zz]</title><link>http://www.cppblog.com/Joe/archive/2011/09/21/156404.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Wed, 21 Sep 2011 05:03:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/21/156404.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/156404.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/21/156404.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/156404.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/156404.html</trackback:ping><description><![CDATA[<span style="color: #696969; font-family: Arial; font-size: 12px; "><strong style="line-height: normal; ">大端模式与小端模式</strong><br style="line-height: normal; " />一、概念及详解<br style="line-height: normal; " />　　在各种体系的计算机中通常采用的字节存储机制主要有两种： big-endian和little-endian，即大端模式和小端模式。<br style="line-height: normal; " />　　先回顾两个关键词，MSB和LSB：<br style="line-height: normal; " />　　MSB:Most Significant Bit ------- 最高有效位<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LSB:Least Significant Bit ------- 最低有效位<br style="line-height: normal; " />　　大端模式（big-edian）<br style="line-height: normal; " />　　big-endian：MSB存放在最低端的地址上。<br style="line-height: normal; " />　　举例，双字节数0x1234以big-endian的方式存在起始地址0x00002000中：<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | data |&lt;-- address<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 0x12 |&lt;-- 0x00002000<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 0x34 |&lt;-- 0x00002001<br style="line-height: normal; " />　　在Big-Endian中，对于bit序列中的序号编排方式如下（以双字节数0x8B8A为例）：<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bit | 0 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 15<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------MSB----------------------------------LSB<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +--------------------------------------------+<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0x8 B 8 A<br style="line-height: normal; " />　　小端模式(little-endian)<br style="line-height: normal; " />　　little-endian：LSB存放在最低端的地址上。<br style="line-height: normal; " />　　举例，双字节数0x1234以little-endian的方式存在起始地址0x00002000中：<br style="line-height: normal; " />| data |&lt;-- address<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 0x34 |&lt;-- 0x00002000<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 0x12 |&lt;-- 0x00002001<br style="line-height: normal; " />　　在Little-Endian中，对于bit序列中的序号编排和Big-Endian刚好相反，其方式如下（以双字节数0x8B8A为例）：<br style="line-height: normal; " />bit | 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------MSB-----------------------------------LSB<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +---------------------------------------------+<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0x8 B 8 A&nbsp;<br style="line-height: normal; " />二、数组在大端小端情况下的存储：<br style="line-height: normal; " />　　以unsigned int value = 0x12345678为例，分别看看在两种字节序下其存储情况，我们可以用unsigned char buf[4]来表示value：<br style="line-height: normal; " />　　Big-Endian: 低地址存放高位，如下：<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 高地址<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---------------<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf[3] (0x78) -- 低位<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf[2] (0x56)<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf[1] (0x34)<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf[0] (0x12) -- 高位<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---------------<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 低地址<br style="line-height: normal; " />Little-Endian: 低地址存放低位，如下：<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 高地址<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---------------<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf[3] (0x12) -- 高位<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf[2] (0x34)<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf[1] (0x56)<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf[0] (0x78) -- 低位<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --------------<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 低地址<br style="line-height: normal; " /><br style="line-height: normal; " />　　三、大端小端转换方法：<br style="line-height: normal; " />　　Big-Endian转换成Little-Endian如下：<br style="line-height: normal; " />#define BigtoLittle16(A)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((((uint16)(A) &amp; 0xff00) &gt;&gt; 8) | \<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((uint16)(A) &amp; 0x00ff) &lt;&lt; 8))<br style="line-height: normal; " />#define BigtoLittle32(A)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((((uint32)(A) &amp; 0xff000000) &gt;&gt; 24) | \<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((uint32)(A) &amp; 0x00ff0000) &gt;&gt; 8) | \<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((uint32)(A) &amp; 0x0000ff00) &lt;&lt; 8) | \<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((uint32)(A) &amp; 0x000000ff) &lt;&lt; 24))<br style="line-height: normal; " /><br style="line-height: normal; " />　　四、大端小端检测方法：<br style="line-height: normal; " />　　如何检查处理器是big-endian还是little-endian?<br style="line-height: normal; " />　　联合体union的存放顺序是所有成员都从低地址开始存放，利用该特性就可以轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。<br style="line-height: normal; " />int checkCPUendian()<br style="line-height: normal; " />{<br style="line-height: normal; " />union<br style="line-height: normal; " />{<br style="line-height: normal; " />unsigned int a;<br style="line-height: normal; " />unsigned char b;<br style="line-height: normal; " />}c;<br style="line-height: normal; " />c.a = 1;<br style="line-height: normal; " />return (c.b == 1);<br style="line-height: normal; " />}<br style="line-height: normal; " />/*return 1 : little-endian, return 0:big-endian*/&nbsp;<br style="line-height: normal; " /><strong style="line-height: normal; "><br style="line-height: normal; " />网络字节顺序</strong><br style="line-height: normal; " />1、字节内的比特位不受这种顺序的影响<br style="line-height: normal; " />比如一个字节 1000 0000 （或表示为十六进制 80H)不管是什么顺序其内存中的表示法都是这样。<br style="line-height: normal; " />2、大于1个字节的数据类型才有字节顺序问题<br style="line-height: normal; " />比如 Byte A，这个变量只有一个字节的长度，所以根据上一条没有字节顺序问题。所以字节顺序是&#8220;字节之间的相对顺序&#8221;的意思。<br style="line-height: normal; " />3、大于1个字节的数据类型的字节顺序有两种<br style="line-height: normal; " />比如 short B，这是一个两字节的数据类型，这时就有字节之间的相对顺序问题了。<br style="line-height: normal; " />网络字节顺序是&#8220;所见即所得&#8221;的顺序。而Intel类型的CPU的字节顺序与此相反。<br style="line-height: normal; " />比如上面的 short B=0102H(十六进制，每两位表示一个字节的宽度）。所见到的是&#8220;0102&#8221;，按一般数学常识，数轴从左到右的方向增加，即内存地址从左到右增加的话，在内存中这个 short B的字节顺序是：<br style="line-height: normal; " />01 02<br style="line-height: normal; " />这就是网络字节顺序。所见到的顺序和在内存中的顺序是一致的！<br style="line-height: normal; " />而相反的字节顺序就不同了，其在内存中的顺序为：02 01<br style="line-height: normal; " />假设通过抓包得到网络数据的两个字节流为：01 02<br style="line-height: normal; " />如果这表示两个 Byte类型的变量，那么自然不需要考虑字节顺序的问题。<br style="line-height: normal; " />如果这表示一个 short 变量，那么就需要考虑字节顺序问题。根据网络字节顺序&#8220;所见即所得&#8221;的规则，这个变量的值就是：0102<br style="line-height: normal; " />假设本地主机是Intel类型的，那么要表示这个变量，有点麻烦：<br style="line-height: normal; " />定义变量 short X，<br style="line-height: normal; " />字节流地址为：pt，按顺序读取内存是为<br style="line-height: normal; " />x=*((short*)pt);<br style="line-height: normal; " />那么X的内存顺序当然是 01 02<br style="line-height: normal; " />按非&#8220;所见即所得&#8221;的规则，这个内存顺序和看到的一样显然是不对的，所以要把这两个字节的位置调换。<br style="line-height: normal; " />调换的方法可以自己定义，但用已经有的API还是更为方便。<br style="line-height: normal; " /><br style="line-height: normal; " />网络字节顺序与主机字节顺序<br style="line-height: normal; " />NBO与HBO 网络字节顺序NBO（Network Byte Order）：按从高到低的顺序存储，在网络上使用统一的网络字节顺序，可以避免兼容性问题。主机字节顺序（HBO，Host Byte Order）：不同的机器HBO不相同，与CPU设计有关计算机数据存储有两种字节优先顺序：高位字节优先和低位字节优先。Internet上数据以高位字节优先顺序在网络上传输，所以对于在内部是以低位字节优先方式存储数据的机器，在Internet上传输数据时就需要进行转换。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />htonl()<br style="line-height: normal; " />简述：<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp; 将主机的无符号长整形数转换成网络字节顺序。<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp; #include &lt;winsock.h&gt;<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp; u_long PASCAL FAR htonl( u_long hostlong);<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp; hostlong：主机字节顺序表达的32位数。<br style="line-height: normal; " />注释：<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp; 本函数将一个32位数从主机字节顺序转换成网络字节顺序。<br style="line-height: normal; " />返回值：<br style="line-height: normal; " />&nbsp;&nbsp;&nbsp; htonl()返回一个网络字节顺序的值。<br style="line-height: normal; " /><br style="line-height: normal; " />inet_ntoa()<br style="line-height: normal; " />简述：<br style="line-height: normal; " />将网络地址转换成&#8220;.&#8221;点隔的字符串格式。<br style="line-height: normal; " />#include &lt;winsock.h&gt;<br style="line-height: normal; " />char FAR* PASCAL FAR inet_ntoa( struct in_addr in);<br style="line-height: normal; " />in：一个表示Internet主机地址的结构。<br style="line-height: normal; " />注释：<br style="line-height: normal; " />本函数将一个用in参数所表示的Internet地址结构转换成以&#8220;.&#8221; 间隔的诸如&#8220;a.b.c.d&#8221;的字符串形式。请注意inet_ntoa()返回的字符串存放在WINDOWS套接口实现所分配的内存中。应用程序不应假设该内存是如何分配的。在同一个线程的下一个WINDOWS套接口调用前，数据将保证是有效。<br style="line-height: normal; " />返回值：<br style="line-height: normal; " />若无错误发生，inet_ntoa()返回一个字符指针。否则的话，返回NULL。其中的数据应在下一个WINDOWS套接口调用前复制出来。<br style="line-height: normal; " /><br style="line-height: normal; " />网络中传输的数据有的和本地字节存储顺序一致，而有的则截然不同，为了数据的一致性，就要把本地的数据转换成网络上使用的格式，然后发送出去，接收的时候也是一样的，经过转换然后才去使用这些数据，基本的库函数中提供了这样的可以进行字节转换的函数，如和htons( ) htonl( ) ntohs( ) ntohl( )，这里n表示network，h表示host，htons( ) htonl( )用于本地字节向网络字节转换的场合，s表示short，即对2字节操作，l表示long即对4字节操作。同样ntohs( )ntohl( )用于网络字节向本地格式转换的场合。</span><img src ="http://www.cppblog.com/Joe/aggbug/156404.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-21 13:03 <a href="http://www.cppblog.com/Joe/archive/2011/09/21/156404.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点 - IO模型– 同步和阻塞，异步和非阻塞的区别</title><link>http://www.cppblog.com/Joe/archive/2011/09/09/155464.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Fri, 09 Sep 2011 09:03:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/09/155464.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/155464.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/09/155464.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/155464.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/155464.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 12px; line-height: 17px; background-color: #ffffff; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">原文在<a href="http://hi.baidu.com/deep_pro/blog/item/cf964b0ade9f4d1594ca6b1b.html" style="color: #2970a6; text-decoration: none; ">http://hi.baidu.com/deep_pro/blog/item/cf964b0ade9f4d1594ca6b1b.html</a></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span id="more-4041"></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">这些词之间的区别难倒了很多人，还有什么同步阻塞， 同步非阻塞， 异步阻塞， 异步非阻塞，乱七八糟的。<br />很多文章也想讲明白这个问题。著名且引起热议的有</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><a href="http://www.ibm.com/developerworks/cn/linux/l-async/">http://www.ibm.com/developerworks/cn/linux/l-async/</a></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><a href="http://www.cppblog.com/converse/archive/2009/05/13/82879.html" style="color: #2970a6; text-decoration: none; ">http://www.cppblog.com/converse/archive/2009/05/13/82879.html</a></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">可是看了之后还是有点将信将疑，跑到图书馆翻了UNP 第一卷，不愧是圣经级别的著作，似有所悟。<br />UNP所述：<br />POSIX定义中，同步IO操作：IO操作将导致请求进程阻塞，直到IO操作完成。<br />异步IO操作：IO操作不导致请求进程阻塞</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">UNP中总结的IO模型有5种之多<br />阻塞IO，非阻塞IO，IO复用，信号驱动IO，异步IO,前四种都属于同步IO。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">阻塞IO不必说了<br />非阻塞IO ，IO请求时加上O_NONBLOCK一类的标志位，立刻返回，IO没有就绪会返回错误，需要请求进程主动轮询不断发IO请求直到返回正确<br />IO复用同非阻塞IO本质一样，不过利用了新的select系统调用，由内核来负责本来是请求进程该做的轮询操作。看似比非阻塞IO还多了一个系统调用开销，不过因为可以支持多路IO，才算提高了效率<br />信号驱动IO，调用sigaltion系统调用，当内核中IO数据就绪时以SIGIO信号通知请求进程，请求进程再把数据从内核读入到用户空间，这一步是阻塞的。<br />异步IO，如定义所说，不会因为IO操作阻塞，IO操作全部完成才通知请求进程。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">这样以来，同步和阻塞，异步和非阻塞就不会被混淆了，它们不是同一个方面上的概念，不能比较区别</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">同步和异步是只跟IO操作过程中进程的状态变化有关<br />阻塞和非阻塞就是进程的两种状态。</p></span><img src ="http://www.cppblog.com/Joe/aggbug/155464.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-09 17:03 <a href="http://www.cppblog.com/Joe/archive/2011/09/09/155464.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点 - C++ 虚函数表解析</title><link>http://www.cppblog.com/Joe/archive/2011/09/07/155300.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Wed, 07 Sep 2011 11:22:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/07/155300.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/155300.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/07/155300.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/155300.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/155300.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: C++&nbsp;虚函数表解析&nbsp;陈皓http://blog.csdn.net/haoel&nbsp;&nbsp;前言&nbsp;C++中的虚函数的作用主要是实现了多态的机制。关于多态，简而言之就是用父类型别的指针指向其子类的实例，然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有&#8220;多种形态&#8221;，这是一种泛型技术。所谓泛型技术，说白了就是试图使用不变...&nbsp;&nbsp;<a href='http://www.cppblog.com/Joe/archive/2011/09/07/155300.html'>阅读全文</a><img src ="http://www.cppblog.com/Joe/aggbug/155300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-07 19:22 <a href="http://www.cppblog.com/Joe/archive/2011/09/07/155300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>epoll方法实现non-blocking socket</title><link>http://www.cppblog.com/Joe/archive/2011/09/05/155151.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Mon, 05 Sep 2011 12:00:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/05/155151.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/155151.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/05/155151.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/155151.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/155151.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: epoll方法实现non-blocking socketPosted on&nbsp;2011/06/17&nbsp;by&nbsp;Min&#169;&nbsp;Min的技术分享 &#8211; 54min.com&nbsp;(RSS订阅) | 原文链接：http://54min.com/post/using-epoll-method-create-non-blocking-socket.htm...&nbsp;&nbsp;<a href='http://www.cppblog.com/Joe/archive/2011/09/05/155151.html'>阅读全文</a><img src ="http://www.cppblog.com/Joe/aggbug/155151.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-05 20:00 <a href="http://www.cppblog.com/Joe/archive/2011/09/05/155151.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点 - HTTP协议</title><link>http://www.cppblog.com/Joe/archive/2011/09/04/155077.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sun, 04 Sep 2011 14:19:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/04/155077.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/155077.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/04/155077.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/155077.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/155077.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: HTTP protocolPosted on&nbsp;2011/05/02&nbsp;by&nbsp;Min&#169;&nbsp;Min的技术分享 &#8211; 54min.com&nbsp;(RSS订阅) | 原文链接：http://54min.com/post/the-http-protocol.htmlHTTP protocolHTTP是应用层协议(传输层采用TCP因此是面向连接的)，...&nbsp;&nbsp;<a href='http://www.cppblog.com/Joe/archive/2011/09/04/155077.html'>阅读全文</a><img src ="http://www.cppblog.com/Joe/aggbug/155077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-04 22:19 <a href="http://www.cppblog.com/Joe/archive/2011/09/04/155077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011面试题 - 逆转整数的二进制表示</title><link>http://www.cppblog.com/Joe/archive/2011/09/04/155056.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sun, 04 Sep 2011 08:03:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/04/155056.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/155056.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/04/155056.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/155056.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/155056.html</trackback:ping><description><![CDATA[问题:<br /><span class="Apple-style-span" style="font-family: simsun; font-size: 18px; line-height: 27px; background-color: #ffffff; ">写一个函数 unsigned RevBit(unsigned val);<br /><br />unsigned x = RevBit(0xf0ec9999);<br />x应该为 0x9999370f。<br /><br />0xf0ec9999 == 11110000111011001001100110011001(二进制)<br /><br />0x9999370f == 10011001100110010011011100001111（二进制)</span><br /><br /><span class="Apple-style-span" style="color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 12px; line-height: 17px; background-color: #ffffff; ">思路：相邻两位互调位置（即一位换一位），再相邻的两位换两位，在相邻的四位与四位互调位置，再八位与八位互调位置，最后前十六位和后十六位互换位置，完成32位整数逆转。思路与归并排序相似。<br /><br /></span>代码:<br /><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; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">;<br />&nbsp;<br />unsigned&nbsp;RevBit(unsigned&nbsp;x)<br />{<br />x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">(x</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">0x55555555</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">|</span><span style="color: #000000; ">(x</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">0x55555555</span><span style="color: #000000; ">;<br />x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">(x</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">0x33333333</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">2</span><span style="color: #000000; ">|</span><span style="color: #000000; ">(x</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">2</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">0x33333333</span><span style="color: #000000; ">;<br />x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">(x</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">0x0f0f0f0f</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">4</span><span style="color: #000000; ">|</span><span style="color: #000000; ">(x</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">4</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">0x0f0f0f0f</span><span style="color: #000000; ">;<br />x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">(x</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">0x00ff00ff</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">8</span><span style="color: #000000; ">|</span><span style="color: #000000; ">(x</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">8</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">0x00ff00ff</span><span style="color: #000000; ">;<br />x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">x</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">16</span><span style="color: #000000; ">|</span><span style="color: #000000; ">x</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">16</span><span style="color: #000000; ">;<br /></span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;x;<br />}<br />&nbsp;<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br />{<br />unsigned&nbsp;x&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;RevBit(</span><span style="color: #000000; ">0xf0ec9999</span><span style="color: #000000; ">);<br />printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%x\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,x);<br /></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></div><br />更多解法:&nbsp;<a href="http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious">http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious</a><br /><img src ="http://www.cppblog.com/Joe/aggbug/155056.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-04 16:03 <a href="http://www.cppblog.com/Joe/archive/2011/09/04/155056.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011面试题 - 找数</title><link>http://www.cppblog.com/Joe/archive/2011/09/04/155055.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sun, 04 Sep 2011 07:37:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/04/155055.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/155055.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/04/155055.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/155055.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/155055.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 12px; line-height: 17px; background-color: #ffffff; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>题目</strong>：</p><ol style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 20px; list-style-position: inside; ">给你n个数，其中有且仅有一个数出现了奇数次，其余的数都出现了偶数次。用线性时间常数空间找出出现了奇数次的那一个数。</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 20px; list-style-position: inside; ">给你n个数，其中有且仅有两个数出现了奇数次，其余的数都出现了偶数次。用线性时间常数空间找出出现了奇数次的那两个数。</li></ol><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>答案</strong>：</p><ol style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 20px; list-style-position: inside; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">从头到尾异或一遍，最后得到的那个数就是出现了奇数次的数。这是因为异或有一个神奇的性质：两次异或同一个数，结果不变。再考虑到异或运算满足交换律，先异或和后异或都是一样的，因此这个算法显然正确。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 20px; list-style-position: inside; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">从头到尾异或一遍，你就得到了需要求的两个数异或后的值。这两个数显然不相等，异或出来的结果不为0。我们可以据此找出两个数的二进制表达中不同的一位，然后把所有这n个数分成两类，在那一位上是0的分成一类，在那一位上是1的分到另一类。对每一类分别使用前一个问题的算法。</p></li></ol></span><img src ="http://www.cppblog.com/Joe/aggbug/155055.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-04 15:37 <a href="http://www.cppblog.com/Joe/archive/2011/09/04/155055.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011分治-平面最近点对（附C++源代码）</title><link>http://www.cppblog.com/Joe/archive/2011/09/03/155031.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sat, 03 Sep 2011 15:17:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/03/155031.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/155031.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/03/155031.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/155031.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/155031.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="color: #333333; font-family: Tahoma, Arial, sans-serif; font-size: 12px; line-height: 20px; background-color: #ffffff; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">求平面最近点对的核心思想乃是二分，用递归实现。具体操作如下：</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 若点的个数很少（比如小于3或者小于5），就直接枚举。</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 如点的个数很多，按现将所有点按X排序，并按X坐标平均的分成左右两个部分（假设分割线为X=nx），分别求出两边的最短距离minl与minr并令ans=min（minl，minr）。</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 求出左右两边的最小值之后，剩下的工作就是合并。易见若该点集存在点对（a，b）的最近距离小于ans，则a，b一定分别在x=nx的两边，切nx-a.x与nx-b.x的绝对值肯定小于ans。</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 据此我们可以将点集中所有X值在（nx-ans，nx+ans）的点都选出来，那么满足条件的（a，b）肯定都在其中。</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 易见若存在（a，b）两点他们之间的距离小于ans，那么a.y-b.y的绝对值也肯定小于ans。</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 综上存在（a，b）两点他们之间的距离小于ans那，（a，b）一定在一个长为2*ans宽为ans的矩形之中。而 且这个矩形被X=nx平分成两个ans*ans的矩形，由于无论是在左边还是在右边，任意两点的之间的距离总是小于等于ans的，所以两个ans*ans 的矩形中最多只有4个点（分别在四个顶点上），长为2*ans宽为ans的矩形最多有8个点。</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 据此我们将所有X值在（nx-ans，nx+ans）的点按他们的Y值进行排序。依次看每个点与它之后的7个点的距离是否小于ans，若小于则更新ans，最后求出来的结果就是平面最近点对的距离。保留产生该距离的两个点即可得到最近点对。</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 练手题目：Pku2107，Vijos1012</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">附C++代码（Pku2107）：</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">#include &lt;iostream&gt;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />#include &lt;cmath&gt;</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">const long maxsize = 100000;</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">typedef struct&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />{&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />double x, y;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />} PointType;</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">long list[maxsize], listlen,n;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />PointType point[maxsize];</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">int sortcmp(const void *,const void *);&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />double dis(PointType,PointType);<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />double getmin(double,double);<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />int listcmp(const void *,const void *);&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />double shortest(long,long);<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />int init(void);</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">int main()&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />{&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />while (init())<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; printf("%.2lf\n",shortest(0, n - 1)/2);&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />return 0;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">int sortcmp(const void *a, const void *b)&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />{&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />if (((PointType*)a)-&gt;x &lt; ((PointType*)b)-&gt;x)&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; return -1;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />else&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; return 1;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">double dis(PointType a, PointType b)&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />{&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">double getmin(double a, double b)&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />{&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />return a&lt;b?a:b;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">int listcmp(const void *a, const void *b)&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />{&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />if (point[*(int*)a].y &lt; point[*(int*)b].y)&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; return -1;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />else&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; return 1;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">double shortest(long l, long r)&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />{&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />if (r - l == 1)&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; return dis(point[l], point[r]);&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />if (r - l == 2)&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; return getmin(getmin(dis(point[l], point[l+1]), dis(point[l], point[r])), dis(point[l+1], point[r]));&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />long i, j, mid = (l + r) &gt;&gt; 1;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />double curmin = getmin(shortest(l, mid), shortest(mid + 1, r));&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />listlen = 0;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />for (i = mid; i &gt;= l &amp;&amp; point[mid+1].x - point[i].x &lt;= curmin; i --)&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; list[listlen++] = i;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />for (i = mid + 1; i &lt;= r &amp;&amp; point[i].x - point[mid].x &lt;= curmin; i ++)&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; list[listlen++] = i;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />qsort(list, listlen, sizeof(list[0]), listcmp);&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />for (i = 0; i &lt; listlen; i ++)&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; for (j = i + 1; j &lt; listlen &amp;&amp; point[list[j]].y - point[list[i]].y &lt;= curmin; j ++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp; curmin = getmin(curmin, dis(point[list[i]], point[list[j]]));&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />return curmin;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}</font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.7em; "><font size="2" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">int init(void)<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />{<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />int i;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />scanf("%d", &amp;n);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />for (i=0;i&lt;n;i++)&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; scanf("%lf%lf",&amp;point[i].x,&amp;point[i].y);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />qsort(point,n,sizeof(point[0]),sortcmp);<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />return n;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}<br /><br /><br />自己写的代码:<br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;*&nbsp;Problem(classic):<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;there're&nbsp;many&nbsp;points&nbsp;in&nbsp;a&nbsp;plane&nbsp;surface,&nbsp;find&nbsp;the&nbsp;nearest&nbsp;two&nbsp;points<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;see:&nbsp;&lt;CLRS&gt;&nbsp;33.4&nbsp;section<br />&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">math.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;INF&nbsp;0x7FFFFFFF</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;NUM_MAX&nbsp;100000</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;THRESHOLD&nbsp;3</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;x,&nbsp;y;<br />};<br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;points[NUM_MAX];<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;total,&nbsp;yindex[NUM_MAX];<br /><br /></span><span style="color: #0000FF; ">double</span><span style="color: #000000; "><br />min(</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;arg1,&nbsp;</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;arg2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(arg1&nbsp;</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">&nbsp;arg2&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;arg1&nbsp;:&nbsp;arg2);<br />}<br /><br /></span><span style="color: #0000FF; ">double</span><span style="color: #000000; "><br />distance(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">arg1,&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">arg2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;x_diff&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;arg1</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">x&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;arg2</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">x;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;y_diff&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;arg1</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">y&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;arg2</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">y;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;sqrt(x_diff</span><span style="color: #000000; ">*</span><span style="color: #000000; ">x_diff&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;y_diff</span><span style="color: #000000; ">*</span><span style="color: #000000; ">y_diff);<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />compare_x(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">arg1,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">arg2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p1&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)arg1;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p2&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)arg2;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(p1</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">x&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;p2</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">x);<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />compare_y(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">arg1,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">arg2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p1&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;points&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: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)arg1;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p2&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;points&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: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)arg2;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(p1</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">y&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;p2</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">y);<br />}<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "><br />init_preprocess()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">total);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">total;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%lf&nbsp;%lf</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">points[i].x,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">points[i].y);<br />&nbsp;&nbsp;&nbsp;&nbsp;qsort(points,&nbsp;total,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Point),&nbsp;compare_x);<br />}<br /><br /></span><span style="color: #0000FF; ">double</span><span style="color: #000000; "><br />find_nearest(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;begin,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;end)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i,&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;INF;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(end</span><span style="color: #000000; ">-</span><span style="color: #000000; ">begin</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">&nbsp;THRESHOLD)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">begin;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">end;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(j</span><span style="color: #000000; ">=</span><span style="color: #000000; ">i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;j</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">end;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">j)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;min(ret,&nbsp;distance(points</span><span style="color: #000000; ">+</span><span style="color: #000000; ">i,&nbsp;points</span><span style="color: #000000; ">+</span><span style="color: #000000; ">j));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;ret;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;mid&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;begin&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;((end&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;begin)&nbsp;</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;dis&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;min(find_nearest(begin,&nbsp;mid),&nbsp;find_nearest(mid</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;end));<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;len&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;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(j</span><span style="color: #000000; ">=</span><span style="color: #000000; ">mid;&nbsp;j</span><span style="color: #000000; ">&gt;=</span><span style="color: #000000; ">begin&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;points[mid</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">].x</span><span style="color: #000000; ">-</span><span style="color: #000000; ">points[j].x</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">dis;&nbsp;</span><span style="color: #000000; ">--</span><span style="color: #000000; ">j)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yindex[len</span><span style="color: #000000; ">++</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(j</span><span style="color: #000000; ">=</span><span style="color: #000000; ">mid</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;j</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">end&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;points[j].x</span><span style="color: #000000; ">-</span><span style="color: #000000; ">points[mid].x</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">dis;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">j)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yindex[len</span><span style="color: #000000; ">++</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;qsort(yindex,&nbsp;len,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">),&nbsp;compare_y);<br />&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;dis;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">len</span><span style="color: #000000; ">-</span><span style="color: #000000; ">7</span><span style="color: #000000; ">;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(j</span><span style="color: #000000; ">=</span><span style="color: #000000; ">i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;j</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">7</span><span style="color: #000000; ">;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">j)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;min(ret,&nbsp;distance(points</span><span style="color: #000000; ">+</span><span style="color: #000000; ">yindex[i],&nbsp;points</span><span style="color: #000000; ">+</span><span style="color: #000000; ">yindex[j]));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;ret;<br />}<br /><br /></span><span style="color: #0000FF; ">double</span><span style="color: #000000; "><br />brute_force(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;begin,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;end)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;INF;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i,&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">begin;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">end;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(j</span><span style="color: #000000; ">=</span><span style="color: #000000; ">i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;j</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">end;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">j)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;min(ret,&nbsp;distance(points</span><span style="color: #000000; ">+</span><span style="color: #000000; ">i,&nbsp;points</span><span style="color: #000000; ">+</span><span style="color: #000000; ">j));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;ret;<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">argv)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;init_preprocess();<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;find_nearest(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;total</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">\nNearest&nbsp;Distance[Brute&nbsp;Force]:&nbsp;%f\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;brute_force(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;total</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">));<br />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">\nNearest&nbsp;Distance:&nbsp;%f\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;ret);<br />}</span></div><br /><br /></font></p></span><img src ="http://www.cppblog.com/Joe/aggbug/155031.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-03 23:17 <a href="http://www.cppblog.com/Joe/archive/2011/09/03/155031.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011知识点-TCP 区分消息边界[zz]</title><link>http://www.cppblog.com/Joe/archive/2011/09/01/154897.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Thu, 01 Sep 2011 10:36:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/09/01/154897.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/154897.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/09/01/154897.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/154897.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/154897.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; line-height: 22px; background-color: #eaf2ec; ">&nbsp;在socket网络程序中，TCP和UDP分别是面向连接和非面向连接的。因此TCP的socket编程，收发两端（客户端和服务器端）都要有一一成对的socket，因此，发送端为了将多个发往接收端的包，更有效的发到对方，使用了优化方法（Nagle算法），将多次间隔较小且数据量小的数据，合并成一个大的数据块，然后进行封包。这样，接收端，就难于分辨出来了，必须提供科学的拆包机制。<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于UDP，不会使用块的合并优化算法，这样，实际上目前认为，是由于UDP支持的是一对多的模式，所以接收端的skbuff(套接字缓冲区）采用了链式结构来记录每一个到达的UDP包，在每个UDP包中就有了消息头（消息来源地址，端口等信息），这样，对于接收端来说，就容易进行区分处理了<br style="line-height: 22px; " /><br style="line-height: 22px; " /><strong style="line-height: 22px; ">保护消息边界和流</strong><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">那么什么是保护消息边界和流呢?</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 保护消息边界，就是指传输协议把数据当作一条独立的消息在网上&nbsp;<br style="line-height: 22px; " />传输,接收端只能接收独立的消息.也就是说存在保护消息边界,接收&nbsp;<br style="line-height: 22px; " />端一次只能接收发送端发出的一个数据包.&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而面向流则是指无保护<strong style="line-height: 22px; color: black; background-color: #a0ffff; ">消息保护边界</strong>的,如果发送端连续发送数据,&nbsp;<br style="line-height: 22px; " />接收端有可能在一次接收动作中,会接收两个或者更多的数据包.</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们举个例子来说,例如,我们连续发送三个数据包,大小分别是2k,&nbsp;<br style="line-height: 22px; " />4k , 8k,这三个数据包,都已经到达了接收端的网络堆栈中,如果使&nbsp;<br style="line-height: 22px; " />用<strong style="line-height: 22px; color: black; background-color: #ffff66; ">UDP</strong>协议,不管我们使用多大的接收缓冲区去接收数据,我们必须有&nbsp;<br style="line-height: 22px; " />三次接收动作,才能够把所有的数据包接收完.而使用TCP协议,我们&nbsp;<br style="line-height: 22px; " />只要把接收的缓冲区大小设置在14k以上,我们就能够一次把所有的&nbsp;<br style="line-height: 22px; " />数据包接收下来.只需要有一次接收动作.</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这就是因为<strong style="line-height: 22px; color: black; background-color: #ffff66; ">UDP</strong>协议的保护消息边界使得每一个消息都是独立的.而&nbsp;<br style="line-height: 22px; " />流传输,却把数据当作一串数据流,他不认为数据是一个一个的消息.</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所以有很多人在使用tcp协议通讯的时候,并不清楚tcp是基于流的&nbsp;<br style="line-height: 22px; " />传输,当连续发送数据的时候,他们时常会认识tcp会丢包.其实不然,&nbsp;<br style="line-height: 22px; " />因为当他们使用的缓冲区足够大时,他们有可能会一次接收到两个甚&nbsp;<br style="line-height: 22px; " />至更多的数据包,而很多人往往会忽视这一点,只解析检查了第一个&nbsp;<br style="line-height: 22px; " />数据包,而已经接收的其他数据包却被忽略了.所以大家如果要作这&nbsp;<br style="line-height: 22px; " />类的网络编程的时候,必须要注意这一点.</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">结论：<br style="line-height: 22px; " /></strong>&nbsp;&nbsp;&nbsp;&nbsp; 根据以上所说，可以这样理解，TCP为了保证可靠传输，尽量减少额外<br style="line-height: 22px; " />开销（每次发包都要验证），因此采用了流式传输，面向流的传输，<br style="line-height: 22px; " />相对于面向消息的传输，可以减少发送包的数量。从而减少了额外开<br style="line-height: 22px; " />销。但是，对于数据传输频繁的程序来讲，使用TCP可能会容易粘包。<br style="line-height: 22px; " />当然，对接收端的程序来讲，如果机器负荷很重，也会在接收缓冲里<br style="line-height: 22px; " />粘包。这样，就需要接收端额外拆包，增加了工作量。因此，这个特<br style="line-height: 22px; " />别适合的是数据要求可靠传输，但是不需要太频繁传输的场合（<br style="line-height: 22px; " />两次操作间隔100ms，具体是由TCP等待发送间隔决定的，取决于内核<br style="line-height: 22px; " />中的socket的写法）<br style="line-height: 22px; " /><br style="line-height: 22px; " />而UDP，由于面向的是消息传输，它把所有接收到的消息都挂接到缓冲<br style="line-height: 22px; " />区的接受队列中，因此，它对于数据的提取分离就更加方便，但是，<br style="line-height: 22px; " />它没有粘包机制，因此，当发送数据量较小的时候，就会发生数据包<br style="line-height: 22px; " />有效载荷较小的情况，也会增加多次发送的系统发送开销（系统调用，<br style="line-height: 22px; " />写硬件等）和接收开销。因此，应该最好设置一个比较合适的数据包<br style="line-height: 22px; " />的包长，来进行UDP数据的发送。（UDP最大载荷为1472，因此最好能<br style="line-height: 22px; " />每次传输接近这个数的数据量，这特别适合于视频，音频等大块数据<br style="line-height: 22px; " />的发送，同时，通过减少握手来保证流媒体的实时性）</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">来自:&nbsp;<a href="http://hi.baidu.com/chongerfeia/blog/item/b1e572f631dd7e28bd310965.html" target="_blank" style="line-height: 22px; text-decoration: none; color: #506f62; "><font color="#9a9a9a" style="line-height: 22px; ">http://hi.baidu.com/chongerfeia/blog/item/b1e572f631dd7e28bd310965.html</font></a></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">TCP无保护消息边界的解决<br style="line-height: 22px; " />&nbsp;针对这个问题，一般有3种解决方案：</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)发送固定长度的消息</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)把消息的尺寸与消息一块发送</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)使用特殊标记来区分消息间隔</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">下面我们主要分析下前两种方法：</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">1、发送固定长度的消息&nbsp;<br style="line-height: 22px; " />这种方法的好处是他非常容易，而且只要指定好消息的长度，没有遗漏未未发的数据，我们重写了一个SendMessage方法。代码如下：</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp; private static int SendMessage(Socket s, byte[] msg)</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int offset = 0;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size = msg.Length;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int dataleft = size;</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (dataleft &gt; 0)&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sent = s.Send(msg, offset, SocketFlags.None);&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset += sent;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dataleft -= sent;</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return offset;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">简要分析一下这个函数：形参s是进行通信的套接字，msg即待发送的字节数组。该方法使用while循环检查是否还有数据未发送，尤其当发送一个很庞大的数据包，在不能一次性发完的情况下作用比较明显。特别的，用sent来记录实际发送的数据量，和recv是异曲同工的作用，最后返回发送的实际数据总数。</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp; 有sentMessage函数后，还要根据指定的消息长度来设计一个新的Recive方法。代码如下：</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp; private byte[] ReciveMessage(Socket s, int size)&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</strong></p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="line-height: 22px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int offset = 0;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int recv;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int dataleft = size;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] msg = new byte[size];</strong></p><strong style="line-height: 22px; "><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (dataleft &gt; 0)</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //接收消息&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; recv = s.Receive(msg, offset, dataleft, 0);&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (recv == 0)</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset += recv;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dataleft -= recv;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return msg;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">以上这种做法比较适合于消息长度不是很长的情况。</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">2、消息长度与消息一同发送</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">我们可以这样做：通过使用消息的整形数值来表示消息的实际大小，所以要把整形数转换为字节类型。下面是发送变长消息的SendMessage方法。具体代码如下：</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp; private static int SendMessage(Socket s, byte[] msg)&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int offset = 0;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sent;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size = msg.Length;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int dataleft = size;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] msgsize = new byte[2];</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //将消息尺寸从整形转换成可以发送的字节型&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msgsize = BitConverter.GetBytes(size);</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //发送消息的长度信息&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sent = s.Send(size);</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (dataleft &gt; 0)</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sent = s.Send(msg, offset, dataleft, SocketFlags.None);</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置偏移量</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset += sent;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dataleft -= sent;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return offset;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br style="line-height: 22px; " />下面是接收变长消息的ReciveVarMessage方法。代码如下：</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">private byte[] ReciveVarMessage(Socket s)&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int offset = 0;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int recv;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] msgsize = new byte[2];</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //将字节数组的消息长度信息转换为整形&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size = BitConverter.ToInt16(msgsize);&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int dataleft = size;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] msg = new byte[size];</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //接收2个字节大小的长度信息&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; recv = s.Receive(msgsize, 0, 2, 0);&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (dataleft &gt; 0)&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //接收数据&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; recv = s.Receive(msg, offset, dataleft, 0);&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (recv == 0)&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset += recv;&nbsp;<br style="line-height: 22px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dataleft -= recv;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return msg;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p></strong></span><img src ="http://www.cppblog.com/Joe/aggbug/154897.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-09-01 18:36 <a href="http://www.cppblog.com/Joe/archive/2011/09/01/154897.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011字符串-最长重复子串，后缀数组</title><link>http://www.cppblog.com/Joe/archive/2011/08/19/153851.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Fri, 19 Aug 2011 07:11:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/08/19/153851.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/153851.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/08/19/153851.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/153851.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/153851.html</trackback:ping><description><![CDATA[from: Programming Pearl<br /><br /><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: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Copyright&nbsp;(C)&nbsp;1999&nbsp;Lucent&nbsp;Technologies&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;From&nbsp;'Programming&nbsp;Pearls'&nbsp;by&nbsp;Jon&nbsp;Bentley&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;longdup.c&nbsp;--&nbsp;Print&nbsp;longest&nbsp;string&nbsp;duplicated&nbsp;M&nbsp;times&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /><br />#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</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; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;pstrcmp(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">p,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">q)<br />{&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;strcmp(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p,&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">q);&nbsp;}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;comlen(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">q)<br />{&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p</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; ">*</span><span style="color: #000000; ">q</span><span style="color: #000000; ">++</span><span style="color: #000000; ">))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</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; ">&nbsp;i;<br />}<br /><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;M&nbsp;1</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MAXN&nbsp;5000000</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;c[MAXN],&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">a[MAXN];<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br />{&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i,&nbsp;ch,&nbsp;n&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;maxi,&nbsp;maxlen&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</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;((ch&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;getchar())&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;EOF)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[n]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">c[n];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c[n</span><span style="color: #000000; ">++</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;ch;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;c[n]&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;&nbsp;&nbsp;qsort(a,&nbsp;n,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">),&nbsp;pstrcmp);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;n</span><span style="color: #000000; ">-</span><span style="color: #000000; ">M;&nbsp;i</span><span style="color: #000000; ">++</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(comlen(a[i],&nbsp;a[i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">M])&nbsp;</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;maxlen)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxlen&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;comlen(a[i],&nbsp;a[i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">M]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxi&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%.*s\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;maxlen,&nbsp;a[maxi]);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}</span></div><img src ="http://www.cppblog.com/Joe/aggbug/153851.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-08-19 15:11 <a href="http://www.cppblog.com/Joe/archive/2011/08/19/153851.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011字符串哈希， 统计词频（from 编程珠玑）</title><link>http://www.cppblog.com/Joe/archive/2011/08/19/153848.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Fri, 19 Aug 2011 06:37:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/08/19/153848.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/153848.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/08/19/153848.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/153848.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/153848.html</trackback:ping><description><![CDATA[代码1（STL的map版本）<br /><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; ">#include</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</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">map</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">using</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; ">&nbsp;std;<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">argv)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;map</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;M;<br />&nbsp;&nbsp;&nbsp;&nbsp;map</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::iterator&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">&nbsp;t;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(cin</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">t)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;M[t]</span><span style="color: #000000; ">++</span><span style="color: #000000; ">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(j</span><span style="color: #000000; ">=</span><span style="color: #000000; ">M.begin();&nbsp;j</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">M.end();&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">j)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">j</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">first</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">\t</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">j</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">second</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}<br /></span></div><br /><br />代码2（自己的Hash）<br /><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; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;WORD_BUF&nbsp;128</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;NHASH&nbsp;29989&nbsp;/*&nbsp;prime&nbsp;number&nbsp;just&nbsp;bigger&nbsp;than&nbsp;needed&nbsp;*/</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MULT&nbsp;31</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">word;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;count;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">next;<br />};<br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">Hash[NHASH]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{NULL};&nbsp;<br /><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;NODEGROUP&nbsp;1000</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">nodebuf;<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;nodeleft&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; "><br />node_alloc()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(nodeleft&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nodebuf&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)malloc(NODEGROUP&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nodeleft&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;NODEGROUP;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">--</span><span style="color: #000000; ">nodeleft;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(nodebuf</span><span style="color: #000000; ">++</span><span style="color: #000000; ">);<br />}<br /><br />unsigned&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />hash(</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: #008000; ">/*</span><span style="color: #008000; ">&nbsp;a&nbsp;simple&nbsp;implementation&nbsp;of&nbsp;string-hash,&nbsp;others&nbsp;like&nbsp;ELFHash<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;ret&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;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">ptr;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(ptr</span><span style="color: #000000; ">=</span><span style="color: #000000; ">str;&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">ptr;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">ptr)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;ret&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;MULT&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">ptr);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(ret&nbsp;</span><span style="color: #000000; ">%</span><span style="color: #000000; ">&nbsp;NHASH);<br />}<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "><br />insert_hash(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">word)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">node;<br />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;h&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;hash(word);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(node</span><span style="color: #000000; ">=</span><span style="color: #000000; ">Hash[h];&nbsp;node</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">NULL;&nbsp;node</span><span style="color: #000000; ">=</span><span style="color: #000000; ">node</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">next)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(strcmp(node</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">word,&nbsp;word)&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">(node</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">count);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">pend&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;node_alloc();<br />&nbsp;&nbsp;&nbsp;&nbsp;pend</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">word&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;strdup(word);<br />&nbsp;&nbsp;&nbsp;&nbsp;pend</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">count&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;pend</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">next&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;Hash[h];<br />&nbsp;&nbsp;&nbsp;&nbsp;Hash[h]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;pend;<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">argv)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;buf[WORD_BUF];<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;buf)&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;EOF)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert_hash(buf);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;HNode&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">node;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">NHASH;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(node</span><span style="color: #000000; ">=</span><span style="color: #000000; ">Hash[i];&nbsp;node</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">NULL;&nbsp;node</span><span style="color: #000000; ">=</span><span style="color: #000000; ">node</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">next)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s\t%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;node</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">word,&nbsp;node</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">count);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}</span></div><br /><img src ="http://www.cppblog.com/Joe/aggbug/153848.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-08-19 14:37 <a href="http://www.cppblog.com/Joe/archive/2011/08/19/153848.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011趣题-寻找除法的循环节</title><link>http://www.cppblog.com/Joe/archive/2011/08/17/153675.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Wed, 17 Aug 2011 08:24:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/08/17/153675.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/153675.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/08/17/153675.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/153675.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/153675.html</trackback:ping><description><![CDATA[代码:<br /><br /><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: #008000; ">/*</span><span style="color: #008000; ">&nbsp;问题:&nbsp;两整数相除，求循环节&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;分析:<br />&nbsp;*&nbsp;模拟整数相除的步骤，记录每次的商、余，当余重复时即发现循环节&nbsp;<br />&nbsp;*&nbsp;余的范围为[0,&nbsp;被除数)，因此记录数组的大小可根据被除数确定<br />&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "><br />get_circle_digits(unsigned&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a,&nbsp;unsigned&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;b)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i,&nbsp;mod,&nbsp;tmp,&nbsp;index&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;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">div&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)malloc(</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;b);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">mod_pos&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)malloc(</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;b);<br />&nbsp;&nbsp;&nbsp;&nbsp;memset(mod_pos,&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">)</span><span style="color: #000000; ">*</span><span style="color: #000000; ">b);<br />&nbsp;&nbsp;&nbsp;&nbsp;mod&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;a&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;a</span><span style="color: #000000; ">%</span><span style="color: #000000; ">b;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(mod</span><span style="color: #000000; ">==</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">||</span><span style="color: #000000; ">&nbsp;mod_pos[mod]</span><span style="color: #000000; ">!=-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">break</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mod_pos[mod]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;index;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mod</span><span style="color: #000000; ">*</span><span style="color: #000000; ">10</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;div[index]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;tmp&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&nbsp;b;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mod&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;tmp&nbsp;</span><span style="color: #000000; ">%</span><span style="color: #000000; ">&nbsp;b;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">index;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(mod&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">No&nbsp;Circle\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">0.</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">mod_pos[mod];&nbsp;i</span><span style="color: #000000; ">++</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;div[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">mod_pos[mod];&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">index;&nbsp;i</span><span style="color: #000000; ">++</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;div[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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 />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">argv)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a,&nbsp;b;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%u&nbsp;%u</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">a,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">b)&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;EOF)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get_circle_digits(a,&nbsp;b);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}<br /></span></div><img src ="http://www.cppblog.com/Joe/aggbug/153675.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-08-17 16:24 <a href="http://www.cppblog.com/Joe/archive/2011/08/17/153675.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011搜索-题，DFS，沿路径搜索</title><link>http://www.cppblog.com/Joe/archive/2011/08/15/153448.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Mon, 15 Aug 2011 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/08/15/153448.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/153448.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/08/15/153448.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/153448.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/153448.html</trackback:ping><description><![CDATA[代码:<br /><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; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MAX_K&nbsp;101</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MAX_N&nbsp;1001</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;matrix[MAX_N][MAX_N];<br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;visited[MAX_N];<br /></span><span style="color: #0000FF; ">short</span><span style="color: #000000; ">&nbsp;count[MAX_N];<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;pastures[MAX_K];<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;K,&nbsp;N,&nbsp;M;<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "><br />dfs(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;pasture)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">count[pasture];<br />&nbsp;&nbsp;&nbsp;&nbsp;visited[pasture]&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; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">N;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(matrix[pasture][i]&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">visited[i])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfs(i);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">argv)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i,&nbsp;x,&nbsp;y,&nbsp;ret&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;&nbsp;&nbsp;scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;%d&nbsp;%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">K,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">N,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">M);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">K;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;pastures</span><span style="color: #000000; ">+</span><span style="color: #000000; ">i);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">M;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">x,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">y);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matrix[x][y]&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;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">K;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(visited,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(visited));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfs(pastures[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">N;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(count[i]&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;K)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">ret;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;ret);<br />}</span></div><br /><br /><span class="Apple-style-span" style="font-family: 'Times New Roman'; line-height: normal; font-size: medium; "><div class="ptt" lang="en-US" style="text-align: center; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Cow Picnic</div><div class="plm" style="text-align: center; font-family: Arial, Helvetica, sans-serif; font-size: 12pt; "><table align="center"><tbody><tr><td><strong>Time Limit:</strong>&nbsp;2000MS</td><td width="10px"></td><td><strong>Memory Limit:</strong>&nbsp;65536K</td></tr><tr><td><strong>Total Submissions:</strong>&nbsp;3878</td><td width="10px"></td><td><strong>Accepted:</strong>&nbsp;1576</td></tr></tbody></table></div><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Description</p><div class="ptx" lang="en-US" style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; "><p>The cows are having a picnic! Each of Farmer John's&nbsp;<em>K</em>&nbsp;(1 &#8804;&nbsp;<em>K</em>&nbsp;&#8804; 100) cows is grazing in one of&nbsp;<em>N</em>&nbsp;(1 &#8804;&nbsp;<em>N</em>&nbsp;&#8804; 1,000) pastures, conveniently numbered 1...<em>N</em>. The pastures are connected by&nbsp;<em>M</em>&nbsp;(1 &#8804;&nbsp;<em>M</em>&nbsp;&#8804; 10,000) one-way paths (no path connects a pasture to itself).</p><p>The cows want to gather in the same pasture for their picnic, but (because of the one-way paths) some cows may only be able to get to some pastures. Help the cows out by figuring out how many pastures are reachable by all cows, and hence are possible picnic locations.</p></div><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Input</p><div class="ptx" lang="en-US" style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; ">Line 1: Three space-separated integers, respectively:&nbsp;<em>K</em>,&nbsp;<em>N</em>, and&nbsp;<em>M</em>&nbsp;<br />Lines 2..<em>K</em>+1: Line&nbsp;<em>i</em>+1 contains a single integer (1..<em>N</em>) which is the number of the pasture in which cow&nbsp;<em>i</em>&nbsp;is grazing.&nbsp;<br />Lines&nbsp;<em>K</em>+2..<em>M</em>+<em>K</em>+1: Each line contains two space-separated integers, respectively&nbsp;<em>A</em>&nbsp;and&nbsp;<em>B</em>&nbsp;(both 1..<em>N</em>&nbsp;and&nbsp;<em>A</em>&nbsp;!=&nbsp;<em>B</em>), representing a one-way path from pasture&nbsp;<em>A</em>&nbsp;to pasture&nbsp;<em>B</em>.</div><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Output</p><div class="ptx" lang="en-US" style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; ">Line 1: The single integer that is the number of pastures that are reachable by all cows via the one-way paths.</div><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Sample Input</p><pre class="sio" style="font-family: 'Courier New', Courier, monospace; font-size: 12pt; ">2 4 4
2
3
1 2
1 4
2 3
3 4</pre><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Sample Output</p><pre class="sio" style="font-family: 'Courier New', Courier, monospace; font-size: 12pt; ">2</pre><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Hint</p><div class="ptx" lang="en-US" style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; ">The cows can meet in pastures 3 or 4.</div><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Source</p><div class="ptx" lang="en-US" style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; "><a href="http://poj.org/searchproblem?field=source&amp;key=USACO+2006+December+Silver" style="text-transform: none; text-decoration: none; ">USACO 2006 December Silver</a></div></span><br /><br /><br /><br /><br /><img src ="http://www.cppblog.com/Joe/aggbug/153448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-08-15 16:13 <a href="http://www.cppblog.com/Joe/archive/2011/08/15/153448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011搜索-题，DFS，图着色</title><link>http://www.cppblog.com/Joe/archive/2011/08/14/153333.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sun, 14 Aug 2011 02:32:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/08/14/153333.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/153333.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/08/14/153333.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/153333.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/153333.html</trackback:ping><description><![CDATA[代码:<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; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">limits.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MAX_NUM&nbsp;26</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;adj[MAX_NUM][MAX_NUM];<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;num,&nbsp;ret,&nbsp;colors[MAX_NUM];<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />is_valid(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;depth,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;color)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">depth;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(adj[i][depth]&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;colors[i]</span><span style="color: #000000; ">==</span><span style="color: #000000; ">color)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&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 />}<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "><br />dfs(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;depth,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;color_used)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(color_used&nbsp;</span><span style="color: #000000; ">&gt;=</span><span style="color: #000000; ">&nbsp;ret)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(depth&nbsp;</span><span style="color: #000000; ">&gt;=</span><span style="color: #000000; ">&nbsp;num)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;color_used;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">color_used;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(is_valid(depth,&nbsp;i))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;colors[depth]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfs(depth</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;color_used);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;colors[depth]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;colors[depth]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;color_used;<br />&nbsp;&nbsp;&nbsp;&nbsp;dfs(depth</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;color_used</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;colors[depth]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">argv)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;info[MAX_NUM</span><span style="color: #000000; ">+</span><span style="color: #000000; ">2</span><span style="color: #000000; ">],&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">ptr;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">num)</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">EOF&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;num)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;INT_MAX;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(colors,&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(colors));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(adj,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(adj));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">num;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;info);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptr&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;info</span><span style="color: #000000; ">+</span><span style="color: #000000; ">2</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">ptr&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">\0</span><span style="color: #000000; ">'</span><span style="color: #000000; ">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;adj[i][(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">ptr)</span><span style="color: #000000; ">-</span><span style="color: #000000; ">'</span><span style="color: #000000; ">A</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; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">ptr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfs(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;%s&nbsp;needed.\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;ret,&nbsp;ret</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">?</span><span style="color: #000000; ">"</span><span style="color: #000000; ">channel</span><span style="color: #000000; ">"</span><span style="color: #000000; ">:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">channels</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /></span></div><br /><span class="Apple-style-span" style="font-family: 'Times New Roman'; line-height: normal; font-size: medium; "><div class="ptt" lang="en-US" style="text-align: center; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Channel Allocation</div><div class="plm" style="text-align: center; font-family: Arial, Helvetica, sans-serif; font-size: 12pt; "><table align="center"><tbody><tr><td><strong>Time Limit:</strong>&nbsp;1000MS</td><td width="10px"></td><td><strong>Memory Limit:</strong>&nbsp;10000K</td></tr><tr><td><strong>Total Submissions:</strong>&nbsp;8353</td><td width="10px"></td><td><strong>Accepted:</strong>&nbsp;4248</td></tr></tbody></table></div><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Description</p><div class="ptx" lang="en-US" style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; ">When a radio station is broadcasting over a very large area, repeaters are used to retransmit the signal so that every receiver has a strong signal. However, the channels used by each repeater must be carefully chosen so that nearby repeaters do not interfere with one another. This condition is satisfied if adjacent repeaters use different channels.&nbsp;<br /><br />Since the radio frequency spectrum is a precious resource, the number of channels required by a given network of repeaters should be minimised. You have to write a program that reads in a description of a repeater network and determines the minimum number of channels required.</div><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Input</p><div class="ptx" lang="en-US" style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; ">The input consists of a number of maps of repeater networks. Each map begins with a line containing the number of repeaters. This is between 1 and 26, and the repeaters are referred to by consecutive upper-case letters of the alphabet starting with A. For example, ten repeaters would have the names A,B,C,...,I and J. A network with zero repeaters indicates the end of input.&nbsp;<br /><br />Following the number of repeaters is a list of adjacency relationships. Each line has the form:&nbsp;<br /><br />A:BCDH&nbsp;<br /><br />which indicates that the repeaters B, C, D and H are adjacent to the repeater A. The first line describes those adjacent to repeater A, the second those adjacent to B, and so on for all of the repeaters. If a repeater is not adjacent to any other, its line has the form&nbsp;<br /><br />A:&nbsp;<br /><br />The repeaters are listed in alphabetical order.&nbsp;<br /><br />Note that the adjacency is a symmetric relationship; if A is adjacent to B, then B is necessarily adjacent to A. Also, since the repeaters lie in a plane, the graph formed by connecting adjacent repeaters does not have any line segments that cross.&nbsp;</div><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Output</p><div class="ptx" lang="en-US" style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; ">For each map (except the final one with no repeaters), print a line containing the minumum number of channels needed so that no adjacent channels interfere. The sample output shows the format of this line. Take care that channels is in the singular form when only one channel is required.</div><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Sample Input</p><pre class="sio" style="font-family: 'Courier New', Courier, monospace; font-size: 12pt; ">2
A:
B:
4
A:BC
B:ACD
C:ABD
D:BC
4
A:BCD
B:ACD
C:ABD
D:ABC
0</pre><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Sample Output</p><pre class="sio" style="font-family: 'Courier New', Courier, monospace; font-size: 12pt; ">1 channel needed.
3 channels needed.
4 channels needed. </pre><p class="pst" style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Source</p><div class="ptx" lang="en-US" style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; "><a href="http://poj.org/searchproblem?field=source&amp;key=Southern+African+2001" style="text-transform: none; text-decoration: none; ">Southern African 2001</a></div></span><br /><br /><img src ="http://www.cppblog.com/Joe/aggbug/153333.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-08-14 10:32 <a href="http://www.cppblog.com/Joe/archive/2011/08/14/153333.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011搜索-题，DFS，类似计算连通区域的个数</title><link>http://www.cppblog.com/Joe/archive/2011/08/14/153332.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Sun, 14 Aug 2011 02:29:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/08/14/153332.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/153332.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/08/14/153332.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/153332.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/153332.html</trackback:ping><description><![CDATA[代码:<br /><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; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MAX_NUM&nbsp;100</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;VALID(x,&nbsp;y)&nbsp;((x)&gt;=0&nbsp;&amp;&amp;&nbsp;(x)&lt;m&nbsp;&amp;&amp;&nbsp;(y)&gt;=0&nbsp;&amp;&amp;&nbsp;(y)&lt;n)</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;m,&nbsp;n,&nbsp;count;<br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;grid[MAX_NUM][MAX_NUM</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">];<br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;visited[MAX_NUM][MAX_NUM</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">];<br /><br /></span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;dx[]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">};<br /></span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;dy[]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">0</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; ">1</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; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">};<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "><br />dfs_inner(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;x,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;y)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i,&nbsp;next_x,&nbsp;next_y;<br />&nbsp;&nbsp;&nbsp;&nbsp;visited[x][y]&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; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">8</span><span style="color: #000000; ">;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_x&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;x&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;dx[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_y&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;y&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;dy[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(VALID(next_x,&nbsp;next_y)&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">visited[next_x][next_y]&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;grid[next_x][next_y]</span><span style="color: #000000; ">==</span><span style="color: #000000; ">'</span><span style="color: #000000; ">@</span><span style="color: #000000; ">'</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfs_inner(next_x,&nbsp;next_y);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "><br />dfs()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i,&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">m;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(j</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;j</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">n;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">j)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(</span><span style="color: #000000; ">!</span><span style="color: #000000; ">visited[i][j]&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;grid[i][j]</span><span style="color: #000000; ">==</span><span style="color: #000000; ">'</span><span style="color: #000000; ">@</span><span style="color: #000000; ">'</span><span style="color: #000000; ">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">count;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfs_inner(i,&nbsp;j);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">argv)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d&nbsp;%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">m,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">n)</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;EOF&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;m)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(visited,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(visited));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">m;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;grid[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfs();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;count);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div><br /><span style="font-family: 'Times New Roman'; font-size: medium; "><div style="text-align: center; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Oil Deposits</div><div style="text-align: center; font-family: Arial, Helvetica, sans-serif; font-size: 12pt; "><table align="center"><tbody><tr><td><strong>Time Limit:</strong>&nbsp;1000MS</td><td width="10px"></td><td><strong>Memory Limit:</strong>&nbsp;10000K</td></tr><tr><td><strong>Total Submissions:</strong>&nbsp;7595</td><td width="10px"></td><td><strong>Accepted:</strong>&nbsp;4267</td></tr></tbody></table></div><p style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Description</p><div style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; ">The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.</div><p style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Input</p><div style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; ">The input contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 &lt;= m &lt;= 100 and 1 &lt;= n &lt;= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.&nbsp;<br /></div><p style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Output</p><div style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; ">are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.</div><p style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Sample Input</p><pre style="font-family: 'Courier New', Courier, monospace; font-size: 12pt; ">1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5  ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0</pre><p style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Sample Output</p><pre style="font-family: 'Courier New', Courier, monospace; font-size: 12pt; ">0 1 2 2 </pre><p style="text-align: left; font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; color: blue; ">Source</p><div style="font-family: 'Times New Roman', Times, serif; font-size: 12pt; "><a href="http://poj.org/searchproblem?field=source&amp;key=Mid-Central+USA+1997" style="text-transform: none; text-decoration: none; ">Mid-Central USA 1997</a></div></span><br /><img src ="http://www.cppblog.com/Joe/aggbug/153332.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-08-14 10:29 <a href="http://www.cppblog.com/Joe/archive/2011/08/14/153332.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011搜索-二分搜索</title><link>http://www.cppblog.com/Joe/archive/2011/08/12/153213.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Fri, 12 Aug 2011 09:19:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/08/12/153213.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/153213.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/08/12/153213.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/153213.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/153213.html</trackback:ping><description><![CDATA[前提: 已排序<br />时间复杂度: O(logN)<br />例如: 找出某个target出现的位置（随机），某个target第一次出现的位置，某个target最后一次出现的位置<br /><br />问题: 如果在未排序的数组中使用二分搜索，结果会怎么样？<br /><br />答: 如果二分搜索声称找到了target，那么该target就一定存在于数组中，<br />&nbsp; &nbsp; &nbsp;但是，在应用于未排序数组时，算法有时会在target实际存在的情况下报告说该target不存在<br /><br />代码:<br /><br /><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: #0000FF; ">int</span><span style="color: #000000; "><br />vector_bsearch(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vector&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">vector,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">target,&nbsp;compare_func&nbsp;compare)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;lo,&nbsp;hi,&nbsp;mid,&nbsp;tmp;<br />&nbsp;&nbsp;&nbsp;&nbsp;lo&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;&nbsp;&nbsp;hi&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(vector</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">count)&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; ">(lo&nbsp;</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">&nbsp;hi)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mid&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;lo&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;((hi&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;lo)&nbsp;</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;compare(vector</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">array[mid],&nbsp;target);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(tmp&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;mid;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(tmp&nbsp;</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hi&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mid&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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lo&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mid&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;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />vector_lower(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vector&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">vector,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">target,&nbsp;compare_func&nbsp;compare)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;lo,&nbsp;hi,&nbsp;mid;<br />&nbsp;&nbsp;&nbsp;&nbsp;lo&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;hi&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;vector</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">count;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;distance&nbsp;between&nbsp;lo&nbsp;and&nbsp;hi&nbsp;at&nbsp;least&nbsp;larger&nbsp;than&nbsp;1,&nbsp;which&nbsp;ensure&nbsp;mid&nbsp;won't&nbsp;equals&nbsp;to&nbsp;either&nbsp;lo&nbsp;or&nbsp;hi&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(lo</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;hi)&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;loop&nbsp;invariant:&nbsp;vector[lo]&lt;target&nbsp;&amp;&amp;&nbsp;vector[hi]&gt;=target&nbsp;&amp;&amp;&nbsp;lo&lt;hi&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mid&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;lo&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;((hi&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;lo)&nbsp;</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(compare(vector</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">array[mid],&nbsp;target)&nbsp;</span><span style="color: #000000; ">&gt;=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hi&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mid;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lo&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mid;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(hi</span><span style="color: #000000; ">&gt;=</span><span style="color: #000000; ">(vector</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">count)&nbsp;</span><span style="color: #000000; ">||</span><span style="color: #000000; ">&nbsp;compare(vector</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">array[hi],&nbsp;target)</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;hi;<br />}<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "><br />vector_upper(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Vector&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">vector,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">target,&nbsp;compare_func&nbsp;compare)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;lo,&nbsp;hi,&nbsp;mid;<br />&nbsp;&nbsp;&nbsp;&nbsp;lo&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;hi&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;vector</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">count;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;distance&nbsp;between&nbsp;lo&nbsp;and&nbsp;hi&nbsp;at&nbsp;least&nbsp;larger&nbsp;than&nbsp;1,&nbsp;which&nbsp;ensure&nbsp;mid&nbsp;won't&nbsp;equals&nbsp;to&nbsp;either&nbsp;lo&nbsp;or&nbsp;hi&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(lo</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;hi)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;loop&nbsp;invariant:&nbsp;vector[lo]&lt;=target&nbsp;&amp;&amp;&nbsp;vector[hi]&gt;target&nbsp;&amp;&amp;&nbsp;lo&lt;hi&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mid&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;lo&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;((hi&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;lo)&nbsp;</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(compare(vector</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">array[mid],&nbsp;target)&nbsp;</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lo&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mid;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hi&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mid;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(lo</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">||</span><span style="color: #000000; ">&nbsp;compare(vector</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">array[lo],&nbsp;target)</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;lo;<br />}<br /></span></div><br /><br /><br /><br /><br /><br /><br /><br /><br /><img src ="http://www.cppblog.com/Joe/aggbug/153213.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-08-12 17:19 <a href="http://www.cppblog.com/Joe/archive/2011/08/12/153213.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011工具-gprof，性能分析</title><link>http://www.cppblog.com/Joe/archive/2011/08/12/153130.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Fri, 12 Aug 2011 02:33:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/08/12/153130.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/153130.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/08/12/153130.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/153130.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/153130.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 程序分析是以某种语言书写的程序为对象，对其内部的运作流程进行分析。程序分析的目的主要有三点：一是通过程序内部各个模块之间的调用关系，整体上把握程序的运行流程，从而更好地理解程序，从中汲取有价值的内容。二是以系统优化为目的，通过对程序中关键函数的跟踪或者运行时信息的统计，找到系统性能的瓶颈，从而采取进一步行动对程序进行优化。最后一点，程序分析也有可能用于系统测试和程序调试中。当系统跟踪起来比较复杂，...&nbsp;&nbsp;<a href='http://www.cppblog.com/Joe/archive/2011/08/12/153130.html'>阅读全文</a><img src ="http://www.cppblog.com/Joe/aggbug/153130.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-08-12 10:33 <a href="http://www.cppblog.com/Joe/archive/2011/08/12/153130.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2011工具-Valgrind，内存管理检验</title><link>http://www.cppblog.com/Joe/archive/2011/08/11/153072.html</link><dc:creator>simplyzhao</dc:creator><author>simplyzhao</author><pubDate>Thu, 11 Aug 2011 09:22:00 GMT</pubDate><guid>http://www.cppblog.com/Joe/archive/2011/08/11/153072.html</guid><wfw:comment>http://www.cppblog.com/Joe/comments/153072.html</wfw:comment><comments>http://www.cppblog.com/Joe/archive/2011/08/11/153072.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Joe/comments/commentRss/153072.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Joe/services/trackbacks/153072.html</trackback:ping><description><![CDATA[转载:&nbsp;<a href="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/">http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/</a><a href="http://valgrind.org/"><br /><br /></a><span class="Apple-style-span" style="font-family: 'Times New Roman'; line-height: normal; background-color: #ffffff; font-size: medium; "><h1 style="font-family: arial, nsimsun, sans-serif; font-size: 1.7em; height: 33px; list-style-type: none; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">应用 Valgrind 发现 Linux 程序的内存问题</h1></span><br /><span style="font-family: 'Times New Roman'; font-size: medium; "><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="2.Valgrind 概述|outline"><span style="font-size: 1.5em; font-weight: bold; ">Valgrind 概述</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N1007C"><span style="font-size: 1.2em; font-weight: bold; ">体系结构</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">Valgrind是一套Linux下，开放源代码（GPL V2）的仿真调试工具的集合。Valgrind由内核（core）以及基于内核的其他调试工具组成。内核类似于一个框架（framework），它模拟了一个CPU环境，并提供服务给其他工具；而其他工具则类似于插件 (plug-in)，利用内核提供的服务完成各种特定的内存调试任务。Valgrind的体系结构如下图所示：</p><br /><a name="N10086"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">图 1 Valgrind 体系结构</strong></a><br /><img alt="Valgrind 体系结构" height="292" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image001.jpg" width="550" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">Valgrind包括如下一些工具：</p><ol type="1" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; "><strong>Memcheck。</strong>这是valgrind应用最广泛的工具，一个重量级的内存检查器，能够发现开发中绝大多数内存错误使用情况，比如：使用未初始化的内存，使用已经释放了的内存，内存访问越界等。这也是本文将重点介绍的部分。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; "><strong>Callgrind</strong>。它主要用来检查程序中函数调用过程中出现的问题。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; "><strong>Cachegrind</strong>。它主要用来检查程序中缓存使用出现的问题。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; "><strong>Helgrind</strong>。它主要用来检查多线程程序中出现的竞争问题。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; "><strong>Massif</strong>。它主要用来检查程序中堆栈使用中出现的问题。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; "><strong>Extension。</strong>可以利用core提供的功能，自己编写特定的内存调试工具。</li></ol><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N100BD"><span style="font-size: 1.2em; font-weight: bold; ">Linux 程序内存空间布局</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">要发现Linux下的内存问题，首先一定要知道在Linux下，内存是如何被分配的？下图展示了一个典型的Linux C程序内存空间布局：</p><br /><a name="N100C7"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">图 2： 典型内存空间布局</strong></a><br /><img alt="典型内存空间布局" height="262" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image002.jpg" width="476" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">一个典型的Linux C程序内存空间由如下几部分组成：</p><ul style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><strong>代码段（.text）。</strong>这里存放的是CPU要执行的指令。代码段是可共享的，相同的代码在内存中只会有一个拷贝，同时这个段是只读的，防止程序由于错误而修改自身的指令。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><strong>初始化数据段（.data）。</strong>这里存放的是程序中需要明确赋初始值的变量，例如位于所有函数之外的全局变量：int val=100。需要强调的是，以上两段都是位于程序的可执行文件中，内核在调用exec函数启动该程序时从源程序文件中读入。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><strong>未初始化数据段（.bss）</strong>。位于这一段中的数据，内核在执行该程序前，将其初始化为0或者null。例如出现在任何函数之外的全局变量：int sum;</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><strong>堆（Heap）。</strong>这个段用于在程序中进行动态内存申请，例如经常用到的malloc，new系列函数就是从这个段中申请内存。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><strong>栈（Stack）。</strong>函数中的局部变量以及在函数调用过程中产生的临时变量都保存在此段中。</li></ul><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N100F7"><span style="font-size: 1.2em; font-weight: bold; ">内存检查原理</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>Memcheck</strong>检测内存问题的原理如下图所示：</p><br /><a name="N10103"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">图 3 内存检查原理</strong></a><br /><img alt="内存检查原理" height="273" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image003.jpg" width="484" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">Memcheck 能够检测出内存问题，关键在于其建立了两个全局表。</p><ol type="1" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; "><strong>Valid-Value&nbsp;</strong><strong>表：</strong></li></ol><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">对于进程的整个地址空间中的每一个字节(byte)，都有与之对应的 8 个 bits；对于 CPU 的每个寄存器，也有一个与之对应的 bit 向量。这些 bits 负责记录该字节或者寄存器值是否具有有效的、已初始化的值。</p><ol type="1" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; "><strong>Valid-Address&nbsp;</strong><strong>表</strong></li></ol><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">对于进程整个地址空间中的每一个字节(byte)，还有与之对应的 1 个 bit，负责记录该地址是否能够被读写。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>检测原理：</strong></p><ul style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">当要读写内存中某个字节时，首先检查这个字节对应的 A bit。如果该A bit显示该位置是无效位置，memcheck 则报告读写错误。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">内核（core）类似于一个虚拟的 CPU 环境，这样当内存中的某个字节被加载到真实的 CPU 中时，该字节对应的 V bit 也被加载到虚拟的 CPU 环境中。一旦寄存器中的值，被用来产生内存地址，或者该值能够影响程序输出，则 memcheck 会检查对应的V bits，如果该值尚未初始化，则会报告使用未初始化内存错误。</li></ul><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; height: 1px; background-position: initial initial; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 15px; "><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/#ibm-pcon" style="color: #4c6e94; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页首</a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="3.Valgrind 使用|outline"><span style="font-size: 1.5em; font-weight: bold; ">Valgrind 使用</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>第一步：准备好程序</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">为了使valgrind发现的错误更精确，如能够定位到源代码行，建议在编译时加上-g参数，编译优化选项请选择O0，虽然这会降低程序的执行效率。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">这里用到的示例程序文件名为：sample.c（如下所示）,选用的编译器为gcc。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">生成可执行程序&nbsp;<strong>gcc &#8211;g &#8211;O0 sample.c &#8211;o sample</strong></p><br /><a name="N10151"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 1</strong></a><br /><img alt="清单 1" height="208" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image004.jpg" width="393" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>第二步：在valgrind下，运行可执行程序。</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">利用valgrind调试内存问题，不需要重新编译源程序，它的输入就是二进制的可执行程序。调用Valgrind的通用格式是：<strong>valgrind [valgrind-options] your-prog [your-prog-options]</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">Valgrind 的参数分为两类，一类是 core 的参数，它对所有的工具都适用；另外一类就是具体某个工具如 memcheck 的参数。Valgrind 默认的工具就是 memcheck，也可以通过&#8220;--tool=<em>tool name</em>&#8221;指定其他的工具。Valgrind 提供了大量的参数满足你特定的调试需求，具体可参考其用户手册。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">这个例子将使用 memcheck，于是可以输入命令入下：<strong>valgrind&nbsp;</strong><strong><em>&lt;Path&gt;/</em></strong><strong>sample.</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>第三步：分析 valgrind 的输出信息。</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">以下是运行上述命令后的输出。</p><br /><a name="N1017F"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 2</strong></a><br /><img alt="清单 2" height="389" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image005.jpg" width="532" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><ul style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">左边显示类似行号的数字（32372）表示的是 Process ID。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">最上面的红色方框表示的是 valgrind 的版本信息。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">中间的红色方框表示 valgrind 通过运行被测试程序，发现的内存问题。通过阅读这些信息，可以发现：<ol type="1" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 1em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; ">这是一个对内存的非法写操作，非法写操作的内存是4 bytes。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; ">发生错误时的函数堆栈，以及具体的源代码行号。</li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; ">非法写操作的具体地址空间。</li></ol></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">最下面的红色方框是对发现的内存问题和内存泄露问题的总结。内存泄露的大小（40 bytes）也能够被检测出来。</li></ul><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">示例程序显然有两个问题，一是fun函数中动态申请的堆内存没有释放；二是对堆内存的访问越界。这两个问题均被valgrind发现。</p><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; height: 1px; background-position: initial initial; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 15px; "><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/#ibm-pcon" style="color: #4c6e94; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页首</a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="4.利用Memcheck发现常见的内存问题|outline"><span style="font-size: 1.5em; font-weight: bold; ">利用Memcheck发现常见的内存问题</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">在Linux平台开发应用程序时，最常遇见的问题就是错误的使用内存，我们总结了常见了内存错误使用情况，并说明了如何用valgrind将其检测出来。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N101B2"><span style="font-size: 1.2em; font-weight: bold; ">使用未初始化的内存</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>问题分析：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">对于位于程序中不同段的变量，其初始值是不同的，全局变量和静态变量初始值为0，而局部变量和动态申请的变量，其初始值为随机值。如果程序使用了为随机值的变量，那么程序的行为就变得不可预期。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">下面的程序就是一种常见的，使用了未初始化的变量的情况。数组a是局部变量，其初始值为随机值，而在初始化时并没有给其所有数组成员初始化，如此在接下来使用这个数组时就潜在有内存问题。</p><br /><a name="N101C3"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 3</strong></a><br /><img alt="清单 3" height="222" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image006.jpg" width="352" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>结果分析：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">假设这个文件名为：<strong>badloop.c</strong>，生成的可执行程序为<strong>badloop</strong>。用memcheck对其进行测试，输出如下。</p><br /><a name="N101DE"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 4</strong></a><br /><img alt="清单 4" height="112" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image007.jpg" width="439" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">输出结果显示，在该程序第11行中，程序的跳转依赖于一个未初始化的变量。准确的发现了上述程序中存在的问题。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N101EE"><span style="font-size: 1.2em; font-weight: bold; ">内存读写越界</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>问题分析：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">这种情况是指：访问了你不应该/没有权限访问的内存地址空间，比如访问数组时越界；对动态内存访问时超出了申请的内存大小范围。下面的程序就是一个典型的数组越界问题。pt是一个局部数组变量，其大小为4，p初始指向pt数组的起始地址，但在对p循环叠加后，p超出了pt数组的范围，如果此时再对p进行写操作，那么后果将不可预期。</p><br /><a name="N101FC"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 5</strong></a><br /><img alt="清单 5" height="286" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image008.jpg" width="406" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>结果分析：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">假设这个文件名为badacc.cpp，生成的可执行程序为badacc，用memcheck对其进行测试，输出如下。</p><br /><a name="N10211"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 6</strong></a><br /><img alt="清单 6" height="235" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image009.jpg" width="511" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">输出结果显示，在该程序的第15行，进行了非法的写操作；在第16行，进行了非法读操作。准确地发现了上述问题。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N10221"><span style="font-size: 1.2em; font-weight: bold; ">内存覆盖</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>问题分析：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">C 语言的强大和可怕之处在于其可以直接操作内存，C 标准库中提供了大量这样的函数，比如 strcpy, strncpy, memcpy, strcat 等，这些函数有一个共同的特点就是需要设置源地址 (src)，和目标地址(dst)，src 和 dst 指向的地址不能发生重叠，否则结果将不可预期。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">下面就是一个 src 和 dst 发生重叠的例子。在 15 与 17 行中，src 和 dst 所指向的地址相差 20，但指定的拷贝长度却是 21，这样就会把之前的拷贝值覆盖。第 24 行程序类似，src(x+20) 与 dst(x) 所指向的地址相差 20，但 dst 的长度却为 21，这样也会发生内存覆盖。</p><br /><a name="N10232"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 7</strong></a><br /><img alt="清单 7" height="429" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image010.jpg" width="396" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>结果分析：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">假设这个文件名为 badlap.cpp，生成的可执行程序为 badlap，用 memcheck 对其进行测试，输出如下。</p><br /><a name="N10247"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 8</strong></a><br /><img alt="清单 8" height="143" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image011.jpg" width="553" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">输出结果显示上述程序中第15，17，24行，源地址和目标地址设置出现重叠。准确的发现了上述问题。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N10257"><span style="font-size: 1.2em; font-weight: bold; ">动态内存管理错误</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>问题分析：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">常见的内存分配方式分三种：静态存储，栈上分配，堆上分配。全局变量属于静态存储，它们是在编译时就被分配了存储空间，函数内的局部变量属于栈上分配，而最灵活的内存使用方式当属堆上分配，也叫做内存动态分配了。常用的内存动态分配函数包括：malloc, alloc, realloc, new等，动态释放函数包括free, delete。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">一旦成功申请了动态内存，我们就需要自己对其进行内存管理，而这又是最容易犯错误的。下面的一段程序，就包括了内存动态管理中常见的错误。</p><br /><a name="N10268"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 9</strong></a><br /><img alt="清单 9" height="303" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image012.jpg" width="313" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">常见的内存动态管理错误包括：</p><ol type="1" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; "><ul style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 1em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; ">申请和释放不一致</li></ul></ol><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">由于 C++ 兼容 C，而 C 与 C++ 的内存申请和释放函数是不同的，因此在 C++ 程序中，就有两套动态内存管理函数。一条不变的规则就是采用 C 方式申请的内存就用 C 方式释放；用 C++ 方式申请的内存，用 C++ 方式释放。也就是用 malloc/alloc/realloc 方式申请的内存，用 free 释放；用 new 方式申请的内存用 delete 释放。在上述程序中，用 malloc 方式申请了内存却用 delete 来释放，虽然这在很多情况下不会有问题，但这绝对是潜在的问题。</p><ol type="1" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; "><ul style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 1em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; ">申请和释放不匹配</li></ul></ol><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">申请了多少内存，在使用完成后就要释放多少。如果没有释放，或者少释放了就是内存泄露；多释放了也会产生问题。上述程序中，指针p和pt指向的是同一块内存，却被先后释放两次。</p><ol type="1" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; "><ul style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 1em; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 3px; ">释放后仍然读写</li></ul></ol><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">本质上说，系统会在堆上维护一个动态内存链表，如果被释放，就意味着该块内存可以继续被分配给其他部分，如果内存被释放后再访问，就可能覆盖其他部分的信息，这是一种严重的错误，上述程序第16行中就在释放后仍然写这块内存。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>结果分析：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">假设这个文件名为badmac.cpp，生成的可执行程序为badmac，用memcheck对其进行测试，输出如下。</p><br /><a name="N102A4"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 10</strong></a><br /><img alt="清单 10" height="254" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image013.jpg" width="462" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">输出结果显示，第14行分配和释放函数不一致；第16行发生非法写操作，也就是往释放后的内存地址写值；第17行释放内存函数无效。准确地发现了上述三个问题。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N102B4"><span style="font-size: 1.2em; font-weight: bold; ">内存泄露</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>问题描述：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">内存泄露（Memory leak）指的是，在程序中动态申请的内存，在使用完后既没有释放，又无法被程序的其他部分访问。内存泄露是在开发大型程序中最令人头疼的问题，以至于有人说，内存泄露是无法避免的。其实不然，防止内存泄露要从良好的编程习惯做起，另外重要的一点就是要加强单元测试（Unit Test），而memcheck就是这样一款优秀的工具。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">下面是一个比较典型的内存泄露案例。main函数调用了mk函数生成树结点，可是在调用完成之后，却没有相应的函数：nodefr释放内存，这样内存中的这个树结构就无法被其他部分访问，造成了内存泄露。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">在一个单独的函数中，每个人的内存泄露意识都是比较强的。但很多情况下，我们都会对malloc/free 或new/delete做一些包装，以符合我们特定的需要，无法做到在一个函数中既使用又释放。这个例子也说明了内存泄露最容易发生的地方：即两个部分的接口部分，一个函数申请内存，一个函数释放内存。并且这些函数由不同的人开发、使用，这样造成内存泄露的可能性就比较大了。这需要养成良好的单元测试习惯，将内存泄露消灭在初始阶段。</p><br /><a name="N102C8"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 11</strong></a><br /><img alt="清单 1" height="209" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image014.jpg" width="352" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><br /><a name="N102D6"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 11.2</strong></a><br /><img alt="清单 11.2" height="336" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image015.jpg" width="400" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><br /><a name="N102E4"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 11.3</strong></a><br /><img alt="清单 11.3" height="254" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image016.jpg" width="418" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>结果分析：</strong></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">假设上述文件名位tree.h, tree.cpp, badleak.cpp，生成的可执行程序为badleak，用memcheck对其进行测试，输出如下。</p><br /><a name="N102F9"><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 12</strong></a><br /><img alt="清单 12" height="139" src="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/images/image017.jpg" width="554" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " />&nbsp;<br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">该示例程序是生成一棵树的过程，每个树节点的大小为12（考虑内存对齐），共8个节点。从上述输出可以看出，所有的内存泄露都被发现。Memcheck将内存泄露分为两种，一种是可能的内存泄露（Possibly lost），另外一种是确定的内存泄露（Definitely lost）。Possibly lost 是指仍然存在某个指针能够访问某块内存，但该指针指向的已经不是该内存首地址。Definitely lost 是指已经不能够访问这块内存。而Definitely lost又分为两种：直接的（direct）和间接的（indirect）。直接和间接的区别就是，直接是没有任何指针指向该内存，间接是指指向该内存的指针都位于内存泄露处。在上述的例子中，根节点是directly lost，而其他节点是indirectly lost。</p><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; height: 1px; background-position: initial initial; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 15px; "><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/#ibm-pcon" style="color: #4c6e94; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页首</a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="5.总结|outline"><span style="font-size: 1.5em; font-weight: bold; ">总结</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">本文介绍了valgrind的体系结构，并重点介绍了其应用最广泛的工具：memcheck。阐述了memcheck发现内存问题的基本原理，基本使用方法，以及利用memcheck如何发现目前开发中最广泛的五大类内存问题。在项目中尽早的发现内存问题，能够极大地提高开发效率，valgrind就是能够帮助你实现这一目标的出色工具。</p></span><img src ="http://www.cppblog.com/Joe/aggbug/153072.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Joe/" target="_blank">simplyzhao</a> 2011-08-11 17:22 <a href="http://www.cppblog.com/Joe/archive/2011/08/11/153072.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>