﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-I smell magic in the air-随笔分类-C/C++</title><link>http://www.cppblog.com/izualzhy/category/15358.html</link><description>坚持 相信自己</description><language>zh-cn</language><lastBuildDate>Tue, 13 Aug 2013 17:44:15 GMT</lastBuildDate><pubDate>Tue, 13 Aug 2013 17:44:15 GMT</pubDate><ttl>60</ttl><item><title>c++实现Url格式解析</title><link>http://www.cppblog.com/izualzhy/archive/2013/08/13/202521.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Tue, 13 Aug 2013 06:15:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2013/08/13/202521.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/202521.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2013/08/13/202521.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/202521.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/202521.html</trackback:ping><description><![CDATA[主要是参考资料的内容<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#ifndef&nbsp;__URL_H__<br /><span style="color: #0000FF; ">#define</span>&nbsp;__URL_H__<br />#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>&gt;<br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><br /><span style="color: #0000FF; ">namespace</span>&nbsp;dk<br />{<br /><span style="color: #0000FF; ">namespace</span>&nbsp;common<br />{<br /><span style="color: #0000FF; ">class</span>&nbsp;Url<br />{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;Url(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;url);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;GetScheme()&nbsp;<span style="color: #0000FF; ">const</span><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_scheme;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;GetHost()&nbsp;<span style="color: #0000FF; ">const</span><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_host;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;GetPort()&nbsp;<span style="color: #0000FF; ">const</span><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_port;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;GetPath()&nbsp;<span style="color: #0000FF; ">const</span><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_path;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;GetQuery()&nbsp;<span style="color: #0000FF; ">const</span><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_query;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;GetFragment()&nbsp;<span style="color: #0000FF; ">const</span><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_fragment;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;GetUserName()&nbsp;<span style="color: #0000FF; ">const</span><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_username;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;GetPassword()&nbsp;<span style="color: #0000FF; ">const</span><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;m_password;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;Init(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;url);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;IsSchemeChar(<span style="color: #0000FF; ">int</span>&nbsp;c)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(!isalpha(c)&nbsp;&amp;&amp;&nbsp;'+'&nbsp;!=&nbsp;c&nbsp;&amp;&amp;&nbsp;'-'&nbsp;!=&nbsp;c&nbsp;&amp;&amp;&nbsp;'.'&nbsp;!=&nbsp;c)&nbsp;?&nbsp;0&nbsp;:&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;m_scheme;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;mandatory&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;m_host;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;mandatory&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;m_port;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;optional&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;m_path;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;optional&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;m_query;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;optional&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;m_fragment;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;optional&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;m_username;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;optional&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;m_password;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;optional&nbsp;</span><span style="color: #008000; ">*/</span><br />};<br />}<br />}<br /><span style="color: #0000FF; ">#endif</span><span style="color: #008000; ">//</span><span style="color: #008000; ">__URL_H__</span></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;"Common/Url.h"<br />#include&nbsp;&lt;ctype.h&gt;<br />#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>.h&gt;<br /><br /><span style="color: #0000FF; ">namespace</span>&nbsp;dk<br />{<br /><span style="color: #0000FF; ">namespace</span>&nbsp;common<br />{<br />Url::Url(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;url)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;Init(url);<br />}<br /><br /><span style="color: #0000FF; ">bool</span>&nbsp;Url::Init(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;url)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*tmpstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;userpass_flag;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;bracket_flag;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;curstr&nbsp;=&nbsp;url;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&lt;scheme&gt;:&lt;scheme-specific-part&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&lt;scheme&gt;&nbsp;:=&nbsp;[a-z\+\-\.]+<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upper&nbsp;case&nbsp;=&nbsp;lower&nbsp;case&nbsp;for&nbsp;resiliency<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Read&nbsp;scheme&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;tmpstr&nbsp;=&nbsp;strchr(curstr,&nbsp;':');<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;NULL&nbsp;==&nbsp;tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Not&nbsp;found&nbsp;the&nbsp;character&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Get&nbsp;the&nbsp;scheme&nbsp;length&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;tmpstr&nbsp;-&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Check&nbsp;restrictions&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;len;&nbsp;i++&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;!IsSchemeChar(curstr[i])&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Invalid&nbsp;format&nbsp;</span><span style="color: #008000; ">*/</span><br />&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 />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Copy&nbsp;the&nbsp;scheme&nbsp;to&nbsp;the&nbsp;storage&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;m_scheme.assign(curstr,&nbsp;len);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Make&nbsp;the&nbsp;character&nbsp;to&nbsp;lower&nbsp;if&nbsp;it&nbsp;is&nbsp;upper&nbsp;case.&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;len;&nbsp;i++&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_scheme[i]&nbsp;=&nbsp;tolower(m_scheme[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Skip&nbsp;':'&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;curstr&nbsp;=&nbsp;tmpstr;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;//&lt;user&gt;:&lt;password&gt;@&lt;host&gt;:&lt;port&gt;/&lt;url-path&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Any&nbsp;":",&nbsp;"@"&nbsp;and&nbsp;"/"&nbsp;must&nbsp;be&nbsp;encoded.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Eat&nbsp;"//"&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;2;&nbsp;i++&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;'/'&nbsp;!=&nbsp;*curstr&nbsp;)&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; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Check&nbsp;if&nbsp;the&nbsp;user&nbsp;(and&nbsp;password)&nbsp;are&nbsp;specified.&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;userpass_flag&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;tmpstr&nbsp;=&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(&nbsp;'\0'&nbsp;!=&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;'@'&nbsp;==&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Username&nbsp;and&nbsp;password&nbsp;are&nbsp;specified&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userpass_flag&nbsp;=&nbsp;1;<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;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;'/'&nbsp;==&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;End&nbsp;of&nbsp;&lt;host&gt;:&lt;port&gt;&nbsp;specification&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userpass_flag&nbsp;=&nbsp;0;<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;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;User&nbsp;and&nbsp;password&nbsp;specification&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;tmpstr&nbsp;=&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;userpass_flag&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Read&nbsp;username&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(&nbsp;'\0'&nbsp;!=&nbsp;*tmpstr&nbsp;&amp;&amp;&nbsp;':'&nbsp;!=&nbsp;*tmpstr&nbsp;&amp;&amp;&nbsp;'@'&nbsp;!=&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;tmpstr&nbsp;-&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_username.assign(curstr,&nbsp;len);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Proceed&nbsp;current&nbsp;pointer&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr&nbsp;=&nbsp;tmpstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;':'&nbsp;==&nbsp;*curstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Skip&nbsp;':'&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Read&nbsp;password&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr&nbsp;=&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(&nbsp;'\0'&nbsp;!=&nbsp;*tmpstr&nbsp;&amp;&amp;&nbsp;'@'&nbsp;!=&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;tmpstr&nbsp;-&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_password.assign(curstr,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr&nbsp;=&nbsp;tmpstr;<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; ">&nbsp;Skip&nbsp;'@'&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;'@'&nbsp;!=&nbsp;*curstr&nbsp;)&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; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;'['&nbsp;==&nbsp;*curstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bracket_flag&nbsp;=&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bracket_flag&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Proceed&nbsp;on&nbsp;by&nbsp;delimiters&nbsp;with&nbsp;reading&nbsp;host&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;tmpstr&nbsp;=&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(&nbsp;'\0'&nbsp;!=&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;bracket_flag&nbsp;&amp;&amp;&nbsp;']'&nbsp;==&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;End&nbsp;of&nbsp;IPv6&nbsp;address.&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<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;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;!bracket_flag&nbsp;&amp;&amp;&nbsp;(':'&nbsp;==&nbsp;*tmpstr&nbsp;||&nbsp;'/'&nbsp;==&nbsp;*tmpstr)&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Port&nbsp;number&nbsp;is&nbsp;specified.&nbsp;</span><span style="color: #008000; ">*/</span><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;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;tmpstr&nbsp;-&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;m_host.assign(curstr,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;curstr&nbsp;=&nbsp;tmpstr;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Is&nbsp;port&nbsp;number&nbsp;specified?&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;':'&nbsp;==&nbsp;*curstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Read&nbsp;port&nbsp;number&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr&nbsp;=&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(&nbsp;'\0'&nbsp;!=&nbsp;*tmpstr&nbsp;&amp;&amp;&nbsp;'/'&nbsp;!=&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;tmpstr&nbsp;-&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_port.assign(curstr,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr&nbsp;=&nbsp;tmpstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;End&nbsp;of&nbsp;the&nbsp;string&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;'\0'&nbsp;==&nbsp;*curstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Skip&nbsp;'/'&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">if&nbsp;(&nbsp;'/'&nbsp;!=&nbsp;*curstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">return&nbsp;false;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">curstr++;</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Parse&nbsp;path&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;tmpstr&nbsp;=&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(&nbsp;'\0'&nbsp;!=&nbsp;*tmpstr&nbsp;&amp;&amp;&nbsp;'#'&nbsp;!=&nbsp;*tmpstr&nbsp;&nbsp;&amp;&amp;&nbsp;'?'&nbsp;!=&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;tmpstr&nbsp;-&nbsp;curstr;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;m_path.assign(curstr,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;curstr&nbsp;=&nbsp;tmpstr;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Is&nbsp;query&nbsp;specified?&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;'?'&nbsp;==&nbsp;*curstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Skip&nbsp;'?'&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Read&nbsp;query&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr&nbsp;=&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(&nbsp;'\0'&nbsp;!=&nbsp;*tmpstr&nbsp;&amp;&amp;&nbsp;'#'&nbsp;!=&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;tmpstr&nbsp;-&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_query.assign(curstr,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr&nbsp;=&nbsp;tmpstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Is&nbsp;fragment&nbsp;specified?&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;'#'&nbsp;==&nbsp;*curstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Skip&nbsp;'#'&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Read&nbsp;fragment&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr&nbsp;=&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(&nbsp;'\0'&nbsp;!=&nbsp;*tmpstr&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpstr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;tmpstr&nbsp;-&nbsp;curstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_fragment.assign(curstr,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curstr&nbsp;=&nbsp;tmpstr;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br />}<br />}<br />}</div>参考资料：<br /><a href="http://draft.scyphus.co.jp/lang/c/url_parser.html">http://draft.scyphus.co.jp/lang/c/url_parser.html</a><img src ="http://www.cppblog.com/izualzhy/aggbug/202521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2013-08-13 14:15 <a href="http://www.cppblog.com/izualzhy/archive/2013/08/13/202521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>回溯法求数组的排列组合</title><link>http://www.cppblog.com/izualzhy/archive/2013/04/13/199400.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 13 Apr 2013 02:13:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2013/04/13/199400.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/199400.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2013/04/13/199400.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/199400.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/199400.html</trackback:ping><description><![CDATA[<h1>组合问题</h1><p style="margin-top: 10px; margin-bottom: 10px; font-family: 宋体; font-size: 16px; line-height: 25px; background-color: #ffffff;">给定一个含有n个元素的整型数组a，从中任取m个元素，求所有组合。比如下面的例子</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: 宋体; font-size: 16px; line-height: 25px; background-color: #ffffff;">a = 1, 2, 3, 4, 5</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: 宋体; font-size: 16px; line-height: 25px; background-color: #ffffff;">m = 3</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: 宋体; font-size: 16px; line-height: 25px; background-color: #ffffff;">输出</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: 宋体; font-size: 16px; line-height: 25px; background-color: #ffffff;">1 2 3, 1 2 4, 1 2 5, 1 3 4, 1 3 5, 1 4 5</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: 宋体; font-size: 16px; line-height: 25px; background-color: #ffffff;">2 3 4, 2 3 5, 2 4 5<br />3 4 5</p><h2>分析</h2><p style="margin-top: 10px; margin-bottom: 10px; font-family: 宋体; font-size: 16px; line-height: 25px; background-color: #ffffff;">典型的排列组合问题，首选回溯法，为了简化问题，我们将a中n个元素值分别设置为1-n<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include&nbsp;&lt;iostream&gt;<br />#include&nbsp;&lt;vector&gt;<br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;array[5]&nbsp;=&nbsp;{0,1,2,3,4};<br />vector&lt;<span style="color: #0000FF; ">int</span>&gt;&nbsp;obj;<br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;NULLELEMENT&nbsp;-1<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">组合问题</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">void</span>&nbsp;selectC(<span style="color: #0000FF; ">int</span>&nbsp;depth)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(depth&nbsp;==&nbsp;3)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<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;obj.size();&nbsp;++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;obj[i]&nbsp;&lt;&lt;&nbsp;"\t";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><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;5;&nbsp;++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(obj.size()&nbsp;&gt;&nbsp;0&nbsp;&amp;&amp;&nbsp;i&nbsp;&lt;=&nbsp;obj[obj.size()&nbsp;-1])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">continue</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj.push_back(array[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectC(depth+1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj.pop_back();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">排列组合</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">void</span>&nbsp;selectA(<span style="color: #0000FF; ">int</span>&nbsp;depth)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(depth&nbsp;==&nbsp;3)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<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;obj.size();&nbsp;++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;obj[i]&nbsp;&lt;&lt;&nbsp;"\t";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br />&nbsp;&nbsp;&nbsp;&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;5;&nbsp;++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(array[i]&nbsp;==&nbsp;NULLELEMENT)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">continue</span>;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj.push_back(i);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[i]&nbsp;=&nbsp;NULLELEMENT;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectA(depth+1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[i]&nbsp;=&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj.pop_back();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;selectA(0);<br />&nbsp;&nbsp;&nbsp;&nbsp;selectC(0);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div></p><img src ="http://www.cppblog.com/izualzhy/aggbug/199400.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2013-04-13 10:13 <a href="http://www.cppblog.com/izualzhy/archive/2013/04/13/199400.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>回溯法求解数独</title><link>http://www.cppblog.com/izualzhy/archive/2013/01/24/197544.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Thu, 24 Jan 2013 11:50:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2013/01/24/197544.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/197544.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2013/01/24/197544.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/197544.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/197544.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 闲逛csdn时看到了这个帖子： http://blog.csdn.net/wutongthucs/article/details/8521292 看了几眼就联想到了之前自己写的24点和猜数字的文章： http://www.cppblog.com/izualzhy/archive/2011/12/25/162800.html 想法其实很简单，回溯不过是枚举的变形，只是在更早的时候会判断当前状态是否合...&nbsp;&nbsp;<a href='http://www.cppblog.com/izualzhy/archive/2013/01/24/197544.html'>阅读全文</a><img src ="http://www.cppblog.com/izualzhy/aggbug/197544.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2013-01-24 19:50 <a href="http://www.cppblog.com/izualzhy/archive/2013/01/24/197544.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux下编码的转换[iconv]</title><link>http://www.cppblog.com/izualzhy/archive/2012/12/21/196505.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Fri, 21 Dec 2012 06:36:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/12/21/196505.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/196505.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/12/21/196505.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/196505.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/196505.html</trackback:ping><description><![CDATA[<p><font color="#0000ff" size="6">1.iconv命令</font></p> <p><font size="3">关于这个命令的详细可以man看一下</font></p> <p><font color="#ff0000" size="5">[基本用法]</font></p> <p><font color="#000000" size="3">iconv –f encoding –t encoding inputfile</font></p> <p><font size="3">-f: –-from-code&nbsp; 指定原始文件编码</font></p> <p><font size="3">-t: –to-code 指定输出编码</font></p> <p><font size="3">例如我存储一个a.txt，文件采用utf-8编码保存，如果要修改为Big5格式的，可以这么写：</font></p> <p><font size="3">$: iconv –f utf-8 –t Big5 a.txt</font></p> <p><font size="3">如果希望结果存储进b.txt</font></p> <p><font size="3">$: iconv –f utf-8 –t Big5 a.txt –o b.txt</font></p> <p><font size="3">-o: –output 指定目标文件</font></p> <p><font size="3">如果不知道该怎么指定编码，可以使用</font></p> <p><font size="3">$: iconv –l</font></p> <p><font size="3">来查看所有已知的字符集</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">上面文件的操作如果没有方便的工具，可以使用word来查看或者建立。</font></p> <p><font color="#0000ff" size="6">2.iconv函数</font></p> <p><font size="3">与iconv command一样，更多的信息同样可以man来查看，注意这里需要man 3 iconv到另外一个manpage。</font></p> <p><font size="3">相关的函数主要有3个：</font></p> <p><font color="#ff0000" size="5">1.iconv_open</font></p> <p><font size="3">[函数原型]： </font></p> <p><font size="3">#include &lt;iconv.h&gt;</font></p> <p><font size="3">iconv_t iconv_open(const char* tocode, const char* fromcode);</font></p> <p><font size="3">[函数说明]</font></p> <p><font size="3">该函数分配一个编码转换的描述符，从fromcode转到tocode</font></p> <p><font size="3">tocode字符串后可以添加//TRANSLIT,//IGNORE。</font></p> <p><font size="3">函数失败则返回-1，同时设置errno</font></p> <p>常见的errno：</p> <p>EINVAL The conversion from fromcode to tocode is not supported by the implementation.</p> <p><font color="#ff0000" size="5">2.iconv_open</font></p> <p><font size="3">[函数原型]： </font></p> <p><font size="3">#include &lt;iconv.h&gt;</font></p> <p><font size="3">size_t iconv(iconv_t cd, char** inbuf, size_t *inbytesleft, char** outbuf, size_t *outbytesleft);</font></p> <p><font size="3">cd:转码描述符</font></p> <p><font size="3">*inbuf:指向源字符串</font></p> <p><font size="3">*inbytesleft：指向需要读取的长度</font></p> <p><font size="3">*outbuf:指向目标字符串</font></p> <p><font size="3">*outbytesleft: 指向可用的目标地址长度</font></p> <p>细心的读者肯定已经发现，这里传入的全是指针，因为这里的参数并不只是起到一个传入的作用！</p> <p>为了不误人子弟，关于iconv的工作流程，直接贴了manpage里的一句话：</p> <p>The argument cd must be a conversion descriptor created using the function iconv_open(3).</p> <p>The main case is when inbuf is not NULL and *inbuf is not NULL.&nbsp; In this case, the iconv() function converts the multibyte sequence starting at *inbuf to a multi‐<br>byte sequence starting at *outbuf.&nbsp; At most *inbytesleft bytes, starting at *inbuf, will be read.&nbsp; At most *outbytesleft bytes, starting at *outbuf, will be writ‐<br>ten.</p> <p>The&nbsp; iconv() function converts one multibyte character at a time, and for each character conversion it increments *inbuf and decrements *inbytesleft by the number<br>of converted input bytes, it increments *outbuf and decrements *outbytesleft by the number of converted output bytes, and it updates&nbsp; the&nbsp; conversion&nbsp; state&nbsp; con‐<br>tained&nbsp; in cd.&nbsp; If the character encoding of the input is stateful, the iconv() function can also convert a sequence of input bytes to an update to the conversion<br>state without producing any output bytes; such input is called a shift sequence.&nbsp; The conversion can stop for four reasons:</p> <p>1. An invalid multibyte sequence is encountered in the input.&nbsp; In this case it sets errno to EILSEQ and returns (size_t) -1.&nbsp;&nbsp; *inbuf&nbsp; is&nbsp; left&nbsp; pointing&nbsp; to&nbsp; the<br>beginning of the invalid multibyte sequence.</p> <p>2.&nbsp; The&nbsp; input byte sequence has been entirely converted, that is, *inbytesleft has gone down to 0.&nbsp; In this case iconv() returns the number of nonreversible con‐<br>versions performed during this call.</p> <p>3. An incomplete multibyte sequence is encountered in the input, and the input byte sequence terminates after it.&nbsp; In this&nbsp; case&nbsp; it&nbsp; sets&nbsp; errno&nbsp; to&nbsp; EINVAL&nbsp; and<br>returns (size_t) -1.&nbsp; *inbuf is left pointing to the beginning of the incomplete multibyte sequence.</p> <p>4. The output buffer has no more room for the next converted character.&nbsp; In this case it sets errno to E2BIG and returns (size_t) -1.</p> <p>A different case is when inbuf is NULL or *inbuf is NULL, but outbuf is not NULL and *outbuf is not NULL.&nbsp; In this case, the iconv() function attempts to set cd's<br>conversion state to the initial state and store a corresponding shift sequence at *outbuf.&nbsp; At most *outbytesleft bytes, starting at *outbuf, will be written.&nbsp; If<br>the&nbsp; output buffer has no more room for this reset sequence, it sets errno to E2BIG and returns (size_t) -1.&nbsp; Otherwise it increments *outbuf and decrements *out‐<br>bytesleft by the number of bytes written.</p> <p>A third case is when inbuf is NULL or *inbuf is NULL, and outbuf is NULL or *outbuf is NULL.&nbsp; In this case, the iconv() function sets cd's conversion state to the<br>initial state.</p> <p>看的不是很懂也没有关系，我再贴下自己的翻译和理解：</p> <p>iconv函数会从*inbuf开始，每转换一个字符，增大*inbuf,减少*inbytesleft,增大/减少的字节数即为转换的input字节数，同时增大*outbuf,减少*outbytesleft,增大/减少的字节数即为转换的output字节数。</p> <p>编码的转换遇到以下四种情况会stop：</p> <blockquote> <p>1.inbuf里碰到非法的字节：这种情况设置errno为EILSEQ，返回(size_t)-1,*inbuf指向非法字符的开始处。</p> <p>2.inbuf里字节完全转换：*inbytesleft减少至0，返回不可逆的转换的字节数（这个不明白什么意思，似乎是由于在目标字符集里找不到字符的问题？）</p> <p>3.inbuf不完整的字符串：设置errno为EINVAL，返回(size_t)-1,*inbuf指向不完整字符的开始处。</p> <p>&nbsp;&nbsp;&nbsp; 比如一个字符占了4个字节，我故意只穿了前3个字节进去。</p> <p>4.outbuf空间不够，此时设置errno为E2BIG，返回-1.</p></blockquote> <p>关于返回值还在纠结的直接看这里，自己体会下：</p> <blockquote> <p>The&nbsp; iconv()&nbsp; function&nbsp; returns&nbsp; the&nbsp; number&nbsp; of characters converted in a nonreversible way during this call; reversible conversions are not counted.&nbsp; In case of<br>error, it sets errno and returns (size_t) -1.</p></blockquote> <p><font color="#ff0000" size="5">3.iconv_close</font></p> <p><font size="3">[函数原型]： </font></p> <p><font size="3">#include &lt;iconv.h&gt;</font></p> <p><font size="3">int iconv_close(iconv_t cd);</font></p> <p><font size="3">关闭转换编码的描述符，成功返回0，否则设置errno并返回-1.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">说了这么多，来个例子看下，其中源代码文件保存为utf-8编码，test.txt可以在word里使用BIG5编码查看。</font></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:adc5052c-0cb2-465b-8bc0-629741143082" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;stdio.h&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#include</span> <span style="color:#259241">&lt;iconv.h&gt;</span></li> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;errno.h&gt;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">int</span> main<span style="color:#2e53d1">()</span></li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#400080">char</span> <span style="color:#2e53d1">*</span>src <span style="color:#2e53d1">=</span> <span style="color:#259241">&quot;你好一二三四五六七八九十&quot;</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">unsigned</span> <span style="color:#400080">int</span> srcLen <span style="color:#2e53d1">=</span> strlen<span style="color:#2e53d1">(</span>src<span style="color:#2e53d1">);</span></li> <li>    <span style="color:#400080">unsigned</span> <span style="color:#400080">int</span> destLen <span style="color:#2e53d1">=</span> <span style="color:#259241">256</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">int</span> iconvLen <span style="color:#2e53d1">=</span> <span style="color:#2e53d1">-</span><span style="color:#259241">1</span><span style="color:#2e53d1">;</span></li> <li>    <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> dest <span style="color:#2e53d1">=</span> <span style="color:#2e53d1">(</span><span style="color:#400080">char</span><span style="color:#2e53d1">*)</span>malloc<span style="color:#2e53d1">(</span>destLen <span style="color:#2e53d1">*</span> <span style="color:#400080">sizeof</span><span style="color:#2e53d1">(</span><span style="color:#400080">char</span><span style="color:#2e53d1">));</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> obj <span style="color:#2e53d1">=</span> dest<span style="color:#2e53d1">;</span><span style="color:#937a42">//记录存储开始位置，iconv里会对dest修改</span></li> <li>    memset<span style="color:#2e53d1">(</span>dest<span style="color:#2e53d1">,</span> <span style="color:#259241">0</span><span style="color:#2e53d1">,</span> <span style="color:#259241">256</span><span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    iconv_t convId<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">if</span> <span style="color:#2e53d1">((</span>convId <span style="color:#2e53d1">=</span> iconv_open<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;BIG-5&quot;</span><span style="color:#2e53d1">,</span> <span style="color:#259241">&quot;utf-8&quot;</span><span style="color:#2e53d1">))</span> <span style="color:#2e53d1">==</span> <span style="color:#2e53d1">-</span><span style="color:#259241">1</span><span style="color:#2e53d1">)</span></li> <li>    {</li> <li style="background: #f3f3f3">        perror<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;iconv open error&quot;</span><span style="color:#2e53d1">);</span></li> <li>    }</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>convId <span style="color:#2e53d1">==</span> <span style="color:#259241">0</span><span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">    {</li> <li>        printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;cd == 0, return&#92;n&quot;</span><span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">        <span style="color:#400080">return</span> <span style="color:#2e53d1">-</span><span style="color:#259241">1</span><span style="color:#2e53d1">;</span></li> <li>    }</li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;</li> <li style="background: #f3f3f3">    printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;before, src: %x, dest: %x, srcLen: %d, destLen: %d&#92;n&quot;</span><span style="color:#2e53d1">,</span> src<span style="color:#2e53d1">,</span> dest<span style="color:#2e53d1">,</span> srcLen<span style="color:#2e53d1">,</span> destLen<span style="color:#2e53d1">);</span></li> <li>    iconvLen <span style="color:#2e53d1">=</span> iconv<span style="color:#2e53d1">(</span>convId<span style="color:#2e53d1">,</span> <span style="color:#2e53d1">&amp;</span>src<span style="color:#2e53d1">,</span> <span style="color:#2e53d1">&amp;</span>srcLen<span style="color:#2e53d1">,</span> <span style="color:#2e53d1">&amp;</span>dest<span style="color:#2e53d1">,</span> <span style="color:#2e53d1">&amp;</span>destLen<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">    printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;after,  src: %x, dest: %x, srcLen: %d, destLen: %d&#92;n&quot;</span><span style="color:#2e53d1">,</span> src<span style="color:#2e53d1">,</span> dest<span style="color:#2e53d1">,</span> srcLen<span style="color:#2e53d1">,</span> destLen<span style="color:#2e53d1">);</span></li> <li>    printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;iconvLen: %d&#92;n&quot;</span><span style="color:#2e53d1">,</span> iconvLen<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>iconvLen <span style="color:#2e53d1">==</span> <span style="color:#2e53d1">-</span><span style="color:#259241">1</span><span style="color:#2e53d1">)</span></li> <li>    {</li> <li style="background: #f3f3f3">        perror<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;error:&quot;</span><span style="color:#2e53d1">);</span></li> <li>    }</li> <li style="background: #f3f3f3">    <span style="color:#400080">unsigned</span> <span style="color:#400080">int</span> convLen <span style="color:#2e53d1">=</span> <span style="color:#259241">256</span> <span style="color:#2e53d1">-</span> destLen<span style="color:#2e53d1">;</span></li> <li>    FILE<span style="color:#2e53d1">*</span> f <span style="color:#2e53d1">=</span> fopen<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;test.txt&quot;</span><span style="color:#2e53d1">,</span> <span style="color:#259241">&quot;w&quot;</span><span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>fwrite<span style="color:#2e53d1">(</span>obj<span style="color:#2e53d1">,</span> <span style="color:#259241">1</span><span style="color:#2e53d1">,</span> convLen<span style="color:#2e53d1">,</span> f<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">!=</span> convLen<span style="color:#2e53d1">)</span></li> <li>    {</li> <li style="background: #f3f3f3">        printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;fwrite error!&#92;n&quot;</span><span style="color:#2e53d1">);</span></li> <li>    }</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    fclose<span style="color:#2e53d1">(</span>f<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">    iconv_close<span style="color:#2e53d1">(</span>convId<span style="color:#2e53d1">);</span></li> <li>    free<span style="color:#2e53d1">(</span>obj<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div> <p>如果还有什么疑问，欢迎评论。</p><img src ="http://www.cppblog.com/izualzhy/aggbug/196505.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-12-21 14:36 <a href="http://www.cppblog.com/izualzhy/archive/2012/12/21/196505.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c语言如何读取一个zip压缩包内的文件列表</title><link>http://www.cppblog.com/izualzhy/archive/2012/12/08/196117.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 08 Dec 2012 08:46:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/12/08/196117.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/196117.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/12/08/196117.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/196117.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/196117.html</trackback:ping><description><![CDATA[<p>闲来无事随便写下，感兴趣的可以参考这里：</p> <p><a href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">http://www.pkware.com/documents/casestudies/APPNOTE.TXT</a></p> <p>#4.3.7 Local file header:的部分</p> <p>更详细的可参考非常nb的zlib：</p> <p><a title="http://www.zlib.net/" href="http://www.zlib.net/">http://www.zlib.net/</a></p> <p>&nbsp;</p> <p>主要的作用是读取一个zip文件，列出压缩前的文件列表。</p> <p>比如：</p> <p>y@y-VirtualBox:~/MyDocuments/Training$ ./a.out test.zip<br>page0.bmp<br>page1.bmp<br>page2.bmp<br>page3.bmp<br></p> <p>代码：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:19a93169-11df-4d99-994c-29bfeddaaf6a" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;stdio.h&gt;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">int</span> main<span style="color:#2e53d1">(</span><span style="color:#400080">int</span> argc<span style="color:#2e53d1">,</span> <span style="color:#400080">char</span> <span style="color:#2e53d1">*</span>argv<span style="color:#2e53d1">[])</span></li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>argc <span style="color:#2e53d1">!=</span> <span style="color:#259241">2</span><span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">    {</li> <li>        printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;usage: ./a.out xxx.zip.&#92;n&quot;</span><span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">        <span style="color:#400080">return</span> <span style="color:#2e53d1">-</span><span style="color:#259241">1</span><span style="color:#2e53d1">;</span></li> <li>    }</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    FILE<span style="color:#2e53d1">*</span> fp <span style="color:#2e53d1">=</span> fopen<span style="color:#2e53d1">(</span>argv<span style="color:#2e53d1">[</span><span style="color:#259241">1</span><span style="color:#2e53d1">],</span> <span style="color:#259241">&quot;r&quot;</span><span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">if</span> <span style="color:#2e53d1">(!</span>fp<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">    {</li> <li>        printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;file %s not found.&#92;n&quot;</span><span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">        <span style="color:#400080">return</span> <span style="color:#2e53d1">-</span><span style="color:#259241">1</span><span style="color:#2e53d1">;</span></li> <li>    }</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    fseek<span style="color:#2e53d1">(</span>fp<span style="color:#2e53d1">,</span> <span style="color:#259241">0</span><span style="color:#2e53d1">,</span> SEEK_END<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">int</span> fileSize <span style="color:#2e53d1">=</span> ftell<span style="color:#2e53d1">(</span>fp<span style="color:#2e53d1">);</span></li> <li>    fseek<span style="color:#2e53d1">(</span>fp<span style="color:#2e53d1">,</span> <span style="color:#259241">0</span><span style="color:#2e53d1">,</span> SEEK_SET<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> fileContent <span style="color:#2e53d1">=</span> <span style="color:#2e53d1">(</span><span style="color:#400080">char</span><span style="color:#2e53d1">*)</span>malloc<span style="color:#2e53d1">(</span>fileSize <span style="color:#2e53d1">*</span> <span style="color:#400080">sizeof</span><span style="color:#2e53d1">(</span><span style="color:#400080">char</span><span style="color:#2e53d1">));</span></li> <li>    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>fileSize <span style="color:#2e53d1">!=</span> fread<span style="color:#2e53d1">(</span>fileContent<span style="color:#2e53d1">,</span> <span style="color:#259241">1</span><span style="color:#2e53d1">,</span> fileSize<span style="color:#2e53d1">,</span> fp<span style="color:#2e53d1">))</span></li> <li style="background: #f3f3f3">    {</li> <li>        printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;read error!&#92;n&quot;</span><span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">    }</li> <li>    </li> <li style="background: #f3f3f3">    <span style="color:#400080">int</span> index <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>    <span style="color:#400080">int</span> centralFileHeaderSignature <span style="color:#2e53d1">=</span> <span style="color:#259241">0x02014b50</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">while</span> <span style="color:#2e53d1">(</span>index <span style="color:#2e53d1">&lt;</span> fileSize<span style="color:#2e53d1">)</span></li> <li>    {</li> <li style="background: #f3f3f3">        <span style="color:#400080">if</span> <span style="color:#2e53d1">(*(</span><span style="color:#400080">int</span><span style="color:#2e53d1">*)(</span>fileContent <span style="color:#2e53d1">+</span> index<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">==</span> centralFileHeaderSignature<span style="color:#2e53d1">)</span></li> <li>        {</li> <li style="background: #f3f3f3">            <span style="color:#400080">unsigned</span> <span style="color:#400080">short</span> fileNameLength <span style="color:#2e53d1">=</span> <span style="color:#2e53d1">*(</span><span style="color:#400080">unsigned</span> <span style="color:#400080">short</span><span style="color:#2e53d1">*)(</span>fileContent <span style="color:#2e53d1">+</span> index <span style="color:#2e53d1">+</span> <span style="color:#259241">28</span><span style="color:#2e53d1">);</span></li> <li>            <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> fileName <span style="color:#2e53d1">=</span> <span style="color:#2e53d1">(</span><span style="color:#400080">char</span><span style="color:#2e53d1">*)</span>malloc<span style="color:#2e53d1">((</span>fileNameLength<span style="color:#2e53d1">+</span><span style="color:#259241">1</span><span style="color:#2e53d1">)</span> <span style="color:#2e53d1">*</span> <span style="color:#400080">sizeof</span><span style="color:#2e53d1">(</span><span style="color:#400080">char</span><span style="color:#2e53d1">));</span></li> <li style="background: #f3f3f3">            strncpy<span style="color:#2e53d1">(</span>fileName<span style="color:#2e53d1">,</span> fileContent <span style="color:#2e53d1">+</span> index <span style="color:#2e53d1">+</span> <span style="color:#259241">46</span><span style="color:#2e53d1">,</span> fileNameLength<span style="color:#2e53d1">);</span></li> <li>            printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;%s&#92;n&quot;</span><span style="color:#2e53d1">,</span> fileName<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">            free<span style="color:#2e53d1">(</span>fileName<span style="color:#2e53d1">);</span></li> <li>        }</li> <li style="background: #f3f3f3">        index<span style="color:#2e53d1">++;</span></li> <li>    }</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    free<span style="color:#2e53d1">(</span>fileContent<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">    fclose<span style="color:#2e53d1">(</span>fp<span style="color:#2e53d1">);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>}</li> </ol> </div> </div> </div> <p>有两个疑惑的地方：</p> <p>1.对于所谓的signature0x01024b50,如何做到压缩后的内容肯定不会是这个值呢，这个估计要看下压缩算法才明白。</p> <p>2.查找signature的方法太朴素了，应当如何改进？</p> <p>3.如何在不一次读取整个文件内容得到结果？</p><img src ="http://www.cppblog.com/izualzhy/aggbug/196117.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-12-08 16:46 <a href="http://www.cppblog.com/izualzhy/archive/2012/12/08/196117.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]new的三中使用方式：placenew,nothrownew,placementnew</title><link>http://www.cppblog.com/izualzhy/archive/2012/12/05/196014.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Wed, 05 Dec 2012 11:01:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/12/05/196014.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/196014.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/12/05/196014.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/196014.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/196014.html</trackback:ping><description><![CDATA[<p>new有三种使用方式：plain new、nothrow new、placement new.</p> <p>1.plain new/delete.普通的new,定义如下： <p>void *operator new(std::size_t) throw(std::bad_alloc); <p>void operator delete(void*) throw(); <p>注：标准C++ plain new失败后抛出标准异常std::bad_alloc而非返回NULL，因此检查返回值是否为NULL判断分配是否成功是徒劳的。 <p>测试程序： <p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2ab32497-c1df-41ea-8bf5-9146155d0267" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;iostream&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">using</span> <span style="color:#400080">namespace</span> std<span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">char</span><span style="color:#2e53d1">*</span> GetMemory<span style="color:#2e53d1">(</span><span style="color:#400080">unsigned</span> <span style="color:#400080">long</span> size<span style="color:#2e53d1">)</span></li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> p <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> <span style="color:#400080">char</span><span style="color:#2e53d1">[</span>size<span style="color:#2e53d1">];</span><span style="color:#937a42">//分配失败，不是返回NULL</span></li> <li>    <span style="color:#400080">return</span> p<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">}</li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">int</span> main<span style="color:#2e53d1">()</span></li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#400080">try</span></li> <li>    {</li> <li style="background: #f3f3f3">        <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> p <span style="color:#2e53d1">=</span> GetMemory<span style="color:#2e53d1">(</span><span style="color:#259241">10e11</span><span style="color:#2e53d1">);</span><span style="color:#937a42">//分配失败抛出异常std::bad_alloc</span></li> <li>        <span style="color:#400080">if</span> <span style="color:#2e53d1">(!</span>p<span style="color:#2e53d1">)</span><span style="color:#937a42">//徒劳</span></li> <li style="background: #f3f3f3">            cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">&quot;failure&quot;</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li>        <span style="color:#400080">delete</span> <span style="color:#2e53d1">[]</span> p<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    }</li> <li>    <span style="color:#400080">catch</span> <span style="color:#2e53d1">(</span><span style="color:#400080">const</span> std<span style="color:#2e53d1">::</span>bad_alloc <span style="color:#2e53d1">&amp;</span> ex<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">    {</li> <li>        cout <span style="color:#2e53d1">&lt;&lt;</span> ex<span style="color:#2e53d1">.</span>what<span style="color:#2e53d1">()</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    }</li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>}</li> </ol> </div> </div> </div></p> <p>输出：</p> <p>std::bad_alloc<br>2.</p> <p>nothrow new/delete不抛出异常的运算符new的形式，new失败时返回NULL。 <p>定义如下： <p>void *operator new(std::size_t,const std::nothrow_t&amp;) throw(); <p>void operator delete(void*) throw(); <p>struct nothrow_t{};&nbsp; const nothrow_t nothrow;//nothrow作为new的标志性哑元 <p>测试程序：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6270af61-870f-49a1-a5b9-d200ac0e5912" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;iostream&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#include</span> <span style="color:#259241">&lt;new&gt;</span></li> <li><span style="color:#400080">using</span> <span style="color:#400080">namespace</span> std<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">char</span><span style="color:#2e53d1">*</span> GetMemory<span style="color:#2e53d1">(</span><span style="color:#400080">unsigned</span> <span style="color:#400080">long</span> size<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> p <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span><span style="color:#2e53d1">(</span>nothrow<span style="color:#2e53d1">)</span> <span style="color:#400080">char</span><span style="color:#2e53d1">[</span>size<span style="color:#2e53d1">];</span><span style="color:#937a42">//分配失败，返回NULL</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>NULL <span style="color:#2e53d1">==</span> p<span style="color:#2e53d1">)</span></li> <li>        cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">&quot;alloc failure!&quot;</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">return</span> p<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">}</li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">int</span> main<span style="color:#2e53d1">()</span></li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#400080">try</span> </li> <li>    {</li> <li style="background: #f3f3f3">        <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> p <span style="color:#2e53d1">=</span> GetMemory<span style="color:#2e53d1">(</span><span style="color:#259241">10e11</span><span style="color:#2e53d1">);</span></li> <li>        <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>p <span style="color:#2e53d1">==</span> NULL<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">            cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">&quot;failure&quot;</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li>        <span style="color:#400080">delete</span> <span style="color:#2e53d1">[]</span> p<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    }</li> <li>    <span style="color:#400080">catch</span> <span style="color:#2e53d1">(</span><span style="color:#400080">const</span> std<span style="color:#2e53d1">::</span>bad_alloc <span style="color:#2e53d1">&amp;</span> ex<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">    {</li> <li>        cout <span style="color:#2e53d1">&lt;&lt;</span> ex<span style="color:#2e53d1">.</span>what<span style="color:#2e53d1">()</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    }</li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>}</li> </ol> </div> </div> </div> <p>输出：</p> <p>alloc failure!<br>failure<br>3.</p> <p>placement new/delete 主要用途是：反复使用一块较大的动态分配成功的内存来构造不同类型的对象或者它们的数组。例如可以先申请一个足够大的字符数组，然后当需要时在它上面构造不同类型的对象或数组。placement new不用担心内存分配失败，因为它根本不分配内存，它只是调用对象的构造函数。 <p>测试程序：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4205a74c-893f-4a6d-ac1b-9a1ac8c17cec" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;iostream&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#include</span> <span style="color:#259241">&lt;new&gt;</span></li> <li><span style="color:#400080">using</span> <span style="color:#400080">namespace</span> std<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">class</span> ADT</li> <li style="background: #f3f3f3">{</li> <li><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">    ADT<span style="color:#2e53d1">()</span> { cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">&quot;ADT::ADT&quot;</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span> }</li> <li>    <span style="color:#2e53d1">~</span>ADT<span style="color:#2e53d1">()</span> { cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">&quot;ADT::~ADT&quot;</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span> }</li> <li style="background: #f3f3f3">    <span style="color:#400080">int</span> i<span style="color:#2e53d1">;</span></li> <li>    <span style="color:#400080">int</span> j<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">}<span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">int</span> main<span style="color:#2e53d1">()</span></li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> p <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span><span style="color:#2e53d1">(</span>nothrow<span style="color:#2e53d1">)</span> <span style="color:#400080">char</span><span style="color:#2e53d1">[</span><span style="color:#400080">sizeof</span><span style="color:#2e53d1">(</span>ADT<span style="color:#2e53d1">)+</span><span style="color:#259241">2</span><span style="color:#2e53d1">];</span></li> <li>    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>p <span style="color:#2e53d1">==</span> NULL<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">        cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">&quot;failure&quot;</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    ADT<span style="color:#2e53d1">*</span> q <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span><span style="color:#2e53d1">(</span>p<span style="color:#2e53d1">)</span> ADT<span style="color:#2e53d1">;</span><span style="color:#937a42">//placement new:不必担心失败</span></li> <li>    <span style="color:#937a42">//delete q;//错误！不能在此处调用delte q;</span></li> <li style="background: #f3f3f3">    q<span style="color:#2e53d1">-&gt;</span>ADT<span style="color:#2e53d1">::~</span>ADT<span style="color:#2e53d1">();</span><span style="color:#937a42">//显示调用细够函数</span></li> <li>    <span style="color:#400080">delete</span> <span style="color:#2e53d1">[]</span>p<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>}</li> </ol> </div> </div> </div> <p>输出：</p> <p>ADT::ADT<br>ADT::~ADT<br></p> <p>参考资料：</p> <p><a title="http://blog.sina.com.cn/s/blog_446b43c10100d7ci.html" href="http://blog.sina.com.cn/s/blog_446b43c10100d7ci.html">http://blog.sina.com.cn/s/blog_446b43c10100d7ci.html</a></p><img src ="http://www.cppblog.com/izualzhy/aggbug/196014.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-12-05 19:01 <a href="http://www.cppblog.com/izualzhy/archive/2012/12/05/196014.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>判断一个字符串是否是UTF8编码</title><link>http://www.cppblog.com/izualzhy/archive/2012/12/03/195933.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Mon, 03 Dec 2012 12:52:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/12/03/195933.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/195933.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/12/03/195933.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/195933.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/195933.html</trackback:ping><description><![CDATA[<p>关于utf-8编码的格式可以参考之前的笔记：</p> <p><a title="http://www.cppblog.com/izualzhy/archive/2012/02/27/166633.html" href="http://www.cppblog.com/izualzhy/archive/2012/02/27/166633.html">http://www.cppblog.com/izualzhy/archive/2012/02/27/166633.html</a></p> <p>根据格式的特点就可以判断一个字符串是否是utf8编码的。</p> <p>参考了资料里的方法，做了简化。</p> <p><strong>主要是以下几个判断的准则：</strong></p> <p>1.如果所有字符都是ascii码,则判断为ascii而非utf8编码(ascii字符占1个字节，从1-127, 最高位为0)</p> <p>2.当为多字节时，先判断第一个字节，从最高位开始，直到出现第一个0,位上为1的个数必须&gt;=2&amp;&amp;&lt;=6，检测剩下的字节，必须是10xx xxxx的形式。</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d099b477-5f94-42e9-9795-bda986c6a85a" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;string.h&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#include</span> <span style="color:#259241">&lt;stdio.h&gt;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">bool</span> IsUTF8String<span style="color:#2e53d1">(</span><span style="color:#400080">const</span> <span style="color:#400080">char</span><span style="color:#2e53d1">*</span> str<span style="color:#2e53d1">,</span> <span style="color:#400080">int</span> length<span style="color:#2e53d1">)</span></li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#400080">int</span> i <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>    <span style="color:#400080">int</span> nBytes <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span><span style="color:#937a42">//UTF8可用1-6个字节编码,ASCII用一个字节</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">unsigned</span> <span style="color:#400080">char</span> chr <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>    <span style="color:#400080">bool</span> bAllAscii <span style="color:#2e53d1">=</span> <span style="color:#400080">true</span><span style="color:#2e53d1">;</span><span style="color:#937a42">//如果全部都是ASCII,说明不是UTF-8</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">while</span> <span style="color:#2e53d1">(</span>i <span style="color:#2e53d1">&lt;</span> length<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">    {</li> <li>        chr <span style="color:#2e53d1">=</span> <span style="color:#2e53d1">*(</span>str <span style="color:#2e53d1">+</span> i<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">        <span style="color:#400080">if</span> <span style="color:#2e53d1">((</span>chr <span style="color:#2e53d1">&amp;</span> <span style="color:#259241">0x80</span><span style="color:#2e53d1">)</span> <span style="color:#2e53d1">!=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">)</span></li> <li>            bAllAscii <span style="color:#2e53d1">=</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">        <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>nBytes <span style="color:#2e53d1">==</span> <span style="color:#259241">0</span><span style="color:#2e53d1">)</span><span style="color:#937a42">//计算字节数</span></li> <li>        {</li> <li style="background: #f3f3f3">            <span style="color:#400080">if</span> <span style="color:#2e53d1">((</span>chr <span style="color:#2e53d1">&amp;</span> <span style="color:#259241">0x80</span><span style="color:#2e53d1">)</span> <span style="color:#2e53d1">!=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">)</span></li> <li>            {</li> <li style="background: #f3f3f3">                <span style="color:#400080">while</span> <span style="color:#2e53d1">((</span>chr <span style="color:#2e53d1">&amp;</span> <span style="color:#259241">0x80</span><span style="color:#2e53d1">)</span> <span style="color:#2e53d1">!=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">)</span></li> <li>                {</li> <li style="background: #f3f3f3">                    chr <span style="color:#2e53d1">&lt;&lt;=</span> <span style="color:#259241">1</span><span style="color:#2e53d1">;</span></li> <li>                    nBytes<span style="color:#2e53d1">++;</span></li> <li style="background: #f3f3f3">                }</li> <li>                <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>nBytes <span style="color:#2e53d1">&lt;</span> <span style="color:#259241">2</span> <span style="color:#2e53d1">||</span> nBytes <span style="color:#2e53d1">&gt;</span> <span style="color:#259241">6</span><span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">                    <span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span><span style="color:#937a42">//第一个字节最少为110x xxxx</span></li> <li>                nBytes<span style="color:#2e53d1">--;</span><span style="color:#937a42">//减去自身占的一个字节</span></li> <li style="background: #f3f3f3">            }</li> <li>        }</li> <li style="background: #f3f3f3">        <span style="color:#400080">else</span><span style="color:#937a42">//多字节除了第一个字节外剩下的字节</span></li> <li>        {</li> <li style="background: #f3f3f3">            <span style="color:#400080">if</span> <span style="color:#2e53d1">((</span>chr <span style="color:#2e53d1">&amp;</span> <span style="color:#259241">0xc0</span><span style="color:#2e53d1">)</span> <span style="color:#2e53d1">!=</span> <span style="color:#259241">0x80</span><span style="color:#2e53d1">)</span></li> <li>                <span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span><span style="color:#937a42">//剩下的字节都是10xx xxxx的形式</span></li> <li style="background: #f3f3f3">            nBytes<span style="color:#2e53d1">--;</span></li> <li>        }</li> <li style="background: #f3f3f3">        <span style="color:#2e53d1">++</span>i<span style="color:#2e53d1">;</span></li> <li>    }</li> <li style="background: #f3f3f3">    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>bAllAscii<span style="color:#2e53d1">)</span></li> <li>        <span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">return</span> nBytes <span style="color:#2e53d1">==</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>}</li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">int</span> main<span style="color:#2e53d1">()</span></li> <li style="background: #f3f3f3">{</li> <li>    printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;%d&#92;n&quot;</span><span style="color:#2e53d1">,</span> IsUTF8String<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;cc&quot;</span><span style="color:#2e53d1">,</span> strlen<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;cc&quot;</span><span style="color:#2e53d1">)));</span></li> <li style="background: #f3f3f3">    printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;%d&#92;n&quot;</span><span style="color:#2e53d1">,</span> IsUTF8String<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;曹操&quot;</span><span style="color:#2e53d1">,</span> strlen<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;曹操&quot;</span><span style="color:#2e53d1">)));</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>}</li> </ol> </div> </div> </div>  <p>参考资料：</p> <p><a title="http://www.cppblog.com/woaidongmao/archive/2011/08/27/154487.html" href="http://www.cppblog.com/woaidongmao/archive/2011/08/27/154487.html">http://www.cppblog.com/woaidongmao/archive/2011/08/27/154487.html</a></p><img src ="http://www.cppblog.com/izualzhy/aggbug/195933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-12-03 20:52 <a href="http://www.cppblog.com/izualzhy/archive/2012/12/03/195933.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]如何测试代码覆盖率</title><link>http://www.cppblog.com/izualzhy/archive/2012/11/27/195742.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Tue, 27 Nov 2012 11:46:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/11/27/195742.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/195742.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/11/27/195742.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/195742.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/195742.html</trackback:ping><description><![CDATA[<p>gcc/g++自带了gcov 工具可以自动生成一个执行代码覆盖率信息的文件gcda。只需要带编译宏 -fprofile-arcs-ftest-coverage 就可以生成gcno文件 <p>具体的信息可见 <a href="http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/Gcov-Intro.html#Gcov-Intro">http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/Gcov-Intro.html#Gcov-Intro</a> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 天主要介绍利用gcov生成的文件生成比较直观的web页面的一款工具lcov ，可以官网<a href="http://ltp.sourceforge.net/coverage/lcov.php">http://ltp.sourceforge.net/coverage/lcov.php</a>去下载这款工具我下的是 这个版本。好了废话不多说，我们通过一个简单的例子来看看如何使用这款工具。 <h4><a name="t0"></a>1.安装lcov</h4> <p># tar -zxvf&nbsp; lcov-1.10.tar.gz <p>#make install <p>这样就可以有两个工具 lcov&nbsp; genhtml 可以直接敲命令看看帮助信息 --help 你懂得。。 <h4><a name="t1"></a>2.测试cpp文件</h4> <p><b>[html]</b> <a href="http://blog.csdn.net/zerolxl/article/details/8201307#">view plain</a><a href="http://blog.csdn.net/zerolxl/article/details/8201307#">copy</a><a href="http://blog.csdn.net/zerolxl/article/details/8201307#">print</a><a href="http://blog.csdn.net/zerolxl/article/details/8201307#">?</a> <ol> <li>#include"stdio.h"&nbsp;&nbsp; <li> <li>#include"string.h"&nbsp;&nbsp; <li> <li> <li> <li> <li> <li>int Test(int i)&nbsp;&nbsp; <li> <li>{&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(i&gt;0)&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("iu&gt;0\n");&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else{&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("i &lt; 0\n");&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;&nbsp;&nbsp; <li> <li>}&nbsp;&nbsp; <li> <li> <li> <li>int main()&nbsp;&nbsp; <li> <li>{&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Test(1);&nbsp;&nbsp; <li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;&nbsp;&nbsp; <li> <li>}&nbsp; </li></ol> <p>可以看到生成了一个test.gcno的文件 <p><img alt="" src="http://img.my.csdn.net/uploads/201211/19/1353331062_7912.JPG"> <h4><a name="t2"></a>3.运行程序</h4> <p>./ok <p>生成了gcda文件 <p><img alt="" src="http://img.my.csdn.net/uploads/201211/19/1353331066_1471.JPG"> <h4><a name="t3"></a>4.执行lcov 生成文件</h4> <p><strong>lcov -d . -t ok -o coverage.info -b . -c</strong> <p>-d 后面带 执行程序（ok）的目录&nbsp; -o 表示生成文件<img alt="" src="http://img.my.csdn.net/uploads/201211/19/1353331068_3432.JPG"> <p>自此生成网页的条件已经完全具备 <h4><a name="t4"></a>5.生成网页端</h4> <p><strong>genhtml -o result coverage.info</strong> <p>-o 路径 + 转换信息 <p>页面信息如下：可以清楚的看到当前的代码哪一些分支没有走到。 <p><img alt="" src="http://img.my.csdn.net/uploads/201211/19/1353331076_5614.JPG"><img alt="" src="http://img.my.csdn.net/uploads/201211/19/1353331087_5404.JPG"> <h4><a name="t5"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 总结：</h4> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 代码覆盖率在一定程度上可以帮助我们很好进行单元测试，我们可以将一些测试用例进行上述检测，就可以知道测试用例是否能很好的覆盖到代码全部分支，进一步提高代码的稳定 <img src ="http://www.cppblog.com/izualzhy/aggbug/195742.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-11-27 19:46 <a href="http://www.cppblog.com/izualzhy/archive/2012/11/27/195742.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个趣味迷宫的问题(2011-&gt;2012)</title><link>http://www.cppblog.com/izualzhy/archive/2012/11/17/195292.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 17 Nov 2012 02:21:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/11/17/195292.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/195292.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/11/17/195292.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/195292.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/195292.html</trackback:ping><description><![CDATA[<p> </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a44a8214-7cc8-478d-9e1c-69ef4d4bd075" class="wlWriterEditableSmartContent">Technorati 标记: <a href="http://technorati.com/tags/%e8%bf%b7%e5%ae%ab" rel="tag">迷宫</a>,<a href="http://technorati.com/tags/bfs" rel="tag">bfs</a></div><p>&nbsp;</p> <p>原题在这里：</p> <p><a title="http://www2.stetson.edu/~efriedma/holiday/2011/index.html" href="http://www2.stetson.edu/~efriedma/holiday/2011/index.html">http://www2.stetson.edu/~efriedma/holiday/2011/index.html</a></p> <p>&nbsp;</p> <p>题目：</p> <p>有这样一个迷宫，从2011开始，不能回头，只能&#8220;朝前&#8221;走，走出迷宫的时候需要变成2012.</p> <p><a href="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/659790e41d92_12571/image_2.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/659790e41d92_12571/image_thumb.png" width="244" height="89" /></a></p> <p>例如从2011开始，有+7,/2两种选择，选择/2后，又有+7,x3/-5三种选择。</p> <p>&nbsp;</p> <p>解法：</p> <p>其实就是2011为根的子树，不断的生成下一层的节点，直到节点值为2012。</p> <p>dfs遍历肯定不现实的，bfs算是比较适合的方法了。不过有更快捷的办法，我使用的是最原始的bfs。</p> <p>运算方式有四种，位置有三种，分别用枚举表示。</p> <p>&nbsp;</p> <p>代码：</p> <p>代码写的很长了，100行以内应该是没问题的，即使是使用我的这种笨方法o(&#9583;&#9633;&#9584;)o。为了条理清楚些，就多定义了些函数。</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:09681f78-7dc0-47d3-ac3a-8e93d661826b" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#937a42">/*</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> * =====================================================================================</span></li> <li><span style="color:#937a42"> *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Filename:&nbsp;&nbsp;puzzle.cpp</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> *&nbsp;&nbsp;&nbsp;&nbsp;Description:&nbsp;&nbsp;</span></li> <li><span style="color:#937a42"> *</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Version:&nbsp;&nbsp;1.0</span></li> <li><span style="color:#937a42"> *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Created:&nbsp;&nbsp;11/16/2012 04:34:49 PM</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> *</span></li> <li><span style="color:#937a42"> *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Author:&nbsp;&nbsp;zhy (), izualzhy@163.com</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> * =====================================================================================</span></li> <li><span style="color:#937a42"> */</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;iostream&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#include</span> <span style="color:#259241">&lt;vector&gt;</span></li> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;queue&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#include</span> <span style="color:#259241">&lt;string&gt;</span></li> <li><span style="color:#400080">using</span> <span style="color:#400080">namespace</span> std<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">class</span> PuzzleGuessor {</li> <li style="background: #f3f3f3"><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">/*可选的数学运算*/</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">enum</span> Op {</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OpNone<span style="color:#2e53d1">,</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddSeven<span style="color:#2e53d1">,</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DivTwo<span style="color:#2e53d1">,</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MultiThree<span style="color:#2e53d1">,</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SubFive<span style="color:#2e53d1">,</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OpCount</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;}<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">/*位置，由位置和数学运算则可以推断下一步可选的运算方式*/</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">enum</span> Position {</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Left<span style="color:#2e53d1">,</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Middle<span style="color:#2e53d1">,</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Right</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;}<span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">/*节点，记录当前的计算结果，位置和到达位置前的运算方式 */</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">struct</span> TreeNode {</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">(</span><span style="color:#400080">double</span> d<span style="color:#2e53d1">,</span> Op op<span style="color:#2e53d1">,</span> Position position<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e53d1">:</span> data<span style="color:#2e53d1">(</span>d<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e53d1">,</span> oper<span style="color:#2e53d1">(</span>op<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e53d1">,</span> pos<span style="color:#2e53d1">(</span>position<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">double</span> data<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Op oper<span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Position pos<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector<span style="color:#2e53d1">&lt;</span>TreeNode<span style="color:#2e53d1">*&gt;</span> children<span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;}<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;PuzzleGuessor<span style="color:#2e53d1">();</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">void</span> BuildTree<span style="color:#2e53d1">();</span><span style="color:#937a42">//构造树</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">private</span><span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;queue<span style="color:#2e53d1">&lt;</span>TreeNode<span style="color:#2e53d1">*&gt;</span> q<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> root<span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;string OpTable<span style="color:#2e53d1">[</span>OpCount<span style="color:#2e53d1">];</span><span style="color:#937a42">//运算对应的字符串表，输出用</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;string result<span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">bool</span> CreateNewChildForNode<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">);</span><span style="color:#937a42">//由节点处根据下一步可进行的运算产生下一层节点</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">bool</span> CalcNextFromLeft<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">);</span><span style="color:#937a42">//在左端时可能的节点</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">bool</span> CalcNextFromMiddle<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">);</span><span style="color:#937a42">//中间位置</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">bool</span> CalcNextFromRight<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">);</span><span style="color:#937a42">//右端</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">bool</span> Achieve2012<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">bool</span> Find<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">,</span> TreeNode<span style="color:#2e53d1">*</span> objNode<span style="color:#2e53d1">);</span></li> <li>}<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>PuzzleGuessor<span style="color:#2e53d1">::</span>PuzzleGuessor<span style="color:#2e53d1">()</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;root <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span><span style="color:#259241">2011.0</span><span style="color:#2e53d1">,</span> OpNone<span style="color:#2e53d1">,</span> Left<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> child1 <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>root<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">+</span> <span style="color:#259241">7</span><span style="color:#2e53d1">,</span> AddSeven<span style="color:#2e53d1">,</span> Middle<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> child2 <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>root<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">/</span> <span style="color:#259241">2</span><span style="color:#2e53d1">,</span> DivTwo<span style="color:#2e53d1">,</span> Middle<span style="color:#2e53d1">);</span> </li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;root<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>child1<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;root<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>child2<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;q<span style="color:#2e53d1">.</span>push<span style="color:#2e53d1">(</span>child1<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;q<span style="color:#2e53d1">.</span>push<span style="color:#2e53d1">(</span>child2<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;OpTable<span style="color:#2e53d1">[</span>OpNone<span style="color:#2e53d1">]</span> <span style="color:#2e53d1">=</span> <span style="color:#259241">"none"</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;OpTable<span style="color:#2e53d1">[</span>AddSeven<span style="color:#2e53d1">]</span> <span style="color:#2e53d1">=</span> <span style="color:#259241">"+7"</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;OpTable<span style="color:#2e53d1">[</span>DivTwo<span style="color:#2e53d1">]</span> <span style="color:#2e53d1">=</span> <span style="color:#259241">"/2"</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;OpTable<span style="color:#2e53d1">[</span>MultiThree<span style="color:#2e53d1">]</span> <span style="color:#2e53d1">=</span> <span style="color:#259241">"x3"</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;OpTable<span style="color:#2e53d1">[</span>SubFive<span style="color:#2e53d1">]</span> <span style="color:#2e53d1">=</span> <span style="color:#259241">"-5"</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;BuildTree<span style="color:#2e53d1">();</span></li> <li>}</li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">void</span> PuzzleGuessor<span style="color:#2e53d1">::</span>BuildTree<span style="color:#2e53d1">()</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;result<span style="color:#2e53d1">.</span>clear<span style="color:#2e53d1">();</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">while</span> <span style="color:#2e53d1">(!</span>q<span style="color:#2e53d1">.</span>empty<span style="color:#2e53d1">())</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> node <span style="color:#2e53d1">=</span> q<span style="color:#2e53d1">.</span>front<span style="color:#2e53d1">();</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CreateNewChildForNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">for</span> <span style="color:#2e53d1">(</span> <span style="color:#400080">int</span> i<span style="color:#2e53d1">=</span><span style="color:#259241">0</span><span style="color:#2e53d1">;</span> i<span style="color:#2e53d1">&lt;</span>node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>size<span style="color:#2e53d1">();</span> <span style="color:#2e53d1">++</span>i<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">[</span>i<span style="color:#2e53d1">]-&gt;</span>data <span style="color:#2e53d1">-</span> <span style="color:#259241">2012</span> <span style="color:#2e53d1">&lt;</span> <span style="color:#259241">1e-6</span> <span style="color:#2e53d1">&amp;&amp;</span> <span style="color:#259241">2012</span> <span style="color:#2e53d1">-</span> node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">[</span>i<span style="color:#2e53d1">]-&gt;</span>data <span style="color:#2e53d1">&lt;</span> <span style="color:#259241">1e-6</span><span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"Achieve 2012!\t"</span> <span style="color:#2e53d1">&lt;&lt;</span> node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">[</span>i<span style="color:#2e53d1">]-&gt;</span>data <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Find<span style="color:#2e53d1">(</span>root<span style="color:#2e53d1">,</span> node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">[</span>i<span style="color:#2e53d1">]);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout <span style="color:#2e53d1">&lt;&lt;</span> result <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result<span style="color:#2e53d1">.</span>clear<span style="color:#2e53d1">();</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">///*如果不retunr，则会一直计算下去&nbsp;&nbsp;&nbsp;*/</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">//return;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q<span style="color:#2e53d1">.</span>push<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">[</span>i<span style="color:#2e53d1">]);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q<span style="color:#2e53d1">.</span>pop<span style="color:#2e53d1">();</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>}</li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">bool</span> PuzzleGuessor<span style="color:#2e53d1">::</span>Find<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">,</span> TreeNode<span style="color:#2e53d1">*</span> objNode<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node <span style="color:#2e53d1">==</span> NULL<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node <span style="color:#2e53d1">==</span> objNode<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result <span style="color:#2e53d1">=</span> OpTable<span style="color:#2e53d1">[</span>node<span style="color:#2e53d1">-&gt;</span>oper<span style="color:#2e53d1">];</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">true</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">for</span> <span style="color:#2e53d1">(</span> <span style="color:#400080">int</span> i<span style="color:#2e53d1">=</span><span style="color:#259241">0</span><span style="color:#2e53d1">;</span> i<span style="color:#2e53d1">&lt;</span>node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>size<span style="color:#2e53d1">();</span> <span style="color:#2e53d1">++</span>i<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span><span style="color:#2e53d1">(</span> Find<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">[</span>i<span style="color:#2e53d1">],</span> objNode<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">//cout &lt;&lt; node-&gt;data &lt;&lt; endl;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>OpNone <span style="color:#2e53d1">==</span> node<span style="color:#2e53d1">-&gt;</span>oper<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result<span style="color:#2e53d1">.</span>insert<span style="color:#2e53d1">(</span><span style="color:#259241">0</span><span style="color:#2e53d1">,</span> <span style="color:#259241">"2011"</span><span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">else</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result<span style="color:#2e53d1">.</span>insert<span style="color:#2e53d1">(</span><span style="color:#259241">0</span><span style="color:#2e53d1">,</span>OpTable<span style="color:#2e53d1">[</span>node<span style="color:#2e53d1">-&gt;</span>oper<span style="color:#2e53d1">]);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">true</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">}</li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">bool</span> PuzzleGuessor<span style="color:#2e53d1">::</span>CreateNewChildForNode<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">)</span></li> <li>{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node <span style="color:#2e53d1">==</span> NULL<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">switch</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>pos<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">case</span> Left<span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CalcNextFromLeft<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">break</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">case</span> Middle<span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CalcNextFromMiddle<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">break</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">case</span> Right<span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CalcNextFromRight<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">break</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>}</li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">bool</span> PuzzleGuessor<span style="color:#2e53d1">::</span>CalcNextFromLeft<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node <span style="color:#2e53d1">==</span> NULL<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">switch</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>oper<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">case</span> AddSeven<span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">/</span> <span style="color:#259241">2</span><span style="color:#2e53d1">,</span> DivTwo<span style="color:#2e53d1">,</span> Middle<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">break</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">case</span> DivTwo<span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">+</span> <span style="color:#259241">7</span><span style="color:#2e53d1">,</span> AddSeven<span style="color:#2e53d1">,</span> Middle<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">break</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">default</span><span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">true</span><span style="color:#2e53d1">;</span></li> <li>}</li> <li style="background: #f3f3f3"><span style="color:#400080">bool</span> PuzzleGuessor<span style="color:#2e53d1">::</span>CalcNextFromMiddle<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">)</span></li> <li>{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node <span style="color:#2e53d1">==</span> NULL<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>oper <span style="color:#2e53d1">==</span> AddSeven <span style="color:#2e53d1">||</span> node<span style="color:#2e53d1">-&gt;</span>oper <span style="color:#2e53d1">==</span> DivTwo<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">*</span> <span style="color:#259241">3</span><span style="color:#2e53d1">,</span> MultiThree<span style="color:#2e53d1">,</span> Right<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">-</span> <span style="color:#259241">5</span><span style="color:#2e53d1">,</span> SubFive<span style="color:#2e53d1">,</span> Right<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>oper <span style="color:#2e53d1">==</span> AddSeven<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">/</span> <span style="color:#259241">2</span><span style="color:#2e53d1">,</span> DivTwo<span style="color:#2e53d1">,</span> Left<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">else</span> <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>oper <span style="color:#2e53d1">==</span> DivTwo<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">+</span> <span style="color:#259241">7</span><span style="color:#2e53d1">,</span> AddSeven<span style="color:#2e53d1">,</span> Left<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">else</span> <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>oper <span style="color:#2e53d1">==</span> MultiThree <span style="color:#2e53d1">||</span> node<span style="color:#2e53d1">-&gt;</span>oper <span style="color:#2e53d1">==</span> SubFive<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">+</span> <span style="color:#259241">7</span><span style="color:#2e53d1">,</span> AddSeven<span style="color:#2e53d1">,</span> Left<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">/</span> <span style="color:#259241">2</span><span style="color:#2e53d1">,</span> DivTwo <span style="color:#2e53d1">,</span>Left<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>oper <span style="color:#2e53d1">==</span> MultiThree<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">-</span> <span style="color:#259241">5</span><span style="color:#2e53d1">,</span> DivTwo<span style="color:#2e53d1">,</span> Right<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">else</span> <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>oper <span style="color:#2e53d1">==</span> SubFive<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">*</span> <span style="color:#259241">3</span><span style="color:#2e53d1">,</span> MultiThree<span style="color:#2e53d1">,</span> Right<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">else</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">true</span><span style="color:#2e53d1">;</span></li> <li>}</li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">bool</span> PuzzleGuessor<span style="color:#2e53d1">::</span>CalcNextFromRight<span style="color:#2e53d1">(</span>TreeNode<span style="color:#2e53d1">*</span> node<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>node <span style="color:#2e53d1">==</span> NULL<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">switch</span> <span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>oper<span style="color:#2e53d1">)</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">case</span> MultiThree<span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">-</span> <span style="color:#259241">5</span><span style="color:#2e53d1">,</span> SubFive<span style="color:#2e53d1">,</span> Middle<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">break</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">case</span> SubFive<span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode<span style="color:#2e53d1">*</span> newNode <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> TreeNode<span style="color:#2e53d1">(</span>node<span style="color:#2e53d1">-&gt;</span>data <span style="color:#2e53d1">*</span> <span style="color:#259241">3</span><span style="color:#2e53d1">,</span> MultiThree<span style="color:#2e53d1">,</span> Middle<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node<span style="color:#2e53d1">-&gt;</span>children<span style="color:#2e53d1">.</span>push_back<span style="color:#2e53d1">(</span>newNode<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">break</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">default</span><span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">false</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#400080">true</span><span style="color:#2e53d1">;</span></li> <li>}</li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">int</span> main<span style="color:#2e53d1">()</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;PuzzleGuessor guesser<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>}</li> </ol> </div> </div> </div> <p>部分输出：</p> <p>Achieve 2012!&nbsp;&nbsp;&nbsp; 2012<br />2011+7/2+7/2+7x3-5/2+7x3-5/2+7x3-5x3-5/2+7/2+7/2+7/2+7x3-5+7<br />Achieve 2012!&nbsp;&nbsp;&nbsp; 2012<br />2011+7/2+7/2+7x3-5/2+7x3-5/2+7-5x3+7/2+7/2+7/2+7/2x3-5x3-5+7<br />Achieve 2012!&nbsp;&nbsp;&nbsp; 2012<br />2011+7/2+7/2+7x3-5x3-5+7/2+7/2+7/2+7/2x3-5/2+7x3-5x3-5+7/2+7<br />Achieve 2012!&nbsp;&nbsp;&nbsp; 2012<br />2011+7/2+7/2+7x3-5x3-5+7/2+7/2+7/2+7/2x3-5/2+7-5x3/2+7x3-5+7<br />Achieve 2012!&nbsp;&nbsp;&nbsp; 2012<br />2011+7/2+7/2+7-5x3/2+7x3-5+7/2+7/2+7/2x3-5/2+7x3-5x3-5+7/2+7<br />Achieve 2012!&nbsp;&nbsp;&nbsp; 2012<br />2011+7/2+7/2+7-5x3/2+7x3-5+7/2+7/2+7/2x3-5/2+7-5x3/2+7x3-5+7<br />Achieve 2012!&nbsp;&nbsp;&nbsp; 2012<br />2011+7/2+7/2+7-5x3/2+7/2+7x3-5/2+7-5x3+7/2+7/2x3-5x3-5+7/2+7<br />Achieve 2012!&nbsp;&nbsp;&nbsp; 2012<br />2011+7/2+7/2+7-5x3/2+7/2+7x3-5/2+7-5x3+7/2+7/2-5x3/2+7x3-5+7<br />Achieve 2012!&nbsp;&nbsp;&nbsp; 2012<br />2011+7/2+7/2+7-5x3/2+7/2+7-5x3/2+7x3-5/2+7x3-5+7/2+7/2x3-5+7</p><img src ="http://www.cppblog.com/izualzhy/aggbug/195292.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-11-17 10:21 <a href="http://www.cppblog.com/izualzhy/archive/2012/11/17/195292.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]\r与\n的区别</title><link>http://www.cppblog.com/izualzhy/archive/2012/11/05/194560.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Mon, 05 Nov 2012 08:18:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/11/05/194560.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/194560.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/11/05/194560.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/194560.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/194560.html</trackback:ping><description><![CDATA[<p>\r ： return 到当前行的最左边。 <p>\n： newline 向下移动一行，并不移动左右。 <p>Linux中\n表示回车+换行； <p>Windows中\r\n表示回车+换行。 <p>Mac中\r表示回车+换行。 <h4><font color="#0000ff" size="5">历史：</font></h4> <p>回车”（Carriage Return）和“换行”（Line Feed）这两个概念的来历和区别。<br> 在计算机还没有出现之 前，有一种叫做电传打字机（Teletype Model 33，Linux/Unix下的tty概念也来自于此）的玩意，每秒钟可以打10个字符。但是它有一个问题，就是打完一行换行的时候，要用去0.2秒，正 好可以打两个字符。要是在这0.2秒里面，又有新的字符传过来，那么这个字符将丢失。<br>于是，研制人员想了个办法解决这个问题，就是在每行后面加两个表示结束的字符。一个叫做“回车(return)”，告诉打字机把打印头定位在左边界；另一个叫做“换行(newline)”，告诉打字机把纸向下移一行。这就是“换行”和“回车”的来历，从它们的英语名字上也可以看出一二。</p><img src ="http://www.cppblog.com/izualzhy/aggbug/194560.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-11-05 16:18 <a href="http://www.cppblog.com/izualzhy/archive/2012/11/05/194560.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>派生类遇到基类的同名虚函数</title><link>http://www.cppblog.com/izualzhy/archive/2012/09/20/191423.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Thu, 20 Sep 2012 12:16:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/09/20/191423.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/191423.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/09/20/191423.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/191423.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/191423.html</trackback:ping><description><![CDATA[<p>举个例子：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b9b592a4-eaed-498b-a33a-30aa6e367365" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;iostream&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">using</span> <span style="color:#400080">namespace</span> std<span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">class</span> A {</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">virtual</span> <span style="color:#400080">void</span> f<span style="color:#2e53d1">()</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"A::f()"</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">virtual</span> <span style="color:#400080">void</span> f<span style="color:#2e53d1">(</span><span style="color:#400080">int</span><span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"A::f(int)"</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>}<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">class</span> B <span style="color:#2e53d1">:</span> <span style="color:#400080">public</span> A {</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">virtual</span> <span style="color:#400080">void</span> f<span style="color:#2e53d1">(</span><span style="color:#400080">int</span><span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"B::f(int)"</span> <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</li> <li>}<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">int</span> main<span style="color:#2e53d1">()</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;B<span style="color:#2e53d1">*</span> pb <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> B<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;pb<span style="color:#2e53d1">-&gt;</span>f<span style="color:#2e53d1">();</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;pb<span style="color:#2e53d1">-&gt;</span>f<span style="color:#2e53d1">(</span><span style="color:#259241">1</span><span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div> <p>编译的结果：</p> <p><font color="#ff0000">test.cpp: In function &#8216;int main()&#8217;:<br />test.cpp:28:11: error: no matching function for call to &#8216;B::f()&#8217;<br />test.cpp:28:11: note: candidate is:<br />test.cpp:19:22: note: virtual void B::f(int)<br />test.cpp:19:22: note:&nbsp;&nbsp; candidate expects 1 argument, 0 provided</font></p> <p>是virtual引起的么，修改为非虚函数后，编译还是报错。</p> <p> </p><hr /> 这里其实是隐藏的概念，B重写了f，并不是重载，而是隐藏，去掉virtual后，并不是覆盖，还是隐藏。。。。<p>&nbsp;</p> <p>在《高质量c++编程指南》里提到了：</p> <p>8.2.2 令人迷惑的隐藏规则<br />&nbsp;&nbsp;&nbsp; 本来仅仅区别重载与覆盖并不算困难，但是C++的隐藏规则使问题复杂性陡然增加。这里&#8220;隐藏&#8221;是指派生类的函数屏蔽了与其同名的基类函数，规则如下：<br />（1）如果派生类的函数与基类的函数同名，但是参数不同。此时，不论有无virtual关键字，基类的函数将被隐藏（<font color="#ff0000">注意别与重载混淆</font>）。<br />（2）如果派生类的函数与基类的函数同名，并且参数也相同，但是基类函数没有virtual关键字。此时，基类的函数被隐藏（<font color="#ff0000">注意别与覆盖混淆</font>）。 </p><p>示例程序8-2-2（a）中：<br />（1）函数Derived::f(float)覆盖了Base::f(float)。<br />（2）函数Derived::g(int)隐藏了Base::g(float)，而不是重载。<br />（3）函数Derived::h(float)隐藏了Base::h(float)，而不是覆盖。</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:79038086-a0bc-4750-9cc6-6a1ec76ed252" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;iostream.h&gt;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">class</span> Base</li> <li style="background: #f3f3f3">{</li> <li><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">virtual</span> <span style="color:#400080">void</span> f<span style="color:#2e53d1">(</span><span style="color:#400080">float</span> x<span style="color:#2e53d1">){</span> cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"Base::f(float) "</span> <span style="color:#2e53d1">&lt;&lt;</span> x <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span> }</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">void</span> g<span style="color:#2e53d1">(</span><span style="color:#400080">float</span> x<span style="color:#2e53d1">){</span> cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"Base::g(float) "</span> <span style="color:#2e53d1">&lt;&lt;</span> x <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span> }</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">void</span> h<span style="color:#2e53d1">(</span><span style="color:#400080">float</span> x<span style="color:#2e53d1">){</span> cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"Base::h(float) "</span> <span style="color:#2e53d1">&lt;&lt;</span> x <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span> }</li> <li>}<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">class</span> Derived <span style="color:#2e53d1">:</span> <span style="color:#400080">public</span> Base</li> <li style="background: #f3f3f3">{</li> <li><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">virtual</span> <span style="color:#400080">void</span> f<span style="color:#2e53d1">(</span><span style="color:#400080">float</span> x<span style="color:#2e53d1">){</span> cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"Derived::f(float) "</span> <span style="color:#2e53d1">&lt;&lt;</span> x <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span> }</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">void</span> g<span style="color:#2e53d1">(</span><span style="color:#400080">int</span> x<span style="color:#2e53d1">){</span> cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"Derived::g(int) "</span> <span style="color:#2e53d1">&lt;&lt;</span> x <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span> }</li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">void</span> h<span style="color:#2e53d1">(</span><span style="color:#400080">float</span> x<span style="color:#2e53d1">){</span> cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">"Derived::h(float) "</span> <span style="color:#2e53d1">&lt;&lt;</span> x <span style="color:#2e53d1">&lt;&lt;</span> endl<span style="color:#2e53d1">;</span> }</li> <li>&nbsp;</li> <li style="background: #f3f3f3">}<span style="color:#2e53d1">;</span></li> <li><span style="color:#937a42">//示例8-2-2（a）成员函数的重载、覆盖和隐藏</span></li> </ol> </div> </div> </div> <p>据作者考察，很多C++程序员没有意识到有&#8220;隐藏&#8221;这回事。由于认识不够深刻，&#8220;隐藏&#8221;的发生可谓神出鬼没，常常产生令人迷惑的结果。</p> <p>示例8-2-2（b）中，bp和dp指向同一地址，按理说运行结果应该是相同的，可事实并非这样。<br /> </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e52b676f-d87a-4d2d-a05d-31b95eed8c41" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">void</span> main<span style="color:#2e53d1">(</span><span style="color:#400080">void</span><span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;Derived&nbsp;&nbsp;d<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;Base <span style="color:#2e53d1">*</span>pb <span style="color:#2e53d1">=</span> <span style="color:#2e53d1">&amp;</span>d<span style="color:#2e53d1">;</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;Derived <span style="color:#2e53d1">*</span>pd <span style="color:#2e53d1">=</span> <span style="color:#2e53d1">&amp;</span>d<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">// Good : behavior depends solely on type of the object</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;pb<span style="color:#2e53d1">-&gt;</span>f<span style="color:#2e53d1">(</span><span style="color:#259241">3.14f</span><span style="color:#2e53d1">);</span> <span style="color:#937a42">// Derived::f(float) 3.14</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;pd<span style="color:#2e53d1">-&gt;</span>f<span style="color:#2e53d1">(</span><span style="color:#259241">3.14f</span><span style="color:#2e53d1">);</span> <span style="color:#937a42">// Derived::f(float) 3.14</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">// Bad : behavior depends on type of the pointer</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;pb<span style="color:#2e53d1">-&gt;</span>g<span style="color:#2e53d1">(</span><span style="color:#259241">3.14f</span><span style="color:#2e53d1">);</span> <span style="color:#937a42">// Base::g(float) 3.14</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;pd<span style="color:#2e53d1">-&gt;</span>g<span style="color:#2e53d1">(</span><span style="color:#259241">3.14f</span><span style="color:#2e53d1">);</span> <span style="color:#937a42">// Derived::g(int) 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(surprise!)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">// Bad : behavior depends on type of the pointer</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;pb<span style="color:#2e53d1">-&gt;</span>h<span style="color:#2e53d1">(</span><span style="color:#259241">3.14f</span><span style="color:#2e53d1">);</span> <span style="color:#937a42">// Base::h(float) 3.14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(surprise!)</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;pd<span style="color:#2e53d1">-&gt;</span>h<span style="color:#2e53d1">(</span><span style="color:#259241">3.14f</span><span style="color:#2e53d1">);</span> <span style="color:#937a42">// Derived::h(float) 3.14</span></li> <li>}</li> <li style="background: #f3f3f3"><span style="color:#937a42">//示例8-2-2（b） 重载、覆盖和隐藏的比较</span></li> </ol> </div> </div> </div> <p>8.2.3 摆脱隐藏<br />&nbsp;&nbsp;&nbsp; 隐藏规则引起了不少麻烦。示例8-2-3程序中，语句pd-&gt;f(10)的本意是想调用函数Base::f(int)，但是Base::f(int)不幸被Derived::f(char *)隐藏了。由于数字10不能被隐式地转化为字符串，所以在编译时出错。<br /> </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2f7200d2-cc68-45d9-a62b-8aa2abb662f7" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">class</span> Base</li> <li style="background: #f3f3f3">{</li> <li><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">void</span> f<span style="color:#2e53d1">(</span><span style="color:#400080">int</span> x<span style="color:#2e53d1">);</span></li> <li>}<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">class</span> Derived <span style="color:#2e53d1">:</span> <span style="color:#400080">public</span> Base</li> <li>{</li> <li style="background: #f3f3f3"><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">void</span> f<span style="color:#2e53d1">(</span><span style="color:#400080">char</span> <span style="color:#2e53d1">*</span>str<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">}<span style="color:#2e53d1">;</span></li> <li><span style="color:#400080">void</span> Test<span style="color:#2e53d1">(</span><span style="color:#400080">void</span><span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;Derived <span style="color:#2e53d1">*</span>pd <span style="color:#2e53d1">=</span> <span style="color:#400080">new</span> Derived<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;pd<span style="color:#2e53d1">-&gt;</span>f<span style="color:#2e53d1">(</span><span style="color:#259241">10</span><span style="color:#2e53d1">);</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#937a42">// error</span></li> <li>}</li> <li style="background: #f3f3f3"><span style="color:#937a42">//示例8-2-3 由于隐藏而导致错误</span></li> </ol> </div> </div> </div><br />&nbsp;&nbsp;&nbsp; 从示例8-2-3看来，隐藏规则似乎很愚蠢。但是隐藏规则至少有两个存在的理由：<br />1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 写语句pd-&gt;f(10)的人可能真的想调用Derived::f(char *)函数，只是他误将参数写错了。有了隐藏规则，编译器就可以明确指出错误，这未必不是好事。否则，编译器会静悄悄地将错就错，程序员将很难发现这个错误，流下祸根。<br />2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 假如类Derived有多个基类（多重继承），有时搞不清楚哪些基类定义了函数f。如果没有隐藏规则，那么pd-&gt;f(10)可能会调用一个出乎意料的基类函数f。尽管隐藏规则看起来不怎么有道理，但它的确能消灭这些意外。<br />示例8-2-3中，如果语句pd-&gt;f(10)一定要调用函数Base::f(int)，那么将类Derived修改为如下即可。<br /> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8056e103-a5c2-4810-bf04-510d0515b506" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">class</span> Derived <span style="color:#2e53d1">:</span> <span style="color:#400080">public</span> Base</li> <li style="background: #f3f3f3">{</li> <li><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">void</span> f<span style="color:#2e53d1">(</span><span style="color:#400080">char</span> <span style="color:#2e53d1">*</span>str<span style="color:#2e53d1">);</span></li> <li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#400080">void</span> f<span style="color:#2e53d1">(</span><span style="color:#400080">int</span> x<span style="color:#2e53d1">)</span> { Base<span style="color:#2e53d1">::</span>f<span style="color:#2e53d1">(</span>x<span style="color:#2e53d1">);</span> }</li> <li style="background: #f3f3f3">}<span style="color:#2e53d1">;</span></li> </ol> </div> </div> </div>  <p>参考：</p> <p>《高质量C++/C编程指南》</p><img src ="http://www.cppblog.com/izualzhy/aggbug/191423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-09-20 20:16 <a href="http://www.cppblog.com/izualzhy/archive/2012/09/20/191423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]C++箴言:绝不在构造或析构期调用虚函数</title><link>http://www.cppblog.com/izualzhy/archive/2012/09/17/190998.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Mon, 17 Sep 2012 10:48:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/09/17/190998.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/190998.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/09/17/190998.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/190998.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/190998.html</trackback:ping><description><![CDATA[<p>你不应该在构造或析构期间调用虚函数，因为这样的调用不会如你想象那样工作，而且它们做的事情保证会让你很郁闷。如果你转为 Java 或 C# 程序员，也请你密切关注本文，因为在 C++ 急转弯的地方，那些语言也紧急转了一个弯。</p> <p> <hr> <br>　　假设你有一套模拟股票处理的类层次结构，例如，购入流程，出售流程等。对这样的处理来说可以核查是非常重要的，所以随时会创建一个 Transaction 对象，将这个创建记录在核查日志中是一个适当的要求。下面是一个看起来似乎合理的解决问题的方法：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:17ed68cb-cb0f-4b2f-9c50-e7c01a97dcf7" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">class</span> Transaction { <span style="color:#937a42">// base class for all</span></li> <li style="background: #f3f3f3">　<span style="color:#400080">public</span><span style="color:#2e53d1">:</span> <span style="color:#937a42">// transactions</span></li> <li>　　Transaction<span style="color:#2e53d1">();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>　　<span style="color:#400080">virtual</span> <span style="color:#400080">void</span> logTransaction<span style="color:#2e53d1">()</span> <span style="color:#400080">const</span> <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span> <span style="color:#937a42">// make type-dependent</span></li> <li style="background: #f3f3f3">　　<span style="color:#937a42">// log entry</span></li> <li>　　<span style="color:#2e53d1">...</span></li> <li style="background: #f3f3f3">}<span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">Transaction<span style="color:#2e53d1">::</span>Transaction<span style="color:#2e53d1">()</span> <span style="color:#937a42">// implementation of</span></li> <li>{ </li> <li style="background: #f3f3f3">　<span style="color:#937a42">// base class ctor</span></li> <li>　<span style="color:#2e53d1">...</span></li> <li style="background: #f3f3f3">　logTransaction<span style="color:#2e53d1">();</span> <span style="color:#937a42">// as final action, log this</span></li> <li>} <span style="color:#937a42">// transaction</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">class</span> BuyTransaction<span style="color:#2e53d1">:</span> <span style="color:#400080">public</span> Transaction { </li> <li style="background: #f3f3f3">　<span style="color:#937a42">// derived class</span></li> <li>　<span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">　　<span style="color:#400080">virtual</span> <span style="color:#400080">void</span> logTransaction<span style="color:#2e53d1">()</span> <span style="color:#400080">const</span><span style="color:#2e53d1">;</span> <span style="color:#937a42">// how to log trans-</span></li> <li>　　<span style="color:#937a42">// actions of this type</span></li> <li style="background: #f3f3f3">　　<span style="color:#2e53d1">...</span></li> <li>}<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">class</span> SellTransaction<span style="color:#2e53d1">:</span> <span style="color:#400080">public</span> Transaction { </li> <li style="background: #f3f3f3"><span style="color:#937a42">// derived class</span></li> <li><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">　<span style="color:#400080">virtual</span> <span style="color:#400080">void</span> logTransaction<span style="color:#2e53d1">()</span> <span style="color:#400080">const</span><span style="color:#2e53d1">;</span> <span style="color:#937a42">// how to log trans-</span></li> <li>　<span style="color:#937a42">// actions of this type</span></li> <li style="background: #f3f3f3"><span style="color:#2e53d1">...</span></li> <li>}<span style="color:#2e53d1">;</span></li> </ol> </div> </div> </div> <p>考虑执行这行代码时会发生什么：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:77f63ef3-a816-4afe-9820-69984036dd43" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>BuyTransaction b<span style="color:#2e53d1">;</span></li> </ol> </div> </div> </div> <p>很明显 BuyTransaction 的构造函数会被调用，但是首先，Transaction 的构造函数必须先被调用，派生类对象中的基类部分先于派生类部分被构造。<strong>Transaction 的构造函数的最后一行调用虚函数 logTransaction，但是结果会让你大吃一惊，被调用的 logTransaction 版本是在 Transaction 中的那个，而不是 BuyTransaction 中的——即使被创建的对象类型是 BuyTransaction。基类构造期间，虚函数从来不会向下匹配（go down）到派生类。取而代之的是，那个对象的行为就好像它的类型是基类。非正式地讲，基类构造期间，虚函数禁止。</strong> <font color="#ff0000">这个表面上看起来匪夷所思的行为存在一个很好的理由。因为基类的构造函数在派生类构造函数之前执行，当基类构造函数运行时，派生类数据成员还没有被初始化。如果基类构造期间调用的虚函数向下匹配（go down）到派生类，派生类的函数理所当然会涉及到本地数据成员，但是那些数据成员还没有被初始化。这就会为未定义行为和悔之晚矣的调试噩梦开了一张通行证。调用涉及到一个对象还没有被初始化的部分自然是危险的，所以 C++ 告诉你此路不通。<br></font>　　在实际上还有比这更多的更深层次的原理。在派生类对象的基类构造期间，对象的类型是那个基类的。不仅虚函数会解析到基类，而且语言中用到运行时类型信息（runtime type information）的配件（例如，dynamic_cast和 typeid），也会将对象视为基类类型。在我们的例子中，当 Transaction 构造函数运行初始化 BuyTransaction 对象的基类部分时，对象的类型是 Transaction。C++ 的每一个配件将以如下眼光来看待它，并对它产生这样的感觉：对象的 BuyTransaction 特有的部分还没有被初始化，所以安全的对待它们的方法就是视若无睹。在派生类构造函数运行之前，一个对象不会成为一个派生类对象。<br>　　同样的原因也适用于析构过程。一旦派生类析构函数运行，这个对象的派生类数据成员就被视为未定义的值，所以 C++ 就将它们视为不再存在。在进入基类析构函数时，对象就成为一个基类对象，C++ 的所有配件——虚函数，dynamic_casts 等——都如此看待它。<br>　　在上面的示例代码中，Transaction 的构造函数直接调用了虚函数，对本 Item 的规则的违例是显而易见的。这一违例是如此显见，以致一些编译器会给出警告。（其它的则不会）甚至除了这样的警告之外，这一问题几乎肯定会在运行之前暴露出来，因为 logTransaction 函数在 Transaction 中是一个纯虚函数。除非它被定义（看似不可能，但确实可能），否则程序将无法连接：连接程序无法找到 Transaction::logTransaction 的必需的实现。<br>　　在构造函数和析构函数中调用虚函数的问题并不总是如此容易被察觉。如果 Transaction 有多个构造函数，每一个都必须完成一些相同的工作，好的软件工程为避免代码重复，会将共用的初始化代码，包括对 logTransaction 的调用，放入一个私有的非虚的初始化函数，叫做 init：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cfa77cee-6372-44e0-9a3c-71de05894331" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">class</span> Transaction {</li> <li style="background: #f3f3f3"><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li>　Transaction<span style="color:#2e53d1">()</span></li> <li style="background: #f3f3f3">　{ init<span style="color:#2e53d1">();</span> } <span style="color:#937a42">// call to non-virtual...</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">　<span style="color:#400080">virtual</span> <span style="color:#400080">void</span> logTransaction<span style="color:#2e53d1">()</span> <span style="color:#400080">const</span> <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>　<span style="color:#2e53d1">...</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">private</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">　<span style="color:#400080">void</span> init<span style="color:#2e53d1">()</span></li> <li>　{</li> <li style="background: #f3f3f3">　　<span style="color:#2e53d1">...</span></li> <li>　　logTransaction<span style="color:#2e53d1">();</span> <span style="color:#937a42">// ...that calls a virtual!</span></li> <li style="background: #f3f3f3">　}</li> <li>}<span style="color:#2e53d1">;</span></li> </ol> </div> </div> </div> <p>这个代码在概念上和早先那个版本相同，但是它更阴险，因为它很具代表性地会躲过编译器和连接程序的抱怨。在这种情况下，因为 logTransaction 在 Transaction 中是纯虚函数，大多数运行时系统在纯虚函数被调用时，程序会异常中止（典型的结果就是给出一条信息）。然而，如果 logTransaction 是一个“常规的”虚函数（也就是说，非纯的虚函数），而且在 Transaction 中有其实现，那个版本被调用，程序会继续一路小跑，让你想象不出为什么派生类对象创建的时候会调用 logTransaction 的错误版本。<font color="#ff0000">避免这个问题的唯一办法就是确保在你的构造函数和析构函数中，决不在你创建或销毁的对象上调用虚函数，构造函数和析构函数所调用的函数也要服从同样的约束。<br></font>　　但是，如何保证在任何时间 Transaction 层次结构中的对象被创建时，都能调用 logTransaction 的正确版本呢？显然，在 Transaction 的构造函数中在这个对象上调用虚函数的做法是错误的。<br>　　有不同的方法来解决这个问题。其中之一是将 Transaction 中的 logTransaction 转变为一个非虚函数，这就需要派生类的构造函数将必要的日志信息传递给 Transaction 的构造函数。那个函数就可以安全地调用非虚的 logTransaction。如下：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7cd0d827-f3d4-48f4-a881-d6570ef0207a" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">class</span> Transaction {</li> <li style="background: #f3f3f3"><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li>　<span style="color:#400080">explicit</span> Transaction<span style="color:#2e53d1">(</span><span style="color:#400080">const</span> std<span style="color:#2e53d1">::</span>string<span style="color:#2e53d1">&amp;</span> logInfo<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>　<span style="color:#400080">void</span> logTransaction<span style="color:#2e53d1">(</span><span style="color:#400080">const</span> std<span style="color:#2e53d1">::</span>string<span style="color:#2e53d1">&amp;</span> logInfo<span style="color:#2e53d1">)</span> <span style="color:#400080">const</span><span style="color:#2e53d1">;</span> <span style="color:#937a42">// now a non-</span></li> <li style="background: #f3f3f3">　<span style="color:#937a42">// virtual func</span></li> <li>　<span style="color:#2e53d1">...</span></li> <li style="background: #f3f3f3">}<span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">Transaction<span style="color:#2e53d1">::</span>Transaction<span style="color:#2e53d1">(</span><span style="color:#400080">const</span> std<span style="color:#2e53d1">::</span>string<span style="color:#2e53d1">&amp;</span> logInfo<span style="color:#2e53d1">)</span></li> <li>{</li> <li style="background: #f3f3f3">　<span style="color:#2e53d1">...</span></li> <li>　logTransaction<span style="color:#2e53d1">(</span>logInfo<span style="color:#2e53d1">);</span> <span style="color:#937a42">// now a non-</span></li> <li style="background: #f3f3f3">} <span style="color:#937a42">// virtual call</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">class</span> BuyTransaction<span style="color:#2e53d1">:</span> <span style="color:#400080">public</span> Transaction {</li> <li><span style="color:#400080">public</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">　BuyTransaction<span style="color:#2e53d1">(</span> parameters <span style="color:#2e53d1">)</span></li> <li>　<span style="color:#2e53d1">:</span> Transaction<span style="color:#2e53d1">(</span>createLogString<span style="color:#2e53d1">(</span> parameters <span style="color:#2e53d1">))</span> <span style="color:#937a42">// pass log info</span></li> <li style="background: #f3f3f3">　{ <span style="color:#2e53d1">...</span> } <span style="color:#937a42">// to base class</span></li> <li>　<span style="color:#2e53d1">...</span> <span style="color:#937a42">// constructor</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">private</span><span style="color:#2e53d1">:</span></li> <li style="background: #f3f3f3">　<span style="color:#400080">static</span> std<span style="color:#2e53d1">::</span>string createLogString<span style="color:#2e53d1">(</span> parameters <span style="color:#2e53d1">);</span></li> <li>}<span style="color:#2e53d1">;</span></li> </ol> </div> </div> </div> <p>换句话说，因为在基类的构造过程中你不能使用虚函数，就改为由派生类传递必要的构造信息给基类的构造函数作为补偿。 在此例中，注意 BuyTransaction 中那个（私有的）static 函数 createLogString 的使用。使用一个辅助函数创建一个值传递给基类的构造函数，通常比通过在成员初始化列表给基类它所需要的东西更加便利（也更加具有可读性）。将那个函数做成 static，就不会有偶然涉及到一个初生的 BuyTransaction 对象的仍未初始化的数据成员的危险。这很重要，因为实际上那些数据成员在一个未定义状态，这就是为什么在基类构造和析构期间虚函数不能首先匹配到派生类的原因。<br>　　Things to Remember<br>　　·在构造和析构期间不要调用虚函数，因为这样的调用不会匹配到当前执行的构造函数或析构函数所属的类的更深的派生层次。  <img src ="http://www.cppblog.com/izualzhy/aggbug/190998.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-09-17 18:48 <a href="http://www.cppblog.com/izualzhy/archive/2012/09/17/190998.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>指针数组与数组的指针</title><link>http://www.cppblog.com/izualzhy/archive/2012/09/15/190784.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 15 Sep 2012 09:54:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/09/15/190784.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/190784.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/09/15/190784.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/190784.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/190784.html</trackback:ping><description><![CDATA[<p>虽然之前特意总结了下题目的内容，不过一不小心还是掉进了陷阱里o(╯□╰)o</p> <p>问题起源于这样一个小题目：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:040415f4-1ea8-48eb-8efe-90a4ef52a4d1" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;stdio.h&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#include</span> <span style="color:#259241">&lt;stdlib.h&gt;</span></li> <li><span style="color:#400080">int</span> main<span style="color:#2e53d1">(</span><span style="color:#400080">void</span><span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#400080">int</span> <span style="color:#2e53d1">(*</span>ptr<span style="color:#2e53d1">)[</span><span style="color:#259241">5</span><span style="color:#2e53d1">]</span> <span style="color:#2e53d1">=</span> <span style="color:#2e53d1">(</span><span style="color:#400080">int</span><span style="color:#2e53d1">(*)[</span><span style="color:#259241">5</span><span style="color:#2e53d1">])</span> <span style="color:#259241">100</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;%d&#92;n&quot;</span><span style="color:#2e53d1">,</span> <span style="color:#2e53d1">(</span><span style="color:#400080">int</span><span style="color:#2e53d1">)(&amp;((*</span>ptr<span style="color:#2e53d1">)[</span><span style="color:#259241">1</span><span style="color:#2e53d1">])));</span></li> <li>    printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;%d&#92;n&quot;</span><span style="color:#2e53d1">,</span> <span style="color:#2e53d1">(</span><span style="color:#400080">int</span><span style="color:#2e53d1">)(&amp;((*</span>ptr<span style="color:#2e53d1">[</span><span style="color:#259241">1</span><span style="color:#2e53d1">]))));</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div> <p>&nbsp;</p> <p>L5，定了了ptr值为100，ptr是一个数组的指针，数组大小为5.</p> <p>L6，(*ptr)为int数组的首地址，即100，(*ptr)[1]=ptr+sizeof(int)*1</p> <p>L7, *ptr[1],ptr地址为100，指向了一个大小为5的数组，20的字节，根据数组+1的定义，ptr+1就意味着要从ptr的位置前进20个字节，即ptr + sizeof(5*sizeof(int))*1</p><img src ="http://www.cppblog.com/izualzhy/aggbug/190784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-09-15 17:54 <a href="http://www.cppblog.com/izualzhy/archive/2012/09/15/190784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Knuth-Morris-Pratt algorithm</title><link>http://www.cppblog.com/izualzhy/archive/2012/09/15/190755.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 15 Sep 2012 06:07:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/09/15/190755.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/190755.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/09/15/190755.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/190755.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/190755.html</trackback:ping><description><![CDATA[<p>看到实在是觉得写得不错，就就转过来了。</p> <p>原文地址：</p> <p><a href="http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm">http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm</a></p> <p>以下为原文内容：</p> <h5><a name="section1">Idea</a></h5> <p>After a shift of the pattern, the naive algorithm has forgotten all information about previously matched symbols. So it is possible that it re-compares a text symbol with different pattern symbols again and again. This leads to its worst case complexity of Θ(<var>nm</var>) (<var>n</var>: length of the text, <var>m</var>: length of the pattern). <p>The algorithm of Knuth, Morris and Pratt <a>[KMP 77]</a> makes use of the information gained by previous symbol comparisons. It never re-compares a text symbol that has matched a pattern symbol. As a result, the complexity of the searching phase of the Knuth-Morris-Pratt algorithm is in <var>O</var>(<var>n</var>). <p>However, a preprocessing of the pattern is necessary in order to analyze its structure. The preprocessing phase has a complexity of<var>O</var>(<var>m</var>). Since <var>m</var><img alt="&lt;=" src="http://www.inf.fh-flensburg.de/lang/symbols/le.gif"><var>n</var>, the overall complexity of the Knuth-Morris-Pratt algorithm is in <var>O</var>(<var>n</var>). <h5><a name="section2">Basic definitions</a></h5> <p>Definition:&nbsp; Let <var>A</var> be an alphabet and&nbsp; <var>x</var> = <var>x</var><sub>0</sub> ... <var>x</var><sub><var>k</var>-1,</sub> <var>k</var> <img alt="element" src="http://www.inf.fh-flensburg.de/lang/symbols/elem.gif"> <img alt="natural numbers" src="http://www.inf.fh-flensburg.de/lang/symbols/n.gif">&nbsp;&nbsp; a string of length <var>k</var> over <var>A</var>. <p>A prefix of <var>x</var> is a substring <var>u</var> with <p><var>u</var>&nbsp; =&nbsp; <var>x</var><sub>0</sub> ... <var>x</var><sub><var>b</var>-1</sub>&nbsp;&nbsp; where&nbsp; <var>b</var> <img alt="element" src="http://www.inf.fh-flensburg.de/lang/symbols/elem.gif"> {0, ..., <var>k</var>} <p>i.e. <var>x</var> starts with <var>u</var>. <p>A suffix of <var>x</var> is a substring <var>u</var> with <p><var>u</var>&nbsp; =&nbsp; <var>x</var><sub><var>k</var>-<var>b</var></sub> ... <var>x</var><sub><var>k</var>-1</sub>&nbsp;&nbsp; where&nbsp; <var>b</var> <img alt="element" src="http://www.inf.fh-flensburg.de/lang/symbols/elem.gif"> {0, ..., <var>k</var>} <p>i.e. <var>x</var> ends with <var>u</var>. <p>A prefix <var>u</var> of <var>x</var> or a suffix <var>u</var> of <var>x</var> is called a proper prefix or suffix, respectively, if <var>u</var><img alt="not equal" src="http://www.inf.fh-flensburg.de/lang/symbols/ne.gif"><var>x</var>, i.e. if its length <var>b</var> is less than <var>k</var>. <p>A border of <var>x</var> is a substring <var>r</var> with <p><var>r</var>&nbsp; =&nbsp; <var>x</var><sub>0</sub> ... <var>x</var><sub><var>b</var>-1</sub>&nbsp; and&nbsp; <var>r</var>&nbsp; =&nbsp; <var>x</var><sub><var>k</var>-<var>b</var></sub> ... <var>x</var><sub><var>k</var>-1</sub>&nbsp;&nbsp; where&nbsp; <var>b</var> <img alt="element" src="http://www.inf.fh-flensburg.de/lang/symbols/elem.gif"> {0, ..., <var>k</var>-1} <p>A border of <var>x</var> is a substring that is both proper prefix and proper suffix of <var>x</var>. We call its length <var>b</var> the width of the border. <p>Example:&nbsp; Let <var>x</var> = abacab. The proper prefixes of <var>x</var> are <p>ε, a, ab, aba, abac, abaca <p>The proper suffixes of <var>x</var> are <p>ε, b, ab, cab, acab, bacab <p>The borders of <var>x</var> are <p>ε, ab <p>The border ε has width 0, the border ab has width 2. <p>The empty string ε is always a border of <var>x</var>, for all <var>x</var> <img alt="element" src="http://www.inf.fh-flensburg.de/lang/symbols/elem.gif"> <var>A</var><sup><small>+</small></sup>. The empty string ε itself has no border. <p>The following example illustrates how the shift distance in the Knuth-Morris-Pratt algorithm is determined using the notion of the border of a string. <p>Example: <p><a href="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/a2e7d706822b_C45A/image_5.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/a2e7d706822b_C45A/image_thumb_1.png" width="243" height="80"></a> <p>The symbols at positions 0, ..., 4 have matched. Comparison c-d at position 5 yields a mismatch. The pattern can be shifted by 3 positions, and comparisons are resumed at position 5. <p>The shift distance is determined by the widest border of the matching prefix of <var>p</var>. In this example, the matching prefix is abcab, its length is <var>j</var> = 5. Its widest border is ab of width <var>b</var> = 2. The shift distance is <var>j</var> – <var>b</var>&nbsp; =&nbsp; 5 – 2&nbsp; =&nbsp; 3. <p>In the preprocessing phase, the width of the widest border of each prefix of the pattern is determined. Then in the search phase, the shift distance can be computed according to the prefix that has matched. <h5><a name="section3">Preprocessing</a></h5> <p>Theorem:&nbsp; Let <var>r</var>, <var>s</var> be borders of a string <var>x</var>, where |<var>r</var>| &lt; |<var>s</var>|. Then <var>r</var> is a border of <var>s</var>. <p>Proof:&nbsp; Figure 1 shows a string <var>x</var> with borders <var>r</var> and <var>s</var>. Since <var>r</var> is a prefix of <var>x</var>, it is also a proper prefix of <var>s</var>, because it is shorter than<var>s</var>. But <var>r</var> is also a suffix of <var>x</var> and, therefore, proper suffix of <var>s</var>. Thus <var>r</var> is a border of <var>s</var>. <p><img alt="Borders r, s of a string x" src="http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/rand.gif"> <p><small>Figure 1:&nbsp; <i>Borders r</i>, <i>s of a string x</i></small> <p>If <var>s</var> is the widest border of <var>x</var>, the next-widest border <var>r</var> of <var>x</var> is obtained as the widest border of <var>s</var> etc. <p>Definition:&nbsp; Let <var>x</var> be a string and <var>a</var> <img alt="element" src="http://www.inf.fh-flensburg.de/lang/symbols/elem.gif"> <var>A</var> a symbol. A border <var>r</var> of <var>x</var> can be extended by <var>a</var>, if <var>ra</var> is a border of <var>xa</var>. <p><img alt="Extension of a border" src="http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/rand2.gif"> <p><small>Figure 2:&nbsp; <i>Extension of a border</i></small> <p>Figure 2 shows that a border <var>r</var> of width <var>j</var> of <var>x</var> can be extended by <var>a</var>, if <var>x</var><sub><var>j</var></sub> = <var>a</var>. <p>In the preprocessing phase an array <var>b</var> of length <var>m</var><small>+</small>1 is computed. Each entry <var>b</var>[<var>i</var>] contains the width of the widest border of the prefix of length <var>i</var> of the pattern (<var>i</var> = 0, ..., <var>m</var>). Since the prefix ε of length <var>i</var> = 0 has no border, we set <var>b</var>[0] = -1. <p><img alt="Prefix of length i of the pattern with border of width b[i]" src="http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/rand4.gif"> <p><small>Figure 3:&nbsp; <i>Prefix of length i of the pattern with border of width b</i>[<i>i</i>]</small> <p>Provided that the values <var>b</var>[0], ..., <var>b</var>[<var>i</var>] are already known, the value of <var>b</var>[<var>i</var><small>+</small>1] is computed by checking if a border of the prefix <var>p</var><sub>0</sub> ... <var>p</var><sub><var>i</var>-1</sub>can be extended by symbol <var>p</var><sub><var>i</var></sub>. This is the case if <var>p</var><sub><var>b</var>[<var>i</var>]</sub> = <var>p</var><sub><var>i</var></sub> (Figure 3). The borders to be examined are obtained in decreasing order from the values <var>b</var>[<var>i</var>], <var>b</var>[<var>b</var>[<var>i</var>]] etc. <p>The preprocessing algorithm comprises a loop with a variable <var>j</var> assuming these values. A border of width <var>j</var> can be extended by <var>p</var><sub><var>i</var></sub>, if<var>p</var><sub><var>j</var></sub> = <var>p</var><sub><var>i</var></sub>. If not, the next-widest border is examined by setting <var>j</var> = <var>b</var>[<var>j</var>]. The loop terminates at the latest if no border can be extended (<var>j</var> = -1). <p>After increasing <var>j</var> by the statement <tt>j++</tt> in each case <var>j</var> is the width of the widest border of <var>p</var><sub>0</sub> ... <var>p</var><sub><var>i</var></sub>. This value is written to <var>b</var>[<var>i</var><small>+</small>1] (to <var>b</var>[<var>i</var>] after increasing <var>i</var> by the statement <tt>i++</tt>). <h6>Preprocessing algorithm</h6><pre>void kmpPreprocess()
{
    int i=0, j=-1;
    b[i]=j;
    while (i&lt;m)
    {
        while (j&gt;=0 &amp;&amp; p[i]!=p[j]) j=b[j];
        i++; j++;
        b[i]=j;
    }
}
</pre>
<p>Example:&nbsp; For pattern <var>p</var> = ababaa the widths of the borders in array <var>b</var> have the following values. For instance we have <var>b</var>[5] = 3, since the prefix ababa of length 5 has a border of width 3.
<p><a href="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/a2e7d706822b_C45A/image_6.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/a2e7d706822b_C45A/image_thumb_2.png" width="244" height="87"></a>
<h5><a name="section4">Searching algorithm</a></h5>
<p>Conceptually, the above preprocessing algorithm could be applied to the string <var>pt</var> instead of <var>p</var>. If borders up to a width of <var>m</var> are computed only, then a border of width <var>m</var> of some prefix <var>x</var> of <var>pt</var> corresponds to a match of the pattern in <var>t</var> (provided that the border is not self-overlapping) (Figure 4).
<p><img alt="Border of length m of a prefix x of pt" src="http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/rand3.gif">
<p><small>Figure 4:&nbsp; <i>Border of length m of a prefix x of pt</i></small>
<p>This explains the similarity between the preprocessing algorithm and the following searching algorithm.
<h6>Searching algorithm</h6><pre>void kmpSearch()
{
    int i=0, j=0;
    while (i&lt;n)
    {
        while (j&gt;=0 &amp;&amp; t[i]!=p[j]) j=b[j];
        i++; j++;
        if (j==m)
        {
            report(i-j);
            j=b[j];
        }
    }
}
</pre>
<p>When in the inner while loop a mismatch at position <var>j</var> occurs, the widest border of the matching prefix of length <var>j</var> of the pattern is considered (Figure 5). Resuming comparisons at position <var>b</var>[<var>j</var>], the width of the border, yields a shift of the pattern such that the border matches. If again a mismatch occurs, the next-widest border is considered, and so on, until there is no border left (<var>j</var> = -1) or the next symbol matches. Then we have a new matching prefix of the pattern and continue with the outer while loop.
<p><img alt="Shift of the pattern when a mismatch at position j occurs" src="http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/rand5.gif">
<p><small>Figure 5:&nbsp; <i>Shift of the pattern when a mismatch at position j occurs</i></small>
<p>If all <var>m</var> symbols of the pattern have matched the corresponding text window (<var>j</var> = <var>m</var>), a function <i>report</i> is called for reporting the match at position <var>i</var>-<var>j</var>. Afterwards, the pattern is shifted as far as its widest border allows.
<p>In the following example the comparisons performed by the searching algorithm are shown, where matches are drawn in green and mismatches in red.
<p>Example:
<p><a href="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/a2e7d706822b_C45A/image_8.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/a2e7d706822b_C45A/image_thumb_3.png" width="244" height="94"></a>
<h5><a name="section5">Analysis</a></h5>
<p>The inner while loop of the preprocessing algorithm decreases the value of <var>j</var> by at least 1, since <var>b</var>[<var>j</var>] &lt; <var>j</var>. The loop terminates at the latest when <var>j</var> = -1, therefore it can decrease the value of <var>j</var> at most as often as it has been increased previously by <tt>j++</tt>. Since <tt>j++</tt> is executed in the outer loop exactly <var>m</var> times, the overall number of executions of the inner while loop is limited to <var>m</var>. The preprocessing algorithm therefore requires <var>O</var>(<var>m</var>) steps.
<p>From similar arguments it follows that the searching algorithm requires <var>O</var>(<var>n</var>) steps. The above example illustrates this: the comparisons (green and red symbols) form "stairs". The whole staircase is at most as wide as it is high, therefore at most 2<var>n</var>comparisons are performed.
<p>Since <var>m</var><img alt="&lt;=" src="http://www.inf.fh-flensburg.de/lang/symbols/le.gif"><var>n</var> the overall complexity of the Knuth-Morris-Pratt algorithm is in <var>O</var>(<var>n</var>).
<h5><a name="section6">References</a></h5>
<p>[KMP 77]<br>D.E. Knuth, J.H. Morris, V.R. Pratt: Fast Pattern Matching in Strings. SIAM Journal of Computing 6, 2, 323-350 (1977)
<p>[1]<br><a href="http://www-igm.univ-mlv.fr/~lecroq/string/">http://www-igm.univ-mlv.fr/~lecroq/string/</a>
<p>[2]<br><a href="http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/stringmatchingclasses/KmpStringMatcher.java">http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/stringmatchingclasses/KmpStringMatcher.java</a>&nbsp;&nbsp; Knuth-Morris-Pratt algorithm as a Java class source file


<img src ="http://www.cppblog.com/izualzhy/aggbug/190755.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-09-15 14:07 <a href="http://www.cppblog.com/izualzhy/archive/2012/09/15/190755.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c语言常用的位操作</title><link>http://www.cppblog.com/izualzhy/archive/2012/09/12/190431.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Wed, 12 Sep 2012 11:26:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/09/12/190431.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/190431.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/09/12/190431.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/190431.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/190431.html</trackback:ping><description><![CDATA[<p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2003d7fb-935c-4ab9-a595-2dc8c3e558a3" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#937a42">//a=targe variable, b=bit number to act upon 0-n</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#define</span> BIT_SET<span style="color:#2e53d1">(</span>a<span style="color:#2e53d1">,</span>b<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">((</span>a<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">|=</span> <span style="color:#2e53d1">(</span><span style="color:#259241">1</span><span style="color:#2e53d1">&lt;&lt;(</span>b<span style="color:#2e53d1">)))</span></li> <li><span style="color:#400080">#define</span> BIT_CLEAR<span style="color:#2e53d1">(</span>a<span style="color:#2e53d1">,</span>b<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">((</span>a<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">&amp;=</span> <span style="color:#2e53d1">~(</span><span style="color:#259241">1</span><span style="color:#2e53d1">&lt;&lt;(</span>b<span style="color:#2e53d1">)))</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#define</span> BIT_TOGGLE<span style="color:#2e53d1">(</span>a<span style="color:#2e53d1">,</span>b<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">((</span>a<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">^=</span> <span style="color:#2e53d1">(</span><span style="color:#259241">1</span><span style="color:#2e53d1">&lt;&lt;(</span>b<span style="color:#2e53d1">)))</span></li> <li><span style="color:#400080">#define</span> BIT_CHECK<span style="color:#2e53d1">(</span>a<span style="color:#2e53d1">,</span>b<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">((</span>a<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">&amp;</span> <span style="color:#2e53d1">(</span><span style="color:#259241">1</span><span style="color:#2e53d1">&lt;&lt;(</span>b<span style="color:#2e53d1">)))</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#937a42">//x=targe varible, y=mask</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#define</span> BITMASK_SET<span style="color:#2e53d1">(</span>x<span style="color:#2e53d1">,</span>y<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">((</span>x<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">|=</span> <span style="color:#2e53d1">(</span>y<span style="color:#2e53d1">))</span></li> <li><span style="color:#400080">#define</span> BITMASK_CLEAR<span style="color:#2e53d1">(</span>x<span style="color:#2e53d1">,</span>y<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">((</span>x<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">&amp;=</span> <span style="color:#2e53d1">(~(</span>y<span style="color:#2e53d1">)))</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#define</span> BITMASK_TOGGLE<span style="color:#2e53d1">(</span>x<span style="color:#2e53d1">,</span>y<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">((</span>x<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">^=</span> <span style="color:#2e53d1">(</span>y<span style="color:#2e53d1">))</span></li> <li><span style="color:#400080">#define</span> BITMASK_CHECK<span style="color:#2e53d1">(</span>x<span style="color:#2e53d1">,</span>y<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">((</span>x<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">&amp;</span> <span style="color:#2e53d1">(</span>y<span style="color:#2e53d1">))</span></li> </ol> </div> </div> </div></p><img src ="http://www.cppblog.com/izualzhy/aggbug/190431.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-09-12 19:26 <a href="http://www.cppblog.com/izualzhy/archive/2012/09/12/190431.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>KMP字符串搜索算法学习笔记</title><link>http://www.cppblog.com/izualzhy/archive/2012/09/11/190311.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Tue, 11 Sep 2012 12:26:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/09/11/190311.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/190311.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/09/11/190311.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/190311.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/190311.html</trackback:ping><description><![CDATA[写在前面：很多网站的文章里介绍到KMP算法时都会用简单，容易理解来形容，实际上，并不是这样的。<br />因此，对于要了解该算法，无论你接下来看不看这篇文章，都要给自己准备加起来至少有半天的时间来学习KMP算法，不要轻敌嘿嘿。<br />这里也只是根据我的理解做的笔记，希望了解的更多请直接移步《算法导论》或者参考资料里的链接。<br />我个人对于该方法的总结是：<br />通过关键字自身的比较进行预处理，得到当不匹配时的偏移量（朴素算法是1）。<br />一直要记住的就是，当两个字符串前n位相同时，如果第n+1位相同，则两个字符串前n+1位还是相同的...是不是太简单~~<br />KMP算法是对朴素的搜索算法的改进，因此，在学习KMP搜索算法前，先来介绍下朴素的搜索算法。<br />不妨设文本<br />S = "aaaaaaaaab"<br />关键字<br />T = "aaaab"<br />朴素的搜索算法，想法很简单，从s的下标0开始，逐个与T比较，成功则返回，否则s的下标+1，继续逐个与T比较，直到结束或返回。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;Len[S];&nbsp;i++)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;Len[T]);&nbsp;j++)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(S[i+j]&nbsp;!=&nbsp;T[j])&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(j&nbsp;==&nbsp;Len[T])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;find&nbsp;T&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;S<br />}</div><br />如果不是很理解，看个直观的图，其中第一个行是S，第二行是T，可以看成一个T不断向后滑动的过程。<br />  <table border="1" cellspacing="0" cellpadding="0" style="background-color: #bfbfbf; border-collapse: collapse; border: none; ">  <tbody><tr>   <td width="57" valign="top" style="width: 42.6pt; border: 1pt solid windowtext; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.65pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.65pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>b</p>   </td>  </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;background:red;padding:0cm 5.4pt 0cm 5.4pt">   <p><span style="color:white;">b</span></p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>  </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;background:red;padding:0cm 5.4pt 0cm 5.4pt">   <p><span style="color:white;">b</span></p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>  </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;background:red;padding:0cm 5.4pt 0cm 5.4pt">   <p><span style="color:white;">b</span></p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>  </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;background:red;padding:0cm 5.4pt 0cm 5.4pt">   <p><span style="color:white;">b</span></p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>  </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>b</p>   </td>  </tr></tbody></table>比较到第5列时，发现不匹配，于是倒回到上一个下标开始的地方+1处(第三行)，继续，如此循环往复。<br />从这里不难看出，这种情况下算法复杂度为O(S.len*T.len).<br />KMP算法的改进点就在这里：<br />第二行不匹配后是否我们应当倒回到第三行的状态继续比较？如果不用，那么应该怎么比较。<br />我们先用这个例子来表示一下，S[0,4]表示的是S字符串下标从0到4的闭区间。<br />提前提示一下： T[0,2] = T[1,3]<br />第二行里，我们比较到了第5列（即下标为4的地方，接下来我们开始只用下标描述，以免产生混乱），即前面的字符串是匹配的，因此有这个结果：<br />S[0,3] = T[0,3],S[1,3] = T[1,3],S[2,3] = T[2,3]...<br />同时根据前面的提示:<br />T[0,2] = T[1,3] = S[1,3]<br />可以看到T[0,2] = S[1,3]就是第三行里前面要比较的内容，也就是说实际上是不需要的。<br />第二行失败后，我们可以直接从S[4]与T[3]比较!<br />也就是说KMP要解决的就是：如果在S的某个下标处不匹配了，那么S的改下标不需要退回，而是选择T的一个下标，来继续比较（因为像前面的例子，T[0,2]=T[1,3]了已经)。<br />简单直观点的说法，就是，当不匹配时，T不是直接滑动回去再前进一步，而是选择一个可以前进的最大值，同时，直接进行与S当前不匹配下标的比较。<br />注意这个最大值不一定为1，S当前选择与T的哪个下标比较，会决定这样一个前进值。<br />再看个例子：<br /><table border="1" cellspacing="0" cellpadding="0" style="background-color: #bfbfbf; border-collapse: collapse; border: none; ">  <tbody><tr>   <td width="57" valign="top" style="width: 42.6pt; border: 1pt solid windowtext; padding: 0cm 5.4pt; ">   <p>a</p>   </td>      <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>b</p>   </td>      <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>      <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>d</p>   </td>      <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>e</p>   </td>      <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>      <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>b</p>   </td>      <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>      <td width="57" valign="top" style="width: 42.65pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>d</p>   </td>      <td width="57" valign="top" style="width: 42.65pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>f</p>   </td>     </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>b</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>d</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;background:red;padding:0cm 5.4pt 0cm 5.4pt">   <p><span style="color:white;">f</span></p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>     </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;background:red;padding:0cm 5.4pt 0cm 5.4pt">   <p><span style="color:white;">a</span></p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>     </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;background:red;padding:0cm 5.4pt 0cm 5.4pt">   <p><span style="color:white;">b</span></p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>     </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;background:red;padding:0cm 5.4pt 0cm 5.4pt">   <p><span style="color:white;">b</span></p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>      <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>     </tr></tbody></table>这是朴素的匹配算法的策略，其中S="abadeabadf",T="abadf"<br />而KMP的策略是：<br /><table border="1" cellspacing="0" cellpadding="0" style="background-color: #bfbfbf; border-collapse: collapse; border: none; ">  <tbody><tr>   <td width="57" valign="top" style="width: 42.6pt; border: 1pt solid windowtext; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>b</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>d</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>e</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>b</p>   </td>   <td width="57" valign="top" style="width: 42.6pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width: 42.65pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>d</p>   </td>   <td width="57" valign="top" style="width: 42.65pt; border-style: solid solid solid none; border-top-color: windowtext; border-right-color: windowtext; border-bottom-color: windowtext; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt; ">   <p>f</p>   </td>  </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>b</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>d</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;background:red;padding:0cm 5.4pt 0cm 5.4pt">   <p><span style="color:white;">f</span></p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>  </tr>  <tr>   <td width="57" valign="top" style="width: 42.6pt; border-style: none solid solid; border-right-color: windowtext; border-bottom-color: windowtext; border-left-color: windowtext; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt; ">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>&nbsp;a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>b</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>a</p>   </td>   <td width="57" valign="top" style="width:42.6pt;border-top:none;border-left:none;   border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>d</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p>f</p>   </td>   <td width="57" valign="top" style="width:42.65pt;border-top:none;border-left:   none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p><br /></p>   </td>  </tr></tbody></table>为什么可以这样选择？<br />因此，kmp就是要计算这样一个数组next[], 当文本S在其下标i处与T不匹配时，来决定与T哪个下标处开始继续比较。<br />我们先看下程序：<br /><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: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;*&nbsp;=====================================================================================<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Filename:&nbsp;&nbsp;kmpsearch.c<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;Description:&nbsp;&nbsp;kmp&nbsp;search<br />&nbsp;*<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Version:&nbsp;&nbsp;1.0<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Created:&nbsp;&nbsp;09/10/2012&nbsp;07:15:07&nbsp;PM<br />&nbsp;*<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Author:&nbsp;&nbsp;zhy&nbsp;(),&nbsp;izualzhy@163.com<br />&nbsp;*&nbsp;=====================================================================================<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><br /><span style="color: #008000; ">/*</span><span style="color: #008000; ">*<br />&nbsp;*&nbsp;@brief&nbsp;KMPSearch&nbsp;kmp搜索字符串算法<br />&nbsp;*<br />&nbsp;*&nbsp;@param&nbsp;src&nbsp;待搜索的文本<br />&nbsp;*&nbsp;@param&nbsp;srcLen&nbsp;待搜索文本长度<br />&nbsp;*&nbsp;@param&nbsp;keyword&nbsp;搜索关键字<br />&nbsp;*&nbsp;@param&nbsp;keywordLen&nbsp;搜索关键字长度<br />&nbsp;*<br />&nbsp;*&nbsp;@return&nbsp;搜索到第一个结果停止，返回关键字在文本出现的索引，否则返回-1<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">int</span>&nbsp;KMPSearch(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;src,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;srcLen,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;keyword,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;keywordLen)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">存储kmp需要的next数组</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;next&nbsp;=&nbsp;(<span style="color: #0000FF; ">char</span>*)malloc(keywordLen*<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">char</span>));<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!next)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;-1;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">初始化next数组的值</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;CalcKMPNext(keyword,&nbsp;keywordLen,&nbsp;next);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0,&nbsp;j&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;;&nbsp;i&lt;keywordLen;&nbsp;++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("next:&nbsp;%d\n",&nbsp;next[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(i&nbsp;&lt;&nbsp;srcLen)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">如果比较结果不同，则需要回退关键字的索引，继续比较，如果回退至关键字开始处(j==0)时break，下次直接从当前i与关键字的第一个字符开始比较</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(j&nbsp;&gt;=&nbsp;0&nbsp;&amp;&amp;&nbsp;src[i]&nbsp;!=&nbsp;keyword[j])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;=&nbsp;next[j];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("i=%d,j=%d\n",i,j);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(j&nbsp;==&nbsp;keywordLen)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;i&nbsp;-&nbsp;keywordLen;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;-1;<br />}<br /><br /><span style="color: #008000; ">/*</span><span style="color: #008000; ">*<br />&nbsp;*&nbsp;@brief&nbsp;CalcKMPNext&nbsp;计算kmp算法需要的next数组<br />&nbsp;*<br />&nbsp;*&nbsp;@param&nbsp;keyword&nbsp;关键字<br />&nbsp;*&nbsp;@param&nbsp;keywordLen&nbsp;关键字长度<br />&nbsp;*&nbsp;@param&nbsp;next&nbsp;存储next<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">void</span>&nbsp;CalcKMPNext(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;keyword,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;keywordLen,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;next)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0,&nbsp;j&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;next[i]&nbsp;=&nbsp;j;<span style="color: #008000; ">//</span><span style="color: #008000; ">初始化next[0],没有什么意义</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(i&nbsp;&lt;&nbsp;keywordLen)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">如果不相等，回退直到相等，或者没有相等</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(j&nbsp;&gt;=&nbsp;0&nbsp;&amp;&amp;&nbsp;keyword[i]!=keyword[j])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;=&nbsp;next[j];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++j;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(i&lt;keywordLen)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next[i]&nbsp;=&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;text[]&nbsp;=&nbsp;"abadeabadf";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;keyword[]&nbsp;=&nbsp;"abadf";<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*char&nbsp;text[]&nbsp;=&nbsp;"this&nbsp;is&nbsp;a&nbsp;demo,&nbsp;is&nbsp;is&nbsp;not&nbsp;u&nbsp;,&nbsp;isnot&nbsp;it?";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*char&nbsp;keyword[]&nbsp;=&nbsp;"is";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;textLen&nbsp;=&nbsp;strlen(text);<br />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;keywordLen&nbsp;=&nbsp;strlen(keyword);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;startIndex&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(1)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;foundIndex&nbsp;=&nbsp;KMPSearch(text&nbsp;+&nbsp;startIndex,&nbsp;textLen,&nbsp;keyword,&nbsp;keywordLen);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(foundIndex&nbsp;==&nbsp;-1)<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;startIndex&nbsp;+=&nbsp;foundIndex;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("find&nbsp;in&nbsp;%d\n",&nbsp;startIndex);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;startIndex&nbsp;+=&nbsp;keywordLen;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div><br /><br />参考资料：<br /><a href="http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm">http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm</a>&nbsp;<br /><a href="http://chaoswork.com/blog/2011/06/14/kmp%E7%AE%97%E6%B3%95%E5%B0%8F%E7%BB%93/">http://chaoswork.com/blog/2011/06/14/kmp%E7%AE%97%E6%B3%95%E5%B0%8F%E7%BB%93/</a>&nbsp;<br /><a href="http://www.matrix67.com/blog/archives/115">http://www.matrix67.com/blog/archives/115</a>&nbsp;<br /><img src ="http://www.cppblog.com/izualzhy/aggbug/190311.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-09-11 20:26 <a href="http://www.cppblog.com/izualzhy/archive/2012/09/11/190311.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]为什么处理排序的数组要比非排序的快？</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/31/188925.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Fri, 31 Aug 2012 10:29:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/31/188925.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/188925.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/31/188925.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/188925.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/188925.html</trackback:ping><description><![CDATA[<h4>问题</h4> <p>看以下代码：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b2f85c56-955f-4b9a-9457-c003a540e7e2" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;algorithm&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#include</span> <span style="color:#259241">&lt;ctime&gt;</span></li> <li><span style="color:#400080">#include</span> <span style="color:#259241">&lt;iostream&gt;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#400080">int</span> main<span style="color:#2e53d1">()</span></li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#937a42">// generate data</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">const</span> <span style="color:#400080">unsigned</span> arraySize <span style="color:#2e53d1">=</span> <span style="color:#259241">32768</span><span style="color:#2e53d1">;</span></li> <li>    <span style="color:#400080">int</span> data<span style="color:#2e53d1">[</span>arraySize<span style="color:#2e53d1">];</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">for</span> <span style="color:#2e53d1">(</span><span style="color:#400080">unsigned</span> c <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span> c <span style="color:#2e53d1">&lt;</span> arraySize<span style="color:#2e53d1">;</span> <span style="color:#2e53d1">++</span>c<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">        data<span style="color:#2e53d1">[</span>c<span style="color:#2e53d1">]</span> <span style="color:#2e53d1">=</span> std<span style="color:#2e53d1">::</span>rand<span style="color:#2e53d1">()</span> <span style="color:#2e53d1">%</span> <span style="color:#259241">256</span><span style="color:#2e53d1">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#937a42">// !!! with this, the next loop runs faster</span></li> <li style="background: #f3f3f3">    <span style="color:#937a42">//std::sort(data, data + arraySize);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#937a42">// test</span></li> <li style="background: #f3f3f3">    clock_t start <span style="color:#2e53d1">=</span> clock<span style="color:#2e53d1">();</span></li> <li>    <span style="color:#400080">long</span> <span style="color:#400080">long</span> sum <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">for</span> <span style="color:#2e53d1">(</span><span style="color:#400080">unsigned</span> i <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span> i <span style="color:#2e53d1">&lt;</span> <span style="color:#259241">100000</span><span style="color:#2e53d1">;</span> <span style="color:#2e53d1">++</span>i<span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">    {</li> <li>        <span style="color:#937a42">// primary loop</span></li> <li style="background: #f3f3f3">        <span style="color:#400080">for</span> <span style="color:#2e53d1">(</span><span style="color:#400080">unsigned</span> c <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span> c <span style="color:#2e53d1">&lt;</span> arraySize<span style="color:#2e53d1">;</span> <span style="color:#2e53d1">++</span>c<span style="color:#2e53d1">)</span></li> <li>        {</li> <li style="background: #f3f3f3">            <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>data<span style="color:#2e53d1">[</span>c<span style="color:#2e53d1">]</span> <span style="color:#2e53d1">&gt;=</span> <span style="color:#259241">128</span><span style="color:#2e53d1">)</span></li> <li>                sum <span style="color:#2e53d1">+=</span> data<span style="color:#2e53d1">[</span>c<span style="color:#2e53d1">];</span></li> <li style="background: #f3f3f3">        }</li> <li>    }</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">double</span> elapsedTime <span style="color:#2e53d1">=</span> <span style="color:#400080">static_cast</span><span style="color:#2e53d1">&lt;</span><span style="color:#400080">double</span><span style="color:#2e53d1">&gt;(</span>clock<span style="color:#2e53d1">()</span> <span style="color:#2e53d1">-</span> start<span style="color:#2e53d1">)</span> <span style="color:#2e53d1">/</span> CLOCKS_PER_SEC<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    std<span style="color:#2e53d1">::</span>cout <span style="color:#2e53d1">&lt;&lt;</span> elapsedTime <span style="color:#2e53d1">&lt;&lt;</span> std<span style="color:#2e53d1">::</span>endl<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    std<span style="color:#2e53d1">::</span>cout <span style="color:#2e53d1">&lt;&lt;</span> <span style="color:#259241">&quot;sum = &quot;</span> <span style="color:#2e53d1">&lt;&lt;</span> sum <span style="color:#2e53d1">&lt;&lt;</span> std<span style="color:#2e53d1">::</span>endl<span style="color:#2e53d1">;</span></li> <li>}</li> </ol> </div> </div> </div> <p>问题就在于，去掉<code>std::sort</code>那一行，以上代码将运行更长的时间。在我的机器上未去掉<code>std::sort</code>耗时8.99s，去掉后耗时24.78s。编译器使用的是gcc4.4.3。事实上，以上代码跟编译器没有关系，甚至跟语言没有关系。那这是为什么呢？ <p>这跟处理这个数组的逻辑有非常大的关系。如以上代码所示，这个循环里有个条件判断。条件判断被编译成二进制代码后，就是一个跳转指令，类似： <p>具体为什么会不同，这涉及到计算机CPU执行指令时的行为。 <h4>CPU的流水线指令执行</h4> <p>想象现在有一堆指令等待CPU去执行，那么CPU是如何执行的呢？具体的细节可以找一本计算机组成原理的书来看。CPU执行一堆指令时，并不是单纯地一条一条取出来执行，而是按照一种流水线的方式，在CPU真正执行一条指令前，这条指令就像工厂里流水线生产的产品一样，已经被经过一些处理。简单来说，一条指令可能经过这些过程：取指(Fetch)、解码(Decode)、执行(Execute)、放回(Write-back)。 <p>假设现在有指令序列ABCDEFG。当CPU正在执行(execute)指令A时，CPU的其他处理单元（CPU是由若干部件构成的）其实已经预先处理到了指令A后面的指令，例如B可能已经被解码，C已经被取指。这就是流水线执行，这可以保证CPU高效地执行指令。 <h4>Branch Prediction</h4> <p>如上所说，CPU在执行一堆顺序执行的指令时，因为对于执行指令的部件来说，其基本不需要等待，因为诸如取指、解码这些过程早就被做了。但是，当CPU面临非顺序执行的指令序列时，例如之前提到的跳转指令，情况会怎样呢？ <p>取指、解码这些CPU单元并不知道程序流程会跳转，只有当CPU执行到跳转指令本身时，才知道该不该跳转。所以，取指解码这些单元就会继续取跳转指令之后的指令。当CPU执行到跳转指令时，如果真的发生了跳转，那么之前的预处理（取指、解码）就白做了。这个时候，CPU得从跳转目标处临时取指、解码，然后才开始执行，这意味着：CPU停了若干个时钟周期！ <p>这其实是个问题，如果CPU的设计放任这个问题，那么其速度就很难提升起来。为此，人们发明了一种技术，称为branch prediction，也就是分支预测。分支预测的作用，就是预测某个跳转指令是否会跳转。而CPU就根据自己的预测到目标地址取指令。这样，即可从一定程度提高运行速度。当然，分支预测在实现上有很多方法。 <p>简单的预测可以直接使用之前的实际执行结果。例如某个跳转指令某一次产生了跳转，那么下一次执行该指令时，CPU就直接从跳转目标地址处取指，而不是该跳转指令的下一条指令。 <h4>答案</h4> <p>了解了以上信息后，文章开头提出的问题就可以解释了。这个代码中有一个循环，这个循环里有一个条件判断。每一次CPU执行这个条件判断时，CPU都可能跳转到循环开始处的指令，即不执行if后的指令。使用分支预测技术，当处理已经排序的数组时，在若干次<code>data[c]&gt;=128</code>都不成立时（或第一次不成立时，取决于分支预测的实现），CPU预测这个分支是始终会跳转到循环开始的指令时，这个时候CPU将保持有效的执行，不需要重新等待到新的地址取指；同样，当<code>data[c]&gt;=128</code>条件成立若干次后，CPU也可以预测这个分支是不必跳转的，那么这个时候CPU也可以保持高效执行。 <p>相反，如果是无序的数组，CPU的分支预测在很大程度上都无法预测成功，基本就是50%的预测成功概率，这将消耗大量的时间，因为CPU很多时间都会等待取指单元重新取指。 <p>本文完。最后感叹下stackoverflow上这个帖子里那个老外回答问题的专业性，我要是楼主早就感动得涕泪横飞了。感谢每一个传播知识的人。 <h4>参考资料</h4> <ol> <li><a href="http://blog.sina.com.cn/s/blog_6c673e570100zfmo.html">http://blog.sina.com.cn/s/blog_6c673e570100zfmo.html</a> <li><a href="http://www.cnblogs.com/dongliqian/archive/2012/04/05/2433847.html">http://www.cnblogs.com/dongliqian/archive/2012/04/05/2433847.html</a> <li><a href="http://en.wikipedia.org/wiki/Branch_predictor">http://en.wikipedia.org/wiki/Branch_predictor</a></li></ol> <p>原文地址： <a href="http://codemacro.com/2012/08/29/branch-predictor/">http://codemacro.com/2012/08/29/branch-predictor/</a><br>written by <a href="http://codemacro.com/">Kevin Lynx</a>&nbsp; posted at <a href="http://codemacro.com/">http://codemacro.com</a></p><img src ="http://www.cppblog.com/izualzhy/aggbug/188925.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-31 18:29 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/31/188925.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++求组合数</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/25/188260.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 25 Aug 2012 09:49:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/25/188260.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/188260.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/25/188260.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/188260.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/188260.html</trackback:ping><description><![CDATA[<p>题目是这样的：</p> <p><strong>求组合数：求n个数中K个数的组合，假设函数原型为&nbsp; intcombination （int n,int k ）,其中&nbsp; n 的范围为&nbsp; 1 ……n, </strong> <p><strong>例如：combination（5 ，3 ） 要求输出：543、542 、541 、531 、532 、521 、432 、431 、421 、321 如果输出时有用到数组，其空间需要在开始动态分配好，结束时释放。</strong> <p><strong>第一想法是5!/3!/2!o(╯□╰)o</strong> <p>写程序的话其实很简单了，我用的递归，递归注意下结束条件就可以了：</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a75fd7ae-67f7-4ba8-9370-f03718d89a4b" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#937a42">/*</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> * =====================================================================================</span></li> <li><span style="color:#937a42"> *       Filename:  intcombination.c</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> *    Description:  求n个数中k个数的组合</span></li> <li><span style="color:#937a42"> *</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> *        Version:  1.0</span></li> <li><span style="color:#937a42"> *        Created:  08/25/2012 05:08:13 PM</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> *</span></li> <li><span style="color:#937a42"> *         Author:  zhy (), izualzhy@163.com</span></li> <li style="background: #f3f3f3"><span style="color:#937a42"> * =====================================================================================</span></li> <li><span style="color:#937a42"> */</span></li> <li style="background: #f3f3f3"><span style="color:#400080">#include</span> <span style="color:#259241">&lt;stdio.h&gt;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">int</span> combination<span style="color:#2e53d1">(</span><span style="color:#400080">int</span> n<span style="color:#2e53d1">,</span> <span style="color:#400080">int</span> k<span style="color:#2e53d1">)</span></li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>k<span style="color:#2e53d1">&gt;</span>n <span style="color:#2e53d1">||</span> k<span style="color:#2e53d1">&lt;</span><span style="color:#259241">0</span><span style="color:#2e53d1">)</span></li> <li>    {</li> <li style="background: #f3f3f3">        <span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>    }</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">if</span> <span style="color:#2e53d1">(</span>k <span style="color:#2e53d1">==</span> <span style="color:#259241">0</span><span style="color:#2e53d1">)</span></li> <li style="background: #f3f3f3">    {</li> <li>        <span style="color:#400080">return</span> <span style="color:#259241">1</span><span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    }</li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="color:#400080">int</span> totalCounts <span style="color:#2e53d1">=</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>    <span style="color:#400080">int</span> i <span style="color:#2e53d1">=</span> n<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">    <span style="color:#400080">for</span> <span style="color:#2e53d1">(</span> <span style="color:#2e53d1">;</span>i <span style="color:#2e53d1">&gt;=</span> k<span style="color:#2e53d1">;</span> <span style="color:#2e53d1">--</span>i<span style="color:#2e53d1">)</span></li> <li>    {</li> <li style="background: #f3f3f3">        totalCounts <span style="color:#2e53d1">+=</span> combination<span style="color:#2e53d1">(</span>i<span style="color:#2e53d1">-</span><span style="color:#259241">1</span><span style="color:#2e53d1">,</span> k<span style="color:#2e53d1">-</span><span style="color:#259241">1</span><span style="color:#2e53d1">);</span></li> <li>    }</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#400080">return</span> totalCounts<span style="color:#2e53d1">;</span></li> <li style="background: #f3f3f3">}</li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#400080">int</span> main<span style="color:#2e53d1">()</span></li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#400080">int</span> a<span style="color:#2e53d1">,</span> b<span style="color:#2e53d1">;</span></li> <li>    scanf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;%d %d&quot;</span><span style="color:#2e53d1">,&amp;</span>a<span style="color:#2e53d1">,&amp;</span>b<span style="color:#2e53d1">);</span></li> <li style="background: #f3f3f3">    printf<span style="color:#2e53d1">(</span><span style="color:#259241">&quot;%d&#92;n&quot;</span><span style="color:#2e53d1">,</span> combination<span style="color:#2e53d1">(</span>a<span style="color:#2e53d1">,</span>b<span style="color:#2e53d1">));</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="color:#400080">return</span> <span style="color:#259241">0</span><span style="color:#2e53d1">;</span></li> <li>}</li> </ol> </div> </div> </div> <p>好吧，写这篇日志其实是为了测试下这个插件好用不好用。。。</p><img src ="http://www.cppblog.com/izualzhy/aggbug/188260.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-25 17:49 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/25/188260.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]字节码问题--wchar和char的区别以及wchar和char之间的相互转换字符编码转换等方法及函数介绍</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/25/188245.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 25 Aug 2012 06:29:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/25/188245.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/188245.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/25/188245.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/188245.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/188245.html</trackback:ping><description><![CDATA[<p><a href="http://www.cnblogs.com/MichaelOwen/articles/2128771.html">http://www.cnblogs.com/MichaelOwen/articles/2128771.html</a></p> <p><b>收集了一些关于字符/宽字符的一些资料，在此与大家一起分享。<br></p></b> <p><b>win2</b><b>下wchar</b><b>占2</b><b>个字节&nbsp;&nbsp; linux</b><b>下wchar</b><b>占4</b><b>个字节</b> <p>wchar_t的高位字节应该存储在char数组的低位字节。 <p>在 C 语言中， char 类型永远都是一个字节， 双字节字符类型是 wchar_t；但它不是内置类型， 定义在 stddef.h. <p>给 wchar_t 类型的字符或字符数组（也就是字符串）赋值要冠以 L； <p>格式化输出（如 printf） wchar_t 类型的字符串， 要用 %S（而非 %s）。（我更多的是看到用ls输出）； <p>而且 要注意一点，printf和wprintf不能混用，否则不会打印。如：<pre>setlocale(LC_ALL,"zh_CN.utf8");<br>printf("1 print chinese by wprintf test: \n");<br>wchar_t *wstr = L"中文";<br>wprintf(L"%ls",wstr);</pre>
<p>上面先使用了printf，又使用了wprintf，所以后面的wprintf无法正常输出，只要把上面printf换成wprintf或是注释掉就可以了。
<p>mbs: multi byte string, 用char作为存储类型, 一个字符可能对应1个或者多个char, 不能直接确定字符边界. charset不确定. 过去的程序都是采用mbs的.
<p>wcs: wide character string, 用wchar_t作为存储类型, 一个字符对于一个wchar_t. 使用unicode编码, charset与OS相关, 在windows平台中为UTF16(UCS-2), 在大多数unix平台中为UTF32(UCS-4).
<p>国际化的程序都应该在内部使用wcs, 在输入输出时做mbs与wcs的转换.
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a><pre>#include &lt;stdlib.h&gt;<br>#include &lt;stdio.h&gt;<br>#include &lt;locale.h&gt; <br><br><br>int main()<br>{<br>    FILE* fp ;<br>    setlocale(LC_ALL,"");             //要先设置语言环境<br>    wchar_t wchar[5] = L"相等相等";    //定义一个宽字节的变量，初始为"相等"<br>    fp = fopen("1.txt", "w+");        //打开文件称奥做<br>    fwprintf(fp, L"%ls\n", wchar);    //输出到文件.此处一定要为%ls，不能用%s<br>    fclose(fp);                       //关闭文件<br>    wchar_t wc2[5];                   //定义第二个宽字节变量<br>    <br>    int i = 0;<br>    //wc开始的有很多宽字节的操作。都和str相对应。<br>    wcscpy(wc2, wchar);                //复制。<br>    int n = wcscmp(wc2, wchar);        //比较<br>    if (n == 0)<br>    {<br>        wprintf(L"相等\n");            <br>    }<br>    else<br>    {<br>        wprintf(L"不相等\n");<br>    }<br><br>    char str[10];                    //定义char字符。<br>    n = wcstombs(str, wc2, 9);       //宽字节转换为muiltychar<br>    printf("1---: %s\n", str);       //输出结果<br><br>    for (i = 0; i &lt; 5; ++i)<br>    {<br>        wc2[i] = L'1' + i;<br>    }<br>    wc2[4] = 0;<br><br>    n = wcstombs(str, wc2, 9);        //宽字节转换为muiltychar<br>    printf("2---:%s\n", str);         //输出结果<br>    <br>    return 0;<br>}</pre>
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a>
<p><b>mbs</b><b>与</b><b>wcs</b><b>的转换函数</b><b>:</b><pre>#include &lt;locale.h&gt;<br>setlocale(LC_ALL, "");<br><br>wcstombs(char * to,wchar_t * from,size_t _maxCount);<br>mbstowcs(wchar_t * to,char * from,size_t _maxCount);</pre>
<p><b>wcstombs/mbstowcs</b>是实现转换的一对函数. 这两个c的库函数其实内部也就是对刚刚windows的api和接下来我们要说的iconv的封装。使用时要注意，如果涉及到中文，要先<b>setlocale</b>，当设置好正确的locale，函数内部才能找到正确的字符集进行转换。
<p>wcs的charset是固定不可变的, 但是mbs的charset是可变的, 可能是ASCII, 可能是gb2312, 也可能是big5. wcstombs/<a name="OLE_LINK1"></a>mbstowcs是根据locale环境设置来决定mbs采用的charset的, 在程序中可以用setlocale来设定locale, 例如 setlocale(LC_ALL, "chinese")
<p>程序启动时, locale设定为 LC_ALL="C", 用 setlocale(LC_ALL, "") 就可以设置成操作系统的locale设定.
<p>Locale决定了当前程序运行的本地化设置方式, 但是在程序中可能需要作其他charset的转换, 例如程序本身语言设定为简体中文, 需要做big5与unicode的转换, 或者是其他两种charset的mbstombs转换, 这时wcstombs/mbstowcs就不能胜任了.
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a><pre>/*<br>linux 下 wchar_t和char的相互转化和测试<br>win32下wchar_t占2个字节，linux下wchar_t占4个字节。wchar_t的高字节应该存放在char数组的低字节。<br>Linux下面的没有命名为 WideCharToMultiByte() 和 MultiByteToWideChar() 函数，WideCharToMultiByte，MultiByteToWideChar是windows下的函数，<br>在linux下也有类似的两个函数：<br>mbstowcs()<br>wcstombs() <br>值得注意的是:<br>size_t mbstowcs(wchar_t *wcstr,const char *mbstr,size_t count);<br>这个函数的第三个参数count，大小一定要是mbstr长度的2倍，否则出来的中文也会是乱码。<br><br>wcstombs和mbstowcs使用<br>#include &lt;locale.h&gt;<br>setlocale(LC_ALL, "");<br>wcstombs(char * to,wchar_t * from,size_t _maxCount);<br>mbstowcs(wchar_t * to,char * from,size_t _maxCount);<br><br>还有呢，转码还可以使iconv函数族，包含以下三个函数（其具体实例可以见demo_iconv.c和code_convert.c）：<br>iconv_t iconv_open(const char *tocode, const char *fromcode);<br>size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);<br>int iconv_close(iconv_t cd);<br>*/<br>#include &lt;stdlib.h&gt;<br>#include &lt;stdio.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;locale.h&gt;<br><br><br>size_t get_wchar_size(const char *str)<br>{<br>   size_t len = strlen(str);<br>   size_t size=0;<br>   size_t i;<br>   for(i=0; i &lt; len; i++)<br>   {<br>      if( str[size] &gt;= 0 &amp;&amp; str[size] &lt;= 127 ) //不是全角字符<br>      size+=sizeof(wchar_t);<br>      else //是全角字符，是中文<br>      {<br>        size+=sizeof(wchar_t);<br>        i+=2;<br>      }<br>   }<br>  return size;<br>}<br><br>char *w2c(const wchar_t *pw)<br>{<br>   if(!pw)<br>   return NULL;<br><br>   size_t size= wcslen(pw)*sizeof(wchar_t);<br>   char *pc;<br>   if(!(pc = (char*)malloc(size)))<br>   {<br>     printf("malloc fail");<br>     return NULL;<br>   }<br>   wcstombs(pc,pw,size);<br>   return pc;<br><br>}<br><br>wchar_t *c2w(const char *pc)<br>{<br>   if(!pc)<br>   return NULL;<br><br>   size_t size_of_ch = strlen(pc)*sizeof(char);<br>   size_t size_of_wc = get_wchar_size(pc);<br>   wchar_t *pw;<br>   if(!(pw = (wchar_t*)malloc(size_of_wc)))<br>   {<br>      printf("malloc fail");<br>      return NULL;<br>   }<br>   mbstowcs(pw,pc,size_of_wc);<br>   return pw;<br><br>}<br><br>int main(void)<br>{<br>   setlocale(LC_ALL,"zh_CN.utf8");<br>   printf("1 print chinese by wprintf test: \n");<br>   wchar_t *wstr = L"中文";<br>   //wprintf(L"%ls",wstr); //此处不要使用wprintf，因为上面已经使用了printf，而他们使用的是不同的流，不能混用<br>   printf("%ls\n",wstr); //ls<br><br>   printf("2 print chinese by printf test: \n");<br>   char *str = "汉字";<br>   printf("%s\n\n\n",str); //s<br><br>   printf("3 char and wchar_t size of system test: \n");<br>   printf("%s%d\n","the size of wchar_t is : ",sizeof(wchar_t)); //4<br>   printf("%s%d\n\n\n","the size of char is : ",sizeof(char));   //1<br><br>   char *pc;<br>   wchar_t *pw = L"中文是abc一门语言abc";<br>   char *tmp = "中文是abc一门语言abc";<br>   printf("%s%s\n","input test wchar_t* ",tmp);<br>   pc = w2c(pw);<br>   printf("4 print char test after w2c (wchar to char):\n");<br>   printf("%s\n",pc);<br><br><br>   wchar_t *cw1 = c2w(pc);   //char to wchar<br>   char *wc1 = w2c(cw1);   //wchar to char<br>   printf("5 print char test after w2c c2w and w2c:\n");<br>   printf("%s\n\n\n",wc1);<br><br>   char *pmc = "abc中文abc";<br>   wchar_t *pmw;<br>   printf("%s%s\n","input test char* ",pmc);<br>   pmw = c2w(pmc);<br>   char *pmc1 = w2c(pmw);<br>   printf("6 print char test after c2w and w2c:\n");<br>   printf("%s\n",pmc1);<br><br>   printf("%ls\n",wstr);<br>   //cout&lt;&lt;wstr&lt;&lt;endl;<br>   return 0;<br><br>} </pre>
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a>
<p>在unix平台中可以使用<b>iconv</b>来做这个转换(iconv lib也有windows版本), 在windows平台可以用MultiByteToWideChar/WideCharToMultiByte 函数.
<p><b>iconv</b><b>库的使用</b><b></b>
<p>利用iconv函数族进行编码转换（如GB2312转换为UTF-8）
<p>iconv函数族的头文件是iconv.h,使用前需包含之。
<p><b>#include &lt;iconv.h&gt;</b>
<p>iconv函数族有三个函数,原型如下:
<p>(1) <b>iconv_t iconv_open(const char *tocode, const char *fromcode);</b>
<p>此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。
<p>(2)<b>size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);</b>
<p>此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。参数cd必须是由iconv_open函数创建的转换描述符。
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a><pre>/*<br>    iconv库的使用<br>    GB2312字符串转换为UTF-8的字符串<br><br>    利用iconv函数族进行编码转换<br>    iconv函数族的头文件是iconv.h,使用前需包含之。<br>    #include &lt;iconv.h&gt;<br>    iconv函数族有三个函数,原型如下:<br>    (1) iconv_t iconv_open(const char *tocode, const char *fromcode);<br>    此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个<br>    转换句柄,供以下两个函数使用。<br>    (2) size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);<br>    此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。<br>    (3) int iconv_close(iconv_t cd);<br>    此函数用于关闭转换句柄,释放资源。<br>*/<br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;iconv.h&gt;<br>#include &lt;string.h&gt;<br><br>int main(void)<br>{<br>    unsigned char *src = "魅影追击和歌姬"; /* 需转换的字串 */<br>    unsigned char dst[256] = {0}; /* 转换后的内容 */<br>    unsigned char buf[1024] = {0}; /* 格式化转换后的字串 */<br>    size_t src_len = strlen(src);<br>    size_t dst_len = sizeof(dst);<br>    unsigned char *in = src;<br>    unsigned char *out = dst;<br>   <br>    iconv_t cd;<br>    int i; <br>    int j; <br>   <br>    cd = iconv_open("UTF-8", "GB2312"); /* 将GB2312字符集转换为UTF-8字符集 */<br>    if ((iconv_t)-1 == cd)<br>    {<br>        return -1;<br>    }<br><br>    printf("src: %s\n", src);<br>    iconv(cd, &amp;in, &amp;src_len, &amp;out, &amp;dst_len); /* 执行转换 */<br><br>    /* 以下将转换后的内容格式化为: %XX%XX...形式的字串 */<br>    printf("dst: ");<br>    j = 0; <br>    for (i = 0; i &lt; strlen(dst); i++)<br>    {<br>        printf("%.2X ", dst[i]);<br>        buf[j++] = '%';<br>        snprintf(buf + j, 3, "%.2X", dst[i]);<br>        j += 2;<br>    }<br>    printf("\n");<br>    printf("buf: %s\n", buf);<br>   <br>    iconv_close(cd); /* 执行清理 */<br>    return 0;<br>}</pre>
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a>
<p>大部分情形是inbuf 不为NULL，*inbuf也不为NULL。这种情况下，iconv函数将以*inbuf起始的多字节序列转换到以*outbuf起始的多字节序列。从*inbuf开始读取,最多*inbytesleft字节，转换后，从*outbuf开始写入,最多*outbytesleft字节。iconv函数一次转换一个多字节字符，每次字符转换，*inbuf增加已转换的字节数，*inbytesleft相应地减少已转换的字节数；对应地，*outbuf和*outbytesleft作相应的修改，同时修改cd的转换状态。
<p><b>以下四种情况不能完成转换：</b>
<p>1．输入中含无效的多字节序列。此时，它将errno设置为EILSEQ并返回(size_t)(-1)。*inbuf指向无效序列的最左端。
<p>2．输入的字节序列已经全部被转换过，也就是*inbytesleft减少至0。此时，iconv返回本次调用中完成转换的数目（可逆的转换不计入）。
<p>3．输入中以不完整多字节序列作结尾。此时，它将errno设置为EINVAL并返回(size_t)(-1)。*inbuf指向不完整多字节序列的最左端。
<p>4．输出缓存区没有足够空间来存储下一个字符。此时，它将errno设置为E2BIG并返回(size_t)(-1)。
<p>另一种情形是inbuf 为NULL或*inbuf为NULL，但*outbuf 不为NULL，*outbuf也不为NULL。这种情况下，iconv函数试图将cd的转换状态设置为初始状态并store a corresponding shift sequence at *outbuf。从*outbuf开始，最多写入*outbytesleft字节。如果输出缓存区没有足够空间来存储这个重置后的序列，他将errno设置为E2BIG并返回(size_t)(-1)。反之，*outbuf增加写入的字节数和*outbytesleft减少写入的字节数。
<p>第三种情形是inbuf 为NULL或*inbuf为NULL，*outbuf 为NULL或*outbuf为NULL。这种情况下，iconv函数试图将cd的转换状态设置为初始状态。
<p><b><br></b>
<p><b>返回值</b>
<p>iconv函数返回本次调用中转换的字符数，可逆的转换不计入。出错时，它将修改errno并返回(size_t)(-1)。
<p><b>错误</b>
<p>除了其它错误以外，出现以下错误：
<p><b>E2BIG</b>
<p>*outbuf没有足够的空间。
<p><b>EILSEQ</b>
<p>输入含无效的多字节序列。
<p><b>EINVAL</b>
<p>输入含不完整多字节序列。
<p>(3) <b>int iconv_close(iconv_t cd);</b>
<p>此函数用于关闭转换句柄,释放资源。
<p>这个库使用很简单，使用举例：
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a><pre>int gbk2utf8(char *dst, int outlen,char *src,int inlen)<br>{<br>     static iconv_t  its_conv;<br>     char *p1;<br>     its_conv = iconv_open("UTF-8","GBK");<br>     const char*  p = src;<br>     p1 = dst;<br>     iconv(its_conv, &amp;p, &amp;inlen, &amp;p1, &amp;outlen);<br>     //printf("%s\n",out);<br>     iconv_close(its_conv);<br>     return 0;<br>}</pre>
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a>
<p><strong>网上一个人写的支持windows和linux的wchar_t与UTF-8编码之间的转换和UTF-16和wchar_t之间的转换代码</strong>
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a><pre>#ifdef WINDOWS  <br> #include &lt;windows.h&gt;   <br> #include &lt;stdio.h&gt;  <br> #include &lt;ctype.h&gt;  <br>#else  <br> #include &lt;iconv.h&gt;  <br> #include &lt;wctype.h&gt;  <br> #include &lt;wchar.h&gt;  <br> #include &lt;errno.h&gt;  <br>#endif  <br>     <br> //wchar_t转成UTF-8  <br>int FW2UTF8Convert( const wchar_t* a_szSrc, int a_nSrcSize, char* a_szDest, int a_nDestSize )  <br>{  <br>     #ifdef WINDOWS  <br>         return WideCharToMultiByte( CP_UTF8, 0, a_szSrc, -1, a_szDest, a_nDestSize, NULL, NULL );  <br>     #else  <br>         size_t result;  <br>         iconv_t env;  <br>         env = iconv_open("UTF-8","WCHAR_T");  <br>         if (env==(iconv_t)-1)  <br>         {  <br>              printf("iconv_open WCHAR_T-&gt;UTF8 error%s %d\n",strerror(errno),errno) ;  <br>              return -1;  <br>         }  <br>         result = iconv(env,(char**)&amp;a_szSrc,(size_t*)&amp;a_nSrcSize,(char**)&amp;a_szDest,(size_t*)&amp;a_nDestSize);  <br>         if (result==(size_t)-1)  <br>         {  <br>              printf("iconv WCHAR_T-&gt;UTF8 error %d\n",errno) ;  <br>              return -1;  <br>         }  <br>         iconv_close(env);  <br>         return (int)result;  <br>     #endif  <br>}  <br>  <br> //UTF-8转成wchar_t  <br>int FUTF82WConvert( const char* a_szSrc, wchar_t* a_szDest, int a_nDestSize )  <br>{  <br>     #ifdef WINDOWS  <br>         return MultiByteToWideChar( CP_UTF8, 0, a_szSrc, -1, a_szDest, a_nDestSize );  <br>     #else  <br>         size_t result;  <br>         iconv_t env;  <br>         int size = strlen(a_szSrc)+1 ;  <br>         env = iconv_open("WCHAR_T","UTF-8");  <br>         if (env==(iconv_t)-1)  <br>         {  <br>              printf("iconv_open UTF8-&gt;WCHAR_T error %d\n",errno) ;  <br>              return -1;  <br>         }  <br>         result = iconv(env,(char**)&amp;a_szSrc,(size_t*)&amp;size,(char**)&amp;a_szDest,(size_t*)&amp;a_nDestSize);  <br>         if (result==(size_t)-1)  <br>         {  <br>              printf("iconv UTF8-&gt;WCHAR_T error %d\n",errno) ;  <br>              return -1;  <br>         }  <br>         iconv_close(env);  <br>         return (int)result;  <br>     #endif  <br>}<br>   <br> //wchar_t转成utf16  <br>int FW2UConvert( const wchar_t* a_szSrc, int  a_nSize,char* a_szDest, int a_nDestSize )  <br>{  <br>     #ifdef WINDOWS  <br>         memcpy_s((wchar_t*)a_szDest,a_nDestSize,a_szSrc,a_nSize);  <br>         return a_nSize ;  <br>     #else  <br>         size_t result;  <br>         iconv_t env;  <br>         env = iconv_open("UCS-2-INTERNAL","UCS-4-INTERNAL");  <br>         if (env==(iconv_t)-1)  <br>         {  <br>              printf("iconv_open WCHAR_T-&gt;UTF16 error%s %d\n", strerror(errno),errno);  <br>              return -1;  <br>         }  <br>         result = iconv(env,(char**)&amp;a_szSrc,(size_t*)&amp;a_nSize,(char**)&amp;a_szDest,(size_t*)&amp;a_nDestSize);  <br>         if (result==(size_t)-1)  <br>         {  <br>              printf("iconv WCHAR_T-&gt;UTF16 error %s %d\n", strerror(errno), errno);  <br>              return -1;  <br>         }  <br>         iconv_close(env);  <br>         return (int)result;  <br>     #endif  <br>}  <br>  <br>  <br> //utf16转成wchar_t  <br>int FU2WConvert( const  char* a_szSrc, int a_nSize, wchar_t* a_szDest, int a_nDestSize )  <br>{  <br>     #ifdef WINDOWS  <br>         memcpy_s(a_szDest,a_nDestSize,(const wchar_t*)a_szSrc,a_nSize);  <br>         return a_nSize ;  <br>     #else  <br>         size_t result;  <br>         iconv_t env;  <br>         env = iconv_open("UCS-4-INTERNAL","UCS-2-INTERNAL");  <br>         if (env==(iconv_t)-1)  <br>         {  <br>              printf("iconv_open error %d\n",errno) ;  <br>              return -1;  <br>         }  <br>         result = iconv(env,(char**)&amp;a_szSrc,(size_t*)&amp;a_nSize,(char**)&amp;a_szDest,(size_t*)&amp;a_nDestSize);  <br>         if (result==(size_t)-1)  <br>         {  <br>              printf("UTF16 -&gt; WCHAR_T conv error %d\n",errno) ;  <br>              return -1;  <br>         }  <br>         iconv_close(env);  <br>         return (int)result;  <br>     #endif  <br>}</pre>
<p><a href="http://www.cnblogs.com/MichaelOwen/articles/"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif"></a>
<p>网上不错的资源：
<p>C/C++ 编程中多国语言处理
<p><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-ccppglb/index.html?ca=drs-">http://www.ibm.com/developerworks/cn/linux/l-cn-ccppglb/index.html?ca=drs-</a>
<p>彻底解密C++宽字符：1、从char到wchar_t
<p><a href="http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740615.aspx">http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740615.aspx</a>
<p>彻底解密C++宽字符：2、Unicode和UTF
<p><a href="http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740616.aspx">http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740616.aspx</a>
<p>彻底解密C++宽字符：3、利用C运行时库函数转换
<p><a href="http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740618.aspx">http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740618.aspx</a>
<p>彻底解密C++宽字符：4、利用codecvt和use_facet转换
<p><a href="http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740620.aspx">http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740620.aspx</a>
<p>彻底解密C++宽字符：5、利用fstream转换
<p><a href="http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740621.aspx">http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740621.aspx</a>
<p>彻底解密C++宽字符：6、国际化策略
<p><a href="http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740622.aspx">http://blog.csdn.net/wallaceli1981/archive/2010/07/16/5740622.aspx</a>
<p>C 源文件内的中文(1)
<p><a href="http://hi.baidu.com/cyclone/blog/item/e48c76099b002ca22eddd4c3.html">http://hi.baidu.com/cyclone/blog/item/e48c76099b002ca22eddd4c3.html</a>
<p>C 源文件内的中文(2)
<p><a href="http://hi.baidu.com/cyclone/blog/item/25b262d973e9d72111df9bcf.html">http://hi.baidu.com/cyclone/blog/item/25b262d973e9d72111df9bcf.html</a>
<p>UTF-8 and Unicode FAQ for Unix/Linux
<p><a href="http://blog.csdn.net/lovekatherine/archive/2007/08/30/1765903.aspx">http://blog.csdn.net/lovekatherine/archive/2007/08/30/1765903.aspx</a><img src ="http://www.cppblog.com/izualzhy/aggbug/188245.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-25 14:29 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/25/188245.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字典树的介绍与实现</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/22/187986.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Wed, 22 Aug 2012 11:56:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/22/187986.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/187986.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/22/187986.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/187986.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/187986.html</trackback:ping><description><![CDATA[<p>假若需要这样的实现，我有一个词典，词典内容如下：</p> <p>pad</p> <p>park</p> <p>panda</p> <p>pan</p> <p>apply</p> <p>apple</p> <p>append</p> <p>app</p> <p>application</p> <p>需要统计以p为前缀的单词个数，好的，最直观的办法，我遍历所有的字符串，记数，ok，作业完成了！</p> <p>A: 完成的很好！那现在我想要pa开始的~</p> <p>Me: 嗯~好的，遍历，记数，ok~</p> <p>A:我要app前缀的个数~</p> <p>Me: 嗯?~好吧。。</p> <p>A:appl的，pan的，前缀个数~</p> <p>Me: &#8230;.</p> <p>&nbsp;</p> <p>是不是很无奈，这个时候字典树就派上用场了。当然首先要明确的是，我们的目标是以空间换时间。</p> <p>字典树，从根节点开始，每个节点可能的child数是26（如果只有英文小写字母的话），当然是随着词汇添加而完善这棵树的。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;*&nbsp;=====================================================================================<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Filename:&nbsp;&nbsp;Trie.cpp<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;Description:&nbsp;&nbsp;字典数的定义和使用<br />&nbsp;*<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Version:&nbsp;&nbsp;1.0<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Created:&nbsp;&nbsp;08/22/2012&nbsp;07:01:05&nbsp;PM<br />&nbsp;*<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Author:&nbsp;&nbsp;zhy&nbsp;(),&nbsp;izualzhy@163.com<br />&nbsp;*&nbsp;=====================================================================================<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><br />#include&nbsp;&lt;stdio.h&gt;<br />#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>.h&gt;<br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;MAX&nbsp;26<span style="color: #008000; ">//</span><span style="color: #008000; ">可以变化，比如只有数字则为10</span><br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">字典数的基础结构</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">struct</span>&nbsp;Trie<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;Trie()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i=0;&nbsp;i&lt;MAX;&nbsp;++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next[i]&nbsp;=&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count&nbsp;=&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;Trie&nbsp;*next[MAX];<span style="color: #008000; ">//</span><span style="color: #008000; ">下一层的节点数目，初始时指针全是null，当添加词汇后会逐步添加</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;count;<span style="color: #008000; ">//</span><span style="color: #008000; ">前缀数目</span><span style="color: #008000; "><br /></span>};<br /><br />Trie*&nbsp;root&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Trie;<span style="color: #008000; ">//</span><span style="color: #008000; ">根节点<br /><br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">根据str完善以root为根节点的词典树</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">void</span>&nbsp;createTrie(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*str)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;Trie*&nbsp;p&nbsp;=&nbsp;root;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(*str)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;index&nbsp;=&nbsp;*str&nbsp;-&nbsp;'a';<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(p-&gt;next[index]!=NULL)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;next[index]-&gt;count++;<span style="color: #008000; ">//</span><span style="color: #008000; ">如果已经存在，前缀数目+1</span><span style="color: #008000; "><br /></span>&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;p-&gt;next[index]&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Trie;<span style="color: #008000; ">//</span><span style="color: #008000; ">不存在则建立</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;=&nbsp;p-&gt;next[index];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str++;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><span style="color: #008000; ">//</span><span style="color: #008000; ">查找str为前缀的词汇数目</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">int</span>&nbsp;findTrie(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;str)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len&nbsp;=&nbsp;strlen(str);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(len&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;Trie*&nbsp;p&nbsp;=&nbsp;root;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">逐个字符遍历str</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(*str)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;index&nbsp;=&nbsp;*str&nbsp;-&nbsp;'a';<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(p-&gt;next[index]&nbsp;!=&nbsp;NULL)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;=&nbsp;p-&gt;next[index];<span style="color: #008000; ">//</span><span style="color: #008000; ">该字符存在，试试下一个字符</span><span style="color: #008000; "><br /></span>&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;<span style="color: #0000FF; ">return</span>&nbsp;0;<span style="color: #008000; ">//</span><span style="color: #008000; ">如果不存在该字符，则不存在该前缀</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str++;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;p-&gt;count;<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;destroyTrie(Trie*&nbsp;node)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(node&nbsp;==&nbsp;NULL)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i=0;&nbsp;i&lt;MAX;&nbsp;++i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(node-&gt;next[i]&nbsp;!=&nbsp;NULL)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destroyTrie(node-&gt;next[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;node;<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;s[100];<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("input&nbsp;the&nbsp;words&nbsp;for&nbsp;trie\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(gets(s)&nbsp;&amp;&amp;&nbsp;strlen(s))<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;createTrie(s);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;printf("search&nbsp;what&nbsp;u&nbsp;want?:\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(gets(s)&nbsp;&amp;&amp;&nbsp;strlen(s))<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s:&nbsp;%d\n",&nbsp;s,&nbsp;findTrie(s));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;destroyTrie(root);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div></p> <p>运行结果：</p> <p>y@y-VirtualBox:/mnt/mydocuments/Training$ ./Trie<br />input the words for trie<br />pad<br />park<br />panda<br />pan<br />apply<br />apple<br />append<br />app<br />application</p> <p>search what u want?:<br />p<br />p: 4<br />a<br />a: 5<br />pa<br />pa: 4<br />pan<br />pan: 2<br />par<br />par: 1<br />app<br />app: 5<br />appl<br />appl: 3<br />appe<br />appe: 1</p><img src ="http://www.cppblog.com/izualzhy/aggbug/187986.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-22 19:56 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/22/187986.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++简单智能指针的实现</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/18/187606.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 18 Aug 2012 09:31:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/18/187606.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/187606.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/18/187606.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/187606.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/187606.html</trackback:ping><description><![CDATA[<p>平时我们使用指针必须是非常小心的，比如这种情况：</p> <p>int *p1 = new int(1);</p> <p>int *p2 = p1;</p> <p>&#8230;//一段足以让我们忘记了p2,p1关系的代码</p> <p>delete p1;</p> <p>*p2 = xxx;//出错，p1已经delete了。</p> <p>这种情况经常让人苦恼，智能指针可以很好的处理这点。</p> <p>原理其实很简单：</p> <p>对于每次指针的复制(类似于int *p2 = p1)，构造等操作,智能指针内部都有一个引用计数来记录，除非引用计数为0，否则不会删除指向的对象。</p> <p>我的简单的实现：</p><pre class="code"><span style="color: #937a42">/*
 * =====================================================================================
 *       Filename:  SmartPointer.cpp
 *    Description:  implement of smart pointer
 *
 *        Version:  1.0
 *        Created:  08/18/2012 04:36:36 PM
 *
 *         Author:  zhy (), izualzhy@163.com
 * =====================================================================================
 */
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;iostream&gt;
</span><span style="color: #400080">using namespace </span>std<span style="color: #2e53d1">;

</span><span style="color: #400080">template </span><span style="color: #2e53d1">&lt;</span><span style="color: #400080">class </span>T<span style="color: #2e53d1">&gt;
</span><span style="color: #400080">class </span>MySmartPointer<span style="color: #2e53d1">;

</span><span style="color: #937a42">/**
 * @brief 引用计数类
 */
</span><span style="color: #400080">template </span><span style="color: #2e53d1">&lt;</span><span style="color: #400080">typename </span>T<span style="color: #2e53d1">&gt;
</span><span style="color: #400080">class </span>MyRefPtr
<span style="color: #2e53d1">{
    </span><span style="color: #400080">friend class </span>MySmartPointer<span style="color: #2e53d1">&lt;</span>T<span style="color: #2e53d1">&gt;;
    </span>MyRefPtr<span style="color: #2e53d1">(</span>T<span style="color: #2e53d1">* </span>p<span style="color: #2e53d1">)
        : </span>ptr<span style="color: #2e53d1">(</span>p<span style="color: #2e53d1">)
        , </span>counter<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {}

    ~</span>MyRefPtr<span style="color: #2e53d1">()
    {
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>counter<span style="color: #2e53d1">&lt;=</span><span style="color: #259241">0</span><span style="color: #2e53d1">)
            </span><span style="color: #400080">delete </span>ptr<span style="color: #2e53d1">;
    }

    </span>T<span style="color: #2e53d1">* </span>ptr<span style="color: #2e53d1">;
    </span><span style="color: #400080">int </span>counter<span style="color: #2e53d1">;
};

</span><span style="color: #400080">template </span><span style="color: #2e53d1">&lt;</span><span style="color: #400080">typename </span>T<span style="color: #2e53d1">&gt;
</span><span style="color: #400080">class </span>MySmartPointer
<span style="color: #2e53d1">{
</span><span style="color: #400080">public</span><span style="color: #2e53d1">:
    </span>MySmartPointer<span style="color: #2e53d1">(</span>T<span style="color: #2e53d1">* </span>p<span style="color: #2e53d1">)
        : </span>refPtr<span style="color: #2e53d1">(</span><span style="color: #400080">new </span>MyRefPtr<span style="color: #2e53d1">&lt;</span>T<span style="color: #2e53d1">&gt;(</span>p<span style="color: #2e53d1">))
    {
        </span>cout <span style="color: #2e53d1">&lt;&lt; </span><span style="color: #259241">"Count: " </span><span style="color: #2e53d1">&lt;&lt; </span>refPtr<span style="color: #2e53d1">-&gt;</span>counter <span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;
    }

    </span>MySmartPointer<span style="color: #2e53d1">(</span><span style="color: #400080">const </span>MySmartPointer<span style="color: #2e53d1">&lt;</span>T<span style="color: #2e53d1">&gt;&amp; </span>SPtr<span style="color: #2e53d1">)
        : </span>refPtr<span style="color: #2e53d1">(</span>SPtr<span style="color: #2e53d1">.</span>refPtr<span style="color: #2e53d1">)
    {
        ++</span>refPtr<span style="color: #2e53d1">-&gt;</span>counter<span style="color: #2e53d1">;
        </span>cout <span style="color: #2e53d1">&lt;&lt; </span><span style="color: #259241">"Count: " </span><span style="color: #2e53d1">&lt;&lt; </span>refPtr<span style="color: #2e53d1">-&gt;</span>counter <span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;
    }

    </span>MySmartPointer<span style="color: #2e53d1">&amp; </span><span style="color: #400080">operator</span><span style="color: #2e53d1">=(</span><span style="color: #400080">const </span>MySmartPointer<span style="color: #2e53d1">&lt;</span>T<span style="color: #2e53d1">&gt;&amp; </span>rhs<span style="color: #2e53d1">)
    {
        +</span>rhs<span style="color: #2e53d1">.</span>refPtr<span style="color: #2e53d1">-&gt;</span>counter<span style="color: #2e53d1">;
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">(--</span>refPtr<span style="color: #2e53d1">-&gt;</span>counter <span style="color: #2e53d1">== </span><span style="color: #259241">0</span><span style="color: #2e53d1">)
            </span><span style="color: #400080">delete </span>refPtr<span style="color: #2e53d1">;
        </span>refPtr <span style="color: #2e53d1">= </span>rhs<span style="color: #2e53d1">.</span>refPtr<span style="color: #2e53d1">;
        </span>cout <span style="color: #2e53d1">&lt;&lt; </span><span style="color: #259241">"Count: " </span><span style="color: #2e53d1">&lt;&lt; </span>refPtr<span style="color: #2e53d1">-&gt;</span>counter <span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;
        </span><span style="color: #400080">return </span><span style="color: #2e53d1">*</span><span style="color: #400080">this</span><span style="color: #2e53d1">;
    }

    ~</span>MySmartPointer<span style="color: #2e53d1">()
    {
        </span>cout <span style="color: #2e53d1">&lt;&lt; </span><span style="color: #259241">"Count: " </span><span style="color: #2e53d1">&lt;&lt; </span>refPtr<span style="color: #2e53d1">-&gt;</span>counter <span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">(--</span>refPtr<span style="color: #2e53d1">-&gt;</span>counter <span style="color: #2e53d1">== </span><span style="color: #259241">0</span><span style="color: #2e53d1">)
            </span><span style="color: #400080">delete </span>refPtr<span style="color: #2e53d1">;
    }

    </span>T<span style="color: #2e53d1">&amp; </span><span style="color: #400080">operator</span><span style="color: #2e53d1">*()
    {
        </span><span style="color: #400080">return </span><span style="color: #2e53d1">*(</span>refPtr<span style="color: #2e53d1">-&gt;</span>ptr<span style="color: #2e53d1">);
    }

    </span>T<span style="color: #2e53d1">* </span><span style="color: #400080">operator</span><span style="color: #2e53d1">-&gt;()
    {
        </span><span style="color: #400080">return </span>refPtr<span style="color: #2e53d1">-&gt;</span>ptr<span style="color: #2e53d1">;
    }

</span><span style="color: #400080">private</span><span style="color: #2e53d1">:
    </span>MyRefPtr<span style="color: #2e53d1">&lt;</span>T<span style="color: #2e53d1">&gt;* </span>refPtr<span style="color: #2e53d1">;
};

</span><span style="color: #400080">class </span>Test
<span style="color: #2e53d1">{
</span><span style="color: #400080">public</span><span style="color: #2e53d1">:
    </span>Test<span style="color: #2e53d1">() { </span>c<span style="color: #2e53d1">=</span><span style="color: #259241">'x'</span><span style="color: #2e53d1">;</span>cout <span style="color: #2e53d1">&lt;&lt; </span><span style="color: #259241">"Test::Test" </span><span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;}
    ~</span>Test<span style="color: #2e53d1">() {</span>cout <span style="color: #2e53d1">&lt;&lt; </span><span style="color: #259241">"Test::~Test" </span><span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;}
    </span><span style="color: #400080">char </span>c<span style="color: #2e53d1">;
};

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span>Test<span style="color: #2e53d1">* </span>test <span style="color: #2e53d1">= </span><span style="color: #400080">new </span>Test<span style="color: #2e53d1">;
    </span>cout <span style="color: #2e53d1">&lt;&lt; </span>test<span style="color: #2e53d1">-&gt;</span>c <span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;
    </span>MySmartPointer<span style="color: #2e53d1">&lt;</span>Test<span style="color: #2e53d1">&gt; </span>sptr1<span style="color: #2e53d1">(</span>test<span style="color: #2e53d1">);
    </span>cout <span style="color: #2e53d1">&lt;&lt; </span>sptr1<span style="color: #2e53d1">-&gt;</span>c <span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;
    </span>sptr1<span style="color: #2e53d1">-&gt;</span>c <span style="color: #2e53d1">= </span><span style="color: #259241">'a'</span><span style="color: #2e53d1">;
    </span>MySmartPointer<span style="color: #2e53d1">&lt;</span>Test<span style="color: #2e53d1">&gt; </span>sptr2<span style="color: #2e53d1">(</span>sptr1<span style="color: #2e53d1">);
    </span>cout <span style="color: #2e53d1">&lt;&lt; </span>sptr2<span style="color: #2e53d1">-&gt;</span>c <span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;
    {
        </span>MySmartPointer<span style="color: #2e53d1">&lt;</span>Test<span style="color: #2e53d1">&gt; </span>sptr3 <span style="color: #2e53d1">= </span>sptr2<span style="color: #2e53d1">;
        </span>cout <span style="color: #2e53d1">&lt;&lt; </span>sptr3<span style="color: #2e53d1">-&gt;</span>c <span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;
    }
    </span>cout <span style="color: #2e53d1">&lt;&lt; </span>test<span style="color: #2e53d1">-&gt;</span>c <span style="color: #2e53d1">&lt;&lt; </span>endl<span style="color: #2e53d1">;

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p>还觉得有问题的地方：</p>
<p>Test* test = new Test;</p>
<p>{</p>
<p>MySmartPointer<span style="color: #2e53d1">&lt;</span>Test<span style="color: #2e53d1">&gt; </span>sptr1<span style="color: #2e53d1">(</span>test<span style="color: #2e53d1">); </span><br />}</p>
<p>看来还是有空找个详细的源码看下才行。</p><img src ="http://www.cppblog.com/izualzhy/aggbug/187606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-18 17:31 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/18/187606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用gcc关键字constructor,destructor实现main执行前后的操作</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/18/187598.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 18 Aug 2012 07:04:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/18/187598.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/187598.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/18/187598.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/187598.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/187598.html</trackback:ping><description><![CDATA[<p>发现gcc有很多之前不明白甚至完全没有听说过的关键字，不知道这些都在什么地方会用上。</p> <p>看个例子：</p><pre class="code"><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;

</span><span style="color: #400080">void </span>__init<span style="color: #2e53d1">()
{
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"before main\n"</span><span style="color: #2e53d1">);
}

</span><span style="color: #400080">void </span>__exit<span style="color: #2e53d1">()
{
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"after main\n"</span><span style="color: #2e53d1">);
}

</span><span style="color: #400080">void </span>__init<span style="color: #2e53d1">() </span>__attribute__ <span style="color: #2e53d1">((</span>constructor<span style="color: #2e53d1">));
</span><span style="color: #400080">void </span>__exit<span style="color: #2e53d1">() </span>__attribute__ <span style="color: #2e53d1">((</span>destructor<span style="color: #2e53d1">));

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"in main\n"</span><span style="color: #2e53d1">);

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p>输出：</p>
<p>y@y-VirtualBox:/mnt/Documents/Training$ gcc -o test test.c<br>y@y-VirtualBox:/mnt/Documents/Training$ ./test<br>before main<br>in main<br>after main</p>
<p>稍微详细点的例子以及更多的属性在参考资料里多一些。但一直没有用到过，似乎并不是很实用的样子。</p>
<p>参考资料：</p>
<p><a href="http://blog.csdn.net/starstarstone/article/details/7490612">http://blog.csdn.net/starstarstone/article/details/7490612</a></p><img src ="http://www.cppblog.com/izualzhy/aggbug/187598.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-18 15:04 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/18/187598.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sscanf常用总结</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/17/187514.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Fri, 17 Aug 2012 12:36:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/17/187514.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/187514.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/17/187514.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/187514.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/187514.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:ca3b4d75-ae64-4627-8186-9bcbaad63d1d" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/sscanf" rel="tag">sscanf</a></div> <p>sscanf用于从字符串中提取数据（整形，字符串等等）。</p> <p>支持类似于正则的表达式，但却没有正则表达式强大。</p> <p>很久不碰，一直只是用”%s”,”%d”,对于”[^a-z]/%[abc]”这种复杂的format却很久不使用，感觉都快遗忘了.</p> <p>转换的一些规则：</p> <p>sscanf() - 从一个字符串中读进与指定格式相符的数据.<br>　　函数原型:<br>　　int sscanf( string str, string fmt, mixed var1, mixed var2 ... );<br>　　int scanf( const char *format [,argument]... );<br>　　说明：<br>　　sscanf与scanf类似，都是用于输入的，只是后者以屏幕(stdin)为输入源，前者以固定字符串为输入源。<br>　　其中的format可以是一个或多个 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符号}<br>　　注：<br>　　1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)<br>　　2、{a|b|c}表示a,b,c中选一，[d],表示可以有d也可以没有d。<br>　　3、width表示读取宽度。<br>　　4、{h | l | I64 | L}:参数的size,通常h表示单字节size，I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。<br>　　5、type :这就很多了，就是%s,%d之类。<br>　　6、特别的：%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉，不会向目标参数中写入值<br>　　支持集合操作：<br>　　%[a-z] 表示匹配a到z中任意字符，贪婪性(尽可能多的匹配)<br>　　%[aB'] 匹配a、B、'中一员，贪婪性<br>　　%[^a] 匹配非a的任意字符，贪婪性 <p>&nbsp; <p>看个例子：</p><pre class="code"><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdlib.h&gt;

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span><span style="color: #400080">char </span>ch<span style="color: #2e53d1">[</span><span style="color: #259241">100</span><span style="color: #2e53d1">] = {</span><span style="color: #259241">0</span><span style="color: #2e53d1">};
    </span>sscanf<span style="color: #2e53d1">(</span><span style="color: #259241">"123456abcdeABCDEF"</span><span style="color: #2e53d1">, </span><span style="color: #259241">"%[1-9a-z]"</span><span style="color: #2e53d1">, </span>ch<span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s\n"</span><span style="color: #2e53d1">,</span>ch<span style="color: #2e53d1">);

    </span>memset<span style="color: #2e53d1">(</span>ch<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">, </span><span style="color: #259241">100</span><span style="color: #2e53d1">);
    </span>sscanf<span style="color: #2e53d1">(</span><span style="color: #259241">"123456abcdefABCDEF"</span><span style="color: #2e53d1">, </span><span style="color: #259241">"%[^A-Z]"</span><span style="color: #2e53d1">, </span>ch<span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s\n"</span><span style="color: #2e53d1">,</span>ch<span style="color: #2e53d1">);

    </span>memset<span style="color: #2e53d1">(</span>ch<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">, </span><span style="color: #259241">100</span><span style="color: #2e53d1">);
    </span>sscanf<span style="color: #2e53d1">(</span><span style="color: #259241">"hello, world"</span><span style="color: #2e53d1">, </span><span style="color: #259241">"%*s%s"</span><span style="color: #2e53d1">, </span>ch<span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s\n"</span><span style="color: #2e53d1">,</span>ch<span style="color: #2e53d1">);

    </span><span style="color: #400080">int </span>a<span style="color: #2e53d1">,</span>b<span style="color: #2e53d1">,</span>c<span style="color: #2e53d1">;
    </span>sscanf<span style="color: #2e53d1">(</span><span style="color: #259241">"2006:03:18"</span><span style="color: #2e53d1">, </span><span style="color: #259241">"%d:%d:%d"</span><span style="color: #2e53d1">,&amp;</span>a<span style="color: #2e53d1">,&amp;</span>b<span style="color: #2e53d1">,&amp;</span>c<span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%d %d %d\n"</span><span style="color: #2e53d1">,</span>a<span style="color: #2e53d1">,</span>b<span style="color: #2e53d1">,</span>c<span style="color: #2e53d1">);

    </span><span style="color: #400080">char </span>ch2<span style="color: #2e53d1">[</span><span style="color: #259241">100</span><span style="color: #2e53d1">] = {</span><span style="color: #259241">0</span><span style="color: #2e53d1">};
    </span>memset<span style="color: #2e53d1">(</span>ch<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">, </span><span style="color: #259241">100</span><span style="color: #2e53d1">);
    </span>sscanf<span style="color: #2e53d1">(</span><span style="color: #259241">"iios/12DDWDFF@123"</span><span style="color: #2e53d1">, </span><span style="color: #259241">"%*[^/]/%[^@]@%s"</span><span style="color: #2e53d1">, </span>ch<span style="color: #2e53d1">,</span>ch2<span style="color: #2e53d1">);//%[]类似于一个type field
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s|%s\n"</span><span style="color: #2e53d1">, </span>ch<span style="color: #2e53d1">, </span>ch2<span style="color: #2e53d1">);

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}
</span></pre><pre class="code"><span style="color: #2e53d1">我的理解是%[],%s,%d等等就是一个type field，如果没有加*，则表示匹配的内容要存入一个buffer里面。
</span></pre>
<p>输出：</p>
<p>y@y-VirtualBox:/mnt/Documents/Training$ ./test<br>123456abcde<br>123456abcdef<br>world<br>2006 3 18<br>12DDWDFF|123</p><img src ="http://www.cppblog.com/izualzhy/aggbug/187514.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-17 20:36 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/17/187514.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>strtoul,strtol,strtod用于字符串到整形，浮点型的数据的转换</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/16/187404.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Thu, 16 Aug 2012 11:52:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/16/187404.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/187404.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/16/187404.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/187404.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/187404.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7e0782f6-0c41-4b1b-94af-426cc38fefca" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/strtol" rel="tag">strtol</a>,<a href="http://technorati.com/tags/strtoul" rel="tag">strtoul</a>,<a href="http://technorati.com/tags/strtod" rel="tag">strtod</a></div> <p>函数原型：</p><pre>long int strtol ( const char * str, char ** endptr, int base );</pre><pre>unsigned long int strtoul ( const char * str, char ** endptr, int base );</pre><pre>double strtod ( const char * str, char ** endptr );</pre><pre>&nbsp;</pre><pre>这几个函数从str指向的字符开始转化，忽略掉前面的空格，遇到错误无法转换的字符则返回，如果endptr不为空，则将该字符存储在endptr里。</pre><pre>对前两个函数，base则表示其进制。</pre><pre>想到之前的一篇笔记：<a href="http://www.cppblog.com/izualzhy/archive/2012/07/09/182456.html">http://www.cppblog.com/izualzhy/archive/2012/07/09/182456.html</a></pre><pre>需要将”0xE4”转到E4(1个字节)</pre><pre>可以简单的这么写了：</pre><pre class="code">    <span style="color: #400080">char </span>str<span style="color: #2e53d1">[] = </span><span style="color: #259241">"E4"</span><span style="color: #2e53d1">;
    </span><span style="color: #400080">int </span>a<span style="color: #2e53d1">;
    </span>a <span style="color: #2e53d1">= </span>strtol<span style="color: #2e53d1">(</span>str<span style="color: #2e53d1">,</span>NULL<span style="color: #2e53d1">,</span><span style="color: #259241">16</span><span style="color: #2e53d1">);
</span></pre><pre>看个详细的例子：</pre><pre class="code"><span style="color: #937a42">/*
 * =====================================================================================
 *       Filename:  strtodata.c
 *    Description:  string to long/unsigned long/double
 *
 *        Version:  1.0
 *        Created:  08/16/2012 07:30:17 PM
 *
 *         Author:  zhy (), izualzhy@163.com
 * =====================================================================================
 */

</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdlib.h&gt;

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span><span style="color: #400080">char </span>numbers<span style="color: #2e53d1">[] = </span><span style="color: #259241">"2001 60c0c0 -1101110100110100100000 0x6fffff"</span><span style="color: #2e53d1">;
    </span><span style="color: #400080">char </span><span style="color: #2e53d1">*</span>pEnd<span style="color: #2e53d1">;
    </span><span style="color: #400080">long int </span>li1<span style="color: #2e53d1">,</span>li2<span style="color: #2e53d1">,</span>li3<span style="color: #2e53d1">,</span>li4<span style="color: #2e53d1">;
    </span>li1 <span style="color: #2e53d1">= </span>strtol<span style="color: #2e53d1">(</span>numbers<span style="color: #2e53d1">, &amp;</span>pEnd<span style="color: #2e53d1">, </span><span style="color: #259241">10</span><span style="color: #2e53d1">);
    </span>li2 <span style="color: #2e53d1">= </span>strtol<span style="color: #2e53d1">(</span>pEnd<span style="color: #2e53d1">, &amp;</span>pEnd<span style="color: #2e53d1">, </span><span style="color: #259241">16</span><span style="color: #2e53d1">);
    </span>li3 <span style="color: #2e53d1">= </span>strtol<span style="color: #2e53d1">(</span>pEnd<span style="color: #2e53d1">, &amp;</span>pEnd<span style="color: #2e53d1">, </span><span style="color: #259241">2</span><span style="color: #2e53d1">);
    </span>li4 <span style="color: #2e53d1">= </span>strtol<span style="color: #2e53d1">(</span>pEnd<span style="color: #2e53d1">, </span>NULL<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"The decimal equivalents are: %ld, %ld, %ld, %ld.\n"</span><span style="color: #2e53d1">,</span>li1<span style="color: #2e53d1">,</span>li2<span style="color: #2e53d1">,</span>li3<span style="color: #2e53d1">,</span>li4<span style="color: #2e53d1">);

    </span><span style="color: #400080">char </span>digits<span style="color: #2e53d1">[] = </span><span style="color: #259241">"365.24   29.53 -1.23456"</span><span style="color: #2e53d1">;    
    </span><span style="color: #400080">double </span>d1<span style="color: #2e53d1">,</span>d2<span style="color: #2e53d1">,</span>d3<span style="color: #2e53d1">;
    </span>d1 <span style="color: #2e53d1">= </span>strtod<span style="color: #2e53d1">(</span>digits<span style="color: #2e53d1">, &amp;</span>pEnd<span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%c\n"</span><span style="color: #2e53d1">, *</span>pEnd<span style="color: #2e53d1">);
    </span>d2 <span style="color: #2e53d1">= </span>strtod<span style="color: #2e53d1">(</span>pEnd<span style="color: #2e53d1">, &amp;</span>pEnd<span style="color: #2e53d1">);
    </span>d3 <span style="color: #2e53d1">= </span>strtod<span style="color: #2e53d1">(</span>pEnd<span style="color: #2e53d1">, </span>NULL<span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"The moon completes %f/%f orbits per Earth yes.%f\n"</span><span style="color: #2e53d1">,</span>d1<span style="color: #2e53d1">,</span>d2<span style="color: #2e53d1">,</span>d3<span style="color: #2e53d1">);

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p>运行结果：</p>
<p>The decimal equivalents are: 2001, 6340800, -3624224, 7340031.<br>&nbsp;<br>The moon completes 365.240000/29.530000 orbits per Earth yes.-1.234560</p>
<p>参考资料：</p>
<p><a href="http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul/">http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul/</a><br></p><pre>&nbsp;</pre><img src ="http://www.cppblog.com/izualzhy/aggbug/187404.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-16 19:52 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/16/187404.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>汉字转化为拼音，取得拼音首字母</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/11/186891.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 11 Aug 2012 03:38:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/11/186891.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/186891.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/11/186891.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/186891.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/186891.html</trackback:ping><description><![CDATA[<p>第一次看到类似的文章是这里：</p> <p><a href="http://blog.csdn.net/feihu521a/article/details/7648625">http://blog.csdn.net/feihu521a/article/details/7648625</a></p> <p>不过本着转化别人程序的想法，我还是根据自己的需求实现了下。</p> <p>当然如原文所讲，最重要的还是源文件，即一张汉字对应拼音的一个列表。</p> <p>可以从这里下载：</p> <p><a title="http://www.kuaipan.cn/file/id_63303578810318861.html" href="http://www.kuaipan.cn/file/id_63303578810318861.html">http://www.kuaipan.cn/file/id_63303578810318861.html</a></p> <p>感谢原作者：Koichi Yasuoka <a href="mailto:yasuoka@kanji.zinbun.kyoto-u.ac.jp">yasuoka@kanji.zinbun.kyoto-u.ac.jp</a></p> <p>&nbsp;</p> <p>基本功能和源程序相同，不过我保留了声调。</p> <p><font color="#0000ff">想着如果是中英文混合不知道该怎么处理？</font></p> <p><font color="#000000">贴下我的程序：</font></p><pre class="code"><span style="color: #937a42">/*
 * =====================================================================================
 *       Filename:  HanZi2PinYin.cpp
 *    Description:  汉字转化为相应的拼音，汉字取得首字母的功能
 *
 *        Version:  1.0
 *        Created:  08/08/2012 07:39:56 PM
 *
 *         Author:  zhy (), izualzhy@163.com
 * =====================================================================================
 */
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdlib.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;string.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;vector&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;string&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;algorithm&gt;
</span><span style="color: #400080">using namespace </span>std<span style="color: #2e53d1">;

</span><span style="color: #400080">typedef </span>vector<span style="color: #2e53d1">&lt;</span>string<span style="color: #2e53d1">&gt; </span>PinyinList<span style="color: #2e53d1">;
</span><span style="color: #400080">typedef </span>vector<span style="color: #2e53d1">&lt;</span><span style="color: #400080">char</span><span style="color: #2e53d1">&gt; </span>FirstLetterList<span style="color: #2e53d1">;

</span><span style="color: #400080">class </span>CHanZi2PinYin
<span style="color: #2e53d1">{
</span><span style="color: #400080">public</span><span style="color: #2e53d1">:
    </span>CHanZi2PinYin<span style="color: #2e53d1">();
    ~</span>CHanZi2PinYin<span style="color: #2e53d1">();
    </span><span style="color: #937a42">/**
     * @brief HanZi2PinYin 处理单个的unicode字符
     *
     * @param wch unicode字符
     * @param pinyinList 存储可能的拼音（多音字）
     * @param firstLetterList 存储可能的首字母
     *
     * @return 返回是否成功处理
     */
    </span><span style="color: #400080">bool </span>HanZi2PinYin<span style="color: #2e53d1">(</span><span style="color: #400080">const wchar_t </span>wch<span style="color: #2e53d1">, </span>PinyinList<span style="color: #2e53d1">&amp; </span>pinyinList<span style="color: #2e53d1">, </span>FirstLetterList<span style="color: #2e53d1">&amp; </span>firstLetterList<span style="color: #2e53d1">);
    </span><span style="color: #937a42">/**
     * @brief HanZi2PinYin 处理unicode字符串
     * 逐个计算字符串内每个字符，每次计算下一个字符时，将现有的结果逐个加上下一个字符的所有结果
     *
     * @param wstr 字符串指针
     * @param len 字符串长度
     * @param pinyinList 存储可能的拼音串，不同字符之间以空格分开
     * @param firstLetterList 存储可能的首字母串
     *
     * @return 返回是否成功处理
     */
    </span><span style="color: #400080">bool </span>HanZi2PinYin<span style="color: #2e53d1">(</span><span style="color: #400080">const wchar_t</span><span style="color: #2e53d1">* </span>wstr<span style="color: #2e53d1">, </span><span style="color: #400080">const int </span>len<span style="color: #2e53d1">, </span>PinyinList<span style="color: #2e53d1">&amp; </span>pinyinList<span style="color: #2e53d1">, </span>PinyinList<span style="color: #2e53d1">&amp; </span>firstLetterList<span style="color: #2e53d1">);

</span><span style="color: #400080">private</span><span style="color: #2e53d1">:
    </span><span style="color: #400080">bool </span>Init<span style="color: #2e53d1">();
    </span><span style="color: #400080">void </span>UnInit<span style="color: #2e53d1">();

</span><span style="color: #400080">private</span><span style="color: #2e53d1">:
    </span><span style="color: #400080">unsigned int </span>mHanZiStartUnicode<span style="color: #2e53d1">;</span><span style="color: #937a42">//汉字开始unicode，与文件对应
    </span><span style="color: #400080">unsigned int </span>mHanZiEndUnicode<span style="color: #2e53d1">;</span><span style="color: #937a42">//汉字结束unicode，与文件对应
    </span><span style="color: #400080">const </span>string mUnicode2PinyinSourceFile<span style="color: #2e53d1">;</span><span style="color: #937a42">//文件位置
    </span>FILE<span style="color: #2e53d1">* </span>mpFile<span style="color: #2e53d1">;</span><span style="color: #937a42">//文件指针
    </span><span style="color: #400080">unsigned int </span>mBasePos<span style="color: #2e53d1">;</span><span style="color: #937a42">//表示汉字开始unicode的文件位置
</span><span style="color: #2e53d1">};

</span>CHanZi2PinYin<span style="color: #2e53d1">::</span>CHanZi2PinYin<span style="color: #2e53d1">()
    : </span>mUnicode2PinyinSourceFile<span style="color: #2e53d1">(</span><span style="color: #259241">"./Uni2Pinyin"</span><span style="color: #2e53d1">)
    , </span>mHanZiStartUnicode<span style="color: #2e53d1">(</span><span style="color: #259241">0x4E00</span><span style="color: #2e53d1">)
    , </span>mHanZiEndUnicode<span style="color: #2e53d1">(</span><span style="color: #259241">0x9FA5</span><span style="color: #2e53d1">)
    , </span>mpFile<span style="color: #2e53d1">(</span>NULL<span style="color: #2e53d1">)
    , </span>mBasePos<span style="color: #2e53d1">(</span><span style="color: #259241">0</span><span style="color: #2e53d1">)
{
    </span>Init<span style="color: #2e53d1">();
}

</span>CHanZi2PinYin<span style="color: #2e53d1">::~</span>CHanZi2PinYin<span style="color: #2e53d1">()
{
    </span>UnInit<span style="color: #2e53d1">();
}

</span><span style="color: #400080">bool </span>CHanZi2PinYin<span style="color: #2e53d1">::</span>Init<span style="color: #2e53d1">()
{
    </span><span style="color: #400080">const unsigned int </span>maxstrlen <span style="color: #2e53d1">= </span><span style="color: #259241">64</span><span style="color: #2e53d1">;
    </span><span style="color: #400080">char </span>strline<span style="color: #2e53d1">[</span>maxstrlen<span style="color: #2e53d1">] = {</span><span style="color: #259241">0</span><span style="color: #2e53d1">};
    </span><span style="color: #400080">int </span>nPos <span style="color: #2e53d1">= </span><span style="color: #259241">0</span><span style="color: #2e53d1">;

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>mpFile<span style="color: #2e53d1">)
    {
        </span>UnInit<span style="color: #2e53d1">();
    }

    </span>mpFile <span style="color: #2e53d1">= </span>fopen<span style="color: #2e53d1">(</span>mUnicode2PinyinSourceFile<span style="color: #2e53d1">.</span>c_str<span style="color: #2e53d1">(), </span><span style="color: #259241">"r"</span><span style="color: #2e53d1">);
    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>mpFile <span style="color: #2e53d1">== </span>NULL<span style="color: #2e53d1">)
    {
        </span><span style="color: #400080">return false</span><span style="color: #2e53d1">;
    }

    </span><span style="color: #400080">bool </span>findStartUnicode <span style="color: #2e53d1">= </span><span style="color: #400080">false</span><span style="color: #2e53d1">;
    </span>nPos <span style="color: #2e53d1">= </span>ftell<span style="color: #2e53d1">(</span>mpFile<span style="color: #2e53d1">);
    </span><span style="color: #937a42">//找到mBasePos的正确位置
    </span><span style="color: #400080">while </span><span style="color: #2e53d1">(</span>fgets<span style="color: #2e53d1">(</span>strline<span style="color: #2e53d1">, </span>maxstrlen<span style="color: #2e53d1">, </span>mpFile<span style="color: #2e53d1">))
    {
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>strtoul<span style="color: #2e53d1">(</span>strline<span style="color: #2e53d1">, </span>NULL<span style="color: #2e53d1">, </span><span style="color: #259241">16</span><span style="color: #2e53d1">) == </span>mHanZiStartUnicode<span style="color: #2e53d1">)
        {
            </span>mBasePos <span style="color: #2e53d1">= </span>nPos<span style="color: #2e53d1">;
            </span>findStartUnicode <span style="color: #2e53d1">= </span><span style="color: #400080">true</span><span style="color: #2e53d1">;
            </span><span style="color: #400080">break</span><span style="color: #2e53d1">;
        }
        </span>nPos <span style="color: #2e53d1">= </span>ftell<span style="color: #2e53d1">(</span>mpFile<span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">return </span>findStartUnicode<span style="color: #2e53d1">;
}

</span><span style="color: #400080">void </span>CHanZi2PinYin<span style="color: #2e53d1">::</span>UnInit<span style="color: #2e53d1">()
{
    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>mpFile<span style="color: #2e53d1">)
        </span>fclose<span style="color: #2e53d1">(</span>mpFile<span style="color: #2e53d1">);
    </span>mBasePos <span style="color: #2e53d1">= </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}


</span><span style="color: #400080">bool </span>CHanZi2PinYin<span style="color: #2e53d1">::</span>HanZi2PinYin<span style="color: #2e53d1">(</span><span style="color: #400080">const wchar_t </span>wch<span style="color: #2e53d1">, </span>PinyinList<span style="color: #2e53d1">&amp; </span>pinyinList<span style="color: #2e53d1">, </span>FirstLetterList<span style="color: #2e53d1">&amp; </span>firstLetterList<span style="color: #2e53d1">)
{
    </span><span style="color: #937a42">//对非汉字的情况暂时不处理
    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>wch<span style="color: #2e53d1">&lt;</span>mHanZiStartUnicode <span style="color: #2e53d1">|| </span>wch<span style="color: #2e53d1">&gt;</span>mHanZiEndUnicode<span style="color: #2e53d1">)
        </span><span style="color: #400080">return false</span><span style="color: #2e53d1">;

    </span><span style="color: #937a42">//文件定位
    </span>fseek<span style="color: #2e53d1">(</span>mpFile<span style="color: #2e53d1">, </span>mBasePos<span style="color: #2e53d1">, </span>SEEK_SET<span style="color: #2e53d1">);

    </span><span style="color: #400080">char </span>strline<span style="color: #2e53d1">[</span><span style="color: #259241">64</span><span style="color: #2e53d1">] = {</span><span style="color: #259241">0</span><span style="color: #2e53d1">};
    </span><span style="color: #400080">unsigned int </span>lineCounts <span style="color: #2e53d1">= </span>wch <span style="color: #2e53d1">- </span>mHanZiStartUnicode<span style="color: #2e53d1">;
    </span><span style="color: #937a42">//找到要查找的字符那一行
    </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">int </span>i<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>i<span style="color: #2e53d1">&lt;=</span>lineCounts<span style="color: #2e53d1">; ++</span>i<span style="color: #2e53d1">)
        </span>fgets<span style="color: #2e53d1">(</span>strline<span style="color: #2e53d1">, </span><span style="color: #259241">64</span><span style="color: #2e53d1">, </span>mpFile<span style="color: #2e53d1">);

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>strtoul<span style="color: #2e53d1">(</span>strline<span style="color: #2e53d1">, </span>NULL<span style="color: #2e53d1">, </span><span style="color: #259241">16</span><span style="color: #2e53d1">) != </span>wch<span style="color: #2e53d1">)
    {
        </span><span style="color: #400080">return false</span><span style="color: #2e53d1">;
    }

    </span><span style="color: #400080">int </span>pinYinStartIndex <span style="color: #2e53d1">= </span><span style="color: #259241">5</span><span style="color: #2e53d1">;
    </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">int </span>i<span style="color: #2e53d1">=</span><span style="color: #259241">5</span><span style="color: #2e53d1">; </span>i<span style="color: #2e53d1">&lt;</span>strlen<span style="color: #2e53d1">(</span>strline<span style="color: #2e53d1">); ++</span>i<span style="color: #2e53d1">)
    {
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>strline<span style="color: #2e53d1">[</span>i<span style="color: #2e53d1">] == </span><span style="color: #259241">0x09 </span><span style="color: #2e53d1">|| </span>strline<span style="color: #2e53d1">[</span>i<span style="color: #2e53d1">] == </span><span style="color: #259241">0x0a</span><span style="color: #2e53d1">)
        {
            </span><span style="color: #937a42">/*与源程序不同，保留了声调，因此并不去掉重复的*/
            </span>pinyinList<span style="color: #2e53d1">.</span>push_back<span style="color: #2e53d1">(</span>string<span style="color: #2e53d1">(</span>strline<span style="color: #2e53d1">+</span>pinYinStartIndex<span style="color: #2e53d1">, </span>i<span style="color: #2e53d1">-</span>pinYinStartIndex<span style="color: #2e53d1">));
            </span><span style="color: #937a42">/*去掉首字母的重复*/
            </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>std<span style="color: #2e53d1">::</span>find<span style="color: #2e53d1">(</span>firstLetterList<span style="color: #2e53d1">.</span>begin<span style="color: #2e53d1">(), </span>firstLetterList<span style="color: #2e53d1">.</span>end<span style="color: #2e53d1">(), </span>strline<span style="color: #2e53d1">[</span>pinYinStartIndex<span style="color: #2e53d1">]) == </span>firstLetterList<span style="color: #2e53d1">.</span>end<span style="color: #2e53d1">())
            {
                </span>firstLetterList<span style="color: #2e53d1">.</span>push_back<span style="color: #2e53d1">(</span>strline<span style="color: #2e53d1">[</span>pinYinStartIndex<span style="color: #2e53d1">]);
            }
            </span>pinYinStartIndex <span style="color: #2e53d1">= </span>i<span style="color: #2e53d1">+</span><span style="color: #259241">1</span><span style="color: #2e53d1">;
        }
    }

    </span><span style="color: #400080">return true</span><span style="color: #2e53d1">;
}

</span><span style="color: #400080">bool </span>CHanZi2PinYin<span style="color: #2e53d1">::</span>HanZi2PinYin<span style="color: #2e53d1">(</span><span style="color: #400080">const wchar_t</span><span style="color: #2e53d1">* </span>wstr<span style="color: #2e53d1">, </span><span style="color: #400080">const int </span>len<span style="color: #2e53d1">, </span>PinyinList<span style="color: #2e53d1">&amp; </span>_pinyinList<span style="color: #2e53d1">, </span>PinyinList<span style="color: #2e53d1">&amp; </span>_firstLetterList<span style="color: #2e53d1">)
{
    </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>wstr<span style="color: #2e53d1">==</span>NULL<span style="color: #2e53d1">)  &amp;&amp; (</span>len<span style="color: #2e53d1">&lt;=</span><span style="color: #259241">0</span><span style="color: #2e53d1">))
    {
        </span><span style="color: #400080">return false</span><span style="color: #2e53d1">;
    }

    </span>vector<span style="color: #2e53d1">&lt;</span>string<span style="color: #2e53d1">&gt; </span>pinyinStrList<span style="color: #2e53d1">;</span><span style="color: #937a42">//存储可能的拼音结果，每查找完成一个字符更新
    </span>vector<span style="color: #2e53d1">&lt;</span>string<span style="color: #2e53d1">&gt; </span>firstLetterStrList<span style="color: #2e53d1">;</span><span style="color: #937a42">//存储可能的首字母结果，没查找完成一个字符更新
    </span>vector<span style="color: #2e53d1">&lt;</span>string<span style="color: #2e53d1">&gt; </span>pinyinStrListStore <span style="color: #2e53d1">= </span>pinyinStrList<span style="color: #2e53d1">;</span><span style="color: #937a42">//临时变量，用于记录查找该字符之前的pinyinStrList结果
    </span>vector<span style="color: #2e53d1">&lt;</span>string<span style="color: #2e53d1">&gt; </span>firstLetterStrListStore <span style="color: #2e53d1">= </span>firstLetterStrList<span style="color: #2e53d1">;</span><span style="color: #937a42">//临时变量，用于记录查找该字符之前的firstLetterStrList结果
    
    </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">int </span>i<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>i<span style="color: #2e53d1">&lt;</span>len<span style="color: #2e53d1">; ++</span>i<span style="color: #2e53d1">)
    {
        </span>PinyinList pinyinList<span style="color: #2e53d1">;</span><span style="color: #937a42">//存储本次对单个字符的拼音查找结果
        </span>FirstLetterList firstLetterList<span style="color: #2e53d1">;</span><span style="color: #937a42">//存储本次对单个字符的首字母查找结果

        </span>HanZi2PinYin<span style="color: #2e53d1">(</span>wstr<span style="color: #2e53d1">[</span>i<span style="color: #2e53d1">], </span>pinyinList<span style="color: #2e53d1">, </span>firstLetterList<span style="color: #2e53d1">);
        </span><span style="color: #937a42">//如果是第一个字符，赋值后返回
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>i<span style="color: #2e53d1">==</span><span style="color: #259241">0</span><span style="color: #2e53d1">)
        {
            </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">unsigned int </span>j<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>j<span style="color: #2e53d1">&lt;</span>pinyinList<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">(); ++</span>j<span style="color: #2e53d1">)
                </span>pinyinStrList<span style="color: #2e53d1">.</span>push_back<span style="color: #2e53d1">(</span>pinyinList<span style="color: #2e53d1">[</span>j<span style="color: #2e53d1">]);
            </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">unsigned int </span>j<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>j<span style="color: #2e53d1">&lt;</span>firstLetterList<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">(); ++</span>j<span style="color: #2e53d1">)
                </span>firstLetterStrList<span style="color: #2e53d1">.</span>push_back<span style="color: #2e53d1">(</span>string<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">, </span>firstLetterList<span style="color: #2e53d1">[</span>j<span style="color: #2e53d1">]));
            </span><span style="color: #400080">continue</span><span style="color: #2e53d1">;
        }

        </span><span style="color: #937a42">/*记录之前的结果，并将结果清除，以便写入   */
        </span>pinyinStrListStore <span style="color: #2e53d1">= </span>pinyinStrList<span style="color: #2e53d1">;
        </span>firstLetterStrListStore <span style="color: #2e53d1">= </span>firstLetterStrList<span style="color: #2e53d1">;
        </span>pinyinStrList<span style="color: #2e53d1">.</span>clear<span style="color: #2e53d1">();
        </span>firstLetterStrList<span style="color: #2e53d1">.</span>clear<span style="color: #2e53d1">();
        
        </span><span style="color: #400080">unsigned int </span>pinyinStrListSize <span style="color: #2e53d1">= </span>pinyinStrListStore<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">();
        </span><span style="color: #400080">unsigned int </span>firstLetterStrListSize <span style="color: #2e53d1">= </span>firstLetterStrListStore<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">();

        </span><span style="color: #937a42">/*更新拼音结果列表,对每个已经上次存储的字符串，加上本次所有可能的拼音结果   */
        </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">unsigned int </span>k<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>k<span style="color: #2e53d1">&lt;</span>pinyinStrListSize<span style="color: #2e53d1">; ++</span>k<span style="color: #2e53d1">)
        {
            </span>string pinyinStore <span style="color: #2e53d1">= </span>pinyinStrListStore<span style="color: #2e53d1">[</span>k<span style="color: #2e53d1">];
            </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">unsigned int </span>j<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>j<span style="color: #2e53d1">&lt;</span>pinyinList<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">(); ++</span>j<span style="color: #2e53d1">)
                </span>pinyinStrList<span style="color: #2e53d1">.</span>push_back<span style="color: #2e53d1">(</span>pinyinStore<span style="color: #2e53d1">+</span><span style="color: #259241">" "</span><span style="color: #2e53d1">+</span>pinyinList<span style="color: #2e53d1">[</span>j<span style="color: #2e53d1">]);
        }
        </span><span style="color: #937a42">/*更新首字母结果列表,对每个已经上次存储的字符串，加上本次所有可能的首字母结果   */
        </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">unsigned int </span>k<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>k<span style="color: #2e53d1">&lt;</span>firstLetterStrListSize<span style="color: #2e53d1">; ++</span>k<span style="color: #2e53d1">)
        {
            </span>string firstletterStore <span style="color: #2e53d1">= </span>firstLetterStrListStore<span style="color: #2e53d1">[</span>k<span style="color: #2e53d1">];
            </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">unsigned int </span>j<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>j<span style="color: #2e53d1">&lt;</span>firstLetterList<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">(); ++</span>j<span style="color: #2e53d1">)
                </span>firstLetterStrList<span style="color: #2e53d1">.</span>push_back<span style="color: #2e53d1">(</span>firstletterStore<span style="color: #2e53d1">+</span>string<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">, </span>firstLetterList<span style="color: #2e53d1">[</span>j<span style="color: #2e53d1">]));
        }
    }
    </span>_pinyinList <span style="color: #2e53d1">= </span>pinyinStrList<span style="color: #2e53d1">;
    </span>_firstLetterList <span style="color: #2e53d1">= </span>firstLetterStrList<span style="color: #2e53d1">;

    </span><span style="color: #400080">return true</span><span style="color: #2e53d1">;

}

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span>CHanZi2PinYin hanzi2pinyin<span style="color: #2e53d1">;
    </span>PinyinList pylist<span style="color: #2e53d1">;
    </span>FirstLetterList fllist<span style="color: #2e53d1">;

    </span><span style="color: #400080">wchar_t </span>wstr <span style="color: #2e53d1">= </span>L<span style="color: #259241">'色'</span><span style="color: #2e53d1">;
    </span>hanzi2pinyin<span style="color: #2e53d1">.</span>HanZi2PinYin<span style="color: #2e53d1">(</span>wstr<span style="color: #2e53d1">, </span>pylist<span style="color: #2e53d1">, </span>fllist<span style="color: #2e53d1">);
    </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">unsigned int </span>i<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>i<span style="color: #2e53d1">&lt;</span>pylist<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">(); ++</span>i<span style="color: #2e53d1">)
    {
        </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s\n"</span><span style="color: #2e53d1">, </span>pylist<span style="color: #2e53d1">[</span>i<span style="color: #2e53d1">].</span>c_str<span style="color: #2e53d1">());
    }
    </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">unsigned int </span>i<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>i<span style="color: #2e53d1">&lt;</span>fllist<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">(); ++</span>i<span style="color: #2e53d1">)
    {
        </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%c\n"</span><span style="color: #2e53d1">, </span>fllist<span style="color: #2e53d1">[</span>i<span style="color: #2e53d1">]);
    }

    </span><span style="color: #400080">wchar_t </span>wstr2<span style="color: #2e53d1">[] = </span>L<span style="color: #259241">"银行行长色即是空"</span><span style="color: #2e53d1">;
    </span>PinyinList pylist2<span style="color: #2e53d1">;
    </span>PinyinList fllist2<span style="color: #2e53d1">;
    </span>hanzi2pinyin<span style="color: #2e53d1">.</span>HanZi2PinYin<span style="color: #2e53d1">(</span><span style="color: #937a42">/*(wchar_t*)*/</span><span style="color: #2e53d1">(</span>wstr2<span style="color: #2e53d1">), </span>wcslen<span style="color: #2e53d1">(</span>wstr2<span style="color: #2e53d1">), </span>pylist2<span style="color: #2e53d1">, </span>fllist2<span style="color: #2e53d1">);
    </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">int </span>i<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>i<span style="color: #2e53d1">&lt;</span>pylist2<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">(); ++</span>i<span style="color: #2e53d1">)
        </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s\n"</span><span style="color: #2e53d1">, </span>pylist2<span style="color: #2e53d1">[</span>i<span style="color: #2e53d1">].</span>c_str<span style="color: #2e53d1">());
    </span><span style="color: #400080">for </span><span style="color: #2e53d1">( </span><span style="color: #400080">int </span>i<span style="color: #2e53d1">=</span><span style="color: #259241">0</span><span style="color: #2e53d1">; </span>i<span style="color: #2e53d1">&lt;</span>fllist2<span style="color: #2e53d1">.</span>size<span style="color: #2e53d1">(); ++</span>i<span style="color: #2e53d1">)
        </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s\n"</span><span style="color: #2e53d1">, </span>fllist2<span style="color: #2e53d1">[</span>i<span style="color: #2e53d1">].</span>c_str<span style="color: #2e53d1">());

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre><img src ="http://www.cppblog.com/izualzhy/aggbug/186891.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-11 11:38 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/11/186891.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>_INTSIZEOF(n)宏的介绍</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/07/186597.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Tue, 07 Aug 2012 12:15:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/07/186597.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/186597.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/07/186597.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/186597.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/186597.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:fea02a56-726f-4e61-98c8-09dec977b766" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/INTSIZEOF" rel="tag">INTSIZEOF</a></div> <p>_INTSIZEOF(n)定义为：</p><pre><code>#define _INTSIZEOF(n)&nbsp;&nbsp; ((sizeof(n)+sizeof(int)-1)&amp;~(sizeof(int) - 1) ) </code></pre><pre><code>举个例子说明，一般机器上int大小为4，即sizeof(int) = 4</code></pre><pre><code>~(sizeof(int) - 1)使得最后两位变为0，而其他位全为1，也就是任何一个值与之&amp;操作，都会为4的倍数。</code></pre><pre><code>而</code></pre><pre><code>sizeof(n) + sizeof(int) - 1的作用：</code></pre><pre><code>a). 如果sizeof(n)是4的倍数，则没有影响,因为加上的sizeof(int) - 1只是使最后两位变为1，在&amp;操作时会忽略掉。</code></pre><pre><code>b). 如果不是，不妨设：</code></pre><pre><code>sizeof(n) = 4*q + r;//4&lt;r&lt;0</code></pre><pre><code>我们实际上是需要的q+1,而不是q，加上sizeof(int) - 1就达到目的了。</code></pre><pre><code></code>&nbsp;</pre><pre><code>如果还有理论控觉得太笼统，</code><code>这里有一个再合适不过的解释：</code></pre>
<p>对于两个正整数 x, n 总存在整数 q, r 使得<br>x = nq + r, 其中&nbsp; 0&lt;= r &lt;n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //最小非负剩余<br>q, r 是唯一确定的。q = [x/n], r = x - n[x/n]. 这个是带余除法的一个简单形式。在 c 语言中， q, r 容易计算出来： q = x/n, r = x % n.<br>所谓把 x 按 n 对齐指的是：若 r=0, 取 qn, 若 r&gt;0, 取 (q+1)n. 这也相当于把 x 表示为：<br>x = nq + r', 其中 -n &lt; r' &lt;=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //最大非正剩余&nbsp;&nbsp; <br>nq 是我们所求。关键是如何用 c 语言计算它。由于我们能处理标准的带余除法，所以可以把这个式子转换成一个标准的带余除法，然后加以处理：<br>x+n = qn + (n+r')，其中 0&lt;n+r'&lt;=n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //最大正剩余<br>x+n-1 = qn + (n+r'-1), 其中 0&lt;= n+r'-1 &lt;n&nbsp;&nbsp;&nbsp; //最小非负剩余<br>所以 qn = [(x+n-1)/n]n. 用 c 语言计算就是：<br>((x+n-1)/n)*n<br>若 n 是 2 的方幂, 比如 2^m，则除为右移 m 位，乘为左移 m 位。所以把 x+n-1 的最低 m 个二进制位清 0就可以了。得到：<br>(x+n-1) &amp; (~(n-1))
<p>来自：<a href="http://bbs.chinaunix.net/forum.php?mod=viewthread&amp;tid=814501">http://bbs.chinaunix.net/forum.php?mod=viewthread&amp;tid=814501</a><img src ="http://www.cppblog.com/izualzhy/aggbug/186597.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-07 20:15 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/07/186597.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>va_start,va_arg的实现</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/07/186596.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Tue, 07 Aug 2012 12:05:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/07/186596.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/186596.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/07/186596.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/186596.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/186596.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:58d99b6e-52ac-406c-b268-dfcf3f8937f4" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/va_start" rel="tag">va_start</a>,<a href="http://technorati.com/tags/va_end" rel="tag">va_end</a>,<a href="http://technorati.com/tags/va_list" rel="tag">va_list</a>,<a href="http://technorati.com/tags/va_arg" rel="tag">va_arg</a></div> <p>这里<a href="http://www.cppblog.com/izualzhy/archive/2012/08/07/186592.html">http://www.cppblog.com/izualzhy/archive/2012/08/07/186592.html</a>介绍了va_xxx的使用方法。</p> <p>这篇文章具体介绍实现，网上参考资料很多，这里只做整理.</p> <p><font color="#0000ff" size="4"><strong>函数实现，实际上为宏：</strong></font></p><pre><code>typedef char *&nbsp;&nbsp; va_list;&nbsp;&nbsp; // x86平台下va_list的定义</code><code></pre><pre><code>#define va_start(ap,v) ( ap = (va_list)&amp;v + _INTSIZEOF(v) )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //第一个可选参数地址<br>#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址<br>#define va_end(ap)&nbsp;&nbsp;&nbsp; ( ap = (va_list)0 )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 将指针置为无效</code></pre><pre><code></code>&nbsp;</pre><pre>_INTSIZEOF实现:</pre><pre><code>#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&amp;~(sizeof(int) - 1) ) </code></pre><pre>它求出变量占用内存空间的大小，是va的实现的基础</pre><pre>&nbsp;</pre><pre><strong><font color="#0000ff" size="4">实例讲解：</font></strong></pre><p>下表是针对函数int TestFunc(int n1, int n2, int n3, …)<br>参数传递时的内存堆栈情况。（C编译器默认的参数传递方式是__cdecl。）<br>对该函数的调用为int result = TestFunc(a, b, c, d. e); 其中e为结束标志。<p><img alt="" src="http://tech.ccidnet.com/pub/attachment/2005/4/418433.gif"><p>从上图中可以很清楚地看出va_xxx宏如此编写的原因。<br>1． va_start。为了得到第一个可选参数的地址，我们有三种办法可以做到：<br>A) = &amp;n3 + _INTSIZEOF(n3)<br>// 最后一个固定参数的地址 + 该参数占用内存的大小<br>B) = &amp;n2 + _INTSIZEOF(n3) + _INTSIZEOF(n2)<br>// 中间某个固定参数的地址 + 该参数之后所有固定参数占用的内存大小之和<br>C) = &amp;n1 + _INTSIZEOF(n3) + _INTSIZEOF(n2) + _INTSIZEOF(n1)<br>// 第一个固定参数的地址 + 所有固定参数占用的内存大小之和<br>从编译器实现角度来看，方法B)，方法C)为了求出地址，编译器还需知道有多少个固定参数，以及它们的大小，没有把问题分解到最简单，所以不是很聪明的途 径，不予采纳；相对来说，方法A)中运算的两个值则完全可以确定。va_start()正是采用A)方法，接受最后一个固定参数。调用va_start ()的结果总是使指针指向下一个参数的地址，并把它作为第一个可选参数。在含多个固定参数的函数中，调用va_start()时，如果不是用最后一个固定 参数，对于编译器来说，可选参数的个数已经增加，将给程序带来一些意想不到的错误。(当然如果你认为自己对指针已经知根知底，游刃有余，那么，怎么用就随 你，你甚至可以用它完成一些很优秀（高效）的代码，但是，这样会大大降低代码的可读性。)<br>注意：宏va_start是对参数的地址进行操作的，要求参数地址必须是有效的。一些地址无效的类型不能当作固定参数类型。比如：寄存器类型，它的地址不是有效的内存地址值；数组和函数也不允许，他们的长度是个问题。因此，这些类型时不能作为va函数的参数的。<br>2． va_arg身兼二职：返回当前参数，并使参数指针指向下一个参数。<br>初看va_arg宏定义很别扭，如果把它拆成两个语句，可以很清楚地看出它完成的两个职责。<pre><code><br>#define va_arg(ap,t)&nbsp;&nbsp;&nbsp; ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址<br>// 将( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )拆成：<br>/* 指针ap指向下一个参数的地址 */<br>1． ap += _INTSIZEOF(t)；&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 当前，ap已经指向下一个参数了<br>/* ap减去当前参数的大小得到当前参数的地址，再强制类型转换后返回它的值 */<br>2． return *(t *)( ap - _INTSIZEOF(t)) <br></code></pre><p>回想到printf/scanf系列函数的%d %s之类的格式化指令，我们不难理解这些它们的用途了- 明示参数强制转换的类型。<br>(注：printf/scanf没有使用va_xxx来实现，但原理是一致的。)<br>3．va_end很简单，仅仅是把指针作废而已。<br>#define va_end(ap) (ap = (va_list)0) // x86平台</p></code>
<p><font color="#0000ff" size="4"><strong>备注：</strong></font></p>
<p>网上找到的资料重点都在上面了.</p>
<p>这里牵扯到一个函数参数入栈的顺序，首先明确的是栈是由高地址往低地址增长的，因此从上图可以猜到参数是从右往左进栈的，举个例子：</p><pre class="code"><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdarg.h&gt;

</span><span style="color: #400080">void </span>foo<span style="color: #2e53d1">(</span><span style="color: #400080">int </span>a<span style="color: #2e53d1">, </span><span style="color: #400080">int </span>b<span style="color: #2e53d1">)
{
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%x, %x\n"</span><span style="color: #2e53d1">, &amp;</span>a<span style="color: #2e53d1">, &amp;</span>b<span style="color: #2e53d1">);
}
</span><span style="color: #400080">int </span>f1<span style="color: #2e53d1">()
{
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"f1\n"</span><span style="color: #2e53d1">);
    </span><span style="color: #400080">return </span><span style="color: #259241">1</span><span style="color: #2e53d1">;
}
</span><span style="color: #400080">int </span>f2<span style="color: #2e53d1">()
{
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"f2\n"</span><span style="color: #2e53d1">);
    </span><span style="color: #400080">return </span><span style="color: #259241">1</span><span style="color: #2e53d1">;
}

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span>foo<span style="color: #2e53d1">(</span>f1<span style="color: #2e53d1">(),</span>f2<span style="color: #2e53d1">());

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p>输出：</p>
<p>f2<br>f1<br>bfec6c20, bfec6c24<br>也就是说函数参数进栈顺序从右往左，而第一个参数总是最低的地址，也就保证了可以直接取到第一个参数。</p><img src ="http://www.cppblog.com/izualzhy/aggbug/186596.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-07 20:05 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/07/186596.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C中的可变参数函数(va_list,va_start, va_arg,va_end)</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/07/186592.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Tue, 07 Aug 2012 11:29:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/07/186592.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/186592.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/07/186592.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/186592.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/186592.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a4f9297d-2d0e-4d23-a079-59e16773e96a" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/va_list" rel="tag">va_list</a>,<a href="http://technorati.com/tags/va_start" rel="tag">va_start</a>,<a href="http://technorati.com/tags/va_arg" rel="tag">va_arg</a>,<a href="http://technorati.com/tags/va_end" rel="tag">va_end</a></div> <p>这个的使用还是非常简单的，还是先以man的一个例子说明：</p><pre class="code"><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdarg.h&gt;

</span><span style="color: #400080">void </span>foo<span style="color: #2e53d1">(</span><span style="color: #400080">char </span><span style="color: #2e53d1">*</span>fmt<span style="color: #2e53d1">, ...)
{
    </span>va_list ap<span style="color: #2e53d1">;
    </span><span style="color: #400080">int </span>d<span style="color: #2e53d1">;
    </span><span style="color: #400080">char </span>c<span style="color: #2e53d1">, *</span>s<span style="color: #2e53d1">;

    </span>va_start<span style="color: #2e53d1">(</span>ap<span style="color: #2e53d1">, </span>fmt<span style="color: #2e53d1">);</span><span style="color: #937a42">//...之前第一个参数

    </span><span style="color: #400080">while </span><span style="color: #2e53d1">(*</span>fmt<span style="color: #2e53d1">)
        </span><span style="color: #400080">switch </span><span style="color: #2e53d1">(*</span>fmt<span style="color: #2e53d1">++) {
            </span><span style="color: #400080">case </span><span style="color: #259241">'s'</span><span style="color: #2e53d1">:</span><span style="color: #937a42">//string
                </span>s <span style="color: #2e53d1">= </span>va_arg<span style="color: #2e53d1">(</span>ap<span style="color: #2e53d1">, </span><span style="color: #400080">char </span><span style="color: #2e53d1">*);
                </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"string %s\n"</span><span style="color: #2e53d1">, </span>s<span style="color: #2e53d1">);
                </span><span style="color: #400080">break</span><span style="color: #2e53d1">;
            </span><span style="color: #400080">case </span><span style="color: #259241">'d'</span><span style="color: #2e53d1">:</span><span style="color: #937a42">//int
                </span>d <span style="color: #2e53d1">= </span>va_arg<span style="color: #2e53d1">(</span>ap<span style="color: #2e53d1">, </span><span style="color: #400080">int</span><span style="color: #2e53d1">);
                </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"int %d\n"</span><span style="color: #2e53d1">, </span>d<span style="color: #2e53d1">);
                </span><span style="color: #400080">break</span><span style="color: #2e53d1">;
            </span><span style="color: #400080">case </span><span style="color: #259241">'c'</span><span style="color: #2e53d1">:
                </span><span style="color: #937a42">/* need a cast here since va_arg only takes fully promoted types  *///注释是照抄的，发现去掉(char)强传后没有影响，为什么？
                </span>c <span style="color: #2e53d1">= (</span><span style="color: #400080">char</span><span style="color: #2e53d1">)</span>va_arg<span style="color: #2e53d1">(</span>ap<span style="color: #2e53d1">, </span><span style="color: #400080">int</span><span style="color: #2e53d1">);
                </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"char %c\n"</span><span style="color: #2e53d1">, </span>c<span style="color: #2e53d1">);
                </span><span style="color: #400080">break</span><span style="color: #2e53d1">;
        }

    </span>va_end<span style="color: #2e53d1">(</span>ap<span style="color: #2e53d1">);
}

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span>foo<span style="color: #2e53d1">(</span><span style="color: #259241">"sdccds"</span><span style="color: #2e53d1">, </span><span style="color: #259241">"Hello"</span><span style="color: #2e53d1">, </span><span style="color: #259241">1</span><span style="color: #2e53d1">, </span><span style="color: #259241">'w'</span><span style="color: #2e53d1">, </span><span style="color: #259241">'w'</span><span style="color: #2e53d1">, </span><span style="color: #259241">2</span><span style="color: #2e53d1">, </span><span style="color: #259241">"World!"</span><span style="color: #2e53d1">);

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p>输出：</p>
<p>y@y-VirtualBox:~/Training$ ./test<br>string Hello<br>int 1<br>char w<br>char w<br>int 2<br>string World!<br><strong><font color="#0000ff" size="4">函数原型：</font></strong></p>
<p>#include &lt;stdarg.h&gt;</p>
<p>void va_start(va_list ap, last);<br>type va_arg(va_list ap, type);<br>void va_end(va_list ap);<br>void va_copy(va_list dest, va_list src);</p>
<p><strong><font color="#0000ff" size="4">注解：</font></strong></p>
<p>va_list:类型，ap即argument pointer</p>
<p>va_start:初始化ap，第二个变量必须是…之前的变量名</p>
<p>va_arg:在使用va_start(last, ap)初始化之后，第一次调用va_arg，它会返回last之后的变长参数表中的第一个参数，并修改ap指向下一个参数；接下来每调用一次va_arg都会返回返回一个参数，有将ap向前移动一步。va_arg除了需要ap这个参数指针之外，还需要一个数据类型type，用来决定一步应该迈多大。</p>
<p>va_end:与va_start对应</p>
<p>va_copy是用来复制va_list的，没有用到，在此就不乱讲了，免得弄错，有懂的读者可以告诉我~~</p>
<p><font color="#0000ff" size="4"><strong>注意：</strong></font></p>
<p>在使用过程中必须设定变长参数表解析的结束条件，可变参数并没有想象的那么智能，不能实现所有参数的类型和数目都自动判断。因此，使用时，多数会通过数值或者条件让程序知道参数的数目。例如，上面例子中的while (*fmt)就是结束条件，下面再举一个以数值边界作为条件的例子。<br></p>
<p><strong><font color="#0000ff" size="4"></font></strong></p><img src ="http://www.cppblog.com/izualzhy/aggbug/186592.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-07 19:29 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/07/186592.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>wchar_t在linux下占4个字节？</title><link>http://www.cppblog.com/izualzhy/archive/2012/07/26/185216.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Thu, 26 Jul 2012 11:08:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/07/26/185216.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/185216.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/07/26/185216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/185216.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/185216.html</trackback:ping><description><![CDATA[<p>按理说wchar_t占2个字节，在ubuntu下，代码如下：</p><pre class="code"><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;malloc.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;string.h&gt;

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span><span style="color: #400080">wchar_t </span>c <span style="color: #2e53d1">= </span><span style="color: #259241">'A'</span><span style="color: #2e53d1">;
    </span><span style="color: #400080">wchar_t </span>a<span style="color: #2e53d1">[] = </span>L<span style="color: #259241">"Hello!"</span><span style="color: #2e53d1">;
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%d\n"</span><span style="color: #2e53d1">, </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span>c<span style="color: #2e53d1">));
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%d\n"</span><span style="color: #2e53d1">, </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span>a<span style="color: #2e53d1">));

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p>结果：</p>
<p>y@y-VirtualBox:~/Training$ ./test<br>4<br>28<br>谁能告诉我是怎么回事？</p><img src ="http://www.cppblog.com/izualzhy/aggbug/185216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-07-26 19:08 <a href="http://www.cppblog.com/izualzhy/archive/2012/07/26/185216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>测试vim不同文件编码下strlen的结果</title><link>http://www.cppblog.com/izualzhy/archive/2012/07/26/185208.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Thu, 26 Jul 2012 10:17:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/07/26/185208.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/185208.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/07/26/185208.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/185208.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/185208.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:07ee9fbc-fe01-4f9c-b00d-1152ada143b2" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/%e7%bc%96%e7%a0%81" rel="tag">编码</a>,<a href="http://technorati.com/tags/strlen" rel="tag">strlen</a></div> <p>代码是相同的：</p><pre class="code"><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;malloc.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;string.h&gt;

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%d\n"</span><span style="color: #2e53d1">, </span>strlen<span style="color: #2e53d1">(</span><span style="color: #259241">"һ"</span><span style="color: #2e53d1">));

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p>在vim下分别输入</p>
<p>: set fileencoding=utf-8</p>
<p>or</p>
<p>: set fileencoding=cp936</p>
<p>会得到不一样的结果。</p>
<p>就是由于编码方式不同引起的，如果直接用gdb查看下也应该很明显了。</p><img src ="http://www.cppblog.com/izualzhy/aggbug/185208.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-07-26 18:17 <a href="http://www.cppblog.com/izualzhy/archive/2012/07/26/185208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>