﻿<?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++博客-Xiao.Zhu C++-文章分类-C/C++</title><link>http://www.cppblog.com/zzh/category/3739.html</link><description>Xiao.Zhu C++</description><language>zh-cn</language><lastBuildDate>Sun, 25 May 2008 11:13:18 GMT</lastBuildDate><pubDate>Sun, 25 May 2008 11:13:18 GMT</pubDate><ttl>60</ttl><item><title>内存池(MemPool)</title><link>http://www.cppblog.com/zzh/articles/19616.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 02:57:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19616.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19616.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19616.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19616.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19616.html</trackback:ping><description><![CDATA[转载声明：本文转自csdn博客，许式伟著，链接：http://blog.csdn.net/xushiweizh/archive/2006/11/22/1402967.aspx <br /><br />小狼注：上次也写了一个简单的内存池，是使用STL的deque来管理的，实现起来比较简单，不过有个缺点就是只能固定分配大小，所以需要根据经验值事先分配内存大小，然后把内存再次划分为等大的小的内存供使用。<br />概述<br /><br />内存池（MemPool）技术备受推崇。我用google搜索了下，没有找到比较详细的原理性的文章，故此补充一个。另外，补充了boost::pool组件与经典MemPool的差异。同时也描述了MemPool在sgi-stl/stlport中的运用。<br /><br /> <br />经典的内存池技术<br /> <br />经典的内存池（MemPool）技术，是一种用于分配大量大小相同的小对象的技术。通过该技术可以极大加快内存分配/释放过程。下面我们详细解释其中的奥妙。<br /> <br />经典的内存池只涉及两个常量：MemBlockSize、ItemSize（小对象的大小，但不能小于指针的大小，在32位平台也就是不能小于4字节），以及两个指针变量MemBlockHeader、FreeNodeHeader。开始，这两个指针均为空。<br /> <br />class MemPool<br />{<br />private:<br />    const int m_nMemBlockSize;<br />    const int m_nItemSize;<br /><br />    struct _FreeNode {<br />        _FreeNode* pPrev;<br />        BYTE data[m_nItemSize - sizeof(_FreeNode*)];<br />    };<br /><br />    struct _MemBlock {<br />        _MemBlock* pPrev;<br />        _FreeNode data[m_nMemBlockSize/m_nItemSize];<br />    };<br />  <br />    _MemBlock* m_pMemBlockHeader;<br />    _FreeNode* m_pFreeNodeHeader;<br /> <br />public:<br />   MemPool(int nItemSize, int nMemBlockSize = 2048)<br />       : m_nItemSize(nItemSize), m_nMemBlockSize(nMemBlockSize),<br />         m_pMemBlockHeader(NULL), m_pFreeNodeHeader(NULL)<br />   {<br />   }<br />};<br /> <br />其中指针变量MemBlockHeader是把所有申请的内存块（MemBlock）串成一个链表，以便通过它可以释放所有申请的内存。FreeNodeHeader变量则是把所有自由内存结点（FreeNode）串成一个链。<br /> <br />这
段话涉及两个关键概念：内存块（MemBlock）和自由内存结点（FreeNode）。内存块大小一般固定为MemBlockSize字节（除去用以建
立链表的指针外）。内存块在申请之初就被划分为多个内存结点（Node），每个Node大小为 ItemSize（小对象的大小），计
MemBlockSize/ItemSize个。这MemBlockSize/ItemSize个内存结点刚开始全部是自由的，他们被串成链表。我们看看
申请/释放内存过程，就很容易明白这样做的目的。<br /> <br />申请内存过程<br />代码如下：<br />void* MemPool::malloc()    // 没有参数<br />{<br />    if (m_pFreeNodeHeader == NULL)<br />    {<br />       const int nCount = m_nMemBlockSize/m_nItemSize;<br />        _MemBlock* pNewBlock = new _MemBlock;<br />        pNewBlock-&gt;data[0].pPrev = NULL;<br />        for (int i = 1; i &lt; nCount; ++i)<br />            pNewBlock-&gt;data[i].pPrev = &amp;pNewBlock-&gt;data[i-1];<br />        m_pFreeNodeHeader = &amp;pNewBlock-&gt;data[nCount-1];<br />        pNewBlock-&gt;pPrev = m_pMemBlock;<br />        m_pMemBlock = pNewBlock;<br />    }<br />    void* pFreeNode = m_pFreeNodeHeader;<br />    m_pFreeNodeHeader = m_pFreeNodeHeader-&gt;pPrev;<br />    return pFreeNode;<br />}<br /> <br />内存申请过程分为两种情况：<br /><br />    * 在自由内存结点链表（FreeNodeList）非空。<br />      在此情况下，Alloc过程只是从链表中摘下一个结点的过程。<br />       <br />    * 否则，意味着需要一个新的内存块(MemBlock)。<br />      这个过程需要将新申请的MemBlock切割成多个Node，并把它们串起来。<br />      MemPool技术的开销主要在这。<br />        <br /><br />释放内存过程<br /> 代码如下：<br />void MemPool::free(void* p)<br />{<br />    _FreeNode* pNode = (_FreeNode*)p;<br />    pNode-&gt;pPrev = m_pFreeNodeHeader;<br />    m_pFreeNodeHeader = pNode;<br />}<br /> <br />释放过程极其简单，只是把要释放的结点挂到自由内存链表（FreeNodeList）的开头即可。<br /> <br />性能分析<br />MemPool技术申请内存/释放内存均极其快（比AutoFreeAlloc慢）。其内存分配过程多数情况下复杂度为O(1)，主要开销在FreeNodeList为空需要生成新的MemBlock时。内存释放过程复杂度为O(1)。<br /> <br /> <br />boost::pool<br /><br />boost::pool是内存池技术的变种。主要的变化如下：<br /><br /> 
   * MemBlock改为非固定长度(MemBlockSize)，而是：第1次申请时
m_nItemSize*32，第2次申请时 m_nItemSize*64，第3次申请时m_nItemSize*128，以此类推。不采用
固定的MemBlockSize，而采用这种做法预测模型（是的，这是一种用户内存需求的预测模型，其实std::vector的内存增长亦采用了该模
型），是一个细节上的改良。<br />       <br />    * 增加了ordered_free(void* p) 函数。<br /><br /> 
     ordered_free区别于free的是，free把要释放的结点挂到自由内存链表
（FreeNodeList）的开头，ordered_free则假设FreeNodeList是有序的，因此会遍历FreeNodeList把要释放的
结点插入到合适的位置。<br /><br />      我们已经看到，free的复杂度是O
(1)，非常快。但请注意ordered_free是比较费的操作，其复杂度是O(N)。这里N是FreeNodeList的大小。对于一个频繁释放/申
请的系统，这个N很可能是个大数。这个boost描述得很清楚：http:
//www.boost.org/libs/pool/doc/interfaces/pool.html <br /><br />注意：不要认为boost提供ordered_free是多此一举。后文我们会在讨论boost::object_pool时解释这一点。<br /> <br />基于内存池技术的通用内存分配组件 <br /> <br />sgi-stl把内存池（MemPool）技术进行发扬光大，用它来实现其最根本的allocator。<br /> <br />其
大体的思想是，建立16个MemPool，&lt;=8字节的内存申请由0号MemPool分配，&lt;=16字节的内存申请由1号 
MemPool分配，&lt;=24字节的内存有2号MemPool分配，以此类推。最后，&gt;128字节的内存申请由普通的malloc分配。<br />注意<br />以上代码属于伪代码（struct _FreeNode、_MemBlock编译通不过），并且去除了出错处理。<img src ="http://www.cppblog.com/zzh/aggbug/19616.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 10:57 <a href="http://www.cppblog.com/zzh/articles/19616.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第九章．指针的安全问题</title><link>http://www.cppblog.com/zzh/articles/19613.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 02:47:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19613.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19613.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19613.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19613.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19613.html</trackback:ping><description><![CDATA[
		<span style="font-size: 10.5pt; color: black;">
				<font size="3">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体">
														<font face="宋体">
																<font face="宋体">看下面的例子：</font>
																<span lang="EN-US">
																		<font face="宋体"> <br />例十七： <br />chars='a'; <br />int*ptr; <br />ptr=(int*)&amp;s; <br />*ptr=1298； <br />指
针ptr是一个int*类型的指针，它指向的类型是int。它指向的地址就是s的首地址。在32位程序中，s占一个字节，int类型占四个字节。最后一条
语句不但改变了s所占的一个字节，还把和s相临的高地址方向的三个字节也改变了。这三个字节是干什么的？只有编译程序知道，而写程序的人是不太可能知道
的。也许这三个字节里存储了非常重要的数据，也许这三个字节里正好是程序的一条代码，而由于你对指针的马虎应用，这三个字节的值被改变了！这会造成崩溃性
的错误。 <br />让我们再来看一例： <br />例十八： <br />1。chara; <br />2。int*ptr=&amp;a; <br />... <br />... <br />3。ptr++; <br />4。*ptr=115; <br />该
例子完全可以通过编译，并能执行。但是看到没有？第3句对指针ptr进行自加1运算后，ptr指向了和整形变量a相邻的高地址方向的一块存储区。这块存储
区里是什么？我们不知道。有可能它是一个非常重要的数据，甚至可能是一条代码。而第4句竟然往这片存储区里写入一个数据！这是严重的错误。所以在使用指针
时，程序员心里必须非常清楚：我的指针究竟指向了哪里。在用指针访问数组的时候，也要注意不要超出数组的低端和高端界限，否则也会造成类似的错误。 <br />在
指针的强制类型转换：ptr1=(TYPE*)ptr2中，如果sizeof(ptr2的类型)大于sizeof(ptr1的类型)，那么在使用指针
ptr1来访问ptr2所指向的存储区时是安全的。如果sizeof(ptr2的类型)小于sizeof(ptr1的类型)，那么在使用指针ptr1来访
问ptr2所指向的存储区时是不安全的。至于为什么，读者结合例十七来想一想，应该会明白的。</font>
																</span>
														</font>
												</font>
										</font>
								</font>
						</font>
				</font>
		</span>
<img src ="http://www.cppblog.com/zzh/aggbug/19613.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 10:47 <a href="http://www.cppblog.com/zzh/articles/19613.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第七章。指针和函数的关系</title><link>http://www.cppblog.com/zzh/articles/19611.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 02:46:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19611.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19611.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19611.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19611.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19611.html</trackback:ping><description><![CDATA[
		<span style="font-size: 10.5pt; color: black;">
				<font size="3">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体">
														<font face="宋体">可以把一个指针声明成为一个指向函数的指针。</font>
														<span lang="EN-US">
																<font face="宋体"> <br />intfun1(char*,int); <br />int(*pfun1)(char*,int); <br />pfun1=fun1; <br />.... <br />.... <br />inta=(*pfun1)("abcdefg",7);//通过函数指针调用函数。 <br />可以把指针作为函数的形参。在函数调用语句中，可以用指针表达式来作为实参。 <br />例十三： <br />intfun(char*); <br />inta; <br />charstr[]="abcdefghijklmn"; <br />a=fun(str); <br />... <br />... <br />intfun(char*s) <br />{ <br />intnum=0; <br />for(inti=0;i{ <br />num+=*s;s++; <br />} <br />returnnum; <br />} <br />这个例子中的函数fun统计一个字符串中各个字符的ASCII码值之和。前面说了，数组的名字也是一个指针。</font>
														</span>
												</font>
										</font>
								</font>
						</font>
				</font>
		</span>
		<font size="3">
				<font face="宋体">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体">
														<span style="font-size: 10.5pt; color: blue;">在函数调用中，当把<span lang="EN-US">str作为实参传递给形参s后，实际是把str的值传递给了s，s所指向的地址就和str所指向的地址一致，但是str和s各自占用各自的存储空间。</span></span>
														<span style="font-size: 10.5pt; color: black;">在函数体内对<span lang="EN-US">s进行自加1运算，并不意味着同时对str进行了自加1运算。</span></span>
												</font>
										</font>
								</font>
						</font>
				</font>
		</font>
<img src ="http://www.cppblog.com/zzh/aggbug/19611.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 10:46 <a href="http://www.cppblog.com/zzh/articles/19611.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第八章。指针类型转换</title><link>http://www.cppblog.com/zzh/articles/19612.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 02:46:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19612.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19612.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19612.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19612.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19612.html</trackback:ping><description><![CDATA[
		<font size="3">
				<font face="宋体">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体">
														<span style="font-size: 10.5pt; color: black;">当我们初始化一个指针或给一个指针赋值时，赋值号的左边是一个指针，赋值号的右边是一个指针表达式。在我们前面所举的例子中，</span>
														<span style="font-size: 10.5pt; color: blue;">绝大多数情况下，指针的类型和指针表达式的类型是一样的，指针所指向的类型和指针表达式所指向的类型是一样的。</span>
												</font>
												<span style="font-size: 10.5pt; color: black;" lang="EN-US">
														<font face="宋体"> <br />例十四： <br />1。floatf=12.3; <br />2。float*fptr=&amp;f; <br />3。int*p; <br />在上面的例子中，假如我们想让指针p指向实数f，应该怎么搞？是用下面的语句吗？ <br />p=&amp;f; <br />不
对。因为指针p的类型是int*，它指向的类型是int。表达式&amp;f的结果是一个指针，指针的类型是float*,它指向的类型是float。两
者不一致，直接赋值的方法是不行的。至少在我的MSVC++6.0上，对指针的赋值语句要求赋值号两边的类型一致，所指向的类型也一致，其它的编译器上我
没试过，大家可以试试。为了实现我们的目的，需要进行"强制类型转换"： <br />p=(int*)&amp;f; <br /></font>
												</span>
												<span style="font-size: 10.5pt; color: blue;">
														<font face="宋体">如果有一个指针</font>
														<span lang="EN-US">
																<font face="宋体">p，我们需要把它的类型和所指向的类型改为TYEP* 和TYPE， <br />那么语法格式是： <br />(TYPE*)p；</font>
														</span>
												</span>
												<font face="宋体">
														<span style="font-size: 10.5pt; color: black;" lang="EN-US"> <br /></span>
														<span style="font-size: 10.5pt; color: blue;">这样强制类型转换的结果是一个新指针，该新指针的类型是<span lang="EN-US">TYPE*，它指向的类型是TYPE，它指向的地址就是原指针指向的地址。而原来的指针p的一切属性都没有被修改。</span></span>
												</font>
												<font face="宋体">
														<span style="font-size: 10.5pt; color: black;" lang="EN-US"> <br />一个函数如果使用了指针作为形参，那么在函数调用语句的实参和形参的结合过程中，也会发生指针类型的转换。 <br />例十五： <br />voidfun(char*); <br />inta=125,b; <br />fun((char*)&amp;a); <br />... <br />... <br />voidfun(char*s) <br />{ <br />charc; <br />c=*(s+3);*(s+3)=*(s+0);*(s+0)=c; <br />c=*(s+2);*(s+2)=*(s+1);*(s+1)=c; <br />} <br />} <br />注
意这是一个32位程序，故int类型占了四个字节，char类型占一个字节。函数fun的作用是把一个整数的四个字节的顺序来个颠倒。注意到了吗？在函数
调用语句中，实参&amp;a的结果是一个指针，它的类型是int*，它指向的类型是int。形参这个指针的类型是char*，它指向的类型是char。
这样，在实参和形参的结合过程中，我们必须进行一次从int*类型到char*类型的转换。结合这个例子，我们可以这样来想象编译器进行转换的过程：编译
器先构造一个临时指针char*temp， 然后执行temp=(char*)&amp;a，最后再把temp的值传递给s。所以最后的结果是：s的类型
是char*,它指向的类型是char，它指向的地址就是a的首地址。 <br />我们已经知道，</span>
														<span style="font-size: 10.5pt; color: blue;">指针的值就是指针指向的地址，在<span lang="EN-US">32位程序中，指针的值其实是一个32位整数。</span></span>
												</font>
												<span style="font-size: 10.5pt; color: black;">
														<font face="宋体">那可不可以把一个整数当作指针的值直接赋给指针呢？就象下面的语句：</font>
														<span lang="EN-US">
																<font face="宋体"> <br />unsignedinta; <br />TYPE*ptr;//TYPE是int，char或结构类型等等类型。 <br />... <br />... <br />a=20345686; <br />ptr=20345686;//我们的目的是要使指针ptr指向地址20345686（十进制 <br />） <br />ptr=a;//我们的目的是要使指针ptr指向地址20345686（十进制） <br />编译一下吧。结果发现后面两条语句全是错的。那么我们的目的就不能达到了吗？不，还有办法： <br />unsignedinta; <br />TYPE*ptr;//TYPE是int，char或结构类型等等类型。 <br />... <br />... <br />a=某个数，这个数必须代表一个合法的地址； <br />ptr=(TYPE*)a；//呵呵，这就可以了。 <br />严格说来这里的(TYPE*)和指针类型转换中的(TYPE*)还不一样。这里的(TYP <br />E*)的意思是把无符号整数a的值当作一个地址来看待。上面强调了a的值必须代表一个合法的地址，否则的话，在你使用ptr的时候，就会出现非法操作错误。 <br />想想能不能反过来，把指针指向的地址即指针的值当作一个整数取出来。完全可以。下面的例子演示了把一个指针的值当作一个整数取出来，然后再把这个整数当作一个地址赋给一个指针： <br />例十六： <br />inta=123,b; <br />int*ptr=&amp;a; <br />char*str; <br />b=(int)ptr;//把指针ptr的值当作一个整数取出来。 <br />str=(char*)b;//把这个整数的值当作一个地址赋给指针str。 <br />好了，现在我们已经知道了，可以把指针的值当作一个整数取出来，也可以把一个整数值当作地址赋给一个指针。</font>
														</span>
												</span>
										</font>
								</font>
						</font>
				</font>
		</font>
<img src ="http://www.cppblog.com/zzh/aggbug/19612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 10:46 <a href="http://www.cppblog.com/zzh/articles/19612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第六章。指针和结构类型的关系</title><link>http://www.cppblog.com/zzh/articles/19610.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 02:45:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19610.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19610.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19610.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19610.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19610.html</trackback:ping><description><![CDATA[
		<span style="font-size: 10.5pt; color: black;">
				<font size="3">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体">可以声明一个指向结构类型对象的指针。</font>
												<span lang="EN-US">
														<font face="宋体"> <br />例十一： <br />struct MyStruct <br />{ <br />inta; <br />intb; <br />intc; <br />} <br />MyStruct ss={20,30,40};//声明了结构对象ss，并把ss的三个成员初始 <br />化为20，30和40。 <br />MyStruct *ptr=&amp;ss;//声明了一个指向结构对象ss的指针。它的类型是 <br />MyStruct*,它指向的类型是MyStruct。 <br /></font>
												</span>
										</font>
								</font>
						</font>
				</font>
		</span>
		<span style="font-size: 10.5pt; color: blue;" lang="EN-US">
				<font size="3">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体">int*pstr=(int*)&amp;ss;//声明了一个指向结构对象ss的指针。但是它的 <br />类型和它指向的类型和ptr是不同的。</font>
										</font>
								</font>
						</font>
				</font>
		</span>
		<font size="3">
				<font face="宋体">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">
												<span style="font-size: 10.5pt; color: black;" lang="EN-US"> <br />请问怎样通过指针ptr来访问ss的三个成员变量？ <br />答案： <br />ptr-&gt;a; <br />ptr-&gt;b; <br />ptr-&gt;c; <br />又请问怎样通过指针pstr来访问ss的三个成员变量？ <br />答案： <br />*pstr；//访问了ss的成员a。 <br />*(pstr+1);//访问了ss的成员b。 <br />*(pstr+2)//访问了ss的成员c。 <br />呵呵，虽然我在我的MSVC++6.0上调式过上述代码，但是要知道，这样使用pstr来访问结构成员是不正规的，为了说明为什么不正规，让我们看看怎样通过指针来访问数组的各个单元： <br />例十二： <br />int array[3]={35,56,37}; <br />int*pa=array; <br />通过指针pa访问数组array的三个单元的方法是： <br />*pa;//访问了第0号单元 <br />*(pa+1);//访问了第1号单元 <br />*(pa+2);//访问了第2号单元 <br />从格式上看倒是与通过指针访问结构成员的不正规方法的格式一样。 <br /></span>
												<span style="font-size: 10.5pt; color: blue;">所有的<span lang="EN-US">C/C++编译器</span></span>
												<span style="font-size: 10.5pt; color: rgb(51, 51, 153);">在排列数组的单元时，总是把各个数组单元存放在连续的存储区里，单元和单元之间没有空隙。</span>
												<span style="font-size: 10.5pt; color: blue;">但在存放结构对象的各个成员时，在某种编译环境下，可能会需要字对齐或双字对齐或者是别的什么对齐，需要在相邻两个成员之间加若干个<span lang="EN-US">"填充字节"，这就导致各个成员之间可能会有若干个字节的空隙。</span></span>
										</font>
										<span style="font-size: 10.5pt; color: black;" lang="EN-US">
												<font face="宋体"> <br />所
以，在例十二中，即使*pstr访问到了结构对象ss的第一个成员变量a，也不能保证*(pstr+1)就一定能访问到结构成员b。因为成员a和成员b之
间可能会有若干填充字节，说不定*(pstr+1)就正好访问到了这些填充字节呢。这也证明了指针的灵活性。要是你的目的就是想看看各个结构成员之间到底
有没有填充字节，嘿，这倒是个不错的方法。 <br />通过指针访问结构成员的正确方法应该是象例十二中使用指针ptr的方法。</font>
										</span>
								</font>
						</font>
				</font>
		</font>
<img src ="http://www.cppblog.com/zzh/aggbug/19610.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 10:45 <a href="http://www.cppblog.com/zzh/articles/19610.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第五章。数组和指针的关系</title><link>http://www.cppblog.com/zzh/articles/19609.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 02:44:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19609.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19609.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19609.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19609.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19609.html</trackback:ping><description><![CDATA[
		<font size="3">
				<font face="宋体">
						<font face="宋体">
								<font face="宋体">
										<span style="font-size: 10.5pt; color: red;" ;="" mso-hansi-font-family:="" times="" new="" roman="">
										</span>
										<span style="font-size: 10.5pt; color: black;" lang="EN-US">
										</span>
								</font>
						</font>
				</font>
		</font>
		<p style="margin: 0cm 0cm 0pt; line-height: 150%; text-align: justify;">
				<span style="font-size: 10.5pt; color: black;">
						<font size="3">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体">如果对声明数组的语句不太明白的话，请参阅我前段时间贴出的文章</font>
												<span lang="EN-US">
														<font face="宋体">&lt;&lt;如何理解c和c++的复杂类型声明&gt;&gt;。 <br />数组的数组名其实可以看作一个指针。看下例： <br />例八： <br /></font>
												</span>
										</font>
								</font>
						</font>
				</span>
				<span style="font-size: 10.5pt; color: blue;" lang="EN-US">
						<font size="3">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体">int array[10]={0,1,2,3,4,5,6,7,8,9}</font>
										</font>
								</font>
						</font>
				</span>
				<font size="3">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">
												<span style="font-size: 10.5pt; color: black;" lang="EN-US">,value; <br />... <br />... <br />value=array[0];//也可写成：value=*array; <br />value=array[3];//也可写成：value=*(array+3); <br />value=array[4];//也可写成：value=*(array+4); <br />上例中，一般而言数组名array代表数组本身，类型是int[10]，但</span>
												<span style="font-size: 10.5pt; color: blue;">如果把<span lang="EN-US">array看做指针的话，它指向数组的第0个单元，类型是int*，所指向的类型是数组单元的类型即int。</span></span>
										</font>
										<span style="font-size: 10.5pt; color: black;">
												<font face="宋体">因此</font>
												<span lang="EN-US">
														<font face="宋体">*array等于0就一点也不奇怪了。同理，array+3是一个指向数组第3个单元的指针，所以*(array+3)等于3。其它依此类推。 <br />例九： <br />例九： <br /></font>
												</span>
										</span>
										<span style="font-size: 10.5pt; color: blue;" lang="EN-US">
												<font face="宋体">char*str[3]={ <br />"Hello,thisisasample!", <br />"Hi,goodmorning.", <br />"Helloworld" <br />}; <br /></font>
										</span>
										<span style="font-size: 10.5pt; color: black;" lang="EN-US">
												<font face="宋体">chars[80]； <br />strcpy(s,str[0]);//也可写成strcpy(s,*str); <br />strcpy(s,str[1]);//也可写成strcpy(s,*(str+1)); <br />strcpy(s,str[2]);//也可写成strcpy(s,*(str+2)); <br />上例中，</font>
										</span>
										<span style="font-size: 10.5pt; color: blue;" lang="EN-US">
												<font face="宋体">str是一个三单元的数组，该数组的每个单元都是一个指针，这些指 <br />针各指向一个字符串。把指针数组名str当作一个指针的话，它指向数组的第0号单元，它的类型是char**，它指向的类型是char*。</font>
										</span>
										<font face="宋体">
												<span style="font-size: 10.5pt; color: black;" lang="EN-US"> <br /></span>
												<span style="font-size: 10.5pt; color: blue;" lang="EN-US">*str也是一个指针，它的类型是char*，它所指向的类型是char，它指向的地址是字符串"Hello,thisisasample!"的第一个字符的地址，即'H'的地址。</span>
												<span style="font-size: 10.5pt; color: black;" lang="EN-US"> </span>
												<span style="font-size: 10.5pt; color: blue;" lang="EN-US">str+1也是一个指针，它指向数组的第1号单元，它的类型是char**，它指向的类型是char*。 </span>
										</font>
										<span style="font-size: 10.5pt; color: black;" lang="EN-US">
												<br />
										</span>
										<span style="font-size: 10.5pt; color: blue;" lang="EN-US">
												<font face="宋体">*(str+1)也是一个指针，它的类型是char*，它所指向的类型是char，它指向 "Hi,goodmorning."的第一个字符'H'，等等。 </font>
										</span>
										<span style="font-size: 10.5pt; color: black;" lang="EN-US">
												<br />
												<font face="宋体">下面总结一下数组的数组名的问题。</font>
										</span>
										<span style="font-size: 10.5pt; color: blue;">
												<font face="宋体">声明了一个数组<span lang="EN-US">TYPE
array[n]，则数组名称array就有了两重含义：第一，它代表整个数组，它的类型是TYPE[n]；第二 ，它是一个指针，该指针的类型是
TYPE*，该指针指向的类型是TYPE，也就是数组单元的类型，该指针指向的内存区就是数组第0号单元，该指针自己占有单独的内存区，注意它和数组第0
号单元占据的内存区是不同的。该指针的值是不能修改的，即类似array++的表达式是错误的。</span></font>
										</span>
										<font face="宋体">
												<span style="font-size: 10.5pt; color: black;" lang="EN-US"> <br />在不同的表达式中数组名array可以扮演不同的角色。 <br /></span>
												<span style="font-size: 10.5pt; color: blue;">在表达式<span lang="EN-US">sizeof(array)中，数组名array代表数组本身，故这时sizeof函数测出的是整个数组的大小。</span></span>
										</font>
										<font face="宋体">
												<span style="font-size: 10.5pt; color: black;" lang="EN-US"> <br /></span>
												<span style="font-size: 10.5pt; color: blue;">在表达式<span lang="EN-US">*array中，array扮演的是指针，因此这个表达式的结果就是数组第0号单元的值。sizeof(*array)测出的是数组单元的大小。</span></span>
										</font>
										<span style="font-size: 10.5pt; color: black;" lang="EN-US">
												<font face="宋体"> <br /></font>
										</span>
										<span style="font-size: 10.5pt; color: blue;">
												<font face="宋体">表达式</font>
												<span lang="EN-US">
														<font face="宋体">array+n（其中n=0，1，2，....。）中，array扮演的是指针，故array+n的结果是一个指针，它的类型是TYPE*，它指向的类型是TYPE，它指向数组第n号单元。故sizeof(array+n)测出的是指针类型的大小。 <br /></font>
												</span>
										</span>
										<span style="font-size: 10.5pt; color: black;">
												<font face="宋体">例十：</font>
												<span lang="EN-US">
														<font face="宋体"> <br />int array[10]; <br />int(*ptr)[10]; <br />ptr=&amp;array; <br />上例中ptr是一个指针，它的类型是int(*)[10]，他指向的类型是int[10] ，我们用整个数组的首地址来初始化它。在语句ptr=&amp;array中，array代表数组本身。 <br />本节中提到了函数sizeof()，那么我来问一问，</font>
												</span>
										</span>
										<font face="宋体">
												<span style="font-size: 10.5pt; color: blue;" lang="EN-US">sizeof(指针名称)测出的</span>
												<span style="font-size: 10.5pt; color: black;">究竟</span>
												<span style="font-size: 10.5pt; color: blue;">是指针自身类型的大小</span>
												<span style="font-size: 10.5pt; color: black;">呢还是指针所指向的类型的大小？答案是前者。</span>
										</font>
										<span style="font-size: 10.5pt; color: blue;">
												<font face="宋体">例如：</font>
												<span lang="EN-US">
														<font face="宋体"> <br />int(*ptr)[10]; <br />则在32位程序中，有： <br />sizeof(int(*)[10])==4 <br />sizeof(int[10])==40 <br />sizeof(ptr)==4 <br /></font>
												</span>
										</span>
										<font face="宋体">
												<span style="font-size: 10.5pt; color: black;">实际上，</span>
												<span style="font-size: 10.5pt; color: blue;" lang="EN-US">sizeof(对象)测出的都是对象自身的类型的大小</span>
										</font>
										<span style="font-size: 10.5pt; color: black;">
												<font face="宋体">，而不是别的什么</font>
												<span lang="EN-US">
														<font face="宋体"> <br />类型的大小。</font>
												</span>
										</span>
								</font>
						</font>
				</font>
		</p>
<img src ="http://www.cppblog.com/zzh/aggbug/19609.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 10:44 <a href="http://www.cppblog.com/zzh/articles/19609.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第四章。指针表达式。</title><link>http://www.cppblog.com/zzh/articles/19608.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 02:43:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19608.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19608.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19608.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19608.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19608.html</trackback:ping><description><![CDATA[
		<p style="margin: 0cm 0cm 0pt; line-height: 150%; text-align: justify;">
				<span style="font-size: 10.5pt; color: blue;">
						<font size="3">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体">一个表达式的最后结果如果是一个指针，那么这个表达式就叫指针表式。</font>
										</font>
								</font>
						</font>
				</span>
				<span style="font-size: 10.5pt; color: black;" lang="EN-US">
						<font size="3">
								<font face="宋体">
										<font face="宋体">
												<font face="宋体"> <br />下面是一些指针表达式的例子： <br />例六： <br />inta,b; <br />intarray[10]; <br />int*pa; <br />pa=&amp;a;//&amp;a是一个指针表达式。 <br />int**ptr=&amp;pa;//&amp;pa也是一个指针表达式。 <br />*ptr=&amp;b;//*ptr和&amp;b都是指针表达式。 <br />pa=array; <br />pa++;//这也是指针表达式。 <br />例七： <br />char*arr[20]; <br />char**parr=arr;//如果把arr看作指针的话，arr也是指针表达式 <br />char*str; <br />str=*parr;//*parr是指针表达式 <br />str=*(parr+1);//*(parr+1)是指针表达式 <br />str=*(parr+2);//*(parr+2)是指针表达式 </font>
										</font>
								</font>
						</font>
				</span>
		</p>
		<span style="font-size: 10.5pt; color: black;">
				<font size="3">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">由于指针表达式的结果是一个指针，所以指针表达式也具有指针所具有的四个要素：指针的类型，指针所指向的类型，指针指向的内存区，指针自身占据的内存。</font>
										<span lang="EN-US">
												<font face="宋体"> <br />好了，</font>
										</span>
								</font>
						</font>
				</font>
		</span>
		<span style="font-size: 10.5pt; color: blue;">
				<font size="3">
						<font face="宋体">
								<font face="宋体">
										<font face="宋体">当一个指针表达式的结果指针已经明确地具有了指针自身占据的内存的话，这个指针表达式就是一个左值，否则就不是一个左值。<span lang="EN-US"> </span></font>
								</font>
						</font>
				</font>
		</span>
		<span style="font-size: 10.5pt; color: black;" lang="EN-US">
				<font size="3">
						<font face="宋体">
								<font face="宋体">
										<br />
										<font face="宋体">在例七中，&amp;a不是一个左值，因为它还没有占据明确的内存。*ptr是一个左值，因为*ptr这个指针已经占据了内存，其实*ptr就是指针pa，既然pa已经在内存中有了自己的位置，那么*ptr当然也有了自己的位置。</font>
								</font>
						</font>
				</font>
		</span>
<img src ="http://www.cppblog.com/zzh/aggbug/19608.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 10:43 <a href="http://www.cppblog.com/zzh/articles/19608.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第三章．运算符&amp;和*</title><link>http://www.cppblog.com/zzh/articles/19607.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 02:42:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19607.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19607.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19607.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19607.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19607.html</trackback:ping><description><![CDATA[
		<span style="font-size: 10.5pt; color: black;">
				<font size="3">
						<font face="宋体">
								<font face="宋体">这里</font>
								<span lang="EN-US">
										<font face="宋体">&amp;是取地址运算符，*是...书上叫做"间接运算符"。 <br /></font>
								</span>
						</font>
				</font>
		</span>
		<span style="font-size: 10.5pt; color: blue;" lang="EN-US">
				<font size="3">
						<font face="宋体">
								<font face="宋体">&amp;a的运算结果是一个指针，指针的类型是a的类型加个*，指针所指向的类型是a的类型，指针所指向的地址嘛，那就是a的地址。 </font>
						</font>
				</font>
		</span>
		<span style="font-size: 10.5pt; color: black;" lang="EN-US">
				<font size="3">
						<font face="宋体">
								<br />
								<font face="宋体">*p的运算结果就五花八门了。</font>
						</font>
				</font>
		</span>
		<font size="3">
				<font face="宋体">
						<font face="宋体">
								<span style="font-size: 10.5pt; color: blue;">总之<span lang="EN-US">*p的结果是p所指向的东西</span></span>
								<span style="font-size: 10.5pt; color: black;">，这个东西有这些特点：</span>
								<span style="font-size: 10.5pt; color: blue;">它的类型是<span lang="EN-US">p指向的类型，它所占用的地址是p所指向的地址。</span></span>
						</font>
						<font face="宋体">
								<span style="font-size: 10.5pt; color: black;" lang="EN-US"> <br />例五： <br /></span>
								<span style="font-size: 10.5pt; color: blue;" lang="EN-US">inta=12;</span>
						</font>
						<font face="宋体">
								<span style="font-size: 10.5pt; color: black;" lang="EN-US"> <br />intb; <br />int*p; <br />int**ptr; <br />p=&amp;a;//</span>
								<span style="font-size: 10.5pt; color: blue;" lang="EN-US">&amp;a的结果是一个指针，类型是int*，指向的类型是int，指向的地址是a的地址。</span>
						</font>
						<span style="font-size: 10.5pt; color: black;" lang="EN-US">
								<font face="宋体"> <br />*p=24;//*p的结果，在这里它的类型是int，它所占用的地址是p所指向的地址，显然，*p就是变量a。 <br />ptr=&amp;p;//&amp;p的结果是个指针，该指针的类型是p的类型加个*，在这里是int **。该指针所指向的类型是p的类型，这里是int*。该指针所指向的地址就是指针p自己的地址。 <br />*ptr=&amp;b;//*ptr是个指针，&amp;b的结果也是个指针，且这两个指针的类型和所指向的类型是一样的，所以用&amp;b来给*ptr赋值就是毫无问题的了。 <br />**ptr=34;//*ptr的结果是ptr所指向的东西，在这里是一个指针，对这个指针再做一次*运算，结果就是一个int类型的变量</font>
						</span>
				</font>
		</font>
<img src ="http://www.cppblog.com/zzh/aggbug/19607.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 10:42 <a href="http://www.cppblog.com/zzh/articles/19607.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第二章．指针的算术运算</title><link>http://www.cppblog.com/zzh/articles/19603.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 02:11:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19603.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19603.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19603.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19603.html</trackback:ping><description><![CDATA[
		<p style="margin: 0cm 0cm 0pt; line-height: 150%; text-align: justify;">
				<span style="font-size: 10.5pt; color: black;">
						<font size="3">
								<font face="宋体">指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的。例如：</font>
								<span lang="EN-US">
										<font face="宋体"> <br />例二： <br />1。chara[20]; <br />2。int*ptr=a; <br />... <br />... <br />3。ptr++; <br />在
上例中，指针ptr的类型是int*,它指向的类型是int，它被初始化为指向整形变量a。接下来的第3句中，指针ptr被加了1，编译器是这样处理的：
它把指针ptr的值加上了sizeof(int)，在32位程序中，是被加上了4。由于地址是用字节做单位的，故ptr所指向的地址由原来的变量a的地址
向高地址方向增加了4个字节。 <br />由于char类型的长度是一个字节，所以，原来ptr是指向数组a的第0号单元开始的四个字节，此时指向了数组a中从第4号单元开始的四个字节。 <br />我们可以用一个指针和一个循环来遍历一个数组，看例子：<br />例三： <br />intarray[20]; <br />int*ptr=array; <br />... <br />//此处略去为整型数组赋值的代码。 <br />... <br />for(i=0;i&lt;20;i++) <br />{ <br />(*ptr)++; <br />ptr++； <br />} <br />这个例子将整型数组中各个单元的值加1。由于每次循环都将指针ptr加1，所以每次循环都能访问数组的下一个单元。 <br />再看例子： <br />例四： <br />1。chara[20]; <br />2。int*ptr=a; <br />... <br />... <br />3。ptr+=5; <br />在
这个例子中，ptr被加上了5，编译器是这样处理的：将指针ptr的值加上5乘sizeof(int)，在32位程序中就是加上了5乘4=20。由于地址
的单位是字节，故现在的ptr所指向的地址比起加5后的ptr所指向的地址来说，向高地址方向移动了20个字节。在这个例子中，没加5前的ptr指向数组
a的第0号单元开始的四个字节，加5后，ptr已经指向了数组a的合法范围之外了。虽然这种情况在应用上会出问题，但在语法上却是可以的。这也体现出了指
针的灵活性。 <br />如果上例中，ptr是被减去5，那么处理过程大同小异，只不过ptr的值是被减去5乘sizeof(int)，新的ptr指向的地址将比原来的ptr所指向的地址向低地址方向移动了20个字节。  <br />总结一下，一个指针ptrold加上一个整数n后，结果是一个新的指针ptrnew， <br />ptrnew
的类型和ptrold的类型相同，ptrnew所指向的类型和ptrold所指向的类型也相同。ptrnew的值将比ptrold的值增加了n乘
sizeof(ptrold所指向的类型)个字节。就是说，ptrnew所指向的内存区将比ptrold所指向的内存区向高地址方向移动了n乘
sizeof(ptrold所指向的类型)个字节。 <br />一个指针ptrold减去一个整数n后，结果是一个新的指针ptrnew，ptrnew的类
型和ptrold的类型相同，ptrnew所指向的类型和ptrold所指向的类型也相同。ptrnew的值将比ptrold的值减少了n乘sizeof
(ptrold所指向的类型)个字节，就是说，ptrnew所指向的内存区将比ptrold所指向的内存区向低地址方向移动了n乘sizeof
(ptrold所指向的类型)个字节。 </font>
								</span>
						</font>
				</span>
		</p>
		<span style="font-size: 10.5pt; color: red;" times="" new="" roman="" ;="" mso-fareast-font-family:="" 宋体;="" mso-font-kerning:="" 1.0pt;="" mso-ansi-language:="" en-us;="" mso-fareast-language:="" zh-cn;="" mso-bidi-language:="" ar-sa="" lang="EN-US">
				<font size="3">
						<font face="宋体">
								<br style="page-break-before: always;" clear="all" />
						</font>
				</font>
		</span>
<img src ="http://www.cppblog.com/zzh/aggbug/19603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 10:11 <a href="http://www.cppblog.com/zzh/articles/19603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第一章．指针的概念</title><link>http://www.cppblog.com/zzh/articles/19601.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 01:52:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19601.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19601.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19601.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19601.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19601.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: 150%;">
				<span style="color: red; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">
						<font size="3">第一章．指针的概念</font>
				</span>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针是一个特殊的变量，它里面存储的数值被解释成为内存里的一个地址。</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> </font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">要搞清一个指针需要搞清指针的四方面的内容：指针的类型，指针所指向的</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> </font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">类型，指针的值或者叫指针所指向的内存区，还有指针本身所占据的内存区。让</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> </font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">我们分别说明。</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">先声明几个指针放着做例子：</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">例一：</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br />(1)int*ptr; <br />(2)char*ptr; <br />(3)int**ptr; <br />(4)int(*ptr)[3]; <br />(5)int*(*ptr)[4]; <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">如果看不懂后几个例子的话，请参阅我前段时间贴出的文章</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">&lt;&lt;</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">如何理解</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">c</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">和</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">c ++</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">的复杂类型声明</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">&gt;&gt;</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">。</span>
				</font>
				<font size="3">
						<font face="Times New Roman">
								<span style="color: black;" lang="EN-US"> <br /></span>
								<span style="color: fuchsia;" lang="EN-US">1</span>
						</font>
						<span style="color: fuchsia; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">。指针的类型。</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">从语法的角度看，你</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">只要把指针声明语句里的指针名字去掉，剩下的部分就是这个指针的类型。</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">这是指针本身所具有的类型。让我们看看例一中各个指针的类型：</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br />(1)int*ptr;//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">int* <br />(2)char*ptr;//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">char* <br />(3)int**ptr;//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">int** <br />(4)int(*ptr)[3];//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">int(*)[3] <br />(5)int*(*ptr)[4];//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">int*(*)[4] <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">怎么样？找出指针的类型的方法是不是很简单？</span>
				</font>
				<font size="3">
						<font face="Times New Roman">
								<span style="color: black;" lang="EN-US"> <br /></span>
								<span style="color: fuchsia;" lang="EN-US">2</span>
						</font>
						<span style="color: fuchsia; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">。指针所指向的类型。</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">当你通过指针来访问指针所指向的内存区时，指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">从语法上看，你只须</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">把指针声明语句中的指针名字和名字左边的指针声明符</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman">*</font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">去掉，剩下的就是指针所指向的类型。</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">例如：</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br />(1)int*ptr;//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">int <br />(2)char*ptr;//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">char <br />(3)int**ptr;//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">int* <br />(4)int(*ptr)[3];//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">int()[3] <br />(5)int*(*ptr)[4];//</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的的类型是</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">int*()[4] <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">在指针的算术运算中，指针所指向的类型有很大的作用。</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针的类型</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">(</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">即指针本身的类型</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">)</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">和指针所指向的类型是两个概念。当你对</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">C</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">越来越熟悉时，你会发现，把与指针搅和在一起的</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">"</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">类型</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">"</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">这个概念分成</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">"</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针的类型</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">"</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">和</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">"</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的类型</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">"</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">两个概念，是精通指针的关键点之一。我看了不少书，发现有些写得差的书中，就把指针的这两个概念搅在一起了，所以看起书来前后矛盾，越看越糊涂。</span>
				</font>
				<font size="3">
						<font face="Times New Roman">
								<span style="color: black;" lang="EN-US"> <br /></span>
								<span style="color: fuchsia;" lang="EN-US">3</span>
						</font>
						<span style="color: fuchsia; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">。指针的值，或者叫指针所指向的内存区或地址。</span>
						<span style="color: fuchsia;" lang="EN-US">
								<font face="Times New Roman"> </font>
						</span>
				</font>
				<span style="color: black;" lang="EN-US">
						<br />
				</span>
				<font size="3">
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针的值是指针本身存储的数值，这个值将被编译器当作一个地址，而不是一个一般的数值。在</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman">32</font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">位程序里，所有类型的指针的值都是一个</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman">32</font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">位整数，因为</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman">32</font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">位程序里内存地址全都是</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman">32</font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">位长。</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman"> </font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的内存区就是从指针的值所代表的那个内存地址开始，长度为</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman">si zeof(</font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的类型</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman">)</font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">的一片内存区。</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">以后，我们说一个指针的值是</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">XX</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">，就相当于说该指针指向了以</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">XX</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">为首地址的一片内存区域；</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">我们说一个指针指向了某块内存区域，就相当于说该指针的值是这块内存区域的首地址。</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中，</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针所指向的类型已经有了，但由于指针还未初始化，所以它所指向的内存区是不存在的，或者说是无意义的。</span>
				</font>
				<font size="3">
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">以后，每遇到一个指针，都应该问问：这个指针的类型是什么？指针指的类型是什么？该指针指向了哪里？</span>
				</font>
				<font size="3">
						<font face="Times New Roman">
								<span style="color: black;" lang="EN-US"> <br /></span>
								<span style="color: fuchsia;" lang="EN-US">4</span>
						</font>
						<span style="color: fuchsia; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">。指针本身所占据的内存区。</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针本身占了多大的内存？你只要用函数</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">sizeof(</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针的类型</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">)</font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">测一下就知道了。</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">在</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman">32</font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">位平台里，指针本身占据了</span>
						<span style="color: blue;" lang="EN-US">
								<font face="Times New Roman">4</font>
						</span>
						<span style="color: blue; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">个字节的长度。</span>
				</font>
				<font size="3">
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman"> <br /></font>
						</span>
						<span style="color: black; font-family: 宋体;" ;="" mso-hansi-font-family:="" times="" new="" roman="">指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。</span>
						<span style="color: black;" lang="EN-US">
								<font face="Times New Roman">  </font>
						</span>
				</font>
		</p>
		<span style="font-size: 10.5pt; color: red;" times="" new="" roman="" ;="" mso-fareast-font-family:="" 宋体;="" mso-font-kerning:="" 1.0pt;="" mso-ansi-language:="" en-us;="" mso-fareast-language:="" zh-cn;="" mso-bidi-language:="" ar-sa="" lang="EN-US">
				<font size="3">
						<br style="page-break-before: always;" clear="all" />
				</font>
		</span>
<img src ="http://www.cppblog.com/zzh/aggbug/19601.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 09:52 <a href="http://www.cppblog.com/zzh/articles/19601.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言字符串函数汇总</title><link>http://www.cppblog.com/zzh/articles/19600.html</link><dc:creator>Xiao.Zhu</dc:creator><author>Xiao.Zhu</author><pubDate>Mon, 12 Mar 2007 01:29:00 GMT</pubDate><guid>http://www.cppblog.com/zzh/articles/19600.html</guid><wfw:comment>http://www.cppblog.com/zzh/comments/19600.html</wfw:comment><comments>http://www.cppblog.com/zzh/articles/19600.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zzh/comments/commentRss/19600.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zzh/services/trackbacks/19600.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="margin: 0cm 0cm 0pt;">
				<span style="font-size: 9pt;" lang="EN-US">
						<font face="Times New Roman">1 /*<br />2  *  linux/lib/string.c<br />3  *<br />4  *  Copyright (C) 1991, 1992  Linus Torvalds<br />5  */<br />6 <br />7 /*<br />8  * stupid library routines.. The optimized versions should generally be found<br />9  * as inline code in &lt;asm-xx/string.h&gt;<br />10  *<br />11  * These are buggy as well..<br />12  */<br />13  <br />14 #include &lt;linux/types.h&gt;<br />15 <br />16 char * ___strtok = NULL;<br />17 <br /></font>
						<font face="Times New Roman">
								<span style="color: blue;">18 char * strcpy(char * dest,const char *src)<br />19 {<br />20         char *tmp = dest;<br />21 <br />22         while ((*dest++ = *src++) != '\0')<br />23                 /* nothing */;<br />24         return tmp;<br />25 }</span>
								<br />26 <br />27 char * strncpy(char * dest,const char *src,size_t count)<br />28 {<br />29         char *tmp = dest;<br />30 <br />31         while (count-- &amp;&amp; (*dest++ = *src++) != '\0')<br />32                 /* nothing */;<br />33 <br />34         return tmp;<br />35 }<br />36 <br /></font>
						<font face="Times New Roman">
								<span style="color: blue;">37 char * strcat(char * dest, const char * src)<br />38 {<br />39         char *tmp = dest;<br />40 <br />41         while (*dest)<br />42                 dest++;<br />43         while ((*dest++ = *src++) != '\0')<br />44                 ;<br />45 <br />46         return tmp;<br />47 }</span>
								<br />48 <br />49 char * strncat(char *dest, const char *src, size_t count)<br />50 {<br />51         char *tmp = dest;<br />52 <br />53         if (count) {<br />54                 while (*dest)<br />55                         dest++;<br />56                 while
((*dest++ = *src++)) {<br />57                         if
(--count == 0)<br />58                                 break;<br />59                 }<br />60         }<br />61 <br />62         return tmp;<br />63 }<br />64 <br /></font>
						<font face="Times New Roman">
								<span style="color: blue;">65 int strcmp(const char * cs,const char * ct)<br />66 {<br />67         register signed char __res;<br />68 <br />69         while (1) {<br />70                 if
((__res = *cs - *ct++) != 0 || !*cs++)<br />71                         break;<br />72         }<br />73 <br />74         return __res;<br />75 }<br /></span>76 <br />77 int strncmp(const char * cs,const char * ct,size_t count)<br />78 {<br />79         register signed char __res = 0;<br />80 <br />81         while (count) {<br />82                 if
((__res = *cs - *ct++) != 0 || !*cs++)<br />83                         break;<br />84                 count--;<br />85         }<br />86 <br />87         return __res;<br />88 }<br />89 <br /></font>
						<font face="Times New Roman">
								<span style="color: blue;">90 char * strchr(const char * s,char c)<br />91 {<br />92         for(; *s != c; ++s)<br />93                 if (*s == '\0')<br />94                         return
NULL;<br />95         return (char *) s;<br />96 }<br /></span>97 <br />98 size_t strlen(const char * s)<br />99 {<br />100         const char *sc;<br />101 <br />102         for (sc = s; *sc != '\0'; ++sc)<br />103                 /* nothing */;<br />104         return sc - s;<br />105 }<br />106 <br /></font>
						<font face="Times New Roman">
								<span style="color: blue;">107 size_t strnlen(const char * s, size_t count)<br />108 {<br />109         const char *sc;<br />110 <br />111         for (sc = s; *sc != '\0' &amp;&amp; count--; ++sc)<br />112                 /* nothing */;<br />113         return sc - s;<br />114 }<br /></span>115 <br />116 size_t strspn(const char *s, const char *accept)<br />117 {<br />118         const char *p;<br />119         const char *a;<br />120         size_t count = 0;<br />121 <br />122         for (p = s; *p != '\0'; ++p) {<br />123                 for
(a = accept; *a != '\0'; ++a) {<br />124                         if
(*p == *a)<br />125                                 break;<br />126                 }<br />127                 if (*a == '\0')<br />128                         return
count;<br />129                 ++count;<br />130         }<br />131 <br />132         return count;<br />133 }<br />134 <br /></font>
						<font face="Times New Roman">
								<span style="color: blue;">135 char * strpbrk(const char * cs,const char * ct)<br />136 {<br />137         const char *sc1,*sc2;<br />138 <br />139         for( sc1 = cs; *sc1 != '\0'; ++sc1) {<br />140                 for(
sc2 = ct; *sc2 != '\0'; ++sc2) {<br />141                         if
(*sc1 == *sc2)<br />142                                 return
(char *) sc1;<br />143                 }<br />144         }<br />145         return NULL;<br />146 }<br /></span>147 <br />148 char * strtok(char * s,const char * ct)<br />149 {<br />150         char *sbegin, *send;<br />151 <br />152         sbegin  = s ? s : ___strtok;<br />153         if (!sbegin) {<br />154                 return NULL;<br />155         }<br />156         sbegin += strspn(sbegin,ct);<br />157         if (*sbegin == '\0') {<br />158                 ___strtok = NULL;<br />159                 return( NULL );<br />160         }<br />161         send = strpbrk( sbegin, ct);<br />162         if (send &amp;&amp; *send != '\0')<br />163                 *send++ = '\0';<br />164         ___strtok = send;<br />165         return (sbegin);<br />166 }<br />167 <br /></font>
						<font face="Times New Roman">
								<span style="color: blue;">168 void * memset(void * s,char c,size_t count)<br />169 {<br />170         char *xs = (char *) s;<br />171 <br />172         while (count--)<br />173                 *xs++ = c;<br />174 <br />175         return s;<br />176 }<br /></span>177 <br />178 char * bcopy(const char * src, char * dest, int count)<br />179 {<br />180         char *tmp = dest;<br />181 <br />182         while (count--)<br />183                 *tmp++ = *src++;<br />184 <br />185         return dest;<br />186 }<br />187 <br /></font>
						<font face="Times New Roman">
								<span style="color: blue;">188 void * memcpy(void * dest,const void *src,size_t count)<br />189 {<br />190         char *tmp = (char *) dest, *s = (char *) src;<br />191 <br />192         while (count--)<br />193                 *tmp++ = *s++;<br />194 <br />195         return dest;<br />196 }<br /></span>197 <br />198 void * memmove(void * dest,const void *src,size_t count)<br />199 {<br />200         char *tmp, *s;<br />201 <br />202         if (dest &lt;= src) {<br />203                 tmp = (char *) dest;<br />204                 s = (char *) src;<br />205                 while (count--)<br />206                         *tmp++
= *s++;<br />207                 }<br />208         else {<br />209                 tmp
= (char *) dest + count;<br />210                 s
= (char *) src + count;<br />211                 while (count--)<br />212                         *--tmp
= *--s;<br />213                 }<br />214 <br />215         return dest;<br />216 }<br />217 <br /></font>
						<font face="Times New Roman">
								<span style="color: blue;">218 int memcmp(const void * cs,const void * ct,size_t count)<br />219 {<br />220         const unsigned char *su1, *su2;<br />221         signed char res = 0;<br />222 <br />223         for( su1 = cs, su2 = ct; 0 &lt; count; ++su1, ++su2, count--)<br />224                 if
((res = *su1 - *su2) != 0)<br />225                         break;<br />226         return res;<br />227 }<br /></span>228 <br />229 /*<br />230  * find the first occurrence of byte 'c', or 1 past the area if none<br />231  */<br />232 void * memscan(void * addr, unsigned char c, size_t size)<br />233 {<br />234         unsigned char * p = (unsigned char *) addr;<br />235 <br />236         while (size) {<br />237                 if (*p == c)<br />238                         return
(void *) p;<br />239                 p++;<br />240                 size--;<br />241         }<br />242         return (void *) p;<br />243 }</font>
				</span>
		</p>
<img src ="http://www.cppblog.com/zzh/aggbug/19600.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zzh/" target="_blank">Xiao.Zhu</a> 2007-03-12 09:29 <a href="http://www.cppblog.com/zzh/articles/19600.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>