﻿<?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++博客-Believe-随笔分类-C/C++</title><link>http://www.cppblog.com/SINE/category/16751.html</link><description>人生就像跑步一样，只要你肯接着跑，就会前进！</description><language>zh-cn</language><lastBuildDate>Sun, 08 May 2011 12:53:15 GMT</lastBuildDate><pubDate>Sun, 08 May 2011 12:53:15 GMT</pubDate><ttl>60</ttl><item><title>通过一个小程序看递归函数如何执行</title><link>http://www.cppblog.com/SINE/archive/2011/05/07/145901.html</link><dc:creator>COS</dc:creator><author>COS</author><pubDate>Sat, 07 May 2011 08:12:00 GMT</pubDate><guid>http://www.cppblog.com/SINE/archive/2011/05/07/145901.html</guid><wfw:comment>http://www.cppblog.com/SINE/comments/145901.html</wfw:comment><comments>http://www.cppblog.com/SINE/archive/2011/05/07/145901.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/SINE/comments/commentRss/145901.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SINE/services/trackbacks/145901.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 递归函数&nbsp;&nbsp;<a href='http://www.cppblog.com/SINE/archive/2011/05/07/145901.html'>阅读全文</a><img src ="http://www.cppblog.com/SINE/aggbug/145901.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SINE/" target="_blank">COS</a> 2011-05-07 16:12 <a href="http://www.cppblog.com/SINE/archive/2011/05/07/145901.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>曾经出现频率最高的笔试题【C/C++ string】之strcpy函数</title><link>http://www.cppblog.com/SINE/archive/2011/04/28/145180.html</link><dc:creator>COS</dc:creator><author>COS</author><pubDate>Thu, 28 Apr 2011 00:16:00 GMT</pubDate><guid>http://www.cppblog.com/SINE/archive/2011/04/28/145180.html</guid><wfw:comment>http://www.cppblog.com/SINE/comments/145180.html</wfw:comment><comments>http://www.cppblog.com/SINE/archive/2011/04/28/145180.html#Feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://www.cppblog.com/SINE/comments/commentRss/145180.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SINE/services/trackbacks/145180.html</trackback:ping><description><![CDATA[题目：<br>&nbsp; &nbsp; 已知strcpy函数的原型是：<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;char * strcpy(char * strDest,const char * strSrc);<br>&nbsp; &nbsp; 1.不调用库函数，实现strcpy函数。<br>&nbsp; &nbsp; 2.解释为什么要返回char *。<br><br>&nbsp; &nbsp; 解说：<br>&nbsp; &nbsp; 1.strcpy的实现代码<br>
<div class=blockcode>
<div id=code0>
<ol>
    <li>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;char * strcpy(char * strDest,const char * strSrc)<br>
    <li>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>
    <li>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; if ((strDest==NULL)||(strSrc==NULL)) //[1]<br>
    <li>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;throw "Invalid argument(s)"; //[2]<br>
    <li>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; char * strDestCopy=strDest;&nbsp;&nbsp;//[3]<br>
    <li>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; while ((*strDest++=*strSrc++)!='\0'); //[4]<br>
    <li>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; return strDestCopy;<br>
    <li>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;} </li>
</ol>
</div>
<em>复制代码</em></div>
<p><br>&nbsp; &nbsp; 错误的做法：<br>&nbsp; &nbsp; [1]<br>&nbsp; &nbsp; (A)不检查指针的有效性，说明答题者不注重代码的健壮性。<br>&nbsp; &nbsp; (B)检查指针的有效性时使用((!strDest)||(!strSrc))或(!(strDest&amp;&amp;strSrc))，说明答题者对C语言中类型的隐式转换没有深刻认识。在本例中char *转换为bool即是类型隐式转换，这种功能虽然灵活，但更多的是导致出错概率增大和维护成本升高。所以C++专门增加了bool、true、false三个关键字以提供更安全的条件表达式。<br>&nbsp; &nbsp; (C)检查指针的有效性时使用((strDest==0)||(strSrc==0))，说明答题者不知道使用常量的好处。直接使用字面常量（如本例中的0）会减少程序的可维护性。0虽然简单，但程序中可能出现很多处对指针的检查，万一出现笔误，编译器不能发现，生成的程序内含逻辑错误，很难排除。而使用NULL代替0，如果出现拼写错误，编译器就会检查出来。<br>&nbsp; &nbsp; [2]<br>&nbsp; &nbsp; (A)return new string("Invalid argument(s)"<img alt="" src="http://bbs.chinaunix.net/images/smilies/default/icon_wink.gif" border=0 smilieid="60">;，说明答题者根本不知道返回值的用途，并且他对<span class=t_tag href="tag.php?name=%C4%DA%B4%E6">内存</span>泄漏也没有警惕心。从函数中返回函数体内分配的内存是十分危险的做法，他把释放内存的义务抛给不知情的调用者，绝大多数情况下，调用者不会释放内存，这导致内存泄漏。<br>&nbsp; &nbsp; (B)return 0;，说明答题者没有掌握异常机制。调用者有可能忘记检查返回值，调用者还可能无法检查返回值（见后面的链式表达式）。妄想让返回值肩负返回正确值和异常值的双重功能，其结果往往是两种功能都失效。应该以抛出异常来代替返回值，这样可以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。<br>&nbsp; &nbsp; [3]<br>&nbsp; &nbsp; (A)忘记保存原始的strDest值，说明答题者逻辑思维不严密。<br>&nbsp; &nbsp; [4]<br>&nbsp; &nbsp; (A)循环写成while (*strDest++=*strSrc++);，同[1](B)。<br>&nbsp; &nbsp; (B)循环写成while (*strSrc!='\0') *strDest++=*strSrc++;，说明答题者对边界条件的检查不力。循环体结束后，strDest字符串的末尾没有正确地加上'\0'。<br><br>&nbsp; &nbsp; 2.返回strDest的原始值使函数能够支持链式表达式，增加了函数的&#8220;附加值&#8221;。同样功能的函数，如果能合理地提高的可用性，自然就更加理想。<br>&nbsp; &nbsp; 链式表达式的形式如：<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;int iLength=strlen(strcpy(strA,strB));<br>&nbsp; &nbsp; 又如：<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;char * strA=strcpy(new char[10],strB);<br>&nbsp; &nbsp; 返回strSrc的原始值是错误的。其一，源字符串肯定是已知的，返回它没有意义。其二，不能支持形如第二例的表达式。其三，为了保护源字符串，形参用const限定strSrc所指的内容，把const char *作为char *返回，类型不符，编译报错。 </p>
<p>上面内容是转自：<a href="http://bbs.chinaunix.net/viewthread.php?tid=25356"><u><font color=#000000>http://bbs.chinaunix.net/viewthread.php?tid=25356</font></u></a><br>下面是自己的一些思考：<br>我想C/C++提供的字符串拷贝函数实现方式应该是下面的方式之一：<br>method 1:&nbsp;&nbsp;&nbsp;&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;strcpy(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;strDest,</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;strSrc)<br><img id=Codehighlighter1_54_331_Open_Image onclick="this.style.display='none'; Codehighlighter1_54_331_Open_Text.style.display='none'; Codehighlighter1_54_331_Closed_Image.style.display='inline'; Codehighlighter1_54_331_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_54_331_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_54_331_Closed_Text.style.display='none'; Codehighlighter1_54_331_Open_Image.style.display='inline'; Codehighlighter1_54_331_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_54_331_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_54_331_Open_Text><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char * strDestCopy=strDest;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;((</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">strDest</span><span style="COLOR: #000000">++=*</span><span style="COLOR: #000000">strSrc</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//strDest</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">strDestCopy;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">指针重置 不好意思，这里的重置是多余的，原因是虽然strDes的位置移动了，但是这只是在当前函数内发生变化，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //而在调用函数的地方，指针的位置还是不变。</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;strDestCopy;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;</span></div>
method 2:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;strcpy(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;strDest,</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;strSrc)<br><img id=Codehighlighter1_52_218_Open_Image onclick="this.style.display='none'; Codehighlighter1_52_218_Open_Text.style.display='none'; Codehighlighter1_52_218_Closed_Image.style.display='inline'; Codehighlighter1_52_218_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_52_218_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_52_218_Closed_Text.style.display='none'; Codehighlighter1_52_218_Open_Image.style.display='inline'; Codehighlighter1_52_218_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;</span><span id=Codehighlighter1_52_218_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_52_218_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;((strDest[i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=*</span><span style="COLOR: #000000">strSrc</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;strDest;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;</span></div>
<br>method 3:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;strcpy(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;strDest,</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;strSrc)<br><img id=Codehighlighter1_52_218_Open_Image onclick="this.style.display='none'; Codehighlighter1_52_218_Open_Text.style.display='none'; Codehighlighter1_52_218_Closed_Image.style.display='inline'; Codehighlighter1_52_218_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_52_218_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_52_218_Closed_Text.style.display='none'; Codehighlighter1_52_218_Open_Image.style.display='inline'; Codehighlighter1_52_218_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;</span><span id=Codehighlighter1_52_218_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_52_218_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;((strDest[i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">strSrc[i])</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;strDest;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;}</span></span></div>
这些方式都可实现类似&lt;string.h&gt;中的strcpy(char *, const char *)的功能。通过下标访问方式不容易出错，当然指针操作效率会更高。 
<img src ="http://www.cppblog.com/SINE/aggbug/145180.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SINE/" target="_blank">COS</a> 2011-04-28 08:16 <a href="http://www.cppblog.com/SINE/archive/2011/04/28/145180.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>