﻿<?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>IT博客-记录成长的过程-随笔分类-C/C++程序设计</title><link>http://www.cnitblog.com/chenlei/category/8785.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 15:18:54 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 15:18:54 GMT</pubDate><ttl>60</ttl><item><title>十进制转二进制、八进制、十六进制的经典程序</title><link>http://www.cnitblog.com/chenlei/archive/2011/09/03/75338.html</link><dc:creator>Mr.雷</dc:creator><author>Mr.雷</author><pubDate>Sat, 03 Sep 2011 13:54:00 GMT</pubDate><guid>http://www.cnitblog.com/chenlei/archive/2011/09/03/75338.html</guid><wfw:comment>http://www.cnitblog.com/chenlei/comments/75338.html</wfw:comment><comments>http://www.cnitblog.com/chenlei/archive/2011/09/03/75338.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/chenlei/comments/commentRss/75338.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/chenlei/services/trackbacks/75338.html</trackback:ping><description><![CDATA[<div><span style="font-family: 宋体; font-size: 12px; ">#include &lt;iostream.h&gt;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">//十进制数转换成二进制数字</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">void fun_1(int n)</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">{</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;if(n&lt;2)&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;n;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;if(n&gt;=2)&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;{</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fun_1(n/2);</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;n%2;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;}</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">}</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">//十进制数字转换成八进制数字</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">void fun_2(int n)</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">{</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;if(n&lt;8)&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;n;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;if(n&gt;=8)&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;{</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; fun_2(n/8);</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; cout&lt;&lt;n%8;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;}</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">}</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">//十进制数转换成十六进制数字</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">void fun_3(int n)</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">{</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;switch(n)</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;{</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 10:&nbsp;&nbsp;&nbsp;cout&lt;&lt;"A"; break;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 11:&nbsp;&nbsp;&nbsp;cout&lt;&lt;"B"; break;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 12:&nbsp;&nbsp;&nbsp;cout&lt;&lt;"C"; break;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 13:&nbsp;&nbsp;&nbsp;cout&lt;&lt;"D"; break;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 14:&nbsp;&nbsp;&nbsp;cout&lt;&lt;"E"; break;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 15:&nbsp;&nbsp;&nbsp;cout&lt;&lt;"F"; break;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:&nbsp;&nbsp;&nbsp;cout&lt;&lt;n;&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;}</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">void fun_4(int n)</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">{</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;if(n&lt;16)&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fun_3(n);</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;if(n&gt;=16)&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;{</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fun_4(n/16);</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fun_3(n%16);</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;}</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">}</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">//主函数</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">void main()</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">{</span>&nbsp;<span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; int n;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; cout&lt;&lt;"请输入n的值:&nbsp;&nbsp;"&lt;&lt;endl;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; cin&gt;&gt;n;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; cout&lt;&lt;"十进制数字转换成二进制，八进制，十六进制数字结果如下："&lt;&lt;endl;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; fun_1(n);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;endl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//输出结果换行</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; fun_2(n);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;endl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; fun_4(n);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;<span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">&nbsp;&nbsp;&nbsp; cout&lt;&lt;endl;&nbsp;&nbsp;&nbsp;</span>&nbsp;<span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">}</span>&nbsp;<span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; "><br /></span><span style="font-family: 宋体; font-size: 12px; ">输出结果：</span></div><img src ="http://www.cnitblog.com/chenlei/aggbug/75338.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/chenlei/" target="_blank">Mr.雷</a> 2011-09-03 21:54 <a href="http://www.cnitblog.com/chenlei/archive/2011/09/03/75338.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>strcpy()、memcpy()、memmove()、memset()的实现</title><link>http://www.cnitblog.com/chenlei/archive/2011/08/24/75173.html</link><dc:creator>Mr.雷</dc:creator><author>Mr.雷</author><pubDate>Wed, 24 Aug 2011 14:50:00 GMT</pubDate><guid>http://www.cnitblog.com/chenlei/archive/2011/08/24/75173.html</guid><wfw:comment>http://www.cnitblog.com/chenlei/comments/75173.html</wfw:comment><comments>http://www.cnitblog.com/chenlei/archive/2011/08/24/75173.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/chenlei/comments/commentRss/75173.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/chenlei/services/trackbacks/75173.html</trackback:ping><description><![CDATA[<div><p style="line-height: 18px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-family: Verdana, ����; font-size: 12px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">strcpy(), 字符串拷贝.<br />char *strcpy(char *strDest, const char *strSrc)<br />{<br />&nbsp;&nbsp;&nbsp; assert((strDest!=NULL) &amp;&amp; (strSrc !=NULL));<br />&nbsp;&nbsp;&nbsp; char *address = strDest;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; while( (*strDest++ = * strSrc++) != '\0')&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL ;&nbsp;<br />&nbsp;&nbsp;&nbsp; return address ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />}</p><p style="line-height: 18px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-family: Verdana, ����; font-size: 12px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">memcpy, 拷贝不重叠的内存块&nbsp;<br />void *memcpy(void* pvTo, void* pvFrom, size_t size) //byte是java里的变量类型<br />{<br />assert(pvTo != NULL &amp;&amp; pvFrom != NULL);<br />void* pbTo = (byte*)pvTo;<br />void* pbFrom = (byte*)pvFrom;<br />/* 内存块重叠吗？如果重叠，就使用memmove */<br />assert(pbTo&gt;=pbFrom+size || pbFrom&gt;=pbTo+size);<br />while(size--&gt;0)<br />&nbsp;&nbsp;&nbsp; *pbTo++ == *pbFrom++;<br />return pvTo;<br />}</p><p style="line-height: 18px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-family: Verdana, ����; font-size: 12px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">void *MemCopy(void *dest,const void *src,size_t count)<br />{<br />&nbsp;&nbsp;&nbsp; char *pDest=static_cast&lt;char *&gt;(dest);<br />&nbsp;&nbsp;&nbsp; const char *pSrc=static_cast&lt;const char *&gt;(src);<br />&nbsp;&nbsp;&nbsp; if( pDest&gt;pSrc &amp;&amp; pDest&lt;pSrc+count )<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(size_t i=count-1; i&lt;=0; ++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pDest[i]=pSrc[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(size_t i=0; i&lt;count; ++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pDest[i]=pSrc[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; return pDest;<br />}</p><p style="line-height: 18px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-family: Verdana, ����; font-size: 12px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">void *Memmove(void *Dst, const void*Src,size_t count)<br />{<br />assert(Dst &amp;&amp; Src);<br />void* pDst = Dst;<br />if (Dst&lt;Src &amp;&amp; (char*)Dst &gt; (char*)Src + count)<br />{<br />while(count--)<br />{<br />&nbsp;&nbsp; *(char*)Dst = *(char*)Src;<br />&nbsp;&nbsp; Dst = (char*)Dst + 1;<br />&nbsp;&nbsp; Src = (char*)Src + 1;<br />}<br />}<br />else<br />{<br />&nbsp;&nbsp; Dst = (char*)Dst + count - 1;<br />&nbsp;&nbsp; Src = (char*)Src + count - 1;<br />&nbsp;&nbsp; while(count--)<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *(char*)Dst = *(char*)Src;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dst = (char*)Dst -1 ;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Src = (char*)Src -1 ;<br />&nbsp;&nbsp; }<br />}<br />return pDst;<br />}</p><p style="line-height: 18px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-family: Verdana, ����; font-size: 12px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "><br />void* memmove(void *dest, const void *src,size_t n)&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp; if (n == 0) return 0;&nbsp;<br />&nbsp;&nbsp;&nbsp; if (dest == NULL) return 0;&nbsp;<br />&nbsp;&nbsp;&nbsp; if (src == NULL)&nbsp;&nbsp;&nbsp; return 0;&nbsp;<br />&nbsp;&nbsp;&nbsp; char *psrc = (char*)src;&nbsp;<br />&nbsp;&nbsp;&nbsp; char *pdest = (char*)dest;&nbsp;<br />&nbsp;&nbsp;&nbsp; if((dest &lt;= psrc) || (pdest &gt;= psrc + n)) /*检查是否有重叠问题 */&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i &lt; n; i++) /*正向拷贝*/&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *pdest = *psrc;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; psrc++;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pdest++;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else /*反向拷贝*/&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; psrc += n;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pdest += n;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;n;i++)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; psrc--;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pdest--;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *pdest = *psrc;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br />&nbsp;&nbsp; return dest;<br />}</p><p style="line-height: 18px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-family: Verdana, ����; font-size: 12px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">memset:把buffer所指内存区域的前count个字节设置成字符c</p><p style="line-height: 18px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-family: Verdana, ����; font-size: 12px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">void * Memset(void* buffer, int c, int count)<br />{<br />char* pvTo=(char*)buffer;<br />assert(buffer != NULL);<br />while(count--&gt;0)<br />*pvTo++=(char)c;<br />return buffer;<br />}</p></div><img src ="http://www.cnitblog.com/chenlei/aggbug/75173.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/chenlei/" target="_blank">Mr.雷</a> 2011-08-24 22:50 <a href="http://www.cnitblog.com/chenlei/archive/2011/08/24/75173.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>空指针与迷途指针（野指针）的区别</title><link>http://www.cnitblog.com/chenlei/archive/2011/08/20/75130.html</link><dc:creator>Mr.雷</dc:creator><author>Mr.雷</author><pubDate>Sat, 20 Aug 2011 03:12:00 GMT</pubDate><guid>http://www.cnitblog.com/chenlei/archive/2011/08/20/75130.html</guid><wfw:comment>http://www.cnitblog.com/chenlei/comments/75130.html</wfw:comment><comments>http://www.cnitblog.com/chenlei/archive/2011/08/20/75130.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/chenlei/comments/commentRss/75130.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/chenlei/services/trackbacks/75130.html</trackback:ping><description><![CDATA[<div><p style="line-height: normal; color: #333333; font-family: Arial; font-size: 14px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">当free或delete一个指针的时候，实际上仅仅是让编译器释放内存，但指针本身依然存在。这时它就像是一个迷途指针，处于悬浮状态。当使用语句P=0（NULL）之后，可以把迷途指针改为空指针。不可以直接使用一个迷途指针或者空指针，这样会使得程序造成崩溃。但是同样是崩溃，空指针造成的崩溃相比于迷途指针造成的崩溃是一种可预料的崩溃。调试起来也比较方便。</p><p style="line-height: normal; color: #333333; font-family: Arial; font-size: 14px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">此外，malloc/free与new/delete的最大区别是前者是库函数而后者是运算符。</p></div><img src ="http://www.cnitblog.com/chenlei/aggbug/75130.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/chenlei/" target="_blank">Mr.雷</a> 2011-08-20 11:12 <a href="http://www.cnitblog.com/chenlei/archive/2011/08/20/75130.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中volatile关键字的作用（volatile应理解为直接存取原始内存地址，英文意思为易改变的）</title><link>http://www.cnitblog.com/chenlei/archive/2010/10/17/70222.html</link><dc:creator>Mr.雷</dc:creator><author>Mr.雷</author><pubDate>Sun, 17 Oct 2010 13:55:00 GMT</pubDate><guid>http://www.cnitblog.com/chenlei/archive/2010/10/17/70222.html</guid><wfw:comment>http://www.cnitblog.com/chenlei/comments/70222.html</wfw:comment><comments>http://www.cnitblog.com/chenlei/archive/2010/10/17/70222.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/chenlei/comments/commentRss/70222.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/chenlei/services/trackbacks/70222.html</trackback:ping><description><![CDATA[<div style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; ">一个定义为volatile的变量是说这变量可能会被意想不到地改变，这样，编译器就不会去假设这个变量的值了。精确地说就是，优化器在用到这个变量时必须每次都小心地重新读取这个变量的值，而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子：&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;1).&nbsp;并行设备的硬件寄存器（如：状态寄存器）&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;2).&nbsp;一个中断服务子程序中会访问到的非自动变量(Non-automatic&nbsp;variables)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;3).&nbsp;多线程应用中被几个任务共享的变量&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。<span style="color: red; ">嵌入式系统程序员经常同硬件、中断、RTOS等等打交道</span>，所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;假设被面试者正确地回答了这几个问题（嗯，怀疑这是否会是这样），我将稍微深究一下，看一下这家伙是不是直正懂得volatile完全的重要性。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;1).&nbsp;一个参数既可以是const还可以是volatile吗？解释为什么。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;2).&nbsp;一个指针可以是volatile&nbsp;吗？解释为什么。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;3).&nbsp;下面的函数有什么错误：&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;square(volatile&nbsp;int&nbsp;*ptr)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;*ptr&nbsp;*&nbsp;*ptr;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;下面是答案：&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;1).&nbsp;是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;2).&nbsp;是的。尽管这并不很常见。一个例子是当一个中断服务子程序修该一个指向一个buffer的指针时。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;3).&nbsp;这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方，但是，由于*ptr指向一个volatile型参数，编译器将产生类似下面的代码：&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;square(volatile&nbsp;int&nbsp;*ptr)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;a,b;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;=&nbsp;*ptr;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;=&nbsp;*ptr;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;*&nbsp;b;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;由于*ptr的值可能被意想不到地该变，因此a和b可能是不同的。结果，这段代码可能返不是你所期望的平方值！正确的代码如下：&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;square(volatile&nbsp;int&nbsp;*ptr)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;a;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;=&nbsp;*ptr;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;*&nbsp;a;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</div><div style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; ">讲讲我的理解：&nbsp;（欢迎打板子...~~！）&nbsp;<br /><br />关键在于两个地方：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;<br />1.&nbsp;编译器的优化&nbsp;&nbsp;(请高手帮我看看下面的理解)&nbsp;<br /><br />在本次线程内,&nbsp;当读取一个变量时，为提高存取速度，编译器优化时有时会先把变量读取到一个寄存器中；以后，再取变量值时，就直接从寄存器中取值；&nbsp;<br /><br />当变量值在本线程里改变时，会同时把变量的新值copy到该寄存器中，以便保持一致&nbsp;<br /><br />当变量在因别的线程等而改变了值，该寄存器的值不会相应改变，从而造成应用程序读取的值和实际的变量值不一致&nbsp;<br /><br />当该寄存器在因别的线程等而改变了值，原变量的值不会改变，从而造成应用程序读取的值和实际的变量值不一致&nbsp;&nbsp;<br /><br /><br />举一个不太准确的例子：&nbsp;&nbsp;<br /><br />发薪资时，会计每次都把员工叫来登记他们的银行卡号；一次会计为了省事，没有即时登记，用了以前登记的银行卡号；刚好一个员工的银行卡丢了，已挂失该银行卡号；从而造成该员工领不到工资&nbsp;&nbsp;<br /><br />员工&nbsp;－－&nbsp;原始变量地址&nbsp;&nbsp;<br />银行卡号&nbsp;－－&nbsp;原始变量在寄存器的备份&nbsp;&nbsp;<br /><br /><br />2.&nbsp;在什么情况下会出现(如1楼所说)&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;1).&nbsp;并行设备的硬件寄存器（如：状态寄存器）&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;2).&nbsp;一个中断服务子程序中会访问到的非自动变量(Non-automatic&nbsp;variables)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;3).&nbsp;多线程应用中被几个任务共享的变量&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />补充：&nbsp;volatile应该解释为&#8220;直接存取原始内存地址&#8221;比较合适，&#8220;易变的&#8221;这种解释简直有点误导人；</div><img src ="http://www.cnitblog.com/chenlei/aggbug/70222.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/chenlei/" target="_blank">Mr.雷</a> 2010-10-17 21:55 <a href="http://www.cnitblog.com/chenlei/archive/2010/10/17/70222.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>友元函数的作用</title><link>http://www.cnitblog.com/chenlei/archive/2010/09/26/69199.html</link><dc:creator>Mr.雷</dc:creator><author>Mr.雷</author><pubDate>Sun, 26 Sep 2010 07:42:00 GMT</pubDate><guid>http://www.cnitblog.com/chenlei/archive/2010/09/26/69199.html</guid><wfw:comment>http://www.cnitblog.com/chenlei/comments/69199.html</wfw:comment><comments>http://www.cnitblog.com/chenlei/archive/2010/09/26/69199.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/chenlei/comments/commentRss/69199.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/chenlei/services/trackbacks/69199.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 友元是一种定义在类外部的普通函数，但它需要在类体内进行说明，为了与该类的成员函数加以区别，在说明时前面加以关键字friend。友元不是成员函数，但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率，但是，它破坏了类的封装性和隐藏性，使得非成员函数可以访问类的私有成员。&nbsp;&nbsp;友元函数&nbsp;通过对象的引用可以直接 访问私有变量，（不能直接访问私有变量），而一般的函数则...&nbsp;&nbsp;<a href='http://www.cnitblog.com/chenlei/archive/2010/09/26/69199.html'>阅读全文</a><img src ="http://www.cnitblog.com/chenlei/aggbug/69199.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/chenlei/" target="_blank">Mr.雷</a> 2010-09-26 15:42 <a href="http://www.cnitblog.com/chenlei/archive/2010/09/26/69199.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中的各种继承方式规则</title><link>http://www.cnitblog.com/chenlei/archive/2010/09/25/69142.html</link><dc:creator>Mr.雷</dc:creator><author>Mr.雷</author><pubDate>Sat, 25 Sep 2010 09:31:00 GMT</pubDate><guid>http://www.cnitblog.com/chenlei/archive/2010/09/25/69142.html</guid><wfw:comment>http://www.cnitblog.com/chenlei/comments/69142.html</wfw:comment><comments>http://www.cnitblog.com/chenlei/archive/2010/09/25/69142.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/chenlei/comments/commentRss/69142.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/chenlei/services/trackbacks/69142.html</trackback:ping><description><![CDATA[<span  style="font-family: Arial; font-size: 14px; line-height: 25px; ">&nbsp;1、C++中的继承方式有：</span><span  style="font-family: Arial; font-size: 14px; line-height: 25px; "><br></span><span  style="font-family: Arial; font-size: 14px; line-height: 25px; ">&nbsp;&nbsp;public、private、protected三种（它们直接影响到派生类的成员、及其对象对基类成员访问的规则）。</span><span  style="font-family: Arial; font-size: 14px; line-height: 25px; "><br></span><span  style="font-family: Arial; font-size: 14px; line-height: 25px; ">&nbsp;&nbsp;（1）public（公有继承）：继承时保持基类中各成员属性不变，并且基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员，而不能访问private成员；派生类的对象只能访问基类中的public成员。</span><span  style="font-family: Arial; font-size: 14px; line-height: 25px; "><br></span><span  style="font-family: Arial; font-size: 14px; line-height: 25px; ">&nbsp;&nbsp;（2）private（私有继承）：继承时基类中各成员属性均变为private，并且基类中private成员被隐藏。派生类的成员也只能访问基类中的public/protected成员，而不能访问private成员；派生类的对象不能访问基类中的任何的成员。</span><span  style="font-family: Arial; font-size: 14px; line-height: 25px; ">&nbsp;</span><span  style="font-family: Arial; font-size: 14px; line-height: 25px; "><br></span><span  style="font-family: Arial; font-size: 14px; line-height: 25px; ">&nbsp;&nbsp;（3）protected（保护性继承）：继承时基类中各成员属性均变为protected，并且基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员，而不能访问private成员；派生类的对象不能访问基类中的任何的成员。</span>
<img src ="http://www.cnitblog.com/chenlei/aggbug/69142.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/chenlei/" target="_blank">Mr.雷</a> 2010-09-25 17:31 <a href="http://www.cnitblog.com/chenlei/archive/2010/09/25/69142.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内存，指针，二重指针的高级实用（GetMemory 例子）</title><link>http://www.cnitblog.com/chenlei/archive/2010/09/05/68647.html</link><dc:creator>Mr.雷</dc:creator><author>Mr.雷</author><pubDate>Sun, 05 Sep 2010 10:42:00 GMT</pubDate><guid>http://www.cnitblog.com/chenlei/archive/2010/09/05/68647.html</guid><wfw:comment>http://www.cnitblog.com/chenlei/comments/68647.html</wfw:comment><comments>http://www.cnitblog.com/chenlei/archive/2010/09/05/68647.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/chenlei/comments/commentRss/68647.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/chenlei/services/trackbacks/68647.html</trackback:ping><description><![CDATA[<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">内存分配方式有三种：<br />（1） 从静态存储区域分配。内存在程序编译的时候就已经分配好，这块内存在程序的<br />整个运行期间都存在。例如全局变量，static 变量。<br />（2） 在栈上创建。在执行函数时，函数内局部变量的存储单元都可以在栈上创建，函<br />数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集<br />中，效率很高，但是分配的内存容量有限。<br />（3） 从堆上分配，亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多<br />少的内存，程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期<br />由我们决定，使用非常灵活，但问题也最多。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">?? 内存分配未成功，却使用了它。<br />编程新手常犯这种错误，因为他们没有意识到内存分配会不成功。常用解决办法是，<br />在使用内存之前检查指针是否为NULL。如果指针p 是函数的参数，那么在函数的入口<br />处用assert(p!=NULL)进行检查。如果是用malloc 或new 来申请内存，应该用if(p==NULL)<br />或if(p!=NULL)进行防错处理。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">?? 内存分配虽然成功，但是尚未初始化就引用它。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">?? 内存分配成功并且已经初始化，但操作越过了内存的边界。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">?? 忘记了释放内存，造成内存泄露。<br />含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足，你<br />看不到错误。终有一次程序突然死掉，系统出现提示：内存耗尽。<br />动态内存的申请与释放必须配对，程序中malloc 与free 的使用次数一定要相同，否<br />则肯定有错误（new/delete 同理）。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">?? 释放了内存却继续使用它。<br />有三种情况：<br />（1）程序中的对象调用关系过于复杂，实在难以搞清楚某个对象究竟是否已经释放了内<br />存，此时应该重新设计数据结构，从根本上解决对象管理的混乱局面。<br />（2）函数的return 语句写错了，注意不要返回指向&#8220;栈内存&#8221;的&#8220;指针&#8221;或者&#8220;引用&#8221;，<br />因为该内存在函数体结束时被自动销毁。<br />（3）使用free 或delete 释放了内存后，没有将指针设置为NULL。导致产生&#8220;野指针&#8221;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; "><br />指针参数是如何传递内存的？<br />如果函数的参数是一个指针，不要指望用该指针去申请动态内存</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; "><br />Test 函数的语句GetMemory(str, 200)并没有使str 获得期望的内存，str 依旧是NULL，<br />为什么？</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">void GetMemory(char *p, int num)<br />{<br />p = (char *)malloc(sizeof(char) * num);<br />}<br />void Test(void)<br />{<br />char *str = NULL;<br />GetMemory(str, 100); // str 仍然为 NULL<br />strcpy(str, "hello"); // 运行错误<br />}</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">毛病出在函数GetMemory 中。编译器总是要为函数的每个参数制作临时副本，指针<br />参数p 的副本是 _p，编译器使 _p = p。如果函数体内的程序修改了_p 的内容，就导致<br />参数p 的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中，_p 申请<br />了新的内存，只是把_p 所指的内存地址改变了，但是p 丝毫未变。所以函数GetMemory<br />并不能输出任何东西。事实上，每执行一次GetMemory 就会泄露一块内存，因为没有用<br />free 释放内存。<br />如果非得要用指针参数去申请内存，那么应该改用&#8220;指向指针的指针&#8221;<br />void GetMemory2(char **p, int num)<br />{<br />*p = (char *)malloc(sizeof(char) * num);<br />}<br />void Test2(void)<br />{<br />char *str = NULL;<br />GetMemory2(&amp;str, 100); // 注意参数是 &amp;str，而不是str<br />strcpy(str, "hello");<br />cout&lt;&lt; str &lt;&lt; endl;<br />free(str);<br />}</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; ">由于&#8220;指向指针的指针&#8221;这个概念不容易理解，我们可以用函数返回值来传递动态<br />内存。这种方法更加简单<br />char *GetMemory3(int num)<br />{<br />char *p = (char *)malloc(sizeof(char) * num);<br />return p;<br />}<br />void Test3(void)<br />{<br />char *str = NULL;<br />str = GetMemory3(100);<br />strcpy(str, "hello");<br />cout&lt;&lt; str &lt;&lt; endl;<br />free(str);<br />}<br />用函数返回值来传递动态内存这种方法虽然好用，但是常常有人把return 语句用错<br />了。这里强调不要用return 语句返回指向&#8220;栈内存&#8221;的指针，因为该内存在函数结束时<br />自动消亡<br />char *GetString(void)<br />{<br />char p[] = "hello world";<br />return p; // 编译器将提出警告<br />}<br />void Test4(void)<br />{<br />char *str = NULL;<br />str = GetString(); // str 的内容是垃圾<br />cout&lt;&lt; str &lt;&lt; endl;<br />}<br />用调试器逐步跟踪Test4，发现执行str = GetString 语句后str 不再是NULL 指针，<br />但是str 的内容不是&#8220;hello world&#8221;而是垃圾。<br />char *GetString2(void)<br />{<br />char *p = "hello world";<br />return p;<br />}<br />void Test5(void)<br />{<br />char *str = NULL;<br />str = GetString2();<br />cout&lt;&lt; str &lt;&lt; endl;<br />}<br />函数Test5 运行虽然不会出错，但是函数GetString2 的设计概念却是错误的。因为<br />GetString2 内的&#8220;hello world&#8221;是常量字符串，位于静态存储区，它在程序生命期内<br />恒定不变。无论什么时候调用GetString2，它返回的始终是同一个&#8220;只读&#8221;的内存块。</p><img src ="http://www.cnitblog.com/chenlei/aggbug/68647.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/chenlei/" target="_blank">Mr.雷</a> 2010-09-05 18:42 <a href="http://www.cnitblog.com/chenlei/archive/2010/09/05/68647.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>