﻿<?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++博客-Q's Playground-随笔分类-C++</title><link>http://www.cppblog.com/qjbest/category/1038.html</link><description>MAX MAGIC</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 17:13:48 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 17:13:48 GMT</pubDate><ttl>60</ttl><item><title>转载：C++中的纯虚函数</title><link>http://www.cppblog.com/qjbest/archive/2006/09/06/12092.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Wed, 06 Sep 2006 07:40:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/09/06/12092.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/12092.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/09/06/12092.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/12092.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/12092.html</trackback:ping><description><![CDATA[
		<p>作者：风生水起     文章来源：风生水起  来源：<a href="http://www.sf.org.cn/Article/base/200608/18991.html">http://www.sf.org.cn/Article/base/200608/18991.html</a><br /><br /><br />一、定义.</p>
		<p>纯虚函数是在<font color="#ff0000">基类</font>中声明的虚函数，它<font color="#ff0000">在基类中没有定义</font>，但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”</p>
		<p>
				<font color="#ff0000">virtual</font> void funtion1()=0</p>
		<p>二、引入原因：</p>
		<p>1、为了方便使用多态特性，我们常常需要在基类中定义虚拟函数。<br />2、在很多情况下，基类本身生成对象是不合情理的。例如，动物作为一个基类可以派生出老虎、孔雀等子类，但动物本身生成对象明显不合常理。</p>
		<p>为了解决上述问题，引入了纯虚函数的概念，将函数定义为纯虚函数（方法：virtual ReturnType Function()= 0;），<font color="#ff0000">则编译器要求在派生类中必须予以重载以实现多态性</font>。同时含有纯虚拟函数的类称为抽象类，它不能生成对象。这样就很好地解决了上述两个问题。</p>
		<p>三、相似概念：</p>
		<p>1、多态性</p>
		<p>指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性：编译时多态性，运行时多态性。</p>
		<p>a.<font color="#ff0000">编译时多态性：通过<font color="#000000">重载函数</font>实现</font></p>
		<p>b <font color="#ff0000">运行时多态性：通过<font color="#000000">虚函数</font>实现。</font></p>
		<p>2、虚函数</p>
		<p>虚函数是在基类中被声明为virtual，并在派生类中重新定义的成员函数，可实现成员函数的动态重载</p>
		<p>3、抽象类</p>
		<p>
				<font color="#ff0000">包含<font color="#000000">纯</font>虚函数的类称为抽象类</font>。由于抽象类包含了没有定义的纯虚函数，所以不能定义抽象类的对象。</p>
		<p>
				<font color="#ff0000">程序举例</font>：</p>
		<div class="postText">
				<p>基类:<br />class A  <br />{<br />public:<br /> A();<br /> void f1();<br /> virtual void f2();<br /> virtual void f3()=0;<br /> virtual ~A();</p>
				<p>};</p>
				<p>子类:<br />class B : public A  <br />{<br />public:<br /> B();<br /> void f1();<br /> void f2();<br /> void f3();<br /> virtual ~B();</p>
				<p>};<br />主函数:<br />int main(int argc, char* argv[])<br />{<br /> A *m_j=new B();<br /> m_j-&gt;f1();<br /> m_j-&gt;f2();<br /> m_j-&gt;f3();<br /> delete m_j;<br /> return 0;<br />}</p>
				<p>f1()是一个普通的重载.<br />调用m_j-&gt;f1();会去调用A类中的f1(),它是在我们写好代码的时候就会定好的.<br />也就是根据它是由A类定义的,这样就调用这个类的函数.<br />f2()是虚函数.<br />调用m_j-&gt;f2();会调用m_j中到底保存的对象中,对应的这个函数.这是由于new的B<br />对象.<br />f3()与f2()一样,只是在基类中不需要写函数现实.</p>
		</div>
<img src ="http://www.cppblog.com/qjbest/aggbug/12092.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-09-06 15:40 <a href="http://www.cppblog.com/qjbest/archive/2006/09/06/12092.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>char ** 这个东东</title><link>http://www.cppblog.com/qjbest/archive/2006/07/20/10251.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Thu, 20 Jul 2006 07:38:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/07/20/10251.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/10251.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/07/20/10251.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/10251.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/10251.html</trackback:ping><description><![CDATA[N久没写过东东了，都快忘了<img height="20" src="http://www.cppblog.com/Emoticons/QQ/14.gif" width="20" border="0" /><br />一般用的最多的怕是char * 了，表示的是指向C风格字串的指针。那 char **p 又是什么呢？p表示的是指向指针的指针。比如：<br /><br />//创建p<br />char **p=new char*[100]; <br />for(int i=0;i&lt;100;i++)<br />{<br />   p[i]=new char[30];  // p[i]为指向最终字串的指针，该字串长度为30，而p 又是指向p[i]的指针<br />}<br /><br />//释放空间<br />for(int i=0;i&lt;100;i++)<br />{<br />   delete p[i];<br />}<br />delete p;<br /><br /><br /><br /><img src ="http://www.cppblog.com/qjbest/aggbug/10251.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-07-20 15:38 <a href="http://www.cppblog.com/qjbest/archive/2006/07/20/10251.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>书啊书~~~~~~~~~~~~</title><link>http://www.cppblog.com/qjbest/archive/2006/05/26/7701.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Fri, 26 May 2006 09:49:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/05/26/7701.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/7701.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/05/26/7701.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/7701.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/7701.html</trackback:ping><description><![CDATA[/*种种原因，很多精力要投入到java的学习和使用中去了，想形成一个学习C++的系列文章，没有什么风格，也没有什么时间表，想到哪就去写。这里想说说自己对于世面上的一些C++书籍的评价，我能保证的是下面所谈到的书，我都基本读过至少一遍，并且对于这样一个比较敏感的话题，我将尽量保持一个客观的态度，不过书籍始终没有最好，只有最适合自己的，我将根据自己的喜好给出四种等级：强烈推荐，推荐，一般，不推荐。需要再次强调的是，光看书，或者光编程都不是计算机的全部。*/<br /><br />《C++程序设计语言》：如果你只买一本C++书，这本就是你的选择，作者Bjarne就是让你做出这样选择的全部理由，没有人能比他更了解什么样才是真正的使用C++编程了，有人说到这本书语言晦涩，或者对与初学者此书不适合，对此评论我颇不以为然，我看的是中文版，起码在我看来语言描叙非常到位，我喜欢这样的技术描叙风格。全书的核心就是告诉你如何去用正确的观念编写正确的C++的代码。强烈推荐。<br /><br /><br /><br />《C++语言设计与演化》：这本书也是我同时拥有中英两版的两本书之一（另外一本是《设计模式》）。如果在得到上面的那本书之后你需要第二本，那么在我看来这就是你的选择，作者同样是Bjarne，他将在这本书中告诉你C++的起源与发展，语言原则与本质，各种特性加入的理由和考量，以及几乎一切关于C++有趣的故事。我阅读过中英两版，都是强烈推荐。<br /><br /><br /><br />《C++标准程序库》：在AMAZON上面关于C++书籍评论最为火暴的一本。全书对于标准程序库的介绍可谓深入浅出，而且全书都是从实际运用出发，书中例子简单却非常说明问题，加上一些图表的陈列，使其概念十分清晰，而且从手册和学习两方面看都有其存在价值。强烈推荐。<br /><br /><br /><br />《EFFECTIVE C++ 中文版》：无须多说，在任何C++书籍推荐目录中都可以找到这本书的身影，盛名之下必无虚士。主要强调的是运用C++的各种特性的时候所必须注意的地方，以及一些比较通用的设计手段。其短小精悍的语言自然非常适合快节奏的现代风格，个人就十分喜欢Meyer的写作方式。强烈推荐。<br /><br /><br /><br />《MORE EFFECTIVE C++ 中文版》：做为上本书的姐妹篇，一样的写作风格，一样的写作目的。只是个人认为和其姐姐相比，存在差距，主要是信息量没有《EFFECTIVE C++ 中文版》那么大，主要说到了一些C++的设计惯用手法。推荐。<br /><br /><br /><br />《C++ PRIMER 中文版》：同样是出自大师之手，作者LIPPMAN，作为早期C++编译器的实现者之一，对与C++的了解以及该如何论序都有自己的独到见解。做为C++的百科全书和《C++程序设计语言》有着一样的地位。但是前者更强调的是C++的语法和其语义，而后者则是以如何用C++进行合理设计做为描叙的中心。全书构思十分巧妙，书的一开始就直接进入C++的主题，前面五章都用类设计一个数据结构，让读者完全明白了各种用户定义类型所代表的抽象能力，然后直接进入第六章标准库中的容器类，这样的设计让读者十分清楚的建立容器和类这两个C++中十分重要的概念。这样的设计针对有一定基础的C++读者来说可以说是非常有效果的。但是对于初学者来说，这确实不是一本合适的书籍，因为一上来太多的名词会把刚刚接触C++的人吓着的。推荐。<br /><br /><br /><br />《C++沉思录》：非常有特点的一本书，全书假设读者已经通晓C++语言，重点告诉读者C++的概念以及一些C++的设计手段，比如用C++到底为什么会比C或者其他过程语言更好？（书中给出的答案是，因为只有对象才有能力保持一定的状态，而算法没有这样的能力），如何进行抽象数据类型的程序设计，如何理解多态，如何通过代理隐藏继承，如何进行引用技数，为了效率如何进行缓时拷贝，以及模板技术是如何发展演进最后构成成STL库的。阅读感觉和《C++程序设计语言》一样，思想性非常强，读这样的书很累，脑子必须一直思考问题，思考作者里面提出的问题和他提出的解决方式。这本书最大的特点是非常直接的把C++语言的核心暴露出来-----三种抽象模型和极其语言设施本身对这三种抽象模型的支持。而《C++沉思录》给我的更深层思考是什么才是运用C++最合理的方式。推荐。<br /><br /><br /><br />《C++ STL中文版》：很朴实，不花俏，但是价值很高。个人认为其主要价值体现在以下几个方面：1，对于STL的实现关键iterator一般都使用了两种方式描叙，一种比较老式的函数方法，一种是新的 traits技巧，这样读者可以非常清楚的知道技术的演进。2，提供了一个STL LITE版本，阅读这样的代码对自己的提高非常大。3，书中提供的测试模块对于读者来说也是非常有的一章，对于想扩展STL的，可以按照上面提供的方法测试自己的STL组件。缺点：装订比较粗糙，与大师之作的地位不相称。推荐<br /><br /><br /><br />《C++ PRIMER PLUS 中文版》：一本思想性不是很强，技巧性不是很强的书，但是对于初学者来说非常合适的书。其中许多论序方式都和具体化，总体来说，这本书是我看过的C++书籍里面最合适初学者的。推荐。<br /><br /><br /><br />《深度探索C++对象模型》：这也是一本比较特别的书，告诉你编译器是如何安排处理对象的内存空间的，以及一些OO特性是如何实现的。不认为这是一本C++必须读物，算是课后读物应该比较合适吧，因为有时间了解C++的OO实现还不如花点时间搞清楚OO理论的本质概念：type theory。推荐。<br /><br /><br /><br />《C++设计新思维——泛型编程与设计模式之应用》：可谓C++中的奇书。这样的一本书，很难让人做出正确的评价与推荐指数（尤其是以我这个实用和人生本就应该享乐为人生观的人来说~：），因为全书所代表的思想前卫到了有点不切实际的地步，模式+泛型—多么高雅的组合。我个人的观点是，只有一部分人需要阅读此书，他们就是所谓的real c++ fans，暂且不提C++本身是否遇到了困难，就其书中所代表的设计思想，对于C++没有一点感情的程序员（感情就是以爱好为基础，而不是以攒钱为前提），我想对于这样的设计技术总会有晕的感觉，而一般程序员多半都不会喜欢这样的感觉~：）。推荐。<br /><br /><br /><br />《对象揭秘：Java、Eiffel和C++》：从书名就可以看出这本书不仅仅和C++有关系。可以说全书就是对C++的一次批判吧（书也起源与作者的一篇批判C++的文章）。有时候听听另外一种声音对自己保持清醒的头脑是非常有帮助的，对待一个人，对待一本书以及对待一门程序设计语言都是如此。这本书好象不是很火，大概跟其宣传不是很到位，或者同能同时了解这三门语言并比较关心这些语言深层次的优略的读者比较少有关系吧，在我看来这本书包含了许多对象与类型方面的理论，最为出彩的就是作者抓住Bjarne的“在C++中一个类就是一个类型”这样的“错误”言论狠批的论证过程。看这本书另外一个好处是能教会大家该如何去合理的辩驳自己的对手~：）。推荐。<br /><br /><br /><br />《大规模C++程序设计》：书在手上很久了，可一直没有仔细看，这也是评论之前必须说明的。总体看来书中涉及的很多东西都鲜见于其他读本。不管AMAZON上的评论是否是这本书比较过时，起码它介绍的许多对与我来说都是我所不知道不了解的，别人说过时是他的事情。而我，还是推荐。<br /><br /><br /><br />《STL和泛型编程》：难得的一本关于泛型编程的理念书籍，同样也是作为手册和学习两用，但是其手册不是使用手册，而是概念手册，对于设计自己的STL组件，这本书有非常好的帮助，虽然网上有篇STL的文档，其中的70%内容和这本书雷同，但此书仍不失可读性。推荐。<br /><br /><br /><br />《C++编程思想 第二版》：非常一般的书，是的这就是我对这本很多人奉为名著的评论，至于为什么是这样的评论，或者你不相信我说的是客观话，在你买了之后看完就知道了。一般。<br /><br /><br /><br />《Essential C++中文版》：总感觉这本书定位不是很清楚，因为对于初学者来说其开始就涉及了太多的名词，初学者看这本书，几乎就不要指望能很好的入门。而对于进阶者来说，其内容并无新意，对于C++高手来说，这样的小读本，根本就没有阅读的必要，也许是LIPPMAN+JJHOU的盛名吧，但我觉得这次算是有虚士了~：）。一般。<br /><br /><br /><br />《STL源码剖析》：侯SIR的大陆两本著作之一，但在我心中其质量好象并不如很多人说的那样好，就同类作品《C++ STL中文版》相比较内容略现单薄，并且三章之后很多东西都给人以堆砌的感觉，而且大部分精彩的材料都出自《STL和泛型编程》一书，给人感觉书中侯SIR自己的东西并不多，但第二章对于内存管理有很好的论叙表现，并且装订精良，尤其是那些图更是侯SIR的拿手好戏，但总体感觉有点华而不实。一般。<br /><br /><br /><br />后面列出两本不推荐的，具体原因也就不再分析。<br /><br />《高质量程序设计指南--C++/C语言》，<br /><br />《C++编码规范》<br /><br /><br /><br />另外两本常见的C++书籍：<br /><br />《Exceptional C++中文版》，《More Exceptional C++中文版》我本人并没有阅读过，但其名声不小，而且加之曾经给此书作者Herb Sutter通邮件的经历，那种考虑到时差都不到24个小时的回信率以及在信中耐心的对技术讲解的态度，同样向大家推荐这两本书，因为在我看来Herb Sutter能力无须考虑加上这样待人的态度，其作品理所值得大家阅读。<br /><br /><br /><br />是的，上面就是我大半年来看过的C++的书籍，肯定不少人要嘲笑我的个书呆子了~：），其实我确实就是一个书呆子，至于是否需要看这么多书，我个人意见是不需要，不然我还给出推荐等级干什么？选择自己需要的就是最好。引用曾经有人说到的---评书其实就是个“如人饮水，冷暖自知”的事情。真正的书评在哪里？各自的心里。<br /><img src ="http://www.cppblog.com/qjbest/aggbug/7701.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-05-26 17:49 <a href="http://www.cppblog.com/qjbest/archive/2006/05/26/7701.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>swap()引起的指针思考</title><link>http://www.cppblog.com/qjbest/archive/2006/05/25/7621.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Thu, 25 May 2006 02:33:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/05/25/7621.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/7621.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/05/25/7621.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/7621.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/7621.html</trackback:ping><description><![CDATA[
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">昨天QQ里有个学C++的朋友问我个问题，怎样利用swap(int *x,int *y)交换x,y指向的地址值。起初我很简单的给了他一个方法：<br /><br />方法一：<br />int *p;<br />void swap(int *x,int *y)<br />{<br /> cout&lt;&lt;"swap("&lt;&lt;*x&lt;&lt;","&lt;&lt;*y&lt;&lt;")"&lt;&lt;endl;<br /> p=x;<br /> x=y;<br /> y=p;<br /> cout&lt;&lt;"swap("&lt;&lt;*x&lt;&lt;","&lt;&lt;*y&lt;&lt;")"&lt;&lt;endl;<br />}<br />int main()<br />{<br /> int a=10;<br /> int b=2;<br /> int *x=&amp;a;<br /> int *y=&amp;b;<br /> cout&lt;&lt;*x&lt;&lt;" "&lt;&lt;*y&lt;&lt;endl;<br /> swap(x,y);<br /> cout&lt;&lt;*x&lt;&lt;" "&lt;&lt;*y&lt;&lt;endl;<br />} <br />运算结果却是：<br />10  2<br />10  2   //swap<br />2    10 //swap<br />10  2<br />从结果上可以看出swap()仍然没有起到效果<br /><br />接着用&amp;来做实验<br />方法二：<br />void swap(int &amp;x,int &amp;y)<br />{<br /> cout&lt;&lt;"swap("&lt;&lt;x&lt;&lt;","&lt;&lt;y&lt;&lt;")"&lt;&lt;endl;<br /> int temp;<br /> temp=x;<br /> x=y;<br /> y=temp;<br /> cout&lt;&lt;"swap("&lt;&lt;x&lt;&lt;","&lt;&lt;y&lt;&lt;")"&lt;&lt;endl;<br />}<br />int main()<br />{<br /> <br /> int a=10;<br /> int b=2;<br /> int &amp;x=a;<br /> int &amp;y=b;<br /> cout&lt;&lt;x&lt;&lt;" "&lt;&lt;y&lt;&lt;endl;<br /> swap(x,y);<br /> cout&lt;&lt;x&lt;&lt;" "&lt;&lt;y&lt;&lt;endl;<br />}<br />运算结果是：<br />10  2<br />10  2   //swap<br />2    10 //swap<br />2    10<br />从结果上可以看出swap()起到预定效果<br /><br />用int *&amp;做实验<br />方法三：<br />int *p;<br />void swap(int *&amp;x,int *&amp;y)<br />{<br /> cout&lt;&lt;"swap("&lt;&lt;*x&lt;&lt;","&lt;&lt;*y&lt;&lt;")"&lt;&lt;endl;<br /> p=x;<br /> x=y;<br /> y=p;<br /> cout&lt;&lt;"swap("&lt;&lt;*x&lt;&lt;","&lt;&lt;*y&lt;&lt;")"&lt;&lt;endl;<br />}<br />int main()<br />{<br /> int a=10;<br /> int b=2;<br /> int *x=&amp;a;<br /> int *y=&amp;b;<br /> cout&lt;&lt;*x&lt;&lt;" "&lt;&lt;*y&lt;&lt;endl;<br /> swap(x,y);<br /> cout&lt;&lt;*x&lt;&lt;" "&lt;&lt;*y&lt;&lt;endl;<br />}  <br />运算结果是：<br />10  2<br />10  2   //swap<br />2    10 //swap<br />2    10<br />从结果上可以看出swap()起到预定效果<br /><br />最后，再次用int *做实验，注意swap()部分的变化<br />方法四：<br />void swap(int *x,int *y)<br />{<br /> int temp=0;<br /> cout&lt;&lt;"swap("&lt;&lt;*x&lt;&lt;","&lt;&lt;*y&lt;&lt;")"&lt;&lt;endl;<br /> temp=*x;<br /> *x=*y;<br /> *y=temp;<br /> cout&lt;&lt;"swap("&lt;&lt;*x&lt;&lt;","&lt;&lt;*y&lt;&lt;")"&lt;&lt;endl;<br />}<br />int main()<br />{<br /> <br /> int a=10;<br /> int b=2;<br /> int *x=&amp;a;<br /> int *y=&amp;b;<br /> cout&lt;&lt;*x&lt;&lt;" "&lt;&lt;*y&lt;&lt;endl;<br /> swap(x,y);<br /> cout&lt;&lt;*x&lt;&lt;" "&lt;&lt;*y&lt;&lt;endl;<br />} <br />运算结果是：<br />10  2<br />10  2   //swap<br />2    10 //swap<br />2    10<br />从结果上可以看出swap()起到预定效果<br />=============================================================<br />好，现在来说下为什么使用方法一和方法四，同样是传递的地址，为什么结果会不同？答案就在swap(int *x,int *y)上。在main()里虽然有x和y指针，但是，在swap()里的x,y却是临时变量。首先说明这一点是有好处的。我们来继续分析以下代码内容：<br /> （一）<br />   p=x;  //该方法看似我们希望通过交换临时指针x,y所指向的地址，来达到交换main()函数中实参x,y所指<br />   x=y;  //向地址，从而达到交换数值的效果。虽然逻辑上是正确的，程序编译也通过，但是，却忽略了  <br />   y=p; //一个非常重要的内容，那就是swap()中的x,y仍然是临时的，虽然该程序确实在swap中暂时交换<br />           //了x,y所指向的地址，<u><strong>但是实际上x,y所指向地址的数值仍然没有被改变！ </strong></u></font>
				</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> （四）<br />   int temp=0;   //通过对 方法一 的总结，我们作如下调整，在swap()函数中，我们立刻改变临时指针 <br />   temp=*x;     //x,y所指向地址的数值，即改变main()函数中实参指针x,y所指向地址的数值。所以，即使<br />   *x=*y;         //swap()函数调用完后内部临时x,y消失，但它们所做的工作已经完成：改变数值！<br />   *y=temp;<br /><br />同理，对于方法三和方法二，通过int &amp; 和int *&amp;也是做了类似方法四的工作，所以能正确swap所需内容。<br />至于说使用哪种方法，就是仁者见仁的事了。<br /></font>
		</p>
<img src ="http://www.cppblog.com/qjbest/aggbug/7621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-05-25 10:33 <a href="http://www.cppblog.com/qjbest/archive/2006/05/25/7621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转载）C++ sizeof 使用规则及陷阱分析</title><link>http://www.cppblog.com/qjbest/archive/2006/05/19/7398.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Fri, 19 May 2006 02:00:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/05/19/7398.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/7398.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/05/19/7398.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/7398.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/7398.html</trackback:ping><description><![CDATA[
		<font style="BACKGROUND-COLOR: #ffffff" color="#000000">From：</font>
		<a href="http://freeman.cnblogs.com/">
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">http://freeman.cnblogs.com/</font>
		</a>
		<br />
		<font style="BACKGROUND-COLOR: #ffffff" color="#000000">1、什么是sizeof</font>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    首先看一下sizeof在msdn上的定义：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t.</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    看到return这个字眼，是不是想到了函数？错了，sizeof不是一个函数，你见过给一个函数传参数，而不加括号的吗？sizeof可以，所以sizeof不是函数。网上有人说sizeof是一元操作符，但是我并不这么认为，因为sizeof更像一个特殊的宏，它是在编译阶段求值的。举个例子：<br /> <br /> cout&lt;&lt;sizeof(int)&lt;&lt;endl; // 32位机上int长度为4<br /> cout&lt;&lt;sizeof(1==2)&lt;&lt;endl; // == 操作符返回bool类型，相当于 cout&lt;&lt;sizeof(bool)&lt;&lt;endl;</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    在编译阶段已经被翻译为：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;4&lt;&lt;endl;<br /> cout&lt;&lt;1&lt;&lt;endl;</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    这里有个陷阱，看下面的程序：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> int a = 0;<br /> cout&lt;&lt;sizeof(a=3)&lt;&lt;endl;<br /> cout&lt;&lt;a&lt;&lt;endl;</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    输出为什么是4，0而不是期望中的4，3？？？就在于sizeof在编译阶段处理的特性。由于sizeof不能被编译成机器码，所以sizeof作用范围内，也就是()里面的内容也不能被编译，而是被替换成类型。=操作符返回左操作数的类型，所以a=3相当于int，而代码也被替换为：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> int a = 0;<br /> cout&lt;&lt;4&lt;&lt;endl;<br /> cout&lt;&lt;a&lt;&lt;endl;</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    所以，sizeof是不可能支持链式表达式的，这也是和一元操作符不一样的地方。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    结论：不要把sizeof当成函数，也不要看作一元操作符，把他当成一个特殊的编译预处理。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">2、sizeof的用法</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    sizeof有两种用法：<br />  <br />    （1）sizeof(object)<br />    也就是对对象使用sizeof，也可以写成sizeof object 的形式。例如：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    （2）sizeof(typename)<br />    也就是对类型使用sizeof，注意这种情况下写成sizeof typename是非法的。下面举几个例子说明一下：</font>
		</p>
		<p>
				<br />
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> int i = 2;<br /> cout&lt;&lt;sizeof(i)&lt;&lt;endl; // sizeof(object)的用法，合理<br /> cout&lt;&lt;sizeof i&lt;&lt;endl; // sizeof object的用法，合理<br /> cout&lt;&lt;sizeof 2&lt;&lt;endl; // 2被解析成int类型的object, sizeof object的用法，合理<br /> cout&lt;&lt;sizeof(2)&lt;&lt;endl; // 2被解析成int类型的object, sizeof(object)的用法，合理<br /> cout&lt;&lt;sizeof(int)&lt;&lt;endl;// sizeof(typename)的用法，合理<br /> cout&lt;&lt;sizeof int&lt;&lt;endl; // 错误！对于操作符，一定要加()</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    可以看出，加()是永远正确的选择。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    结论：不论sizeof要对谁取值，最好都加上()。</font>
		</p>
		<p>
				<br />
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">3、数据类型的sizeof</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">（1）C++固有数据类型</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    32位C++中的基本数据类型，也就char,short int(short),int,long int(long),float,double, long double<br />大小分别是：1，2，4，4，4，8, 10。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    考虑下面的代码：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;sizeof(unsigned int) == sizeof(int)&lt;&lt;endl; // 相等，输出 1</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    unsigned影响的只是最高位bit的意义，数据长度不会被改变的。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    结论：unsigned不能影响sizeof的取值。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">（2）自定义数据类型</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    typedef可以用来定义C++自定义类型。考虑下面的问题：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> typedef short WORD;<br /> typedef long DWORD;<br /> cout&lt;&lt;(sizeof(short) == sizeof(WORD))&lt;&lt;endl; // 相等，输出1<br /> cout&lt;&lt;(sizeof(long) == sizeof(DWORD))&lt;&lt;endl; // 相等，输出1</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    结论：自定义类型的sizeof取值等同于它的类型原形。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">（3）函数类型</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    考虑下面的问题：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> int f1(){return 0;};<br /> double f2(){return 0.0;}<br /> void f3(){}</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;sizeof(f1())&lt;&lt;endl; // f1()返回值为int，因此被认为是int<br /> cout&lt;&lt;sizeof(f2())&lt;&lt;endl; // f2()返回值为double，因此被认为是double<br /> cout&lt;&lt;sizeof(f3())&lt;&lt;endl; // 错误！无法对void类型使用sizeof<br /> cout&lt;&lt;sizeof(f1)&lt;&lt;endl;  // 错误！无法对函数指针使用sizeof   <br /> cout&lt;&lt;sizeof*f2&lt;&lt;endl;  // *f2，和f2()等价，因为可以看作object，所以括号不是必要的。被认为是double</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    结论：对函数使用sizeof，在编译阶段会被函数返回值的类型取代，</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">4、指针问题</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    考虑下面问题：<br /> <br /> cout&lt;&lt;sizeof(string*)&lt;&lt;endl; // 4<br /> cout&lt;&lt;sizeof(int*)&lt;&lt;endl; // 4<br /> cout&lt;&lt;sizof(char****)&lt;&lt;endl; // 4</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    可以看到，不管是什么类型的指针，大小都是4的，因为指针就是32位的物理地址。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    结论：只要是指针，大小就是4。（64位机上要变成8也不一定）。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    顺便唧唧歪歪几句，C++中的指针表示实际内存的地址。和C不一样的是，C++中取消了模式之分，也就是不再有small,middle,big,取而代之的是统一的flat。flat模式采用32位实地址寻址，而不再是c中的 segment:offset模式。举个例子，假如有一个指向地址 f000:8888的指针，如果是C类型则是8888(16位, 只存储位移，省略段)，far类型的C指针是f0008888(32位，高位保留段地址，地位保留位移),C++类型的指针是f8888(32位，相当于段地址*16 + 位移，但寻址范围要更大)。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">5、数组问题</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    考虑下面问题：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> char a[] = "abcdef";<br /> int b[20] = {3, 4};<br /> char c[2][3] = {"aa", "bb"};<br /> </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;sizeof(a)&lt;&lt;endl; // 7<br /> cout&lt;&lt;sizeof(b)&lt;&lt;endl; // 20*4<br /> cout&lt;&lt;sizeof(c)&lt;&lt;endl; // 6<br /> </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    数组a的大小在定义时未指定，编译时给它分配的空间是按照初始化的值确定的，也就是7。c是多维数组，占用的空间大小是各维数的乘积，也就是6。可以看出，数组的大小就是他在编译时被分配的空间，也就是各维数的乘积*数组元素的大小。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    结论：数组的大小是各维数的乘积*数组元素的大小。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    这里有一个陷阱：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> int *d = new int[10];</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;sizeof(d)&lt;&lt;endl; // 4</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    d是我们常说的动态数组，但是他实质上还是一个指针，所以sizeof(d)的值是4。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    再考虑下面的问题：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> double* (*a)[3][6];<br /> <br /> cout&lt;&lt;sizeof(a)&lt;&lt;endl;  // 4<br /> cout&lt;&lt;sizeof(*a)&lt;&lt;endl;  // 72<br /> cout&lt;&lt;sizeof(**a)&lt;&lt;endl; // 24<br /> cout&lt;&lt;sizeof(***a)&lt;&lt;endl; // 4<br /> cout&lt;&lt;sizeof(****a)&lt;&lt;endl; // 8</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    a是一个很奇怪的定义，他表示一个指向 double*[3][6]类型数组的指针。既然是指针，所以sizeof(a)就是4。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    既然a是执行double*[3][6]类型的指针，*a就表示一个double*[3][6]的多维数组类型，因此sizeof(*a)=3*6*sizeof(double*)=72。同样的，**a表示一个double*[6]类型的数组，所以sizeof(**a)=6*sizeof(double*)=24。***a就表示其中的一个元素，也就是double*了，所以sizeof(***a)=4。至于****a，就是一个double了，所以sizeof(****a)=sizeof(double)=8。</font>
		</p>
		<p>
				<br />
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">6、向函数传递数组的问题。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    考虑下面的问题：<br />#include &lt;iostream&gt;<br />using namespace std;</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int Sum(int i[])<br />{<br /> int sumofi = 0;<br /> for (int j = 0; j &lt; sizeof(i)/sizeof(int); j++) //实际上，sizeof(i) = 4<br /> {<br />  sumofi += i[j];<br /> }<br /> return sumofi;<br />}</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int main()<br />{<br /> int allAges[6] = {21, 22, 22, 19, 34, 12};<br /> cout&lt;&lt;Sum(allAges)&lt;&lt;endl;<br /> system("pause");<br /> return 0;<br />}</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    Sum的本意是用sizeof得到数组的大小，然后求和。但是实际上，传入自函数Sum的，只是一个int 类型的指针，所以sizeof(i)=4，而不是24，所以会产生错误的结果。解决这个问题的方法使是用指针或者引用。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    使用指针的情况：<br />int Sum(int (*i)[6])<br />{<br /> int sumofi = 0;<br /> for (int j = 0; j &lt; sizeof(*i)/sizeof(int); j++) //sizeof(*i) = 24<br /> {<br />  sumofi += (*i)[j];<br /> }<br /> return sumofi;<br />}</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int main()<br />{<br /> int allAges[] = {21, 22, 22, 19, 34, 12};<br /> cout&lt;&lt;Sum(&amp;allAges)&lt;&lt;endl;<br /> system("pause");<br /> return 0;<br />}<br />    在这个Sum里，i是一个指向i[6]类型的指针，注意，这里不能用int Sum(int (*i)[])声明函数，而是必须指明要传入的数组的大小，不然sizeof(*i)无法计算。但是在这种情况下，再通过sizeof来计算数组大小已经没有意义了，因为此时大小是指定为6的。<br />使用引用的情况和指针相似：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int Sum(int (&amp;i)[6])<br />{<br /> int sumofi = 0;<br /> for (int j = 0; j &lt; sizeof(i)/sizeof(int); j++)<br /> {<br />  sumofi += i[j];<br /> }<br /> return sumofi;<br />}</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int main()<br />{<br /> int allAges[] = {21, 22, 22, 19, 34, 12};<br /> cout&lt;&lt;Sum(allAges)&lt;&lt;endl;<br /> system("pause");<br /> return 0;<br />}<br />    这种情况下sizeof的计算同样无意义，所以用数组做参数，而且需要遍历的时候，函数应该有一个参数来说明数组的大小，而数组的大小在数组定义的作用域内通过sizeof求值。因此上面的函数正确形式应该是：<br />#include &lt;iostream&gt;<br />using namespace std;</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int Sum(int *i, unsigned int n)<br />{<br /> int sumofi = 0;<br /> for (int j = 0; j &lt; n; j++)<br /> {<br />  sumofi += i[j];<br /> }<br /> return sumofi;<br />}</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int main()<br />{<br /> int allAges[] = {21, 22, 22, 19, 34, 12};<br /> cout&lt;&lt;Sum(i, sizeof(allAges)/sizeof(int))&lt;&lt;endl;<br /> system("pause");<br /> return 0;<br />}</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">7、字符串的sizeof和strlen</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    考虑下面的问题：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> char a[] = "abcdef";<br /> char b[20] = "abcdef";<br /> string s = "abcdef";</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;strlen(a)&lt;&lt;endl;  // 6，字符串长度<br /> cout&lt;&lt;sizeof(a)&lt;&lt;endl;  // 7，字符串容量<br /> cout&lt;&lt;strlen(b)&lt;&lt;endl;  // 6，字符串长度<br /> cout&lt;&lt;strlen(b)&lt;&lt;endl;  // 20，字符串容量<br /> cout&lt;&lt;sizeof(s)&lt;&lt;endl;  // 12, 这里不代表字符串的长度，而是string类的大小<br /> cout&lt;&lt;strlen(s)&lt;&lt;endl;  // 错误！s不是一个字符指针。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> a[1] = '\0';<br /> cout&lt;&lt;strlen(a)&lt;&lt;endl;  // 1<br /> cout&lt;&lt;sizeof(a)&lt;&lt;endl;  // 7，sizeof是恒定的</font>
		</p>
		<p>
				<br />
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    strlen是寻找从指定地址开始，到出现的第一个0之间的字符个数，他是在运行阶段执行的，而sizeof是得到数据的大小，在这里是得到字符串的容量。所以对同一个对象而言，sizeof的值是恒定的。string是C++类型的字符串，他是一个类，所以sizeof(s)表示的并不是字符串的长度，而是类string的大小。strlen(s)根本就是错误的，因为strlen的参数是一个字符指针，如果想用strlen得到s字符串的长度，应该使用sizeof(s.c_str())，因为string的成员函数c_str()返回的是字符串的首地址。实际上，string类提供了自己的成员函数来得到字符串的容量和长度，分别是Capacity()和Length()。string封装了常用了字符串操作，所以在C++开发过程中，最好使用string代替C类型的字符串。</font>
		</p>
		<p>
				<br />
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">8、从union的sizeof问题看cpu的对界</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    考虑下面问题：（默认对齐方式）</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> union u<br /> {<br />  double a;<br />  int b;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> union u2<br /> {<br />  char a[13];<br />  int b;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> union u3<br /> {<br />  char a[13];<br />  char b;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;sizeof(u)&lt;&lt;endl;  // 8<br /> cout&lt;&lt;sizeof(u2)&lt;&lt;endl;  // 16<br /> cout&lt;&lt;sizeof(u3)&lt;&lt;endl;  // 13</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    都知道union的大小取决于它所有的成员中，占用空间最大的一个成员的大小。所以对于u来说，大小就是最大的double类型成员a了，所以sizeof(u)=sizeof(double)=8。但是对于u2和u3，最大的空间都是char[13]类型的数组，为什么u3的大小是13，而u2是16呢？关键在于u2中的成员int b。由于int类型成员的存在，使u2的对齐方式变成4，也就是说，u2的大小必须在4的对界上，所以占用的空间变成了16（最接近13的对界）。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    结论：复合数据类型，如union，struct，class的对齐方式为成员中对齐方式最大的成员的对齐方式。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    顺便提一下CPU对界问题，32的C++采用8位对界来提高运行速度，所以编译器会尽量把数据放在它的对界上以提高内存命中率。对界是可以更改的，使用#pragma pack(x)宏可以改变编译器的对界方式，默认是8。C++固有类型的对界取编译器对界方式与自身大小中较小的一个。例如，指定编译器按2对界，int类型的大小是4，则int的对界为2和4中较小的2。在默认的对界方式下，因为几乎所有的数据类型都不大于默认的对界方式8（除了long double），所以所有的固有类型的对界方式可以认为就是类型自身的大小。更改一下上面的程序：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> #pragma pack(2)<br /> union u2<br /> {<br />  char a[13];<br />  int b;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> union u3<br /> {<br />  char a[13];<br />  char b;<br /> };<br /> #pragma pack(8)</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;sizeof(u2)&lt;&lt;endl;  // 14<br /> cout&lt;&lt;sizeof(u3)&lt;&lt;endl;  // 13</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    由于手动更改对界方式为2，所以int的对界也变成了2，u2的对界取成员中最大的对界，也是2了，所以此时sizeof(u2)=14。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    结论：C++固有类型的对界取编译器对界方式与自身大小中较小的一个。</font>
		</p>
		<p>
				<br />
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">9、struct的sizeof问题</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    因为对齐问题使结构体的sizeof变得比较复杂，看下面的例子：(默认对齐方式下)</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s1<br /> {<br />  char a;<br />  double b;<br />  int c;<br />  char d; <br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s2<br /> {<br />  char a;<br />  char b;<br />  int c;<br />  double d;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;sizeof(s1)&lt;&lt;endl; // 24<br /> cout&lt;&lt;sizeof(s2)&lt;&lt;endl; // 16</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    同样是两个char类型，一个int类型，一个double类型，但是因为对界问题，导致他们的大小不同。计算结构体大小可以采用元素摆放法，我举例子说明一下：首先，CPU判断结构体的对界，根据上一节的结论，s1和s2的对界都取最大的元素类型，也就是double类型的对界8。然后开始摆放每个元素。<br />    对于s1，首先把a放到8的对界，假定是0，此时下一个空闲的地址是1，但是下一个元素d是double类型，要放到8的对界上，离1最接近的地址是8了，所以d被放在了8，此时下一个空闲地址变成了16，下一个元素c的对界是4，16可以满足，所以c放在了16，此时下一个空闲地址变成了20，下一个元素d需要对界1，也正好落在对界上，所以d放在了20，结构体在地址21处结束。由于s1的大小需要是8的倍数，所以21-23的空间被保留，s1的大小变成了24。<br />    对于s2，首先把a放到8的对界，假定是0，此时下一个空闲地址是1，下一个元素的对界也是1，所以b摆放在1，下一个空闲地址变成了2；下一个元素c的对界是4，所以取离2最近的地址4摆放c，下一个空闲地址变成了8，下一个元素d的对界是8，所以d摆放在8，所有元素摆放完毕，结构体在15处结束，占用总空间为16，正好是8的倍数。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    这里有个陷阱，对于结构体中的结构体成员，不要认为它的对齐方式就是他的大小，看下面的例子：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s1<br /> {<br />  char a[8];<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s2<br /> {<br />  double d;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s3<br /> {<br />  s1 s;<br />  char a;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s4<br /> {<br />  s2 s;<br />  char a; <br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;sizeof(s1)&lt;&lt;endl; // 8<br /> cout&lt;&lt;sizeof(s2)&lt;&lt;endl; // 8<br /> cout&lt;&lt;sizeof(s3)&lt;&lt;endl; // 9<br /> cout&lt;&lt;sizeof(s4)&lt;&lt;endl; // 16;</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    s1和s2大小虽然都是8，但是s1的对齐方式是1，s2是8（double），所以在s3和s4中才有这样的差异。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    所以，在自己定义结构体的时候，如果空间紧张的话，最好考虑对齐因素来排列结构体里的元素。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">10、不要让double干扰你的位域</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    在结构体和类中，可以使用位域来规定某个成员所能占用的空间，所以使用位域能在一定程度上节省结构体占用的空间。不过考虑下面的代码：</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s1<br /> {<br />  int i: 8;<br />  int j: 4;<br />  double b;<br />  int a:3;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s2<br /> {<br />  int i;<br />  int j;<br />  double b;<br />  int a;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s3<br /> {<br />  int i;<br />  int j;<br />  int a;<br />  double b;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> struct s4<br /> {<br />  int i: 8;<br />  int j: 4;<br />  int a:3;<br />  double b;<br /> };</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000"> cout&lt;&lt;sizeof(s1)&lt;&lt;endl;  // 24<br /> cout&lt;&lt;sizeof(s2)&lt;&lt;endl;  // 24<br /> cout&lt;&lt;sizeof(s3)&lt;&lt;endl;  // 24<br /> cout&lt;&lt;sizeof(s4)&lt;&lt;endl;  // 16</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    可以看到，有double存在会干涉到位域（sizeof的算法参考上一节），所以使用位域的的时候，最好把float类型和double类型放在程序的开始或者最后。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    第一次写东西，发现自己的表达能力太差了，知道的东西讲不出来，讲出来的东西别人也看不懂，呵呵。另外，C99标准的sizeof已经可以工作在运行时了，打算最近找个支持C99的编译器研究一下。</font>
		</p>
<img src ="http://www.cppblog.com/qjbest/aggbug/7398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-05-19 10:00 <a href="http://www.cppblog.com/qjbest/archive/2006/05/19/7398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>继续关于char *的错误</title><link>http://www.cppblog.com/qjbest/archive/2006/05/18/7370.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Thu, 18 May 2006 10:00:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/05/18/7370.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/7370.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/05/18/7370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/7370.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/7370.html</trackback:ping><description><![CDATA[
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">/********错误程序********/<br />void key(char *p)<br />{<br /> p="ac";<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int main()<br />{<br /> char *p="d";<br /> cout&lt;&lt;p&lt;&lt;endl;<br /> key(p);<br /> cout&lt;&lt;p&lt;&lt;endl;<br /> delete p;<br />}<br />//该程序只输出 "d"<br />/***********************/<br /><br />/*******正确程序*******/<br />void key(char *p)<br />{<br /> strcpy(p,"ac");<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int main()<br />{<br /> char *p=new char[5];<br /> strcpy(p,"e");<br /> cout&lt;&lt;p&lt;&lt;endl;<br /> key(p);<br /> cout&lt;&lt;p&lt;&lt;endl;<br /> delete[] p;<br />}<br />先输出 "e",再输出"ac"<br />/**********************/<br /><br />==================================<br />第一个程序：<br />char *p="d";//p指向常量字符串<br /> cout&lt;&lt;p&lt;&lt;endl;<br /> key(char *p) //试图改变p，语法无误，但逻辑不允许，故编译正确，运行错误。在程序编译的时候； void key(char *p)类似被解释成：void key(const char *p){p="ac";}<br /><br />第二个程序：<br />char *p = new char[100];//p指向数组的首地址，内容可变<br /> strcpy(p, "d");//内容变为“d”<br /> cout&lt;&lt;p&lt;&lt;endl;<br /> key(p);//内容变为“ac”，strcpy（）不改变它的地址，只改变p所指的数组的内容，故输出为ac<br />C风格字串不支持直接赋值，要使用strcpy()。<br /><br /></font>
		</p>
<img src ="http://www.cppblog.com/qjbest/aggbug/7370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-05-18 18:00 <a href="http://www.cppblog.com/qjbest/archive/2006/05/18/7370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>再次关于C风格字符串的几个小问题</title><link>http://www.cppblog.com/qjbest/archive/2006/05/17/7295.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Wed, 17 May 2006 02:18:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/05/17/7295.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/7295.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/05/17/7295.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/7295.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/7295.html</trackback:ping><description><![CDATA[
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">倒掉，严重倒掉，不通过这次写程序，还真不知道自己犯了个比较夸张的错误。<img height="20" src="http://www.cppblog.com/Emoticons/QQ/01.gif" width="20" border="0" /><br />======================================================<br />char a[6];             //需要对a赋值<br />strcpy(a,"hello");   //正确<br />a="hello";             //错误<br /><br />另外，对于字串数组的初始化<br />char a[6]={0x00}; //正确<br />char a[6]="\0";       //正确<br />char a[6]="hello";   //正确<br />char a[6]={"hello"}; //正确<br />char a[5]={'h','e','l','l','o'}; //正确<br /><br />对于：<br />char a[6];  <br />a[0]={0x00} //错误<br />正确方法如下：<br />char a[6];<br /> memset(a,0x00,sizeof(a)); </font>
		</p>
<img src ="http://www.cppblog.com/qjbest/aggbug/7295.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-05-17 10:18 <a href="http://www.cppblog.com/qjbest/archive/2006/05/17/7295.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转帖 《程序员》推荐C++ 图书三人谈</title><link>http://www.cppblog.com/qjbest/archive/2006/05/09/6827.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Tue, 09 May 2006 08:51:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/05/09/6827.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/6827.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/05/09/6827.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/6827.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/6827.html</trackback:ping><description><![CDATA[
		<table id="table11" cellspacing="0" bordercolordark="#ffffff" cellpadding="0" width="100%" bordercolorlight="#c0c0c0" border="1">
				<tbody>
						<tr>
								<td bgcolor="#dfdfdf" height="23">
										<font style="BACKGROUND-COLOR: #ffffff" color="#000000">
										</font>
								</td>
						</tr>
						<tr>
								<td>
										<div align="center">
												<table id="table12" cellspacing="0" cellpadding="0" width="98%" border="0">
														<tbody>
																<tr>
																		<td>
																				<table id="Table99" style="TABLE-LAYOUT: fixed; WORD-WRAP: break-word" cellspacing="0" cellpadding="0" width="572" border="0">
																						<tbody>
																								<tr>
																										<td>
																												<div align="center">
																														<table id="table100" cellspacing="0" cellpadding="0" width="98%" border="0">
																																<tbody>
																																		<tr>
																																				<td>
																																						<font style="BACKGROUND-COLOR: #ffffff" color="#000000">主持人：熊节（透明），《程序员》杂志编辑，C-View成员<br />嘉   宾：孟岩（梦魇）,联想公司掌上设备事业部应用开发处任职，C-View成员。与侯捷先生合译了《C++ Standard Library》一书<br />        金尹（恶魔），上海天宇公司CTO，在《程序员》连载有“自由与繁荣的国度”系列文章 </font>
																																						<p>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：“学C++用哪本书入门”，这是被问得最多的一个问题。但是哪一本书是最好的入门书？似乎很难找到答案。《C++ Primer》太厚，《Effective C++》对读者要求比较高，《Essential C++》又常常被批评为“太浅”。<br />其实说穿了：no silver bullet。想从一本书学会C++，那是不可能的。有朋友问我如何学C++，我会建议他先去找本数据结构书，把里面的习题全部用C++做一遍，然后再去看《Effective C++》。myan经常说“要在学习初期养成好习惯”，我对此颇不以为然。<br />个人认为，《Essential C++》适合作教材，《C++ Primer》适合作参考书，《Effective C++》适合作课外读物。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">恶魔：很后悔当初买了《C++ Primer》。因为从我个人角度来看，它的功能效用基本是和《The C++ Programming Language》重合。当然对于入门来说，它还是很不错的。但是《C++ Primer》太厚，一来导致看书极其不方便，二来系统学习需要花比较长的时间。对于目前这个越来越快餐化的时代来说，的确有很多不适合的地方，不过可以作为初学者的参考书。现在我以一块K3 CPU的代价把它借给了别人，希望我那位同事能够从中得到一些益处。<br />如果已经具备了C基础，我建议看国内的书，例如钱能的《 C++大学教程（第二版） 》。(如果没有C的基础还是看谭浩强的C语言)。这本书对C讲得还算比较清晰，有很多习题值得一做，特别是最后的struct和union两个部分。其中的一些算法比较拖沓和繁琐（比如树和链表的遍历算法），读者可以尝试修改这些例子，作为最后对C语言的一些总结测试。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：这个问题让我想起四五年前的情形。今天对于C++有一点认识的人，多半是从那几年就开始学C++了。那时根本没有品牌观念。从书店里找一本C++书，如果看着还算明白，就买下来。我记得那时候宛延闿、张国锋、麦中凡教授的书都受到很高的赞誉。我个人最早的一本C++书是Greg Perry的一本书，今天想起来，其实是一本打着C++旗号的C语言教程。对我作用最大的一本书是国防科技出版社出版的一本书，书名记不得了，作者叫斯蒂芬·布莱哈。<br />透明：还记得以前曾批评过一本C++书，是北航出的，整本书就没有出现过class关键字。那本书，说穿了其实只是介绍了C语言和iostream库的用法，根本不能算C++。而当时我常常推荐的一本书是电子科技大学张松梅老师的C++教程。那本书，直到今天来看也没有太大的问题，唯一的缺憾就是由于年代久远，许多东西已经过时了。而对于一本技术书籍来说，“过时”是最不可接受的。<br />总体来说，那时使用C++的人真是在“盲人摸象”。不过这也有好处，就是对C++的很多细节能搞清楚，以后看到经典好书时比较容易理解；当然坏处就是概念不清，甚至都不知道C++和Visual C++、Borland C++到底有什么不一样。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：整个90年代，其实大部分人对于C++的认识都似是而非。一开始是等同于Borland C++，后来是等同于Visual C++和MFC。所以一般来说，打着BC和VC旗号的书卖得很好，人们觉得这就是C++。而我比较幸运，布莱哈的那本书虽然从现在的眼光来看谈不上高超，但基本路子是对的。可能是因为原书是给UNIX程序员的培训教材，所以没有让我一开始就形成“C++ == VC++”的认识。<br />其实一直到1996年，我们那里搞计算机的都是唯Borland C++马首是瞻的，到了VC 4.0出来，一下子格局全变了。1997年VC5推出之后，书店里MFC书铺天盖地，学MFC的人，头抬得都比别人高一些。不过现在看来，那时候大部分的MFC书都是三流货色。我曾经有一段时间认为，那一批程序员中间有不少被误导了。根本原因就是相对的封闭。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：我觉得一本书的价值有两方面：第一，教给你实用的技术；第二，促使你去思考。对于一本介绍VC（或者说MFC）使用方法的书，我根本不希望它能促使我有什么思考，所以我就一定要求它在技术上精益求精完美无瑕。我刚开始用VC的时候，买的第一本书就是潘爱民老师翻译的《VC技术内幕》（第四版），没有受到那些“三流货色”的误导，应该说是很幸运的。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：1999年机械工业出版社开始出版“计算机科学丛书”，其中的《Thinking in C++》第一版受到了广泛的欢迎。其实我一直不认为这本书很出色，虽然拿过一次大奖。然而我们都得承认，这本书在C++书籍领域里第一次建立了品牌观念，很多初学者开始知道，不是随便买哪一本都一样的。再往后就是2000年的《 深入浅出MFC（第二版） 》第二版，以及侯先生在《程序员》上发表的那一篇《C++/OOP大系》，加上整个大环境的变化，品牌观念深入人心，C++书籍市场终于开始逐渐与世界同步。<br />回想往事，我的感觉是，那个需要战战兢兢选择入门书的时代已经过去，今天的C++初学者，大可以放心地买口碑好、自己读起来思路顺畅的书，入门不再是太大的问题。还有一些程序员已经学了几年C++，但看到今天出版的一些新书，感觉比较陌生，这也不是什么问题。侯先生经常说“凡走过必留下足迹”，所谓“走弯路”，未必不是一件好事。<br />至于具体的推荐表，就不好一概而论了。总之在我的印象里，《Essential C++》、《C++ Primer》、钱能教授的C++教程，都不错。甚至有人一上来就看Bjarne Stroustrup的《The C++ Programming Language》，只要他喜欢，也没什么不可以。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：我同意你的观点。不管怎么说，编程是门实践性非常强的学问。要想对C++对象模型有深入的了解，最好的办法就是写一串程序去看结果；要想学会OOP，也只能从项目中学。对于初学者，最好的学习方法就是不停地写程序，写真正有用的程序，写到有问题的时候就去查书，于是自然就会知道哪本书好哪本书不好。不过我们的教育制度能不能让大学里的学生们有这样的学习机会，我表示怀疑。<br />以我的经验，学C++有两个门槛：入门和使用。完全看不懂C++，这是一个门槛，但是只要有一本合适的入门书，很快就能跨过。要想真正用上C++，却不是件很容易的事情。尤其对于学生来说，接触到的东西多是“玩具”，很难有实战的机会。所以经常看见有人问“C++到底能做什么”，这是C++学习中一个比较麻烦的问题。我们都是做了相当长时间的C++程序之后才看到一些真正经典的书，也正是因为走了相当长的弯路之后才知道这些书的经典之所在。所谓弯路，我想也是一种必须的积累。就算一开始就看《Essential C++》和《C++ Primer》，没有两三年的时间恐怕还是难有所得。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">恶魔：有两句十分有道理的话，一是我大学的C语言老师说的“写程序不如说是抄程序”，另一句是一网友说的“好的设计来自借鉴，天才的设计来自剽窃”。对于我这个理性批判主义者来说，这两句话的确不太适合。但是无论从哪个角度来讲，对于初学者来说，剽窃大师的作品是通向成功的最快捷径。<br />我个人认为，对于C++的初学者来说，首先要确定自己专业领域内主要使用的特性的方向。因为C++的特性如此众多，初学者想贪多基本是不可能成功的。C++的编程范式基本可以分为ADT+PP、GP和OO三个方向。对于ADT+PP范式来说，初学者的主要问题不是学习C++，而是学习C的使用。对于这样的初学者，国内的几本书还是写得比较清楚，符合中国人的习惯，比如谭浩强的《C语言教程》、钱能的《C++语言大学教程》。这两本书我首推第一本，因为这一本我潜心研究了一年，这本书当中很多程序是可以剽窃的，而且可以对这些程序进行加工和提升。比如结构这一章中，它所给出的用struct来实现链表、二叉树的算法是相当蹩脚的。学习ADT+PP的初学者将这本书揣摩透以后可以尝试修改这两个程序。另外这本书的第二版稍微涉及了一些关于“类”的内容。学习ADT+PP的初学者，可以不被OO中的一些专有特性扰乱自己的思路，对于类层次扁平、无继承、无多态的程序编写是有很大好处的。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：你好象比较推崇国内教授写的书。现在社会上有种不好的风气：一捧就捧上天，一贬就贬下地。就好象对待谭教授的书，前几年是奉为经典，这几年又有很多人使劲批评。学C++更是有点“崇洋媚外”，总是觉得初学就应该看《Essential C++》。我看这种观点也是片面的。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">恶魔：当然《Essential C++》也值得看看。但是我个人觉得这本书没有谭浩强的《C语言教程》来得好。主要原因是：第一，C++的所有特性都点到了，但是不深，看了以后会三心二意没有方向；第二，可以抄袭借鉴的例子太少。《C语言教程》中有很多有趣的问题，比如猴子吃桃、汉诺塔等等，这些例子对于刚刚涉及C/C++语言编程的人来说是学习编程很好的例子。《Essential C++》只能是前两本书看透以后，作为学习C++特性的一个过渡性的书籍。让读者真正领略到什么是C++的编程、和C编程的不同点在哪里。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：我发现一个很有趣的现象：初学者往往喜欢问“哪本书比较好”，这让我很是不解。这有点像一个刚学打篮球的人问“王治郅和科比谁比较厉害”。当然科比更厉害一些。但如果你是想学打篮球，这两个人都非常非常有资格教你，你跟谁学都能学得很强——关键不是在于你选哪个老师，而是在于你自己用多少功夫去学。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：回到原来话题。学会了C++的语法，能看懂C++代码之后，必须有些书来指导进阶（或者叫指点迷津）。我觉得《设计模式》很好，能够让读者看到一些精妙的用法。不过正如我经常说的，模式带来的麻烦和好处一样多，甚至麻烦还要更多。而且，C++本身的问题使得在C++中使用GoF模式愈加麻烦。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：《Design Patterns》这本书绝对是不可以没有的，而且中英文版都不可少。最初我看中文版，说实话看不懂，但是也不觉得人家翻译得不好，所以就想，大概是原文就很难懂，加上自己水平有限。于是总是想着再找几本patterns的书来看。后来找到几本书，口碑还不错，不过水平高下，一比就出来了，还是那本《Design Patterns》最经典，最耐看。英文版出来之后，两个版本对照看，明白多了。现在觉得，其实就设计模式来讲，把这本看明白了就很不错了，不用再花费很多心思找其他的书。我现在的包里始终夹着这本书，随身携带，有备无患。<br />至于说设计模式的副作用，和可能带来的弊端，我的体会也挺多。不过是这样，我们想一想，究竟什么情况下设计模式可以用得很好呢？一种是有经验丰富的人引导，比如要是Robert Martin带队，你在某个地方用错了设计模式，他就会指出来，说这里不对，将来会产生什么样的弊端。对于他来说，丰富的实践经验足以支持他进行“预测型”设计。但是大部分人没这个能力，因此我们只好走第二条路和第三条路，就是“试探型”设计和“重构型”设计。遇到一个问题，你觉得用某种模式挺合适的，就大胆地用了，成功是积累经验，发现不好，出了问题了，只好改回来，那也是积累教训。这叫做“试探型”。至于重构，应该算是最有组织、成功率最高的工程化方法。先把问题“quick and dirty”地解决了，所有的暗礁都暴露出来，然后再根据实际情况采用合适的模式优化设计。现在XP和UP都高度重视refactory，UP在Elaboration和Construction阶段都鼓励抽出专门的iterations进行重构。所以说如果组织快速的软件开发，当然比较倾向于这条路——打成功率嘛。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：讲到重构，我顺便说说《Refactoring》这本书的影响。从工程本身的角度来说，你所谓的“重构型设计”是没有什么问题的。但中国的开发者（也包括我在内）往往比较冲动，比较容易相信银弹的存在。曾经有那么一段时间，我在Java中尝试过了重构的方法之后，又拿到C++中去尝试。结果发现，在Java中速度非常快的重构过程，到C++中就被减慢了。究其原因，就是因为C++和Java的约束条件不同。拿着Java中成功的案例直接套C++，不失败才怪。<br />所以，我必须说：《Refactoring》这本书很有价值。但对于C++程序员来说，它的价值是让你思考，思考这种方法的可行性。如果一个C++程序员没有打算迁移到Java，那么我必须告诉他：《Refactoring》这本书不是让你照着它用的，甚至不是让你去相信它的。对于C++程序员，《Refactoring》全书可以放心相信的只有第13章，其他的部分，都必须非常谨慎地对待。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：我还要就“试探型”的方法多说两句，我觉得对于个人发展来讲，“试探”也是必不可少的，撞墙不可怕，高水平的人不都是撞出来的吗？你失败了一次，就知道这个模式有什么潜在的问题，下次再用，就会多看几步，像下棋似的。撞的多了，路数就出来了。<br />我不知道你们是否有这个感觉：用错了模式，吃了亏，再回过头去翻翻《Design Patterns》，看到人家早就指出来这个问题，不过就是那么几句话，原来看上去干巴巴的，现在觉得句句都讲到心坎上，GoF的形象马上就高大起来，还带着光环，感觉是既兴奋又懊悔。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：现在回头来看，我更欣赏myan推荐给我的《Designing Object-Oriented C++ Applications Using Booch Method》。这本书能够帮助C++程序员理清思路培养习惯，可惜国内没有引进。相比后来商业味浓厚的UML系列书籍，我觉得这本书对于面向对象的阐释精辟独到，至今未有能出其右者。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：刚才我们两人都说到Robert Martin，他可是我的榜样。那本1995年的《Designing Object Oriented C++ Application》，我觉得是每一个C++软件工程师都应该反复研读的书。可惜不仅国内没有引进，在国外的名气也不大。如果你觉得面向对象的那些道理你好像都明白，可就是一遇到实际问题就使不上劲，那这本书就是你的最佳导师。<br />提到理清思路，还有一本书不得不提，就是Andrew Koenig的《Ruminations On C++》。每个人都应该问自己，我学了这么多年的C++，究竟什么是C++最基本的设计理念？遇到问题我第一个直觉是什么？第一个试探型的解决方案应该具有那些特点？如果你不能给出明确的答案，就应该认真地去读这本书，读完了你就有了“主心骨”。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：插一句话，谈谈“推荐书”的问题。入门书基本上是放之四海而皆准的，所以推荐的意义也不大。而入门后的发展方向，每个人不同，这个时候就需要“高人”的指点。举个例子：我学C++的时候，myan还不认识我，所以也没有给我推荐书，我还是学过来了，所以即使你当时向我推荐了《Essential C++》或者《C++ Primer》，我也不会太感谢你；但在我认真研究OO的时候，你推荐Robert Martin那本书给我，对我帮助就特别大，而且我从别的地方也很难找到类似的推荐，所以我就很感谢你。<br />一个程序员，必须有framework的意识，要学会用framework，还要主动去分析framework（在这方面，《Design Patterns》能有一定的帮助）。但是，真正高质量、成气候的framework的书恐怕也就只有针对MFC的。从这个角度来说，MFC纵有千般不是，C++程序员都非常有必要先去用它、熟悉它、研究它，甚至借助《深入浅出MFC》这样的书来剖析它。不然，很难有framework的意识和感觉。<br />当然，另一个framework也很好，那就是STL。不管用不用MFC、STL，对这两个东西的掌握和理解都是极有帮助的。最近我又在看《深入浅出MFC》，虽然已经不用MFC编程了，但帮助是一定有的。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：MFC和STL方面，我还是比较推崇侯先生的两本书《深入浅出MFC》和《STL源码解析》。<br />《深入浅出MFC》这本书，名气自然是大得不得了，不过也有不少人批评。其实书也没有十全十美的，批评当然是少不了的，不过有的时候我看到有人评论这本书，把它跟Inside VC相比，真的是牛头不对马嘴。<br />你刚才其实说得很对，程序员应该有一点framework意识。而这本《深入浅出MFC》与其说是在讲MFC编程，不如说通篇是在拿MFC为例分析Application Framework的架构和脉络。所以无论你对于MFC本身是什么态度，这本书对每一个C++程序员都有很大的益处。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：是的。《VC技术内幕》会告诉你“DYNAMIC_CREATE这个宏怎么用”，《深入浅出MFC》则告诉你“DYNAMIC_CREATE这个宏是怎么实现的”。所以，如果你只需要在VC下写一些小应用程序，《深入浅出MFC》的价值并不太大；但是，如果你需要设计一个稍微大一点的东西（不一定是framework），MFC的设计思想就会有所帮助。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：另外，我觉得对于MFC也应该有一个公允的评价。过去是吹捧得天上有地下无，书店里铺天盖地都是MFC的书，搞得大家只知有MFC，不知有C++，甚至直到现在还有人问：“我是学MFC呢，还是学C++？VC++是不是比C++更高级的语言？”MFC成了一尊神像，阻碍了人们的视线。所以得把它从神坛上拉下来。这就是过去一两年有很多人，包括我在内批评MFC的一个目的。可是现在大家视野开阔了，.NET也出来了，MFC不再是神像了，少数人就开始以贬损MFC为乐了。我觉得这种态度是不对的。<br />什么叫好的框架？我觉得在十几年的时间能够象MFC这样保持稳定并且不断进步的框架就是好的框架。可能我们在一些具体的设计问题上有不同看法，觉得“这个地方这么设计不是更漂亮吗？”很多时候是的，但是这不重要，重要的是MFC成熟稳定、有十几年的成功经验，这是最了不起的东西。<br />另外一点，MFC中间包括着学习Win32 API编程的最佳资料。这是除了其framework方面之外的另一个亮点。我现在使用Win32 API开发，但是经常参考MFC的源代码，收获很大。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：STL方面，我对于剖析它的源代码兴趣并不大，毕竟里面源代码多是算法问题。所以，《STL源码剖析》我也只是随便翻翻就束之高阁了。我觉得这本书用来做计算机系的数据结构和算法教材不错，不知道有没有老师乐意这样做。<br />对于STL，我的态度一向都是“应用至上”。不过，我一直认为SGI STL本身就是一本精彩的书，一本数据结构和算法的经典参考书，同时也是泛型技术的参考书。想知道一个算法是如何实现的，看看STL源代码就行；想知道如何使用type traits，STL源代码里面也有例子。看别人写的书，总觉得隔着一层纱，有点挠不到痒处的感觉。SGI STL的代码写得非常漂亮，一个C++程序员如果不看看这本书，实在是可惜。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：至于STL，除了《STL源码解析》之外，我举贤不避亲，强烈推荐侯先生与我合译的那本《The C++ Standard Library》。这本书质量之高是无需怀疑的。我现在手边常备此书，随时查阅，对我帮助很大。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：C++和Java相比，最大的优势就是它没有一个专门的公司来管它，最大的弱点也是它没有一个专门的公司来管它。Java程序员在学会简单的语法之后，立刻进入SUN提供的framework，一边用这个现成的framework做实际开发，一边在开发过程中继续学习Java一些幽深的特性。而这个时候，C++程序员恐怕还在问“VC和BCB哪个好”呢。这无疑是浪费时间。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">梦魇：刚才你说Java和C++的优劣，这个话题已经成了我们这个年代永不消失的声波了。我也不想再谈这个。不过有一点我得说清楚：现在我们很多用C++的人吃了不少苦头，探过脖子去看看Java，觉得它真是太可爱了，这种印象是不准确的。另外，Java也不简单，而且会越来越庞大复杂。在很多场合，Java还不具有竞争力。至于将来如何，我看有些Java爱好者也过分乐观了，似乎计算机科学界几十年解决不了的问题都可以借着Java的东风解决掉，恐怕没那么容易。 </font>
																																						</p>
																																						<p>
																																								<font style="BACKGROUND-COLOR: #ffffff" color="#000000">透明：那当然。我再次强调：No Silver Bullet。读书很重要，但古人说“行万里路，读万卷书”，还是把“行路”放在“读书”前面。尤其对于技术书籍，如果它不能帮我解决问题、不能给我带来非常实际的利益，那么我是不会去读它的。恶魔说得对，我们这个社会很快餐，我们这个行业尤其很快餐，我们也只能努力适应它。<br /> <br />转载自: </font>
																																								<a href="http://bbs.cnitexam.com/simple/index.php?t22602.html" target="_blank">
																																										<font style="BACKGROUND-COLOR: #ffffff" color="#000000">http://bbs.cnitexam.com/simple/index.php?t22602.html </font>
																																								</a>
																																								<br />
																																						</p>
																																				</td>
																																		</tr>
																																</tbody>
																														</table>
																												</div>
																										</td>
																								</tr>
																						</tbody>
																				</table>
																		</td>
																</tr>
														</tbody>
												</table>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/qjbest/aggbug/6827.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-05-09 16:51 <a href="http://www.cppblog.com/qjbest/archive/2006/05/09/6827.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer里一个类似string的简单类</title><link>http://www.cppblog.com/qjbest/archive/2006/04/28/6423.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Fri, 28 Apr 2006 07:44:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/04/28/6423.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/6423.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/04/28/6423.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/6423.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/6423.html</trackback:ping><description><![CDATA[
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">#include&lt;iostream&gt;<br />#include&lt;cstring&gt;<br />#include&lt;cassert&gt;<br />#include&lt;iomanip&gt; </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">using namespace std;<br />class String;<br />istream&amp; operator&gt;&gt;(istream&amp;, String&amp;);<br />ostream&amp; operator&lt;&lt;(ostream&amp;,const String&amp;); </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">class String<br />{<br />public:<br /> //构造函数<br /> //String s1();<br /> //String s1("abc");<br /> //String s2(s1);<br /> String();<br /> String(const char*);<br /> String(const String&amp;);<br /> //析构函数<br /> ~String();<br /> //赋值操作<br /> String&amp; operator=(const char*);<br /> String&amp; operator=(const String&amp;);<br /> //等于操作<br /> bool operator==(const char*);<br /> bool operator==(const String&amp;);<br /> //加操作<br /> String operator+(const String&amp;) const;<br /> //下标操作<br /> char&amp; operator[](int);<br /> //成员操作<br /> int size(){return _size;}<br /> char* c_str(){return _string;}<br /> //记数操作<br /> int count(const char) const;<br />private:<br /> int  _size;<br /> char *_string; <br />}; </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline String::String()                                    //构造函数<br />{<br /> _size=0;<br /> _string=0;<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline String::String(const char* str)                     //构造函数<br />{<br /> if(!str)<br /> {<br />  _size=0;<br />  _string=0;<br /> }<br /> else<br /> {<br />  _size=strlen(str);<br />  _string=new char[_size+1];<br />  strcpy(_string,str);<br /> }<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline String::String(const String&amp; str)                  //拷贝构造函数<br />{<br /> if(!str._size)<br /> {<br />  _size=0;<br />  _string=0;<br /> }<br /> else<br /> {<br />  _size=strlen(str._string);<br />  _string=new char[_size+1];<br />  strcpy(_string,str._string);<br /> }<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline String::~String()                                  //析构函数<br />{<br /> delete[] _string;<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline String&amp; String::operator=(const char* str)         //赋值操作<br />{<br /> if(!str)<br /> {<br />  _size=0;<br />  delete[] _string;<br />  _string=0;<br /> }<br /> else<br /> {<br />  _size=strlen(str);<br />  delete[] _string;<br />  _string=new char[_size+1];<br />  strcpy(_string,str);<br /> }<br /> return *this;<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline String&amp; String::operator=(const String &amp;str)      //赋值操作<br />{<br /> if(this!=&amp;str)<br /> {<br />  _size=str._size;<br />  delete[] _string;<br />  _string=new char[_size+1];<br />  strcpy(_string,str._string);<br /> }<br /> return *this;<br />} </font>
		</p>
		<p>
				<br />
				<font color="#000000">
						<font style="BACKGROUND-COLOR: #ffffff">inline bool String::operator==(const String &amp;rhs)          //等于操作符重载<br />{<br /> if(_size!=rhs._size)<br />  return false;<br /> return strcmp(_string,rhs._string)?false:true;<br />}</font>
						<font style="BACKGROUND-COLOR: #ffffff">
						</font>
				</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline bool String::operator==(const char *str)            //等于操作符重载<br />{<br /> return strcmp(_string,str)?false:true;<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline char&amp; String::operator[](int n)                     //下标访问符<br />{<br /> assert(n&gt;=0 &amp;&amp; n&lt;_size);<br /> return _string[n];<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline int String::count(const char s) const               //记数操作<br />{<br /> int tempCount=0;<br /> for(int i=0;i&lt;_size;i++)<br /> {<br />     if(_string[i]==s)<br />   ++tempCount;<br /> }<br /> return tempCount;<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline String String::operator+(const String&amp; str) const  //加操作<br />{<br /> String tempStr;<br /> tempStr._size=_size+str._size;<br /> tempStr._string=new char[tempStr._size+1];<br /> strcpy(tempStr._string,_string);<br /> strcat(tempStr._string,str._string);<br /> return tempStr;<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline istream&amp; operator&gt;&gt;(istream &amp;io,String &amp;str)       //输入流<br />{<br /> const int limit_string_size =4096;<br /> char inBuf[limit_string_size];<br /> io&gt;&gt;setw(limit_string_size)&gt;&gt;inBuf;<br /> str=inBuf;<br /> return io;<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">inline ostream&amp; operator&lt;&lt;(ostream &amp;os,String &amp;str)       //输出流<br />{<br /> return os&lt;&lt;str.c_str();<br />} </font>
		</p>
		<p>
				<br />
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">int main()<br />{<br /> String str1="abc";<br /> String str2="def";<br /> str1.size();<br /> cout&lt;&lt;"size :"&lt;&lt;str1.size()&lt;&lt;endl;<br /> cout&lt;&lt;"b count :"&lt;&lt;str1.count('b')&lt;&lt;endl;<br /> String str3=str1+str2;<br /> cout&lt;&lt;str3;      //该处不能为String&amp;，只能为String。见String operator+()和ostream&amp; operator&lt;&lt;(ostream &amp;os,String &amp;str)<br /> return 0;<br />} </font>
		</p>
		<p>
				<font size="+0">
						<font style="BACKGROUND-COLOR: #ffffff" color="#000000">SO GOOD! <br /></font>
				</font>
		</p>
<img src ="http://www.cppblog.com/qjbest/aggbug/6423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-04-28 15:44 <a href="http://www.cppblog.com/qjbest/archive/2006/04/28/6423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础部分----文字常量</title><link>http://www.cppblog.com/qjbest/archive/2006/04/19/5859.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Wed, 19 Apr 2006 01:47:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/04/19/5859.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/5859.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/04/19/5859.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/5859.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/5859.html</trackback:ping><description><![CDATA[
		<font style="BACKGROUND-COLOR: #ffffff" color="#000000">对于文字常量，列出如下关键信息，都是以前自己不太清楚的部分<br />文字常量类型：<br />1、整型<br />2、浮点型<br />3、bool型<br />4、字符型<br />5、字符串型<br />6、转移序列<br />===========================================<br />1、整型：有short,int,long int。默认情况下都是有符号型的：1024。最左边为符号位，1表示负数，0表示正数。如果要表示无符号型，则为：1024U。如果要表示长整型，则为：1024L。<br />2、浮点型：默认情况下都是double型的：3.141592。如果要表示为float型，则为3.141592F。如果要表示长双精度（即扩展精度），则为3.141592L。<br />4、字符型：'A' ，数据类型为char。L'A' 为宽字符型，数据类型wchar_t。<br />5、字符串型："hello,world"，数据类型为const常量数组。特别需要注意的是：编译后的字符串长度=编译前的字符串长度+编译器为表示字串结束而自动为其在最后位加入的NULL（即'\0'），这在字符型里是不会出现的。 L"hello,world"：宽字符串型。<br />6、转移序列： 常见的有\"（双引号）  \'（单引号） \\（反斜杠）等<img height="20" src="http://www.cppblog.com/Emoticons/QQ/laf.gif" width="20" border="0" />（自己太懒了，都不想写了）<br /><br />对于1、2有特别需要注意的地方，有符号型的只能是整型数据，不能用在浮点型上。<br />如果要让一行未结束的字串换行继续写，则可以用如下表示：<br />"hello ,my \<br /> girlfirend"<br />也就是说，要在最后一个字符后面加"\"反斜杠。 </font>
<img src ="http://www.cppblog.com/qjbest/aggbug/5859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-04-19 09:47 <a href="http://www.cppblog.com/qjbest/archive/2006/04/19/5859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)文件的输入输出函数－－超赞的内容！</title><link>http://www.cppblog.com/qjbest/archive/2006/04/14/5580.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Fri, 14 Apr 2006 13:05:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/04/14/5580.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/5580.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/04/14/5580.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/5580.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/5580.html</trackback:ping><description><![CDATA[
		<font style="BACKGROUND-COLOR: #ffffff" color="#000000">  键盘、显示器、打印机、磁盘驱动器等逻辑设备, 其输入输出都可以通过文 <br />件管理的方法来完成。而在编程时使用最多的要算是磁盘文件, 因此本节主要以 <br />磁盘文件为主, 详细介绍Turbo C2.0提供的文件操作函数, 当然这┒晕募牟? <br />作函数也适合于非磁盘文件的情况。 <br />    另外, Turbo C2.0提供了两类关于文件的函数。一类称做标准文件函数也称 <br />缓冲型文件函数, 这是ANSI标准定义的函数; 另一类叫非标准文件函数, 也称非 <br />缓冲型文件函数。这类函数最早公用于UNIX操作系统, 但现在MS-DOS3.0 以上版 <br />本的操作系统也可以使用。下面分别进行介绍。 <br />  <br />    1.2.1  标准文件函数 <br />    标准文件函数主要包括文件的打开、关闭、读和写等函数。不象BASIC 、 <br />FORTRAN语方有顺序文件和随机文件之分,   在打开时就应按不同的方式确定。 <br />Turbo C2.0并不区分这两种文件, 但提供了两组函数, 即顺序读写函数和随机读 <br />写函数。 <br />    一、文件的打开和关闭 <br />    任何一个文件在使用之前和使用之后, 必须要进行打开和关闭, 这是因为操 <br />作系统对于同时打开的文件数目是有限制的, DOS操作系统中,    可以在DEVICE <br />.SYS中定义允许同时打开的文件数n(用files=n定义)。其中n 为可同时打开的文 <br />件数, 一般n&lt;=20。因此在使用文件前应打开文件, 才可对其中的信息进行存取。 <br />用完之后需要关闭, 否则将会出现一些意想不到的错误。Turbo C2.0提供了打开 <br />和关闭文件的函数。 <br /></font>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    1. fopen()函数 <br />    fopen函数用于打开文件, 其调用格式为: <br />     FILE *fopen(char *filename, *type); <br />    在介绍这个函数之;前, 先了解一下下面的知识。 <br />    (1) 流(stream)和文件(file) <br />    流和文件 在Turbo C2.0中是有区别的, Turbo C2.0 为编程者和被访问的设 <br />备之间提供了一层抽象的东西, 称之为"流", 而将具体的实际设备叫做文件。 <br />流是一个逻辑设备, 具有相同的行为。因此, 用来进行磁盘文件写的函数也同样 <br />可以用来进行打印机的写入。在Turbo C2.0中有两种性质的流:   文字流( text <br />stream)和二进制(binary stream)。对磁盘来说就是文本文件和二进制文件。本 <br />软件为了便于让读者易理解Turbo C2.0语言而没有对流和文件作特别区分。 <br />    (2) 文件指针FILE <br />    实际上FILE是一个新的数据类型。它是Turbo C2.0的基本数据类型的集合, <br />称之为结构指针。有关结构的概念将在第四节中详细介绍, 这里只要将FILE理解 <br />为一个包括了文件管理有关信息的数据结构, 即在打开文件时必须先定义一个文 <br />件指针。 <br />    (3) 以后介绍的函数调用格式将直接写出形式参数的数据类型和函数返回值 <br />的数据类型。例如: 上面打开文件的函数, 返回一个文件指针, 其中形式参数有 <br />两个, 均为字符型变量(字符串数组或字符串指针)。本软件不再对函数的调用格 <br />式作详细说明。 <br />    现在再来看打开文件函数的用法。 <br />    fopen()函数中第一个形式参数表示文件名, 可以包含路径和文件名两部分。 <br />如: <br />     "B:TEST.DAT" <br />     "C:\\TC\\TEST.DAT" <br />    如果将路径写成"C:\TC\TEST.DAT"是不正确的, 这一点要特别注意。 <br />    第二个形式参数表示打开文件的类型。关于文件类型的规定参见下表。 <br />                       表  文件操作类型 <br />    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <br />          字符                含义 <br />    ──────────────────────────── <br />           "r"           打开文字文件只读 <br />           "w"           创建文字文件只写 <br />           "a"           增补, 如果文件不存在则创建一个 <br />           "r+"          打开一个文字文件读/写 <br />           "w+"          创建一个文字文件读/写 <br />           "a+"          打开或创建一个文件增补 <br />           "b"           二进制文件(可以和上面每一项合用) <br />           "t"           文这文件(默认项) <br />    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <br />    如果要打开一个CCDOS子目录中, 文件名为CLIB的二进制文件, 可写成: <br />     fopen("c:\\ccdos\\clib", "rb"); <br />    如果成功的打开一个文件, fopen()函数返回文件指针,   否则返回空指针 <br />(NULL)。由此可判断文件打开是否成功。 <br />    2. fclose()函数 <br />    fclose()函数用来关闭一个由fopen()函数打开的文件 , 其调用格式为: <br />      int fclose(FILE *stream); <br />    该函数返回一个整型数。当文件关闭成功时, 返回0,　否则返回一个非零值。 <br />可以根据函数的返回值判断文件是否关闭成功。 <br />    例10: <br />     #iclude&lt;stdio.h&gt; <br />     main() <br />     { <br />          FILE *fp;                /*定义一个文件指针*/ <br />          int i; <br />          fp=fopen("CLIB", "rb");  /*打开当前目录名为CLIB的文件只读*/ <br />          if(fp==NULL)             /*判断文件是否打开成功*/ <br />             puts("File open error");/*提示打开不成功*/ <br />          i=fclose(fp);            /*关闭打开的文件*/ <br />          if(i==0)                 /*判断文件是否关闭成功*/ <br />            printf("O,K");         /*提示关闭成功*/ <br />          else <br />            puts("File close error");/*提示关闭不成功*/ <br />     } <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    二、有关文件操作的函数 <br />    本节所讲的文件读写函数均是指顺序读写, 即读写了一条信息后, 指针自动 <br />加1。下面分别介绍写操作函数和读操作函数。 <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    1. 文件的顺序写函数 <br />    fprintf()、fputs()和fputc()函数 <br />    函数fprintf()、fputs()和fputc()均为文件的顺序写操作函数,  其调用格 <br />式如下: <br />    int fprintf(FILE *stream, char *format, &lt;variable-list&gt;); <br />    int fputs(char *string, FILE *steam); <br />    int fputc(int ch, FILE *steam); <br />    上述三个函数的返回值均为整型量。fprintf() 函数的返回值为实际写入文 <br />件中的字罕个数(字节数)。如果写错误, 则返回一个负数, fputs()函数返回0时 <br />表明将string指针所指的字符串写入文件中的操作成功, 返回非0时,  表明写操 <br />作失败。fputc()函数返回一个向文件所写字符的值, 此时写操作成功,  否则返 <br />回EOF(文件结束结束其值为-1, 在stdio.h中定义)表示写操作错误。 <br />     fprintf( ) 函数中格式化的规定与printf( ) 函数相同,   所不同的只是 <br />fprintf()函数是向文件中写入。而printf()是向屏幕输出。 <br />    下面介绍一个例子, 运行后产后一个test.dat的文件。 <br />    例11: <br />     #include&lt;stdio.h&gt; <br />     main() <br />     { <br />          char *s="That's good news");  /*定义字符串指针并初始化*/ <br />          int i=617;                    /*定义整型变量并初始化*/ <br />          FILE *fp;                     /*定义文件指针*/ <br />          fp=fopne("test.dat", "w");    /*建立一个文字文件只写*/ <br />          fputs("Your score of TOEFLis", fp);/*向所建文件写入一串字符*/ <br />          fputc(':', fp);               /*向所建文件写冒号:*/ <br />          fprintf(fp, "%d\n", i);       /*向所建文件写一整型数*/ <br />          fprintf(fp, "%s", s);         /*向所建文件写一字符串*/ <br />          fclose(fp);                   /*关闭文件*/ <br />     } <br />    用DOS的TYPE命令显示TEST.DAT的内容如下所示: <br />    屏幕显示 <br />      Your score of TOEFL is: 617 <br />      That's good news <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    2. 文件的顺序读操作函数 <br />    fscanf()、fgets()和fgetc()函数 <br />    函数fscanf()、fgets()和fgetc()均为文件的顺序读操作函数, 其调用格式 <br />如下: <br />     int fscanf(FILE *stream, char *format, &lt;address-list&gt;); <br />     char fgets(char *string, int n, FILE *steam); <br />     int fgetc(FILE *steam); <br />    fscanf()函数的用法与scanf()函数相似,   只是它是从文件中读到信息。 <br />fscanf()函数的返回值为EOF(即-1), 表明读错误, 否则读数据成功。fgets()函 <br />数从文件中读取至多n-1个字符(n用来指定字符数), 并把它们放入string指向的 <br />字符串中, 在读入之后自动向字符串未尾加一个空字符, 读成功返回string指针, <br />失败返回一个空指针。fgetc()函数返回文件当前位置的一个字符,  读错误时返 <br />回EOF。 <br />    下面程序读取例11产生的test.dat文件, 并将读出的结果显示在屏幕上。 <br />    例12 <br />     #include&lt;stdio.h&gt; <br />     main() <br />     { <br />          char *s, m[20]; <br />          int i; <br />          FILE  *fp; <br />          fp=fopen("test.dat", "r");    /*打开文字文件只读*/ <br />          fgets(s, 24, fp);             /*从文件中读取23个字符*/ <br />          printf("%s", s);              /*输出所读的字符串*/ <br />          fscanf(fp, "%d", &amp;i);         /*读取整型数*/ <br />          printf("%d", i);              /*输出所读整型数*/ <br />          putchar(fgetc(fp));           /*读取一个字符同时输出*/ <br />          fgets(m, 17, fp);             /*读取16个字符*/ <br />          puts(m);                      /*输出所读字符串*/ <br />          fclose(fp);                   /*关闭文件*/ <br />          getch();                      /*等待任一键*/ <br />     } <br />    运行后屏幕显示: <br />    Your score of TOEFL is: 617 <br />    That's good news <br />    如果将上例中fscanf(fp, "%d", &amp;i)改为fscanf(fp, "%s", m),  再将其后 <br />的输出语句改为printf("%s", m), 则可得出同样的结果。由此可见Turbo C2. 0 <br />中只要是读文字文件, 则不论是字符还是数字都将按其ASCII值处理。 另外还要 <br />说明的一点就是fscanf()函数读到空白符时, 便自动结束, 在使用时要特别注意。 <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    3. 文件的随机读写 <br />    有时用户想直接读取文件中间某处的信息, 若用文件的顺序读写必须从文件 <br />头开始直到要求的文件位置再读, 这显然不方便。Turbo C2.0提供了一组文件的 <br />随机读写函数, 即可以将文件位置指针定位在所要求读写的地方直接读写。 <br />    文件的随机读写函数如下: <br />    int fseek (FILE *stream, long offset, int fromwhere); <br />    int fread(void *buf, int size, int count, FILE *stream); <br />    int fwrite(void *buf, int size, int count, FILE *stream); <br />    long ftell(FILE *stream); <br />    fseek()函数的作用是将文件的位置指针设置到从fromwhere开始的第offset <br />字节的位置上, 其中fromwhere是下列几个宏定义之一: <br />    文件位置指针起始计算位置fromwhere <br />━━━━━━━━━━━━━━━━━━━━━━━━━━━ <br />    符号常数        数值           含义 <br />─────────────────────────── <br />    SEEK_SET          0        从文件开头 <br />    SEEK_CUR          1        从文件指针的现行位置 <br />    SEEK_END          2        从文件末尾 <br />━━━━━━━━━━━━━━━━━━━━━━━━━━━ <br />    offset是指文件位置指针从指定开始位置(fromwhere指出的位置)跳过的字 <br />节数。它是一个长整型量, 以支持大于64K字节的文件。fseek()函数一般用于对 <br />二进制文件进行操作。 <br />    当fseek()函数返回0时表明操作成功, 返回非0表示失败。 <br />    下面程序从二进制文件test_b.dat中读取第8个字节。 <br />    例13: <br />     #include&lt;stdio.h&gt; <br />     main() <br />     { <br />          FILE *fp; <br />          if((fp=fopen("test_b.dat", "rb"))==NULL) <br />            { <br />              printf("Can't open file"); <br />              exit(1); <br />            } <br />          fseek(fp, 8. 1, SEEK_SET); <br />          fgetc(fp); <br />          fclose(fp); <br />     } <br />    fread()函数是从文件中读count个字段, 每个字段长度为size个字节, 并把 <br />它们存放到buf指针所指的缓冲器中。 <br />    fwrite()函数是把buf指针所指的缓冲器中, 长度为size个字节的count个字 <br />段写到stream指向的文件中去。 <br />    随着读和写字节数的增大, 文件位置指示器也增大, 读多少个字节, 文件位 <br />置指示器相应也跳过多少个字节。读写完毕函数返回所读和所写的字段个数。 <br />    ftell()函数返回文件位置指示器的当前值,  这个值是指示器从文件头开始 <br />算起的字节数, 返回的数为长整型数, 当返回-1时, 表明出现错误。 <br />    下面程序把一个浮点数组以二进制方式写入文件test_b.dat中。 <br />    例14: <br />     #include &lt;stdio.h&gt; <br />     main() <br />     { <br />          float f[6]={3.2, -4.34, 25.04, 0.1, 50.56, 80.5}; <br />                         /*定义浮点数组并初始化*/ <br />          int i; <br />          FILE *fp; <br />          fp=fopen("test_b.dat", "wb"); /*创建一个二进制文件只写*/ <br />          fwrite(f, sizeof(float), 6, fp);/*将6个浮点数写入文件中*/ <br />          fclose(fp);                   /*关闭文件*/ <br />     } <br />    下面例子从test_b.dat文件中读100个整型数, 并把它们放到dat数组中。 <br />    例15: <br />     #include &lt;stdio.h&gt; <br />     main() <br />     { <br />          FILE *fp; <br />          int dat[100]; <br />          fp=fopen("test_b.dat", "rb");/*打开一个二进制文件只读*/ <br />          if(fread(dat, sizeof(int), 100, fp)!=100) <br />                                        /*判断是否读了100个数*/ <br />            { <br />               if(feof(fp)) <br />                 printf("End of file"); /*不到100个数文件结束*/ <br />               else <br />                 printf("Read error");  /*读数错误*/ <br />          fclose(fp);                   /*关闭文件*/ <br />     } <br />    注意: <br />    当用标准文件函数对文件进行读写操作时, 首先将所读写的内容放进缓冲区, <br />即写函数只对输出缓冲区进行操作, 读函数只对输入缓冲区进行操作。例如向一 <br />个文件写入内容, 所写的内容将首先放在输出缓冲区中, 直到输出缓冲区存满或 <br />使用fclose()函数关闭文件时, 缓冲区的内容才会写入文件中。若无fclose() <br />函数, 则不会向文件中存入所写的内容或写入的文件内容不全。有一个对缓冲区 <br />进行刷新的函数, 即fflush(), 其调用格式为: <br />    int fflush(FILE *stream); <br />    该函数将输出缓冲区的内容实际写入文件中, 而将输入缓冲区的内容清除掉。 <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    4. feof()和rewind()函数 <br />    这两个函数的调用格式为: <br />     int feof(FILE *stream); <br />     int rewind(FILE *stream); <br />    feof()函数检测文件位置指示器是否到达了文件结尾,  若是则返回一个非0 <br />值, 否则返回0。这个函数对二进制文件操作特别有用, 因为二进制文件中,  文 <br />件结尾标志EOF也是一个合法的二进制数,  只简单的检查读入字符的值来判断文 <br />件是否结束是不行的。如果那样的话, 可能会造成文件未结尾而被认为结尾, 所 <br />以就必须有feof()函数。 <br />    下面的这条语句是常用的判断文件是否结束的方法。 <br />     while(!feof(fp)) <br />        fgetc(fp); <br />    while为循环语句, 将在下面介绍。 <br />    rewind()函数用于把文件位置指示器移到文件的起点处, 成功时返回0,  否 <br />则, 返回非0值。 <br />  <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    1.2.2  非标准文件函数 <br />    这类函数最早用于UNIX操作系统, ANSI标准未定义,   但有时也经常用到, <br />DOS 3.0以上版本支持这些函数。它们的头文件为io.h。 <br />    一、文件的打开和关闭 <br />    1. open()函数 <br />    open()函数的作用是打开文件, 其调用格式为: <br />     int open(char *filename, int access); <br />    该函数表示按access的要求打开名为filename的文件, 返回值为文件描述字, <br />其中access有两部分内容: 基本模式和修饰符, 两者用" "("或")方式连接。修 <br />饰符可以有多个, 但基本模式只能有一个。access的规定如表3-2。 <br />               表 access的规定 <br />━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <br />基本模式    含义    修饰符         含  义 <br />──────────────────────────── <br />O_RDONLY    只读   O_APPEND   文件指针指向末尾 <br />O_WRONLY    只写   O_CREAT    文件不存在时创建文件, <br />                              属性按基本模式属性 <br />O_RDWR      读写   O_TRUNC    若文件存在, 将其长度 <br />                              缩为0, 属性不变 <br />                   O_BINARY   打开一个二进制文件 <br />                   O_TEXT     打开一个文字文件 <br />━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <br />    open()函数打开成功, 返回值就是文件描述字的值(非负值), 否则返回-1。 <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    2. close()函数 <br />    close()函数的作用是关闭由open()函数打开的文件, 其调用格式为: <br />     int close(int handle); <br />    该函数关闭文件描述字handle相连的文件。 <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    二、读写函数 <br />    1. read()函数 <br />    read()函数的调用格式为: <br />     int read(int handle, void *buf, int count); <br />    read()函数从handle(文件描述字)相连的文件中, 读取count个字节放到buf <br />所指的缓冲区中, 返回值为实际所读字节数, 返回-1表示出错。返回0 表示文件 <br />结束。 <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    2. write()函数 <br />    write()函数的调用格式为: <br />     int write(int handle, void *buf, int count); <br />    write()函数把count个字节从buf指向的缓冲区写入与handle相连的文件中, <br />返回值为实际写入的字节数。 <br />  <br />    三、随机定位函数 <br />    1. lseek()函数 <br />    lseek()函数的调用格式为: <br />     int lseek(int handle, long offset, int fromwhere); <br />    该函数对与handle相连的文件位置指针进行定位, 功能和用法与fseek() 函 <br />数相同。 <br /></font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">    2. tell()函数 <br />    tell()函数的调用格式为: <br />     long tell(int handle); <br />    该函数返回与handle相连的文件现生位置指针, 功能和用法与ftell()相同。 </font>
		</p>
<img src ="http://www.cppblog.com/qjbest/aggbug/5580.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-04-14 21:05 <a href="http://www.cppblog.com/qjbest/archive/2006/04/14/5580.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>memset ,memcpy 和strcpy 的根本区别?</title><link>http://www.cppblog.com/qjbest/archive/2006/04/14/5549.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Fri, 14 Apr 2006 08:55:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/04/14/5549.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/5549.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/04/14/5549.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/5549.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/5549.html</trackback:ping><description><![CDATA[
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">这次在工作上分别遇到过strcpy、memset、memcpy，也在网络上看到过一些关于三者区别的文章，罗列大概内容如下:<br />strcpy()来自C语言，在C++里得以保留。首先，要指明的是，C++里strcpy()里接受的参数是C-串，并非string,更不可能是其他类型的数据。它表示一个字串的内容拷贝到另一个字串。拷贝会在源字串里第一个'\0'时停止拷贝. </font>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">strcpy(目标字串，源字串);<br /></font>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">ex:<br />char *temp1,*temp2="test";<br />strcpy(temp1,temp2);<br /><br />memset()主要用于对一个内存区域初始化。一般用在字符数组上，至少我现在工作上遇到的多为这样的情况。 </font>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">memset(目标内存空间，拷贝内容，限制)；<br /></font>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">ex:<br />char temp[30];<br />memset(temp,'\0',sizeof(temp));<br />正如上面所见，char temp[30]只是分配了一定的内存空间给该字符数组，但并未初始化该内存空间，即数组。所以，需要使用memset()来进行初始化。<br /><br />memcpy() 除了和strcpy()一样能拷贝字串外，还可以拷贝其他任何类型的数据. <br /></font>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">ex:<br />int a[3],b[4];<br />b[4]={0,1,2,3};<br />memcpy(a,b,sizeof(a)); //若为sizeof(b),则会造成数组a[]内存外溢<br /><br />＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝<br />如下内容为网络“原版”内容<br /><strong><font size="5">Memset<span style="mso-spacerun: yes">  </span></font></strong><span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">用来对一段内存空间全部设置为某个字符，一般用在对定义的字符串进行初始化为</span><span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">‘ ’</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">或</span><span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">‘\<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /?><st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="’" w:st="on">0’</st1:chmetcnv></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">；</span><span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 27pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd; mso-char-indent-count: 2.25" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">例</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">:char a[100];memset(a, '\0', sizeof(a));<o:p></o:p></span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<span style="mso-spacerun: yes"> </span>
										<span style="mso-spacerun: yes">    </span>memset</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">可以方便的清空一个结构类型的变量或数组。</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<o:p>
										</o:p>
								</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-char-indent-count: 2.0" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">如：</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<o:p>
										</o:p>
								</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 53.75pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 5.12gd" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">struct sample_struct<br />{<br /> char   csName[16];<br /> int    iSeq;<br /> int    iType;<br />};<o:p></o:p></span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">对于变量</span>
						</font>
				</font>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
						<br />
						<font style="BACKGROUND-COLOR: #ffffff">
								<font color="#000000">struct sample_strcut  stTest; <o:p></o:p></font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">一般情况下，清空</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">stTest</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">的方法：</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<o:p>
										</o:p>
								</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
						<font style="BACKGROUND-COLOR: #ffffff">
								<font color="#000000">stTest.csName[0]='\0';<br />stTest.iSeq=0;<br />stTest.iType=0; <o:p></o:p></font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">用</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">memset</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">就非常方便：</span>
						</font>
				</font>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
						<br />
						<font style="BACKGROUND-COLOR: #ffffff">
								<font color="#000000">memset(&amp;stTest,0,sizeof(struct sample_struct));<o:p></o:p></font>
						</font>
				</span>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">如果是数组：</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<o:p>
										</o:p>
								</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<span style="mso-spacerun: yes"> </span>struct sample_struct   TEST[10];<br /></span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">则</span>
						</font>
				</font>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
						<br />
						<font style="BACKGROUND-COLOR: #ffffff">
								<font color="#000000">memset(TEST,0,sizeof(struct sample_struct)*10);<o:p></o:p></font>
						</font>
				</span>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 35pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd; mso-char-indent-count: 2.49" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<b style="mso-bidi-font-weight: normal">
										<span lang="EN-US" style="FONT-SIZE: 14pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">memcpy<span style="mso-spacerun: yes">  </span></span>
								</b>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">用来做内存拷贝，你可以拿它拷贝任何数据类型的对象，可以指定拷贝的数据长度。</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<o:p>
										</o:p>
								</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 23.9pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd; mso-char-indent-count: 1.99" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">例：</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">char a[100],b[50]; memcpy(b, a, sizeof(b));</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">注意如用</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">sizeof(a)</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">，会造成</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">b</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">的内存地址溢出。</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<o:p>
										</o:p>
								</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 56.2pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-char-indent-count: 4.0" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<b style="mso-bidi-font-weight: normal">
										<span lang="EN-US" style="FONT-SIZE: 14pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">Strcpy<span style="mso-spacerun: yes">   </span></span>
								</b>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">就只能拷贝字符串了，它遇到</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">'\0'</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">就结束拷贝。</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<o:p>
										</o:p>
								</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 33pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd; mso-char-indent-count: 2.75" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">例：</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">char a[100],b[50];strcpy(a,b);</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">如用</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">strcpy(b,a)</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">，要注意</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">a</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">中的字符串长度（第一个</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">‘\<st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="’" w:st="on">0’</st1:chmetcnv></span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">之前）是否超过</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">50</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">位，如超过，则会造成</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">b</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'">的内存地址溢出。</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt; mso-fareast-font-family: 仿宋_GB2312">
										<o:p>
										</o:p>
								</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 36pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd; mso-char-indent-count: 3.0" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">str</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">也可以用用个参数的</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">strncpy(a,b,n)<o:p></o:p></span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">========================================================<o:p></o:p></span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">memset</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">主要应用是初始化某个内存空间。</span>
						</font>
				</font>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">
						<br />
						<font style="BACKGROUND-COLOR: #ffffff" color="#000000">memcpy</font>
				</span>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">是用于</span>
						<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">copy</span>
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">源空间的数据到目的空间中。</span>
				</font>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">
						<br />
						<font style="BACKGROUND-COLOR: #ffffff" color="#000000">strcpy</font>
				</span>
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">用于字符串</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">copy,</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">遇到</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">‘\<st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="’" w:st="on">0’</st1:chmetcnv></span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">，将结束。</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">
										<o:p>
										</o:p>
								</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-para-margin-left: 2.0gd" align="left">
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">如果你理解了这些，你应该知道他们的区别：例如你初始化某块空间的时候，用到</span>
								<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">memcpy</span>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">，那么应该怎么写，是不是显得很笨。</span>
						</font>
				</font>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">
						<br />
						<font style="BACKGROUND-COLOR: #ffffff">
								<font color="#000000">
										<span style="mso-spacerun: yes">  </span>int  m[100]<br />-&gt;memset((void*)m,0x00,sizeof(int)*100);//Ok</font>
						</font>
				</span>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 仿宋_GB2312; mso-ascii-font-family: 'Times New Roman'">！</span>
				</font>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 仿宋_GB2312">
						<br />
						<font style="BACKGROUND-COLOR: #ffffff">
								<font color="#000000">…memcpy((void*)m,"\0\0\0\0....",sizeof(int)*100);//it’s wrong.<o:p></o:p></font>
						</font>
				</span>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">
				</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">
				</font>
		</p>
		<style><![CDATA[
TD { FONT-SIZE: 12px }
.commentTextBox { FONT-SIZE: 12px }
]]&gt;</style>
		<!--Beging Temp Save-->
		<style><![CDATA[userData { BEHAVIOR: url(#default#userdata) }
	]]&gt;</style>
		<br />
		<br />
<img src ="http://www.cppblog.com/qjbest/aggbug/5549.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-04-14 16:55 <a href="http://www.cppblog.com/qjbest/archive/2006/04/14/5549.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内存分配：二</title><link>http://www.cppblog.com/qjbest/archive/2006/03/30/4834.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Thu, 30 Mar 2006 14:36:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/03/30/4834.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/4834.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/03/30/4834.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/4834.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/4834.html</trackback:ping><description><![CDATA[
		<font style="BACKGROUND-COLOR: #ffffff" color="#000000">来自CSDN的问题 <br /><br /><br />举个例子<br />=======================<br />Name *name1=new Name[4];<br />Name *name2=new Name();<br />假设Name类有一方法void show();<br />======================<br />我一直以为由于都是由new 构成的，所以，第一个name 和第二个name都是指针。今天刚好用第一个类对象的方法:name1[0]-&gt;show(); 编译器就报错，当我换成name1[0].show();时候，就能正确运行了<br />想请问下大家，既然动态内存是由new分配的，那name1应该也是指针啊，因为name1前有个*（即*name1），并且又是又new分配空间的。但是它调用方法时候却又只是表现出只是个Name[]的数组元素。<br />有朋友能告诉下我到底什么样的new 才算真正的动态内存分配，才算指针吗？？？<br />谢谢！！！<br /><br />以下为解答内容，各段为一个解答。<br /></font>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">name1是数组指针,name1[0]就是数组中的值了. </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">你可以直接用name1-&gt;来调用.<br />name1就是指针,它和name2并没有什么不同,同样你也可以用name2[0].来调用函数. </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">Name[0]指的是数组中的第一个元素，不是个指针~~~~~~~<br />在定义Name *name1=new Name[4]时name1确实是个指针，他指向了数组Name[] 而用name1-&gt;show()应该是正确的，这样的话就相当于将函数show的首地址给了name1， Name *name2=new Name();表示开辟了一个函数Name的内存地址，name2表示了这个函数的首地址 </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">我一直以为由于都是由new 构成的，所以，第一个name 和第二个name都是指针。<br />－－－－－－－－－－－－－－－－－－－－<br />正是如此！<br />都是指针，但是,name1[0]就是值了 ... 同样，name2[0]也是一个值，楼主自己试试就知道了 .. </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">Name *name2=new Name();<br />//首先构造Name()默认构造函数对象然后new出对象拷贝构造出来<br />Name *name2=new Name[3]；<br />//是先分配空间然后构造对象 </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">Name1[0]是个对象（如果你拷贝了其他对象给他，当然你是要拷给他才能用）<br />Name1,Name2都是指针 </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">和<br />int* p1 = new int[4];<br />int* p2 = new int; <br />一样 </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">指针是这样用滴~~~<br />for(int i = 0;i &lt; 4; i++) {<br />(name1+i)-&gt;show();<br />} </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">name2 是构造单个对象指针<br />name1是构造四个对象的指针。具体到每一个对象就不是指针，而是数组 </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">
						<font color="#000000">//#include<stdio><br />class A<br />{<br />public:<br />int a;<br />int&amp; get(){return a;};<br />void set(int i){ a=i;};<br />A()<br />{<br />a=1;<br />};<br />};<br />int main()<br />{<br />//<br />A* a1=new A();<br />A* a2=new A();<br />A* pA[2]={a1,a2};<br />int b=pA[0]-&gt;get(); <br />//<br />int pI[2]={1,2};<br />int sum=pI[1]+pI[2];<br />//<br />A* pB=new A[2];<br />pB[1].set(1);<br />int x=pB[1].a;<br />return 0;<br /><br />} </stdio></font>
				</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">是指针,但是是数组的指针<br />比如这样<br />name *p = new name[4];<br />p-&gt;show()相当于p[0].show();<br />通俗的说,你在定义的时候的那个name*中的*号指的是对象数组,并不是对象指针 </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" color="#000000">name1[0]-&gt;show();里的name1[0]改成name1就OK了。楼主可以补一补数组的有关知识。<br /><br />========================================================<br />copy了这篇文章，其实我只想说下我的看法。<br />Name *p=new Name[4];<br />p-&gt;show();      //正确<br />p[0].show();    //正确<br />第一个可以这样理解：指针P指向数组首地址，其实就是P指向Name[4]数组中第一个元素的地址，所以，如果使用p-&gt;show(),则意思其实就是让数组中第一个元素，即第一个对象name调用自身show(),再说白点，就是name.show()；<br />第2个可以这样理解：p[0]可以理解成P指向数组中第[0]个元素，所以就有了p[0]，所以更会有了p[0].show();<br /></font>
		</p>
<img src ="http://www.cppblog.com/qjbest/aggbug/4834.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-03-30 22:36 <a href="http://www.cppblog.com/qjbest/archive/2006/03/30/4834.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内存分配:一</title><link>http://www.cppblog.com/qjbest/archive/2006/03/30/4832.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Thu, 30 Mar 2006 14:02:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/03/30/4832.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/4832.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/03/30/4832.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/4832.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/4832.html</trackback:ping><description><![CDATA[
		<font style="BACKGROUND-COLOR: #ffffff" color="#000000">C++内存分配有两种：静态分配和动态分配。<br />举个简单的例子如下<br />int a=1024;<br />对象a的内存空间就是静态分配的，是在编译器对程序进行编译时分配的，当然对它空间的回收也是编译器自动完成的，开发者只需要知道这个事实就好，不需要我们显示的回收。<br /><br />int *p=new int(1024);<br />先来说下这句程序的意思：现在分配一个新的空间给一个没有名字的Int型对象，并且为这个空间赋予初始化数值为1024。由于该Int型对象没有名字，所以如果需要访问它的话，就需要使用指针来指向该对象所在的内存地址。注意，new int(1024)这个表达式返回的是该没有名字的对象的内存地址。<br /><br />int *p=new int[1024];<br />这个和上面的就有点不一样了。可以看的出，这个是动态分配数组，这个P叫数组指针。意思是什么呢：现在分配新的空间给数组里面的1024个元素，但是这1024个元素我们没有办法显式的为它们分配初始化数值。并且这个指针只指向这个数组第一个元素的地址。如果想要访问其他数组元素，可以用*p++来实现。<br /><br />既然上面两个new 都是动态分配的，那么自然需要手动删除所分配的空间了。<br />第一个是 delete p;<br />第二个是 delete[] p;<br /></font>
<img src ="http://www.cppblog.com/qjbest/aggbug/4832.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-03-30 22:02 <a href="http://www.cppblog.com/qjbest/archive/2006/03/30/4832.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不能松懈，努力看C++ Primer</title><link>http://www.cppblog.com/qjbest/archive/2006/03/05/3756.html</link><dc:creator>Q</dc:creator><author>Q</author><pubDate>Sun, 05 Mar 2006 09:42:00 GMT</pubDate><guid>http://www.cppblog.com/qjbest/archive/2006/03/05/3756.html</guid><wfw:comment>http://www.cppblog.com/qjbest/comments/3756.html</wfw:comment><comments>http://www.cppblog.com/qjbest/archive/2006/03/05/3756.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qjbest/comments/commentRss/3756.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qjbest/services/trackbacks/3756.html</trackback:ping><description><![CDATA[
		<font style="BACKGROUND-COLOR: #ffffff" color="#000000">可能是我眼拙，普遍受欢迎的C++ 编程思想（II）我居然看着觉得很普通，写的思路是有点新鲜，但是所叙述的内容却有点泛泛而谈，让人不能完全过瘾的感觉。有的文字居然还不通，让人看了觉得有点莫名其妙。这可能就是大家普遍认为的中文版不好的地方吧。<img height="20" src="http://www.cppblog.com/Emoticons/hitwall.gif" width="25" border="0" />于是转向去看C++ Primer（III）这本大部头，感觉写的很不错，虽然提前讲解了OOP方面的内容，或许会让很多新手觉得一头雾水，但是确实是讲的都是精华的东西（听说有些人因为看了C++ Primer后居然投奔JAVA去了，因为大多觉得自己连Primer这样的书都看的不懂<img height="20" src="http://www.cppblog.com/Emoticons/QQ/02.gif" width="20" border="0" />）。个人感觉钱能老师的C++程序设计（II）写的so good，虽然有些方面没有编程思想和Primer写的详细，甚至没有涉及，但是确实为一本入门级好书。还有一本就是SAMS的21天学通C++（V），可以说是对钱能老师书内容的相对部分的补充，大家可以去看下  ：P   希望自己能努力看完网络上提到的很多经典书籍，提高自己在C++思想方面的认识，早日进入C++中级者行列（虽然本人现在还是新手<img height="20" src="http://www.cppblog.com/Emoticons/QQ/14.gif" width="20" border="0" />）。<br />+U！</font>
<img src ="http://www.cppblog.com/qjbest/aggbug/3756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qjbest/" target="_blank">Q</a> 2006-03-05 17:42 <a href="http://www.cppblog.com/qjbest/archive/2006/03/05/3756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>