﻿<?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++博客-yg2362-随笔分类-C</title><link>http://www.cppblog.com/yg2362/category/18458.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 02 Oct 2012 02:12:04 GMT</lastBuildDate><pubDate>Tue, 02 Oct 2012 02:12:04 GMT</pubDate><ttl>60</ttl><item><title>两个小问题</title><link>http://www.cppblog.com/yg2362/archive/2012/10/01/192562.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Mon, 01 Oct 2012 07:53:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/10/01/192562.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/192562.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/10/01/192562.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/192562.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/192562.html</trackback:ping><description><![CDATA[<span style="font-family: Tahoma; ">开门见山，我先提出几个问题，大家可以先想想，然后我再说出我的方法<br />
1.如何判断一个数M是否为2的N次方？<br />
</span>2.一个数N，如何得到一个数是M，M是不小于N的最小2的K次方<br />
<br />
先说第一个问题，我有两个思路<br />
第一，可以通过判断M的二进制中1的个数。而判断M中1的个数可以通过下面方法获得<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"><span style="color: #0000ff; ">int</span>&nbsp;GetOneCnt(<span style="color: #0000ff; ">int</span>&nbsp;m)&nbsp;<br />{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;m&nbsp;==&nbsp;0&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;cnt&nbsp;=&nbsp;1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(m&nbsp;&amp;&nbsp;(m-1))<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnt++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m--;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;cnt;<br />
}</div>很明显M中1的个数为1和M是2的N次方互为冲要条件<br />第二个思路，我们可以这样，还是利用M的二进制表示，从最高位开始，以变量high_pos表示第一个1的下标，接着从最低位开始，变量low_pos表示第一个1的下标，如果high_pos=low_pos,则M为2的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 />--><span style="color: #0000FF; ">int</span>&nbsp;HighestBitSet(<span style="color: #0000FF; ">int</span>&nbsp;input)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;register&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;result;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(input&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />#ifdef&nbsp;WIN32<br />&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;bsr&nbsp;eax,&nbsp;input<br />&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;mov&nbsp;result,&nbsp;eax<br /><span style="color: #0000FF; ">#else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;asm("bsr&nbsp;%1,&nbsp;%%eax;"<br />&nbsp;&nbsp;&nbsp;&nbsp;"movl&nbsp;%%eax,&nbsp;%0"<br />&nbsp;&nbsp;&nbsp;&nbsp;:"=r"(result)<br />&nbsp;&nbsp;&nbsp;&nbsp;:"r"(input)<br />&nbsp;&nbsp;&nbsp;&nbsp;:"%eax");<br /><span style="color: #0000FF; ">#endif</span><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;result;<br />}</div><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span>&nbsp;LowestBitSet(<span style="color: #0000FF; ">int</span>&nbsp;input)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;register&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;result;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(input&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />#ifdef&nbsp;WIN32<br />&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;bsf&nbsp;eax,&nbsp;input<br />&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;mov&nbsp;result,&nbsp;eax<br /><span style="color: #0000FF; ">#else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;asm("bsf&nbsp;%1,&nbsp;%%eax;"<br />&nbsp;&nbsp;&nbsp;&nbsp;"movl&nbsp;%%eax,&nbsp;%0"<br />&nbsp;&nbsp;&nbsp;&nbsp;:"=r"(result)<br />&nbsp;&nbsp;&nbsp;&nbsp;:"r"(input)<br />&nbsp;&nbsp;&nbsp;&nbsp;:"%eax");<br /><span style="color: #0000FF; ">#endif</span><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;result;<br />}</div><br />再说第二个问题<br />其实有了第一个问题的思路，这个问题就更好解决了，先判断一个数是否为2^N，如果是，直接返回，否则返回2^(N+1)<br />代码如下<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span>&nbsp;CeilingPowerOfTwo(<span style="color: #0000FF; ">int</span>&nbsp;iInput)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(iInput&nbsp;&lt;=&nbsp;1)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&nbsp;1;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;int32_t&nbsp;highestBit&nbsp;=&nbsp;HighestBitSet(iInput);<br />&nbsp;&nbsp;&nbsp;&nbsp;int32_t&nbsp;mask&nbsp;=&nbsp;iInput&nbsp;&amp;&nbsp;((1&nbsp;&lt;&lt;&nbsp;highestBit)&nbsp;-&nbsp;1);&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;相当于input对2^highestBit求余</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;highestBit&nbsp;+=&nbsp;(&nbsp;mask&nbsp;&gt;&nbsp;0&nbsp;);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(1&lt;&lt;highestBit);<br />}</div><img src ="http://www.cppblog.com/yg2362/aggbug/192562.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-10-01 15:53 <a href="http://www.cppblog.com/yg2362/archive/2012/10/01/192562.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浅谈内存池几种设计方式</title><link>http://www.cppblog.com/yg2362/archive/2012/07/19/184175.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Thu, 19 Jul 2012 03:41:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/07/19/184175.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/184175.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/07/19/184175.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/184175.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/184175.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;写服务器的，通常会涉及到内存池的东西，自己在这方面也看了写了一些东西，有些体会，写出来跟大家分享下。<br />
&nbsp; &nbsp; &nbsp; 内存池基本包含以下几个东西，第一，初始化。第二，分配内存。第三，回收内存。所谓初始化，就是在服务器启动的时候，或者第一次需要内存的时候，系统分配很大的一块内存，方便之后的使用。分配内存，就是从内存池中取出需要的内存给外部使用，当然这里需要考虑的是当内存池中没有内存可分配时候的处理。回收内存，简单来说，就是外面对象生命期结束了，将分配出去的内存回收入内存池中。好了简单概念就说完了，我们先来看一种最简单的设计方式。<font class="Apple-style-span" color="#0000ff" size="2"><br />
</font>
<div style="border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><font class="Apple-style-span" color="#0000ff" size="2">//为了方便描述，这里附上几个简单的链表操作宏</font><br />
<div>
<div>#define INSERT_TO_LIST( head, item, prev, next )<span style="white-space: pre; "> </span>\</div>
<div>do{<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre">	</span>if ( head )<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre"> </span>(head)-&gt;prev = (item);<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre">	</span>(item)-&gt;next = (head);<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre">	</span>(head) = (item);<span style="white-space:pre"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>\</div>
<div>}while(0)<br />
</div>
</div>
<div>
<div>#define REMOVE_FROM_LIST(head, item, prev, next)<span style="white-space:pre"> </span>\</div>
<div>do{<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre">	</span>if ( (head) == (item) )<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre">	</span>{<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre"> </span>(head) = (item)-&gt;next;<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre"> </span>if ( head )<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre"> </span>(head)-&gt;prev = NULL;<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre">	</span>}<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre">	</span>else<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre">	</span>{<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre"> </span>if ( (item)-&gt;prev )<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre"> </span>(item)-&gt;prev-&gt;next = (item)-&gt;next;<span style="white-space:pre"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>\</div>
<div><span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre"> </span>if ( (item)-&gt;next )<span style="white-space:pre"> </span>\</div>
<div><span style="white-space:pre"> </span>(item)-&gt;next-&gt;prev = (item)-&gt;prev;<span style="white-space:pre"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>\</div>
<div><span style="white-space:pre">	</span>}<span style="white-space:pre"> </span>\</div>
<div>}while(0)<br />
</div>
</div>
<font class="Apple-style-span" color="#0000ff" size="2">struct</font><span style="font-size: 13px; color: #000000; ">&nbsp;student</span><br />
<font class="Apple-style-span" size="2">{</font><br />
<font class="Apple-style-span" size="2">&nbsp; &nbsp; &nbsp; char name[32];</font><br />
<font class="Apple-style-span" size="2">&nbsp; &nbsp; &nbsp; byte sex;</font><br />
<font class="Apple-style-span" size="2">&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;</font><br />
<font class="Apple-style-span" size="2">&nbsp; &nbsp; &nbsp; struct student *prev,*next;</font><br />
<font class="Apple-style-span" size="2">};</font><br />
<br />
<font class="Apple-style-span" size="2">static struct mem_pool</font><br />
<font class="Apple-style-span" size="2">{</font><br />
<font class="Apple-style-span" size="2">&nbsp; &nbsp; &nbsp; //该指针用来记录空闲节点</font><br />
<font class="Apple-style-span" size="2">&nbsp; &nbsp; &nbsp;&nbsp;</font>
<div style="font-size: 13px; display: inline-block; "></div>
<span style="font-size: 13px; color: #0000ff; ">struct</span><span style="font-size: 13px; color: #000000; ">&nbsp;student *free;<br />
&nbsp; &nbsp; &nbsp; //该变量记录分配结点个数<br />
&nbsp; &nbsp; &nbsp; size_t alloc_cnt;<br />
</span><font class="Apple-style-span" size="2">}s_mem_pool;</font><br />
<br />
//分配内存&#8220;块&#8221;的函数<br />
bool mem_pool_resize(size_t size)<br />
{<br />
&nbsp; &nbsp; &nbsp; //该函数创建size个不连续的对象，把他们通过链表的方式加入到s_mem_pool.free中<br />
&nbsp; &nbsp; &nbsp; for ( size_t i = 0;i &lt; size;++i )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
<div style="display: inline-block; "></div>
<span class="Apple-style-span" style="font-size: small; ">struct student *p = (struct student *)malloc(sizeof(struct student));<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
<div style="display: inline-block; "></div>
</span><span class="Apple-style-span" style="font-size: small; ">if ( !p )<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return false;<br />
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p-&gt;prev = p-&gt;next = NULL;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT_TO_LIST(s_mem_pool.free,p,prev,next);</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp; &nbsp; &nbsp; s_mem_pool.alloc_cnt += size;<br />
}<br />
<br />
<div>
<div>#define MEM_INIT_SIZE<span style="white-space:pre">	</span>512 &nbsp;</div>
<div>#define MEM_INC_SIZE<span style="white-space:pre">	</span>256</div>
<div>//初始化函数</div>
<div>bool mem_pool_init()</div>
<div>{</div>
<div><span style="white-space:pre">	</span>if ( !mem_pool_resize(MEM_INIT_SIZE) )</div>
<div><span style="white-space:pre"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>return false;</div>
<div><span style="white-space:pre"> </span></div>
<div><span style="white-space:pre">	</span>return true;</div>
<div>}</div>
<div></div>
<div>struct student *get_data()</div>
<div>{</div>
<div><span style="white-space:pre">	</span>if ( s_mem_pool.free == NULL )</div>
<div><span style="white-space:pre">	</span>{</div>
<div><span style="white-space:pre"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>if ( !mem_pool_resize(MEM_INC_SIZE) )</div>
<div><span style="white-space:pre"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>return NULL;</div>
<div><span style="white-space:pre">	</span>}</div>
<div><span style="white-space:pre">	</span></div>
<div><span style="white-space:pre">	</span>struct student *ret = s_mem_pool.free;</div>
<div><span style="white-space:pre">	</span>REMOVE_FROM_LIST(s_mem_pool.free,ret,prev,next)</div>
<div><span style="white-space:pre">	</span>return ret;</div>
<div>}</div>
<div></div>
<div>void free_data(struct student *p)</div>
<div>{</div>
<div><span style="white-space:pre">	</span>if ( !p )</div>
<div><span style="white-space:pre"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>return;</div>
<div><span style="white-space:pre"> </span></div>
<div><span style="white-space:pre">	</span>memset(p,0,sizeof(struct student));</div>
<div><span style="white-space:pre">	</span>INSERT_TO_LIST(s_mem_pool.free,p,prev,next)</div>
<div>}</div>
</div>
<font class="Apple-style-span" size="2"></font></div>
好了最简单的内存池的大致框架就是这样。我们先来看下他的过程。首先，在mem_pool_init()函数中，他先分配512个不连续的student对象。每分配出来一个就把它加入到free链表中，初始化完成后内存池大概是这样的<br />
<img src="http://www.cppblog.com/images/cppblog_com/yg2362/7.png" width="368" height="141" alt="" /><br />
接下来就是从内存池中取出一个对象get_data()。函数先去判断是否有空闲的对象，有则直接分配，否则再向系统获取一"块"大的内存。调用一次后的内存池大概是这样的<br />
<img src="http://www.cppblog.com/images/cppblog_com/yg2362/8.png" width="286" height="122" alt="" /><br />
释放对象，再把对象加入到Free链表中。<br />
以上就是过程的简单分析，下面我们来看看他的缺点。<br />
第一，内存不是连续的，容易产生碎片<br />
第二，一个类型就得写一个这样的内存池，很麻烦<br />
第三，为了构建这个内存池，每个没对象必须加上一个prev,next指针<br />
好了，我们来优化一下它。我们重新定义下我们的结构体<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">union&nbsp;student<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;index;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;name[</span><span style="color: #000000; ">32</span><span style="color: #000000; ">];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">byte</span><span style="color: #000000; ">&nbsp;sex;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}s;<br />
};<br />
<br />
</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;mem_pool<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">该下标用来记录空闲节点</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;free;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">内存池</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">mem;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">已分配结点个数</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;alloc_cnt；<br />
}s_mem_pool;<br />
<br />
</span><span style="color: #008000; ">//</span><span style="color: #008000; ">分配内存块的函数</span><span style="color: #008000; "><br />
</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;mem_pool_resize(size_t&nbsp;size)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;new_size&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.alloc_cnt</span><span style="color: #000000; ">+</span><span style="color: #000000; ">size;<br />
&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">tmp&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(union&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)realloc(s_mem_pool.mem,new_size</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(union&nbsp;student))；<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">tmp&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;memset(tmp</span><span style="color: #000000; ">+</span><span style="color: #000000; ">s_mem_pool.alloc_cnt,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,size</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(union&nbsp;student));<br />
&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.alloc_cnt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(&nbsp;;i&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;new_size&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp[i].index&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;i&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;tmp[i].index&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.free&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.alloc_cnt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.mem&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;tmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.alloc_cnt&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;new_size;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">;<br />
}<br />
<br />
</span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MEM_INIT_SIZE&nbsp;&nbsp;&nbsp;&nbsp;512&nbsp;&nbsp;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MEM_INC_SIZE&nbsp;&nbsp;&nbsp;&nbsp;256</span><span style="color: #000000; "><br />
</span><span style="color: #008000; ">//</span><span style="color: #008000; ">初始化函数</span><span style="color: #008000; "><br />
</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;mem_pool_init()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">mem_pool_resize(MEM_INIT_SIZE)&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">;<br />
}<br />
<br />
union&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">get_data()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;s_mem_pool.free&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">mem_pool_resize(MEM_INC_SIZE)&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.mem</span><span style="color: #000000; ">+</span><span style="color: #000000; ">s_mem_pool.free;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.free&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;ret</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">index;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;ret;<br />
}<br />
<br />
</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;free_data(union&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">p&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;p</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">index&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.free;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.free&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;p&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;s_mem_pool.mem;<br />
}</span></div>
我们来看看改进了些什么。第一student改成了联合体，这主要是为了不占用额外的内存，也就是我们上面所说的第三个缺点，第二，我们使用了realloc函数，这样我们可以使我们分配出来的内存是连续的。我们初始化的时候多了一个for循环，这是为了记录空闲对象的下标，当我们取出一个对象时，free可以立刻知道下一个空闲对象的位置，释放的时候，对象先记录free此时的值，接着再把free赋值成该对象在数组的下标，这样就完成了回收工作。<br />
我们继续分析这段代码，问题在realloc函数上，如果我们的s_mem_pool.mem已经很大了，在realloc的时候我们都知道，先要把原来的数据做一次拷贝，所以如果数据量很大的情况下做一次拷贝，是会消耗性能的。那这里有没有好的办法呢，我们进一步优化<br />
思路大概是这样<br />
初始化<br />
<img src="http://www.cppblog.com/images/cppblog_com/yg2362/9.png" width="356" height="347" alt="" /><br />
再次分配的时候，我们只需要重新分配新的内存单元，而不需要拷贝之前的内存单元。<br />
<img src="http://www.cppblog.com/images/cppblog_com/yg2362/10.png" width="562" height="315" alt="" /><br />
因此基于此思路，我们修改我们的代码<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />
#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdlib.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />
<br />
</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;index;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;name[</span><span style="color: #000000; ">32</span><span style="color: #000000; ">];<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">byte</span><span style="color: #000000; ">&nbsp;sex;<br />
};<br />
<br />
</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;mem_pool<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">该下标用来记录空闲节点</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;free;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">内存池</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">mem;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">已分配块个数</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;block_cnt；<br />
}s_mem_pool;<br />
<br />
</span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;BLOCK_SIZE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;256&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">每块的大小</span><span style="color: #000000; "><br />
</span><span style="color: #008000; ">//</span><span style="color: #008000; ">分配内存块的函数</span><span style="color: #008000; "><br />
</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;mem_pool_resize(size_t&nbsp;block_size)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;new_cnt&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.block_cnt&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;block_size;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">tmp&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student&nbsp;</span><span style="color: #000000; ">**</span><span style="color: #000000; ">)realloc(s_mem_pool.mem,new_size</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">))；<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">tmp&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;memset(tmp</span><span style="color: #000000; ">+</span><span style="color: #000000; ">s_mem_pool.block_cnt,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,size</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student</span><span style="color: #000000; ">*</span><span style="color: #000000; ">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(&nbsp;size_t&nbsp;i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.block_cnt;i&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;new_cnt;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp[i]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)calloc(BLOCK_SIZE,</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">tmp[i]&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;j&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(;j&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;BLOCK_SIZE&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">j&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp[i][j].index&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;i</span><span style="color: #000000; ">*</span><span style="color: #000000; ">BLOCK_SIZE</span><span style="color: #000000; ">+</span><span style="color: #000000; ">j</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;i&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;new_cnt</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp[i][j].index&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)</span><span style="color: #000000; ">*</span><span style="color: #000000; ">BLOCK_SIZE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp[i][j].index&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.free&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.alloc_cnt</span><span style="color: #000000; ">*</span><span style="color: #000000; ">BLOCK_SIZE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.mem&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;tmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.block_cnt&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;new_cnt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">;<br />
}<br />
&nbsp;<br />
</span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;MEM_INC_SIZE&nbsp;&nbsp;&nbsp;&nbsp;10</span><span style="color: #000000; "><br />
</span><span style="color: #008000; ">//</span><span style="color: #008000; ">初始化函数</span><span style="color: #008000; "><br />
</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;mem_pool_init()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">mem_pool_resize(MEM_INIT_SIZE)&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">;<br />
}<br />
<br />
</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">get_data()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;s_mem_pool.free&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">mem_pool_resize(MEM_INC_SIZE)&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">ret&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.mem[s_mem_pool.free</span><span style="color: #000000; ">/</span><span style="color: #000000; ">BLOCK_SIZE]</span><span style="color: #000000; ">+</span><span style="color: #000000; ">s_mem_pool.free</span><span style="color: #000000; ">%</span><span style="color: #000000; ">BLOCK_SIZE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;pos&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.free;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.free&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;ret</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">index;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">index&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;pos;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;ret;<br />
}<br />
<br />
</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;free_data(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;</span><span style="color: #000000; ">!</span><span style="color: #000000; ">p&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;pos&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;p</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">index;<br />
&nbsp;&nbsp;&nbsp;&nbsp;p</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">index&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;s_mem_pool.free;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s_mem_pool.free&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;pos;<br />
}</span></div>
<span style="font-size: 10pt; ">这里不一样的地方主要在</span><font class="Apple-style-span" size="2"><span style="font-size: 10pt; ">mem_pool_resize函数中，mem变成了2级指针，每次realloc的时候只需要分配指针数组的大小，无须拷贝对象，这样可以提高效率，但是为了在释放的时候把对象放回该放的位置，我们这里在结构体里加入了index变量，记录它的下标。在内存池里，它表示下个空闲对象的下标，在内存池外，它表示在内存池中的下标。总的来说满足了一个需求，却又带来了新的问题，有没有更好的方法呢，答案是肯定，不过今天先写到这里，明天继续。</span></font><img src ="http://www.cppblog.com/yg2362/aggbug/184175.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-07-19 11:41 <a href="http://www.cppblog.com/yg2362/archive/2012/07/19/184175.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浅谈二进制文件读写和文本文件读写的区别</title><link>http://www.cppblog.com/yg2362/archive/2012/07/12/182956.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Thu, 12 Jul 2012 01:59:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/07/12/182956.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/182956.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/07/12/182956.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/182956.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/182956.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="color: #4b4b4b; font-family: georgia, verdana, Arial, helvetica, sans-seriff; font-size: 13px; line-height: 20px; background-color: #ffffff; ">&nbsp; &nbsp; &nbsp; 昨天在看一篇文章的时候，突然想起了这个基础性的问题，自己一直对它的区别不是很清楚，于是今天上午研究下了，分享下自己的理解。(对它很清楚的同学们可以略过此篇文章)<br />
&nbsp; &nbsp; &nbsp; 从存储方式来说，文件在磁盘上的存储方式都是二进制形式，所以，文本文件其实也应该算二进制文件。那么他们的区别呢，各自的优缺点呢？不急，我慢慢道来。<br />
&nbsp; &nbsp; &nbsp; 先从他们的区别来说，虽然都是二进制文件，但是二进制代表的意思不一样。打个比方，一个人，我们可以叫他的大名，可以叫他的小名，但其实都是代表这个人。二进制读写是将内存里面的数据直接读写入文本中，而文本呢，则是将数据先转换成了字符串，再写入到文本中。下面我用个例子来说明。<br />
我们定义了一个结构体，表示一个学生信息，我们打算把学生的信息分别用二进制和文本的方式写入到文件中。<br />
</span>
<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; ">struct</span><span style="color: #000000; ">&nbsp;Student&nbsp;<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;num;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;name[</span><span style="color: #000000; ">20</span><span style="color: #000000; ">];<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">float</span><span style="color: #000000; ">&nbsp;score;<br />
};</span></div>
我们定义两个方法，分别表示内存写入和文本写入<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000; ">//</span><span style="color: #008000; ">使用二进制写入</span><span style="color: #008000; "><br />
</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;write_to_binary_file()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Student&nbsp;stdu;<br />
&nbsp;&nbsp;&nbsp;&nbsp;stdu.num&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">111</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;sprintf_s(stdu.name,</span><span style="color: #000000; ">20</span><span style="color: #000000; ">,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">shine</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;stdu.score&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">80.0f</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;fstream&nbsp;binary_file(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">test1.dat</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,ios::</span><span style="color: #0000FF; ">out</span><span style="color: #000000; ">|</span><span style="color: #000000; ">ios::binary</span><span style="color: #000000; ">|</span><span style="color: #000000; ">ios::app);&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">此处省略文件是否打开失败的判断</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;binary_file.write((</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">stdu,</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Student));</span><span style="color: #008000; ">//</span><span style="color: #008000; ">二进制写入的方式</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;binary_file.close();<br />
}&nbsp;<br />
</span><span style="color: #008000; ">//</span><span style="color: #008000; ">文本格式写入</span><span style="color: #008000; "><br />
</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;write_to_text_file()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Student&nbsp;stdu;<br />
&nbsp;&nbsp;&nbsp;&nbsp;stdu.num&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">111</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;sprintf_s(stdu.name,</span><span style="color: #000000; ">20</span><span style="color: #000000; ">,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">shine</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;stdu.score&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">80.0f</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;FILE&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">fp&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;fopen(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">test2.dat</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">a+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">此处省略文件是否打开失败的判断</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;fprintf(fp,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d%s%f</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,stdu.num,stdu.name,stdu.score);&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">将数据转换成字符串（字符串的格式可以自己定义）</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);<br />
}&nbsp;<br />
</span><span style="color: #008000; ">//</span><span style="color: #008000; ">MAIN函数调用前面两个方法</span><span style="color: #008000; "><br />
</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;_tmain(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;argv[])<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;write_to_binary_file();<br />
&nbsp;&nbsp;&nbsp;&nbsp;write_to_text_file();<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />
}</span></div>
我们来看下，文件里面的格式
2进制文件<br /><img src="http://www.cppblog.com/images/cppblog_com/yg2362/未命名文件.jpg" width="603" height="38" alt="" /><br /><span class="Apple-style-span" style="color: #4b4b4b; font-family: georgia, verdana, Arial, helvetica, sans-seriff; font-size: 13px; line-height: 20px; background-color: #ffffff; ">文本文件</span><br /><img src="http://www.cppblog.com/images/cppblog_com/yg2362/未命名文件1.jpg" width="644" height="39" alt="" /><br /><br /><span class="Apple-style-span" style="color: #4b4b4b; font-family: georgia, verdana, Arial, helvetica, sans-seriff; font-size: 13px; line-height: 20px; background-color: #ffffff; ">2进制文件里面将111编码成6F，1个字节，这刚好是111的16进制表示，而文本文件中则写成31，31，31用了3个字节，表示111。73 &nbsp; 68 &nbsp; 69 &nbsp; 6E &nbsp; 65 表示shine，之后2进制文件里是几个连续的FE，而文本文件中是38 &nbsp; 30......文本文件将浮点数80.000000用了38(表示8) &nbsp; 30(表示0) &nbsp;2E(表示.) &nbsp; 30(表示0)&nbsp;&nbsp;&nbsp;30(表示0)&nbsp;&nbsp;&nbsp;30(表示0)&nbsp;&nbsp;&nbsp;30(表示0)&nbsp;&nbsp;&nbsp;30(表示0)&nbsp;&nbsp;&nbsp;30(表示0)，二进制文件用了4个字节表示浮点数00 &nbsp; 00 &nbsp; A0 &nbsp; 42<br />通过这里我们可以初见端倪了，二进制将数据在内存中的样子原封不动的搬到文件中，文本格式则是将每一个数据转换成字符写入到文件中，他们在大小上，布局上都有着区别。由此可以看出，2进制文件可以从读出来直接用，但是文本文件还多一个&#8220;翻译&#8221;的过程，因此2进制文件的可移植性好。</span><img src ="http://www.cppblog.com/yg2362/aggbug/182956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-07-12 09:59 <a href="http://www.cppblog.com/yg2362/archive/2012/07/12/182956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不定参数的分析</title><link>http://www.cppblog.com/yg2362/archive/2012/07/12/182955.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Thu, 12 Jul 2012 01:51:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/07/12/182955.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/182955.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/07/12/182955.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/182955.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/182955.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="color: #4b4b4b; font-family: georgia, verdana, Arial, helvetica, sans-seriff; font-size: 13px; line-height: 20px; background-color: #ffffff; ">
<p>先看一个简单的使用例子</p>
<p>求任意个自然数的平方和：</p>
</span>
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;SqSum(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;n,)&nbsp;&nbsp;&nbsp;<br />
{&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;va_list&nbsp;arg_ptr;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;sum&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,_n&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;n;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;arg_ptr&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;va_start(arg_ptr,n);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(_n&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;(_n</span><span style="color: #000000; ">*</span><span style="color: #000000; ">_n);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_n&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;va_arg(arg_ptr,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;va_end(arg_ptr);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;sum;&nbsp;&nbsp;&nbsp;<br />
}<br />
</span>
</div>
首先解释下函数参数入栈情况
在VC等绝大多数C编译器中，默认情况下，参数进栈的顺序是由右向左的，因此，参数进栈以后的内存模型如下图所示：<br />最后一个固定参数的地址位于第一个可变参数之下，并且是连续存储的。
<br />| 最后一个可变参数(高内存地址处) | 第N个可变参数 | 第一个可变参数 | 最后一个固定参数 | 第一个固定参数(低内存地址处)
<br />明白上面那个顺序，就知道其实可变参数就是玩弄参数的地址，已达到&#8220;不定&#8221;的目的
下面我摘自VC中的源码来解释<br />va_list,va_start,va_arg,va_end宏
<br />1.其实va_list就是我们平时经常用的char*
typedef char * va_list;<br />
2.va_start该宏的目的就是将指针指向最后一个固定参数的后面，即第一个不定参数的起始地址
#define va_start(ap,v)( ap = (va_list)&amp;v + _INTSIZEOF(v) )
v即表示最后一个固定参数，&amp;v表示v的地址，
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) &amp; ~(sizeof(int) - 1) )
该宏其实是一个内存对齐的操作。即表示大于sizeof(n)且为sizeof(int)倍数的最小整数。这句话有点绕，其实举几个例子就简单了。比如1--4，则返回4,5--8则返回8
<br />3.va_arg 该宏的目的是将ap指针继续后移，读取后面的参数，t表示参数类型。该宏首先将ap指针移动到下一个参数的起始地址ap += _INTSIZEOF(t)，然后将本参数的值返回
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
<br />4.va_end将指针赋空
#define va_end(ap) ap = (va_list)0
有了这个分析我们可以把上例中的代码重新翻译下<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;SqSum(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;n,)&nbsp;&nbsp;&nbsp;<br />
{&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">arg_ptr;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;sum&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,_n&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;n;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;arg_ptr&nbsp;</span><span style="color: #000000; ">=</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; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">n&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">4</span><span style="color: #000000; ">;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">本机上sizeof(int)&nbsp;=&nbsp;4&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(_n&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;(_n</span><span style="color: #000000; ">*</span><span style="color: #000000; ">_n);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arg_ptr&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">4</span><span style="color: #000000; ">;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_n&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)(arg_ptr</span><span style="color: #000000; ">-</span><span style="color: #000000; ">4</span><span style="color: #000000; ">);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;arg_ptr&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;&nbsp;&nbsp;<br />
} &nbsp;</span></div>
这样我们也可以写出我们自己的printf了<img src ="http://www.cppblog.com/yg2362/aggbug/182955.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-07-12 09:51 <a href="http://www.cppblog.com/yg2362/archive/2012/07/12/182955.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>