﻿<?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++博客-Oo缘来是你oO</title><link>http://www.cppblog.com/majianan/</link><description>&lt;br&gt;
&lt;br&gt;
人本是人，不必刻意去做人；世本是世，无须精心去处世；自然的才是快乐的。
&lt;br&gt;&lt;br&gt;
</description><language>zh-cn</language><lastBuildDate>Wed, 15 Apr 2026 06:17:48 GMT</lastBuildDate><pubDate>Wed, 15 Apr 2026 06:17:48 GMT</pubDate><ttl>60</ttl><item><title>垃圾收集趣史（转载）</title><link>http://www.cppblog.com/majianan/archive/2006/11/04/14666.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Sat, 04 Nov 2006 08:19:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/11/04/14666.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/14666.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/11/04/14666.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/14666.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/14666.html</trackback:ping><description><![CDATA[<p><font face=Verdana size=2><font color=#000080 size=4>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 垃圾收集趣史（转）</font> <br></font></p>
<p><font face=Verdana size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 王咏刚，2003年12月<br><br></font><br>写作本文的初衷是想和大家分享垃圾收集（ Garbage Collection ）技术简单而有趣的发展史。动笔之前，我站在窗边，望了望正在小区里装运垃圾的清洁车。和生活中环卫工人们清运垃圾的工作相似，软件开发里的垃圾收集其实就是一种自动打扫和清除内存垃圾的技术，它可以有效防范动态内存分配中可能发生的两个危险：因内存垃圾过多而引发的内存耗尽（这和生活垃圾堵塞排污管道的危险并没有什么本质的不同），以及不恰当的内存释放所造成的内存非法引用（这类似于我们在生活中买到了一瓶已经过期三年的牛奶）。 </p>
<p><font face=Verdana size=2>据历史学家们介绍，四千多年前的古埃及人已经在城市里建设了完善的排污和垃圾清运设施，一千多年前的中国人更是修筑了当时世界上保洁能力最强的都市 ——长安。今天，当我们在软件开发中体验自动垃圾收集的便捷与舒适时，我们至少应当知道，这种拒绝杂乱、追求整洁的&#8220;垃圾收集&#8221;精神其实是人类自古以来就已经具备了的。 </font></p>
<div class=section id=S01><a name=S01></a>
<h3>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>拓荒时代</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>国内的程序员大多是在 Java 语言中第一次感受到垃圾收集技术的巨大魅力的，许多人也因此把 Java 和垃圾收集看成了密不可分的整体。但事实上，垃圾收集技术早在 Java 语言问世前 30 多年就已经发展和成熟起来了， Java 语言所做的不过是把这项神奇的技术带到了广大程序员身边而已。 </font></p>
<p><font face=Verdana size=2>如果一定要为垃圾收集技术找一个孪生兄弟，那么， Lisp 语言才是当之无愧的人选。 1960 年前后诞生于 MIT 的 Lisp 语言是第一种高度依赖于动态内存分配技术的语言： Lisp 中几乎所有数据都以&#8220;表&#8221;的形式出现，而&#8220;表&#8221;所占用的空间则是在堆中动态分配得到的。 Lisp 语言先天就具有的动态内存管理特性要求 Lisp 语言的设计者必须解决堆中每一个内存块的自动释放问题（否则， Lisp 程序员就必然被程序中不计其数的 free 或 delete 语句淹没），这直接导致了垃圾收集技术的诞生和发展——说句题外话，上大学时，一位老师曾告诉我们， Lisp 是对现代软件开发技术贡献最大的语言。我当时对这一说法不以为然：布满了圆括号，看上去像迷宫一样的 Lisp 语言怎么能比 C 语言或 Pascal 语言更伟大呢？不过现在，当我知道垃圾收集技术、数据结构技术、人工智能技术、并行处理技术、虚拟机技术、元数据技术以及程序员们耳熟能详的许多技术都起源于 Lisp 语言时，我特别想向那位老师当面道歉，并收回我当时的幼稚想法。 </font></p>
<p><font face=Verdana size=2>知道了 Lisp 语言与垃圾收集的密切关系，我们就不难理解，为什么垃圾收集技术的两位先驱者 J. McCarthy 和 M. L. Minsky 同时也是 Lisp 语言发展史上的重要人物了。 J. McCarthy 是 Lisp 之父，他在发明 Lisp 语言的同时也第一次完整地描述了垃圾收集的算法和实现方式； M. L. Minsky 则在发展 Lisp 语言的过程中成为了今天好几种主流垃圾收集算法的奠基人——和当时不少技术大师的经历相似， J. McCarthy 和 M. L. Minsky 在许多不同的技术领域里都取得了令人艳羡的成就。也许，在 1960 年代那个软件开发史上的拓荒时代里，思维敏捷、意志坚定的研究者更容易成为无所不能的西部硬汉吧。 </font></p>
<p><font face=Verdana size=2>在了解垃圾收集算法的起源之前，有必要先回顾一下内存分配的主要方式。我们知道，大多数主流的语言或运行环境都支持三种最基本的内存分配方式，它们分别是： </font></p>
<p><font face=Verdana size=2>一、静态分配（ Static Allocation ）：静态变量和全局变量的分配形式。我们可以把静态分配的内存看成是家里的耐用家具。通常，它们无需释放和回收，因为没人会天天把大衣柜当作垃圾扔到窗外。 </font></p>
<p><font face=Verdana size=2>二、自动分配（ Automatic Allocation ）：在栈中为局部变量分配内存的方法。栈中的内存可以随着代码块退出时的出栈操作被自动释放。这类似于到家中串门的访客，天色一晚就要各回各家，除了个别不识时务者以外，我们一般没必要把客人捆在垃圾袋里扫地出门。 </font></p>
<p><font face=Verdana size=2>三、动态分配（ Dynamic Allocation ）：在堆中动态分配内存空间以存储数据的方式。堆中的内存块好像我们日常使用的餐巾纸，用过了就得扔到垃圾箱里，否则屋内就会满地狼藉。像我这样的懒人做梦都想有一台家用机器人跟在身边打扫卫生。在软件开发中，如果你懒得释放内存，那么你也需要一台类似的机器人——这其实就是一个由特定算法实现的垃圾收集器。 </font></p>
<p><font face=Verdana size=2>也就是说，下面提到的所有垃圾收集算法都是在程序运行过程中收集并清理废旧&#8220;餐巾纸&#8221;的算法，它们的操作对象既不是静态变量，也不是局部变量，而是堆中所有已分配内存块。 <br><br><br></font></p>
<div class=section id=S0101>
<h3><font face=Verdana color=#000080 size=3></font>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>引用计数（ Reference Counting ）算法</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>1960 年以前，人们为胚胎中的 Lisp 语言设计垃圾收集机制时，第一个想到的算法是引用计数算法。拿餐巾纸的例子来说，这种算法的原理大致可以描述为： </font></p>
<p><font face=Verdana size=2>午餐时，为了把脑子里突然跳出来的设计灵感记下来，我从餐巾纸袋中抽出一张餐巾纸，打算在上面画出系统架构的蓝图。按照&#8220;餐巾纸使用规约之引用计数版&#8221;的要求，画图之前，我必须先在餐巾纸的一角写上计数值 1 ，以表示我在使用这张餐巾纸。这时，如果你也想看看我画的蓝图，那你就要把餐巾纸上的计数值加 1 ，将它改为 2 ，这表明目前有 2 个人在同时使用这张餐巾纸（当然，我是不会允许你用这张餐巾纸来擦鼻涕的）。你看完后，必须把计数值减 1 ，表明你对该餐巾纸的使用已经结束。同样，当我将餐巾纸上的内容全部誊写到笔记本上之后，我也会自觉地把餐巾纸上的计数值减 1 。此时，不出意外的话，这张餐巾纸上的计数值应当是 0 ，它会被垃圾收集器——假设那是一个专门负责打扫卫生的机器人——捡起来扔到垃圾箱里，因为垃圾收集器的惟一使命就是找到所有计数值为 0 的餐巾纸并清理它们。 </font></p>
<p><font face=Verdana size=2>引用计数算法的优点和缺陷同样明显。这一算法在执行垃圾收集任务时速度较快，但算法对程序中每一次内存分配和指针操作提出了额外的要求（增加或减少内存块的引用计数）。更重要的是，引用计数算法无法正确释放循环引用的内存块，对此， D. Hillis 有一段风趣而精辟的论述： </font></p>
<p><font face=Verdana size=2>一天，一个学生走到 Moon 面前说：&#8220;我知道如何设计一个更好的垃圾收集器了。我们必须记录指向每个结点的指针数目。&#8221; Moon 耐心地给这位学生讲了下面这个故事：&#8220;一天，一个学生走到 Moon 面前说：&#8216;我知道如何设计一个更好的垃圾收集器了&#8230;&#8230;&#8217;&#8221; </font></p>
<p><font face=Verdana size=2>D. Hillis 的故事和我们小时候常说的&#8220;从前有座山，山上有个庙，庙里有个老和尚&#8221;的故事有异曲同工之妙。这说明，单是使用引用计数算法还不足以解决垃圾收集中的所有问题。正因为如此，引用计数算法也常常被研究者们排除在狭义的垃圾收集算法之外。当然，作为一种最简单、最直观的解决方案，引用计数算法本身具有其不可替代的优越性。 1980 年代前后， D. P. Friedman ， D. S. Wise ， H. G. Baker 等人对引用计数算法进行了数次改进，这些改进使得引用计数算法及其变种（如延迟计数算法等）在简单的环境下，或是在一些综合了多种算法的现代垃圾收集系统中仍然可以一展身手。 </font></p>
</div>
<div class=section id=S0102><a name=S0102></a>
<h3>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>标记－清除（ Mark-Sweep ）算法</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>第一种实用和完善的垃圾收集算法是 J. McCarthy 等人在 1960 年提出并成功地应用于 Lisp 语言的标记－清除算法。仍以餐巾纸为例，标记－清除算法的执行过程是这样的： </font></p>
<p><font face=Verdana size=2>午餐过程中，餐厅里的所有人都根据自己的需要取用餐巾纸。当垃圾收集机器人想收集废旧餐巾纸的时候，它会让所有用餐的人先停下来，然后，依次询问餐厅里的每一个人：&#8220;你正在用餐巾纸吗？你用的是哪一张餐巾纸？&#8221;机器人根据每个人的回答将人们正在使用的餐巾纸画上记号。询问过程结束后，机器人在餐厅里寻找所有散落在餐桌上且没有记号的餐巾纸（这些显然都是用过的废旧餐巾纸），把它们统统扔到垃圾箱里。 </font></p>
<p><font face=Verdana size=2>正如其名称所暗示的那样，标记－清除算法的执行过程分为&#8220;标记&#8221;和&#8220;清除&#8221;两大阶段。这种分步执行的思路奠定了现代垃圾收集算法的思想基础。与引用计数算法不同的是，标记－清除算法不需要运行环境监测每一次内存分配和指针操作，而只要在&#8220;标记&#8221;阶段中跟踪每一个指针变量的指向——用类似思路实现的垃圾收集器也常被后人统称为跟踪收集器（ Tracing Collector ） </font></p>
<p><font face=Verdana size=2>伴随着 Lisp 语言的成功，标记－清除算法也在大多数早期的 Lisp 运行环境中大放异彩。尽管最初版本的标记－清除算法在今天看来还存在效率不高（标记和清除是两个相当耗时的过程）等诸多缺陷，但在后面的讨论中，我们可以看到，几乎所有现代垃圾收集算法都是标记－清除思想的延续，仅此一点， J. McCarthy 等人在垃圾收集技术方面的贡献就丝毫不亚于他们在 Lisp 语言上的成就了。 </font></p>
</div>
<div class=section id=S0103><a name=S0103></a>
<h3>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>复制（ Copying ）算法</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>为了解决标记－清除算法在垃圾收集效率方面的缺陷， M. L. Minsky 于 1963 年发表了著名的论文&#8220;一种使用双存储区的 Lisp 语言垃圾收集器（ A LISP Garbage Collector Algorithm Using Serial Secondary Storage ）&#8221;。 M. L. Minsky 在该论文中描述的算法被人们称为复制算法，它也被 M. L. Minsky 本人成功地引入到了 Lisp 语言的一个实现版本中。 </font></p>
<p><font face=Verdana size=2>复制算法别出心裁地将堆空间一分为二，并使用简单的复制操作来完成垃圾收集工作，这个思路相当有趣。借用餐巾纸的比喻，我们可以这样理解 M. L. Minsky 的复制算法： </font></p>
<p><font face=Verdana size=2>餐厅被垃圾收集机器人分成南区和北区两个大小完全相同的部分。午餐时，所有人都先在南区用餐（因为空间有限，用餐人数自然也将减少一半），用餐时可以随意使用餐巾纸。当垃圾收集机器人认为有必要回收废旧餐巾纸时，它会要求所有用餐者以最快的速度从南区转移到北区，同时随身携带自己正在使用的餐巾纸。等所有人都转移到北区之后，垃圾收集机器人只要简单地把南区中所有散落的餐巾纸扔进垃圾箱就算完成任务了。下一次垃圾收集的工作过程也大致类似，惟一的不同只是人们的转移方向变成了从北区到南区。如此循环往复，每次垃圾收集都只需简单地转移（也就是复制）一次，垃圾收集速度无与伦比——当然，对于用餐者往返奔波于南北两区之间的辛劳，垃圾收集机器人是决不会流露出丝毫怜悯的。 </font></p>
<p><font face=Verdana size=2>M. L. Minsky 的发明绝对算得上一种奇思妙想。分区、复制的思路不仅大幅提高了垃圾收集的效率，而且也将原本繁纷复杂的内存分配算法变得前所未有地简明和扼要（既然每次内存回收都是对整个半区的回收，内存分配时也就不用考虑内存碎片等复杂情况，只要移动堆顶指针，按顺序分配内存就可以了），这简直是个奇迹！不过，任何奇迹的出现都有一定的代价，在垃圾收集技术中，复制算法提高效率的代价是人为地将可用内存缩小了一半。实话实说，这个代价未免也太高了一些。 </font></p>
<p><font face=Verdana size=2>无论优缺点如何，复制算法在实践中都获得了可以与标记－清除算法相比拟的成功。除了 M. L. Minsky 本人在 Lisp 语言中的工作以外，从 1960 年代末到 1970 年代初， R. R. Fenichel 和 J. C. Yochelson 等人也相继在 Lisp 语言的不同实现中对复制算法进行了改进， S. Arnborg 更是成功地将复制算法应用到了 Simula 语言中。 </font></p>
<p><font face=Verdana size=2>至此，垃圾收集技术的三大传统算法——引用计数算法、标记－清除算法和复制算法——都已在 1960 年前后相继问世，三种算法各有所长，也都存在致命的缺陷。从 1960 年代后期开始，研究者的主要精力逐渐转向对这三种传统算法进行改进或整合，以扬长避短，适应程序设计语言和运行环境对垃圾收集的效率和实时性所提出的更高要求。 </font></p>
</div>
</div>
<div class=section id=S02><a name=S02></a>
<h3>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>走向成熟</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>从 1970 年代开始，随着科学研究和应用实践的不断深入，人们逐渐意识到，一个理想的垃圾收集器不应在运行时导致应用程序的暂停，不应额外占用大量的内存空间和 CPU 资源，而三种传统的垃圾收集算法都无法满足这些要求。人们必须提出更新的算法或思路，以解决实践中碰到的诸多难题。当时，研究者的努力目标包括： </font></p>
<p><font face=Verdana size=2>第一，提高垃圾收集的效率。使用标记－清除算法的垃圾收集器在工作时要消耗相当多的 CPU 资源。早期的 Lisp 运行环境收集内存垃圾的时间竟占到了系统总运行时间的 40% ！——垃圾收集效率的低下直接造就了 Lisp 语言在执行速度方面的坏名声；直到今天，许多人还条件反射似地误以为所有 Lisp 程序都奇慢无比。 </font></p>
<p><font face=Verdana size=2>第二，减少垃圾收集时的内存占用。这一问题主要出现在复制算法中。尽管复制算法在效率上获得了质的突破，但牺牲一半内存空间的代价仍然是巨大的。在计算机发展的早期，在内存价格以 KB 计算的日子里，浪费客户的一半内存空间简直就是在变相敲诈或拦路打劫。 </font></p>
<p><font face=Verdana size=2>第三，寻找实时的垃圾收集算法。无论执行效率如何，三种传统的垃圾收集算法在执行垃圾收集任务时都必须打断程序的当前工作。这种因垃圾收集而造成的延时是许多程序，特别是执行关键任务的程序没有办法容忍的。如何对传统算法进行改进，以便实现一种在后台悄悄执行，不影响——或至少看上去不影响——当前进程的实时垃圾收集器，这显然是一件更具挑战性的工作。 </font></p>
<p><font face=Verdana size=2>研究者们探寻未知领域的决心和研究工作的进展速度同样令人惊奇：在 1970 年代到 1980 年代的短短十几年中，一大批在实用系统中表现优异的新算法和新思路脱颖而出。正是因为有了这些日趋成熟的垃圾收集算法，今天的我们才能在 Java 或 .NET 提供的运行环境中随心所欲地分配内存块，而不必担心空间释放时的风险。 </font></p>
<div class=section id=S0201><a name=S0201></a>
<h3>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>标记－整理（ Mark-Compact ）算法</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>标记－整理算法是标记－清除算法和复制算法的有机结合。把标记－清除算法在内存占用上的优点和复制算法在执行效率上的特长综合起来，这是所有人都希望看到的结果。不过，两种垃圾收集算法的整合并不像 1 加 1 等于 2 那样简单，我们必须引入一些全新的思路。 1970 年前后， G. L. Steele ， C. J. Cheney 和 D. S. Wise 等研究者陆续找到了正确的方向，标记－整理算法的轮廓也逐渐清晰了起来： </font></p>
<p><font face=Verdana size=2>在我们熟悉的餐厅里，这一次，垃圾收集机器人不再把餐厅分成两个南北区域了。需要执行垃圾收集任务时，机器人先执行标记－清除算法的第一个步骤，为所有使用中的餐巾纸画好标记，然后，机器人命令所有就餐者带上有标记的餐巾纸向餐厅的南面集中，同时把没有标记的废旧餐巾纸扔向餐厅北面。这样一来，机器人只消站在餐厅北面，怀抱垃圾箱，迎接扑面而来的废旧餐巾纸就行了。 </font></p>
<p><font face=Verdana size=2>实验表明，标记－整理算法的总体执行效率高于标记－清除算法，又不像复制算法那样需要牺牲一半的存储空间，这显然是一种非常理想的结果。在许多现代的垃圾收集器中，人们都使用了标记－整理算法或其改进版本。 </font></p>
</div>
<div class=section id=S0202><a name=S0202></a>
<h3>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>增量收集（ Incremental Collecting ）算法</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>对实时垃圾收集算法的研究直接导致了增量收集算法的诞生。 </font></p>
<p><font face=Verdana size=2>最初，人们关于实时垃圾收集的想法是这样的：为了进行实时的垃圾收集，可以设计一个多进程的运行环境，比如用一个进程执行垃圾收集工作，另一个进程执行程序代码。这样一来，垃圾收集工作看上去就仿佛是在后台悄悄完成的，不会打断程序代码的运行。 </font></p>
<p><font face=Verdana size=2>在收集餐巾纸的例子中，这一思路可以被理解为：垃圾收集机器人在人们用餐的同时寻找废弃的餐巾纸并将它们扔到垃圾箱里。这个看似简单的思路会在设计和实现时碰上进程间冲突的难题。比如说，如果垃圾收集进程包括标记和清除两个工作阶段，那么，垃圾收集器在第一阶段中辛辛苦苦标记出的结果很可能被另一个进程中的内存操作代码修改得面目全非，以至于第二阶段的工作没有办法开展。 </font></p>
<p><font face=Verdana size=2>M. L. Minsky 和 D. E. Knuth 对实时垃圾收集过程中的技术难点进行了早期的研究， G. L. Steele 于 1975 年发表了题为&#8220;多进程整理的垃圾收集（ Multiprocessing compactifying garbage collection ）&#8221;的论文，描述了一种被后人称为&#8220; Minsky-Knuth-Steele 算法&#8221;的实时垃圾收集算法。 E. W. Dijkstra ， L. Lamport ， R. R. Fenichel 和 J. C. Yochelson 等人也相继在此领域做出了各自的贡献。 1978 年， H. G. Baker 发表了&#8220;串行计算机上的实时表处理技术（ List Processing in Real Time on a Serial Computer ）&#8221;一文，系统阐述了多进程环境下用于垃圾收集的增量收集算法。 </font></p>
<p><font face=Verdana size=2>增量收集算法的基础仍是传统的标记－清除和复制算法。增量收集算法通过对进程间冲突的妥善处理，允许垃圾收集进程以分阶段的方式完成标记、清理或复制工作。详细分析各种增量收集算法的内部机理是一件相当繁琐的事情，在这里，读者们需要了解的仅仅是： H. G. Baker 等人的努力已经将实时垃圾收集的梦想变成了现实，我们再也不用为垃圾收集打断程序的运行而烦恼了。 </font></p>
</div>
<div class=section id=S0203><a name=S0203></a>
<h3>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>分代收集（ Generational Collecting ）算法</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>和大多数软件开发技术一样，统计学原理总能在技术发展的过程中起到强力催化剂的作用。 1980 年前后，善于在研究中使用统计分析知识的技术人员发现，大多数内存块的生存周期都比较短，垃圾收集器应当把更多的精力放在检查和清理新分配的内存块上。这个发现对于垃圾收集技术的价值可以用餐巾纸的例子概括如下： </font></p>
<p><font face=Verdana size=2>如果垃圾收集机器人足够聪明，事先摸清了餐厅里每个人在用餐时使用餐巾纸的习惯——比如有些人喜欢在用餐前后各用掉一张餐巾纸，有的人喜欢自始至终攥着一张餐巾纸不放，有的人则每打一个喷嚏就用去一张餐巾纸——机器人就可以制定出更完善的餐巾纸回收计划，并总是在人们刚扔掉餐巾纸没多久就把垃圾捡走。这种基于统计学原理的做法当然可以让餐厅的整洁度成倍提高。 </font></p>
<p><font face=Verdana size=2>D. E. Knuth ， T. Knight ， G. Sussman 和 R. Stallman 等人对内存垃圾的分类处理做了最早的研究。 1983 年， H. Lieberman 和 C. Hewitt 发表了题为&#8220;基于对象寿命的一种实时垃圾收集器（ A real-time garbage collector based on the lifetimes of objects ）&#8221;的论文。这篇著名的论文标志着分代收集算法的正式诞生。此后，在 H. G. Baker ， R. L. Hudson ， J. E. B. Moss 等人的共同努力下，分代收集算法逐渐成为了垃圾收集领域里的主流技术。 </font></p>
<p><font face=Verdana size=2>分代收集算法通常将堆中的内存块按寿命分为两类，年老的和年轻的。垃圾收集器使用不同的收集算法或收集策略，分别处理这两类内存块，并特别地把主要工作时间花在处理年轻的内存块上。分代收集算法使垃圾收集器在有限的资源条件下，可以更为有效地工作——这种效率上的提高在今天的 Java 虚拟机中得到了最好的证明。 </font></p>
</div>
</div>
<div class=section id=S03><a name=S03></a>
<h3>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>应用浪潮</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>Lisp 是垃圾收集技术的第一个受益者，但显然不是最后一个。在 Lisp 语言之后，许许多多传统的、现代的、后现代的语言已经把垃圾收集技术拉入了自己的怀抱。随便举几个例子吧：诞生于 1964 年的 Simula 语言， 1969 年的 Smalltalk 语言， 1970 年的 Prolog 语言， 1973 年的 ML 语言， 1975 年的 Scheme 语言， 1983 年的 Modula-3 语言， 1986 年的 Eiffel 语言， 1987 年的 Haskell 语言&#8230;&#8230;它们都先后使用了自动垃圾收集技术。当然，每一种语言使用的垃圾收集算法可能不尽相同，大多数语言和运行环境甚至同时使用了多种垃圾收集算法。但无论怎样，这些实例都说明，垃圾收集技术从诞生的那一天起就不是一种曲高和寡的&#8220;学院派&#8221;技术。 </font></p>
<p><font face=Verdana size=2>对于我们熟悉的 C 和 C++ 语言，垃圾收集技术一样可以发挥巨大的功效。正如我们在学校中就已经知道的那样， C 和 C++ 语言本身并没有提供垃圾收集机制，但这并不妨碍我们在程序中使用具有垃圾收集功能的函数库或类库。例如，早在 1988 年， H. J. Boehm 和 A. J. Demers 就成功地实现了一种使用保守垃圾收集算法（ Conservative GC Algorithmic ）的函数库（参见 </font><a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc"><font face=Verdana size=2>http://www.hpl.hp.com/personal/Hans_Boehm/gc </font></a><font face=Verdana size=2>）。我们可以在 C 语言或 C++ 语言中使用该函数库完成自动垃圾收集功能，必要时，甚至还可以让传统的 C/C++ 代码与使用自动垃圾收集功能的 C/C++ 代码在一个程序里协同工作。 </font></p>
<p><font face=Verdana size=2>1995 年诞生的 Java 语言在一夜之间将垃圾收集技术变成了软件开发领域里最为流行的技术之一。从某种角度说，我们很难分清究竟是 Java 从垃圾收集中受益，还是垃圾收集技术本身借 Java 的普及而扬名。值得注意的是，不同版本的 Java 虚拟机使用的垃圾收集机制并不完全相同， Java 虚拟机其实也经过了一个从简单到复杂的发展过程。在 Java 虚拟机的 1.4.1 版中，人们可以体验到的垃圾收集算法就包括分代收集、复制收集、增量收集、标记－整理、并行复制（ Parallel Copying ）、并行清除（ Parallel Scavenging ）、并发（ Concurrent ）收集等许多种， Java 程序运行速度的不断提升在很大程度上应该归功于垃圾收集技术的发展与完善。 </font></p>
<p><font face=Verdana size=2>尽管历史上已经有许多包含垃圾收集技术的应用平台和操作系统出现，但 Microsoft .NET 却是第一种真正实用化的、包含了垃圾收集机制的通用语言运行环境。事实上， .NET 平台上的所有语言，包括 C# 、 Visual Basic .NET 、 Visual C++ .NET 、 J# 等等，都可以通过几乎完全相同的方式使用 .NET 平台提供的垃圾收集机制。我们似乎可以断言， .NET 是垃圾收集技术在应用领域里的一次重大变革，它使垃圾收集技术从一种单纯的技术变成了应用环境乃至操作系统中的一种内在文化。这种变革对未来软件开发技术的影响力也许要远远超过 .NET 平台本身的商业价值。 </font></p>
</div>
<div class=section id=S04><a name=S04></a>
<h3>&nbsp;</h3>
<h3><font face=Verdana color=#000080 size=3>大势所趋</font> </h3>
<p><font face=Verdana color=#000080>-------------------------------------------------------------------------------------------------------</font> </p>
<p><font face=Verdana size=2>今天，致力于垃圾收集技术研究的人们仍在不懈努力，他们的研究方向包括分布式系统的垃圾收集、复杂事务环境下的垃圾收集、数据库等特定系统的垃圾收集等等。 </font></p>
<p><font face=Verdana size=2>但在程序员中间，仍有不少人对垃圾收集技术不屑一顾，他们宁愿相信自己逐行编写的 free 或 delete 命令，也不愿把垃圾收集的重任交给那些在他们看来既蠢又笨的垃圾收集器。 </font></p>
<p><font face=Verdana size=2>我个人认为，垃圾收集技术的普及是大势所趋，这就像生活会越来越好一样毋庸置疑。今天的程序员也许会因为垃圾收集器要占用一定的 CPU 资源而对其望而却步，但二十多年前的程序员还曾因为高级语言速度太慢而坚持用机器语言写程序呢！在硬件速度日新月异的今天，我们是要吝惜那一点儿时间损耗而踟躇不前，还是该坚定不移地站在代码和运行环境的净化剂——垃圾收集的一边呢？ </font></p>
</div>
<img src ="http://www.cppblog.com/majianan/aggbug/14666.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-11-04 16:19 <a href="http://www.cppblog.com/majianan/archive/2006/11/04/14666.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2006-10-28 技术网摘</title><link>http://www.cppblog.com/majianan/archive/2006/10/28/14303.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Sat, 28 Oct 2006 01:59:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/10/28/14303.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/14303.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/10/28/14303.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/14303.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/14303.html</trackback:ping><description><![CDATA[
		<br />
		<font face="Verdana" color="#0000ff">
				<font color="#000080">
						<strong>1.</strong>
				</font>   </font>
		<a class="" title="" href="http://dev.yesky.com/msdn/332/2628832.shtml" target="">
				<font face="Verdana" color="#0000ff">解析C++/CLI之头文件、内联函数与数组</font>
		</a>
		<br />
		<br />
		<font face="Verdana" color="#0000ff">
				<font color="#000080">
						<strong>2.</strong>
				</font>  </font>
		<a class="" title="" href="http://tech.sina.com.cn/s/2006-10-23/09081197247.shtml" target="">
				<font face="Verdana" color="#0000ff"> 解析C++/CLI之头文件、内联函数与数组(2)</font>
		</a>
		<br />
		<br />
		<font face="Verdana" color="#0000ff">
				<font color="#000080">
						<strong>3.</strong>
				</font>  </font>
		<a class="" title="" href="http://tech.sina.com.cn/s/2006-10-23/09081197248.shtml" target="">
				<font face="Verdana" color="#0000ff"> 解析C++/CLI之头文件、内联函数与数组(3)</font>
		</a>
		<br />
		<br />
		<font face="Verdana" color="#000080">
				<strong>4.</strong>    <a class="" title="" href="http://soft.yesky.com/234/2536734.shtml?324" target="">保卫C++：安全STL编程中的受检迭代子</a><br /><br /><strong>5.</strong>   </font>
<img src ="http://www.cppblog.com/majianan/aggbug/14303.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-10-28 09:59 <a href="http://www.cppblog.com/majianan/archive/2006/10/28/14303.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>人生价值的计算 </title><link>http://www.cppblog.com/majianan/archive/2006/10/20/13893.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Fri, 20 Oct 2006 03:46:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/10/20/13893.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/13893.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/10/20/13893.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/13893.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/13893.html</trackback:ping><description><![CDATA[
		<div class="postbody">
				<p>
						<font face="Verdana" size="2">本文内容来自网络，但不知道原创和出处<br /><br /></font>
				</p>
				<div class="Section1" style="LAYOUT-GRID:  15.6pt none">
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">如果令</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">A</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">B</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">C</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">D……X</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">Y</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">Z</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">这</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">26</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">个英文字母，分别等于百分之</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">1</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">2</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">3</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">4……24</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">25</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">、</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">26</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">这</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">26</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">个数值，那么我们就能得出如下有趣的结论：</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
														<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
														<o:p>
														</o:p>
												</span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
										<font size="2">
												<font face="Verdana">
														<o:p> </o:p>
												</font>
										</font>
								</span>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">努力工作：</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">H+A+R+D+W+O+R+K=8+1+18+4+23+15+18+11=98%<o:p></o:p></span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">知识：</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">K+N+O+W+L+E+D+G+E=11+14+15+23+12+5+4+7+5=96%<o:p></o:p></span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">爱情：</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">L+O+V+E=12+5+22+5=54%<o:p></o:p></span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">好运：</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">L+U+C+K=12+21+3+11=47%<o:p></o:p></span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
										<font size="2">
												<font face="Verdana">
														<o:p> </o:p>
												</font>
										</font>
								</span>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">这些我们通常非常看重的东西都不是最完满的，虽然它们非常重要。那么，究竟什么能使得生活变得圆满？</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
														<span lang="EN-US">
																<o:p>
																</o:p>
														</span>
												</span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">是金钱吗？</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
														<span lang="EN-US">M+O+N+E+Y=13+15+14+5+25=72%<o:p></o:p></span>
												</span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">是领导力吗？</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
														<span lang="EN-US">L+E+A+D+E+R+S+H+I+P=12+5+1+4+5+18+19+9+16=89%<o:p></o:p></span>
												</span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">是性吗？</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">S+E+X=19+24+5=48%<o:p></o:p></span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
										<font size="2">
												<font face="Verdana">
														<o:p> </o:p>
												</font>
										</font>
								</span>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">那么，什么能使生活变成</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">100%</span>
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">得圆满呢？</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
														<o:p>
														</o:p>
												</span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
										<font size="2">
												<font face="Verdana">
														<o:p> </o:p>
												</font>
										</font>
								</span>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">心态！</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">A+T+T+I+T+U+D+E=1+20+20+9+20+21+4+5=100%<o:p></o:p></span>
										</font>
								</font>
						</p>
						<p class="MsoNormal">
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">正是我们对待工作、生活得态度能够使我们的生活达到</span>
												<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">100%</span>
										</font>
								</font>
								<font size="2">
										<font face="Verdana">
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.0pt">的圆满！</span>
												<br />
												<br />
												<span style="FONT-SIZE: 9pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt">
														<span lang="EN-US">
																<o:p>
																</o:p>
														</span>
												</span>
										</font>
								</font>
						</p>
				</div>
		</div>
<img src ="http://www.cppblog.com/majianan/aggbug/13893.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-10-20 11:46 <a href="http://www.cppblog.com/majianan/archive/2006/10/20/13893.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用指针调用函数的不同形式</title><link>http://www.cppblog.com/majianan/archive/2006/09/14/12436.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Thu, 14 Sep 2006 02:08:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/09/14/12436.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/12436.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/09/14/12436.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/12436.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/12436.html</trackback:ping><description><![CDATA[
		<table class="description" cellspacing="0" cellpadding="0" align="center" border="0">
				<tbody>
						<tr>
								<td align="middle">
										<div class="sysBr500 text" id="articleText476cd87801000279" align="left">
												<p align="center">
														<font face="Verdana" color="#0000ff" size="2">
																<strong>
																		<a href="http://blog.sina.com.cn/pic/476cd87802000114" target="_blank">
																				<img src="http://blog.sina.com.cn/pic/476cd87802000114" border="0" &#111;nload="resizeImg(this,500)" />
																		</a>
																</strong>
														</font>
												</p>
												<div align="center">
														<font color="#0000ff">
																<font size="2">
																		<font face="Verdana">
																				<strong>用指针调用函数的不同形式</strong>
																		</font>
																</font>
														</font>
												</div>
												<div align="center">
														<strong>
																<font face="Verdana" color="#0000ff" size="2">
																</font>
														</strong> </div>
												<div align="center">
														<strong>
																<font face="Verdana" color="#0000ff" size="2">Ma Jia nan </font>
														</strong>
												</div>
												<div align="center">
														<strong>
																<font size="2">
																		<font face="Verdana">
																				<font color="#0000ff">2006-1-16</font>
																		</font>
																</font>
														</strong>
												</div>
												<div align="center">
														<strong>
																<font face="Verdana" color="#0000ff" size="2">
																</font>
														</strong> </div>
												<div>
														<font face="Verdana" size="2">    最初一个函数指针必须用*操作符（和一对括号）“转换为”一个“真正的”函数才能调用，如下所示： </font>
												</div>
												<div>
														<font face="Verdana" size="2">
														</font> </div>
												<div>
														<font face="Verdana" size="2">    int r, func(), (*pf)() = func; //函数指针的初始化<br />    r = (*pf)();  //函数的指针调用形式1，等价于 r = func(); </font>
												</div>
												<div>
														<font face="Verdana" size="2">
														</font> </div>
												<div>
														<font face="Verdana" size="2">    函数总是通过指针进行调用的，所有“真正的”函数名总是隐式的退化为指向该函数的指针， 正如在对函数指针pf初始化做的那样： </font>
												</div>
												<div>
														<font face="Verdana" size="2">
														</font> </div>
												<div>
														<font face="Verdana" size="2">    int func();<br />    int (*pf)() = func; </font>
												</div>
												<div>
														<font face="Verdana" size="2">
														</font> </div>
												<div>
														<font face="Verdana" size="2">    这有点类似数组名的行为（不带下标操作符的数组名会被解释成指向数组首元素的指针）。 </font>
												</div>
												<div>
														<br />
														<font face="Verdana" size="2">    以上结论表明，下面的语句也是正确的。 </font>
												</div>
												<div>
														<font face="Verdana" size="2">
														</font>
												</div>
												<font face="Verdana" size="2"> </font>
										</div>
										<div>
												<font face="Verdana" size="2">    r = pf();     //函数的指针调用形式2 </font>
										</div>
										<div>
												<font face="Verdana" size="2">
												</font> </div>
										<div>
												<font face="Verdana" size="2">    ANSI C 标准实际上接受形式2，这意味着不再需要*操作符，但形式1依然允许。两种形式产生相同的结果，但是形式1让读者更清楚该调用是通过函数指针执行的。 </font>
										</div>
										<div>
												<font face="Verdana" size="2">
												</font> </div>
										<div>
												<font face="Verdana" size="2">
												</font> </div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/majianan/aggbug/12436.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-09-14 10:08 <a href="http://www.cppblog.com/majianan/archive/2006/09/14/12436.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>顺序容器操作</title><link>http://www.cppblog.com/majianan/archive/2006/09/14/12435.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Thu, 14 Sep 2006 02:07:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/09/14/12435.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/12435.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/09/14/12435.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/12435.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/12435.html</trackback:ping><description><![CDATA[
		<table class="description" cellspacing="0" cellpadding="0" align="center" border="0">
				<tbody>
						<tr>
								<td align="middle">
										<div class="sysBr500 text" id="articleText476cd87801000236" align="left">
												<p align="center">
														<font color="#0000ff">
																<strong>
																		<a href="http://blog.sina.com.cn/pic/476cd878020000zs" target="_blank">
																				<font face="Verdana" size="2">
																						<img src="http://blog.sina.com.cn/pic/476cd878020000zs" border="0" &#111;nload="resizeImg(this,500)" />
																				</font>
																		</a>
																		<font face="Verdana" size="2">    </font>
																</strong>
														</font>
														<font color="#0000ff">
																<strong>
																		<font face="Verdana" size="2">C++ Primer 学习札记   </font>
																		<a href="http://blog.sina.com.cn/pic/476cd878020000zt" target="_blank">
																				<font face="Verdana" size="2">
																						<img src="http://blog.sina.com.cn/pic/476cd878020000zt" border="0" &#111;nload="resizeImg(this,500)" />
																				</font>
																		</a>
																</strong>
														</font>
												</p>
												<p align="center">
														<font color="#0000ff">
																<font size="2">
																		<font face="Verdana">
																				<strong>Ma Jia nan</strong>
																		</font>
																</font>
														</font>
												</p>
												<p>
														<font face="Verdana" size="2">
														</font>
												</p>
												<font face="Verdana" size="2">
														<hr id="null" />
												</font>
												<p>
												</p>
												<div>
														<font color="#0000ff">
																<font size="2">
																		<font face="Verdana">
																				<strong>一 顺序容器操作之插入（insert）</strong>
																		</font>
																</font>
														</font>
												</div>
												<div>
														<font face="Verdana" size="2">
														</font> </div>
												<div>
														<font face="Verdana" size="2">向容器中插入元素有以下几种形式： </font>
												</div>
												<div>
														<font face="Verdana" size="2">
														</font> </div>
												<div>
														<font face="Verdana" size="2">1） 最一般的形式： </font>
														<table style="BORDER-RIGHT: #999 1px solid; BORDER-TOP: #999 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #999 1px solid; WIDTH: 80%; BORDER-BOTTOM: #999 1px solid" align="center">
																<tbody>
																		<tr>
																				<td>
																						<p>
																								<font face="Verdana" size="2">   </font>
																								<font face="Verdana" size="2">vector&lt;string&gt; svec;<br />   list&lt;string&gt; slist; </font>
																						</p>
																						<p>
																								<font face="Verdana" size="2">   string s( "MaJianan" );<br />   slist.insert( slist.begin(), s );<br />   svec.insert( svec.begin(), s ); </font>
																						</p>
																				</td>
																		</tr>
																</tbody>
														</table>
												</div>
												<p>
														<font face="Verdana" size="2">insert()将第二个参数（要被插入的值）插入到第一个参数（指向容器中某个位置的iterator）指向的位置的前面。 </font>
												</p>
												<p>
														<font face="Verdana" size="2">更为随机的插入操作可以如下实现： </font>
												</p>
												<p>
														<font face="Verdana" size="2">
														</font>
												</p>
												<table style="BORDER-RIGHT: #999 1px solid; BORDER-TOP: #999 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #999 1px solid; WIDTH: 79.57%; BORDER-BOTTOM: #999 1px solid; HEIGHT: 117px" align="center">
														<tbody>
																<tr>
																		<td>
																				<p>
																						<font face="Verdana" size="2">   string s1( "yuanlaishini" );<br />   list&lt;string&gt;::iterator iter; </font>
																				</p>
																				<p>
																						<font face="Verdana" size="2">   iter = find( slist.begin(), slist.end(), s1 );<br />   slist.insert( iter, s1 ); </font>
																				</p>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana" size="2">find()返回被查找元素在容器中的位置，如果查找失败，返回end()iterator.<br />   <br />//slist.push_back( value )等价于    <br />slist.insert( slist.end(), value ); </font>
												</p>
												<p>
														<font face="Verdana" size="2">
														</font> </p>
												<p>
														<font face="Verdana" size="2">2） 在某个位置插入指定数量的元素.<br />   例如，在vector的开始处插入10个MaJianan： </font>
												</p>
												<p>
														<font face="Verdana" size="2">
														</font>
												</p>
												<table style="BORDER-RIGHT: #999 1px solid; BORDER-TOP: #999 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #999 1px solid; WIDTH: 80%; BORDER-BOTTOM: #999 1px solid" align="center">
														<tbody>
																<tr>
																		<td>
																				<p>
																						<font face="Verdana" size="2">   </font>
																						<font face="Verdana" size="2">vector&lt;string&gt; svec;<br />   string mjn( "MaJianan" ); </font>
																				</p>
																				<p>
																						<font face="Verdana" size="2">   svec.insert( svec.begin(), 10, mjn ); </font>
																				</p>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana" size="2">
														</font> </p>
												<p>
														<font face="Verdana" size="2">3）向容器插入一段范围内的元素： </font>
												</p>
												<p>
														<font face="Verdana" size="2">
														</font>
												</p>
												<table style="BORDER-RIGHT: #999 1px solid; BORDER-TOP: #999 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #999 1px solid; WIDTH: 80%; BORDER-BOTTOM: #999 1px solid" align="center">
														<tbody>
																<tr>
																		<td>
																				<p>
																						<font face="Verdana" size="2"> string sa[3] = { "MaJianan", "yuanlaishini", "blog.sina.com.cn"}; </font>
																				</p>
																				<p>
																						<font face="Verdana" size="2">   //插入数组中的全部元素<br />   svec.insert( svec.begin(), sa, sa+3 ); </font>
																				</p>
																				<p>
																						<font face="Verdana" size="2">   //插入数组中的部分元素<br />   svec.insert( svec.begin() + svec.size()/2, sa+1, sa+3 );   </font>
																				</p>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana" size="2">
														</font> </p>
												<p>
														<font face="Verdana" size="2">4）通过一对iterator来标记带插入值的范围，可以是另一个vector </font>
												</p>
												<p>
														<font face="Verdana" size="2">
														</font>
												</p>
												<table style="BORDER-RIGHT: #999 1px solid; BORDER-TOP: #999 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #999 1px solid; WIDTH: 87.04%; BORDER-BOTTOM: #999 1px solid; HEIGHT: 228px" align="center">
														<tbody>
																<tr>
																		<td>
																				<p>
																						<font face="Verdana" size="2">例一：<br />   //插入svec中含有的元素，从svec2中间开始<br />   svec2.insert( svec2.begin() + svec2.size()/2, svec.begin(), svec.end() ); </font>
																				</p>
																				<p>
																						<font face="Verdana" size="2">   例二：<br />   //把sevc中的元素插入到slist中sValue的前面<br />   list&lt;string&gt; slist;<br />   list&lt;string&gt;::iterator iter = find( slist.begin(), slist.end(), sValue );<br />   slist.insert( iter, svec.begin(), svec.end() ); </font>
																				</p>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana" size="2">
														</font>
												</p>
												<font face="Verdana" size="2">
														<hr id="null" />
												</font>
												<p>
												</p>
												<p>
														<font color="#0000ff">
																<font size="2">
																		<font face="Verdana">
																				<strong>二 顺序容器操作之删除（erase）</strong>
																		</font>
																</font>
														</font>
												</p>
												<p>
														<font face="Verdana" size="2">1） 删除单个元素 </font>
												</p>
												<table style="BORDER-RIGHT: #999 1px solid; BORDER-TOP: #999 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #999 1px solid; WIDTH: 80%; BORDER-BOTTOM: #999 1px solid" align="center">
														<tbody>
																<tr>
																		<td>
																				<p>
																						<font face="Verdana" size="2">list&lt;string&gt; slist;<br />... ...<br />sting sValue( "yuanlaishini" );<br />list&lt;string&gt;::iterator iter=find( slist.begin(), slist.end(), sValue );<br />if( iter!=slist.end() )<br />       slist.erase( iter ); </font>
																				</p>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana" size="2">
														</font> </p>
												<p>
														<font face="Verdana" size="2">2） 删除有一对iterator标记的一段范围内的元素 </font>
												</p>
												<p>
														<font face="Verdana" size="2">
														</font>
												</p>
												<table style="BORDER-RIGHT: #999 1px solid; BORDER-TOP: #999 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #999 1px solid; WIDTH: 80%; BORDER-BOTTOM: #999 1px solid; HEIGHT: 316px" align="center">
														<tbody>
																<tr>
																		<td>
																				<p>
																						<font face="Verdana" size="2">//删除所有元素<br />slist.erase( slist.begin(), slist.end() ); </font>
																				</p>
																				<p>
																						<font face="Verdana" size="2">//删除部分元素<br />例一：<br />slist.erase( slist.begin()+slist.size()/2, slist.end() ); </font>
																				</p>
																				<p>
																						<font face="Verdana" size="2">例二：<br />list&lt;string&gt;::iterator first, last;<br />first=find( slist.begin(), slist.end(). value1);<br />last=find( slist.begin(), slist.end(). value2);<br />//检验first和last的有效性<br />slist.erase( first, last ); </font>
																				</p>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<br />
														<font face="Verdana" size="2">3） 与push_back()相对应，pop_back()删除容器的末尾元素。 </font>
												</p>
												<p>
														<font face="Verdana" size="2">
														</font>
												</p>
												<font face="Verdana" size="2">
														<hr id="null" />
												</font>
												<p>
												</p>
												<p>
														<font color="#0000ff">
																<font size="2">
																		<font face="Verdana">
																				<strong>三 顺序容器操作之赋值(=)和对换(swap)</strong>
																		</font>
																</font>
														</font>
												</p>
												<p>
														<font face="Verdana" size="2">//slist1含有8个元素<br />//slist2含有16个元素<br />1)如果 </font>
														<font face="Verdana" size="2">slist1 = slist2;<br /> <br />  slist1拥有与被拷贝容器相同的元素数目---16.slist2有16个元素，没有变化。<br />  slist1中原来的8个元素被删除(调用string的析构函数) </font>
												</p>
												<p>
														<font face="Verdana" size="2">2)如果 slist1.swap( slist2 );<br />  <br />  slist1现在有16个元素，而slist2函数slist1中原有的8个元素的拷贝<br />  如果两个容器长度不同，则重置容器的长度  <br /></font>
												</p>
												<font face="Verdana" size="2">
														<hr id="null" />
												</font>
												<p>
												</p>
												<p>
														<font face="Verdana" size="2">
														</font> </p>
												<p align="center">
														<a href="http://blog.sina.com.cn/pic/476cd878020000zu" target="_blank">
																<font face="Verdana" size="2">
																		<img src="http://blog.sina.com.cn/pic/476cd878020000zu" border="0" &#111;nload="resizeImg(this,500)" />
																</font>
														</a>
												</p>
												<p align="center">
														<font face="Verdana" size="2">
														</font> </p>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/majianan/aggbug/12435.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-09-14 10:07 <a href="http://www.cppblog.com/majianan/archive/2006/09/14/12435.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>确定基类有虚析购函数</title><link>http://www.cppblog.com/majianan/archive/2006/09/14/12434.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Thu, 14 Sep 2006 02:05:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/09/14/12434.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/12434.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/09/14/12434.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/12434.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/12434.html</trackback:ping><description><![CDATA[
		<div>
				<font face="Verdana" size="2">当通过基类的指针去删除派生类的对象，而基类有没有虚析购函数的时候，结果将是不可确定的。（实际运行时常发生的情况是，派生类的析购函数永远不会被调用） </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">虚函数的目的是让派生类去制定自己的行为，所以几乎所有的基类都有虚函数。 </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">如果某个类不包含虚函数，那一般是表示他将不作为基类来使用，当一个类不准备做基类使用的时候，使析购函数为虚一般是个错误的选择。 </font>
		</div>
<img src ="http://www.cppblog.com/majianan/aggbug/12434.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-09-14 10:05 <a href="http://www.cppblog.com/majianan/archive/2006/09/14/12434.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>极限编程――理解和实践（转载）</title><link>http://www.cppblog.com/majianan/archive/2006/08/26/11728.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Sat, 26 Aug 2006 02:15:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/08/26/11728.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/11728.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/08/26/11728.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/11728.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/11728.html</trackback:ping><description><![CDATA[<p><font face=Verdana size=2>作为敏捷软件开发领域主流的开发方法，极限编程与其说是一种系统的方法学，倒更像是一系列最佳实践的有机结合。在这些最佳实践中，有些是已经广为人们所接受的（如编码标准），而更多的则极具颠覆性，初看之下让人似乎难以接受。</font> </p>
<p><font face=Verdana size=2>本文中，我将针对这些看似怪异的最佳实践阐述我的观点，并简述我对实施这些最佳实践的一些思考。</font> </p>
<p><font face=Verdana size=2>一、计划游戏</font> </p>
<p><font face=Verdana size=2>能够把计划叫做&#8220;游戏&#8221;是需要一定勇气的。在传统的软件开发方法学中，计划是举足轻重的一环，在制订计划前需要仔细的估算，在计划实施的过程中，还要不停的跟踪、修正，直至整个项目完成。</font> </p>
<p><font face=Verdana size=2>而在XP中，计划似乎要轻松许多。这并不是因为计划本身变得草率和无关痛痒，而是得益于XP的小版本发布思维。软件的一个版本是如此短小简单，以至于对它进行完整的评估、预算、跟踪和修正要容易许多。事实上，XP中采用的计划方式（业务人员和开发人员共同参与，各司其职）在大多数现代软件企业中早已采用，但是由于项目过于庞大，很难在开始阶段制订出完善的计划。而在XP中，人们只需要针对一个一两个月的小项目进行跟踪和管理，无形中降低了计划的风险。</font> </p>
<p><font face=Verdana size=2>二、隐喻</font> </p>
<p><font face=Verdana size=2>&nbsp;&nbsp;&nbsp; 在XP中，人们经常会使用隐喻来代替传统开发过程中的体系结构设计。从指导开发的角度来说，隐喻似乎不够精确，容易让人误解。但是，对于具有类似背景的同一个项目组中的开发人员来说，隐喻则更便于理解和交流。很难想象两个程序员面对着一张庞大的体系结构图时能够真正有效的沟通，而隐喻很好的解决了这个问题。</font> </p>
<p><font face=Verdana size=2>三、简单设计</font> </p>
<p><font face=Verdana size=2>不知道从什么时候开始，开发人员习惯了为明天而设计。一个开发人员设计了一个复杂的类继承结构，只是为了提高程序的所谓灵活性。没人知道这样值不值，并不是软件的每一个部分都需要扩展。但是，对于传统的软件开发人员来说，这么做又是迫不得已。如果没有预先做好准备，在变化来临时就会措手不及，付出沉重的代价。</font> </p>
<p><font face=Verdana size=2>但是在XP中，小版本发行的方法使得变化并不那么可怕，而重构的广泛采用，使得代码总是可以在需要时变得更加灵活。此外，由于你的代码总是会被别人审查（代码集体所有权和结对编程），因此也可以避免过于追求简单而忽视了重要的细节。</font> </p>
<p><font face=Verdana size=2>四、测试优先</font> </p>
<p><font face=Verdana size=2>没有代码要测试程序有什么用？这是测试优先最容易让人误解的地方。测试优先能够让开发人员更清楚的认识到，程序将会如何被使用。通过对不同的测试用例的思考，开发人员也能够更清晰的认识到程序的功能外延。而更多的其他的开发人员，则通过测试用例就可以获得一份精确的使用手册，在这份使用手册中，描述了作者考虑到的所有输入和输出结果，这样不仅便于人们了解程序，更增加了发现程序错误的机会（缺失的测试用例往往体现出作者忽视的某些使用情况）。</font> </p>
<p><font face=Verdana size=2>五、结对编程</font> </p>
<p><font face=Verdana size=2>两个程序员坐在一起，能够提高开发效率吗？程序员难道不是一群高傲的猫，习惯于离群索居，把头抬得高高吗？</font> </p>
<p><font face=Verdana size=2>事实并非如此。在一个正确的、合理的、能够实现的大目标下，程序员们不仅能够和平共处，更可以相互合作，创造出优秀的、高质量的程序。沟通一直是软件项目管理中的一个重要议题，而结对编程提供了一个十分有效的沟通渠道。此外，结对编程也更容易让新人融入团体。在几个高级程序员的指引下，他会更容易找出程序的脉络，把握程序的思想。较之正规的培训，这种方式更轻松也更有效。对于团队中的所有程序员来说，结对编程都是一个了解其他人设计思想的机会，通过结对编程，能够更好的实现代码集体所有权，也能够降低因为人员流动造成的风险。</font> </p>
<p><font face=Verdana size=2>结对编程最大的好处在于，能够极大的减少程序中潜在变化的可能性。两个人通过交流互相交换自己对程序的不同理解，更容易找出程序中可能出现的变化或错误，从而使程序更加可靠和健壮。</font> </p>
<p><font face=Verdana size=2>六、持续集成</font> </p>
<p><font face=Verdana size=2>集成一直是最费力的工作之一，本来工作的好好的代码，放在一起就不能运转，更糟糕的是成百上千条不知所云的错误码，没有人知道这些错误码来自何处。这是每个项目几乎都会遇到的最困难的阶段，程序员们必须集合在一起，翻阅数量巨大的接口定义文件，反复查看代码，同时还要不断的做出承诺。</font> </p>
<p><font face=Verdana size=2>持续集成正是解决上述问题的方法。通过多次、小增量的集成，我们总是能够以最快的速度定位错误出现的位置（因为增加的代码很少），结合大量测试用例，我们也可以确保每一个集成版本都尽可能的可靠。</font> </p>
<p><font face=Verdana size=2>此外，持续集成几乎可以在任何时间向我们提供一个可以工作的版本，我们可以将这个版本用于内部讨论和测试、客户展示、客户测试、小版本发布等等，这使得我们不需要花费太多的时间对现有的程序修修补补，以生成一个demo。</font> </p>
<p><font face=Verdana size=2>上文简单叙述了XP中常会引起争议的六个最佳实践的优点。下面本文将结合实际谈谈实施XP中需要注意的一些问题。</font> </p>
<p><font face=Verdana size=2>一、适用性问题</font> </p>
<p><font face=Verdana size=2>XP理论在提出时，明确的说明：XP是适用于中小型团队在需求不明确或者迅速变化的情况下进行软件开发的轻量级方法。这就意味着，XP并不适用于所有情况。在准备实施XP前，你也许需要仔细评估项目的具体情况，以决定是否真的需要采用XP。</font> </p>
<p><font face=Verdana size=2>二、最佳实践间的关联</font> </p>
<p><font face=Verdana size=2>XP的一个特点是，它所推崇的最佳实践几乎总是和其它实践关联紧密，在实施一项最佳实践时，如果不同时实施其它实践，往往难以达到最初的目的。因此，在实施XP时，需要仔细研究各项实践间的关联，以确定最佳的实施方案。</font> </p>
<p><font face=Verdana size=2>三、宽松的环境</font> </p>
<p><font face=Verdana size=2>XP是一种追求自然的工作方法。它所倡导的是，程序员们以最自然开发的方式完成他们的工作。对于习惯了传统开发方法严格管理制度的管理人员来说，这往往是很难接受的。于是就出现了，虽然最高决策人决定实施XP，但管理层却无法（或不愿）给开发人员提供宽松的环境。在一个古板僵化的方框里，开发人员不会真正的回复自然，他们会装作正在实践XP，但事实上，他们依然在老路上行走（可以见到很多这样的例子，比如一些虚张声势的测试用例等等）。</font> </p>
<p><font face=Verdana size=2>四、忍受变化</font> </p>
<p><font face=Verdana size=2>XP对于传统软件项目管理思想的冲击，可能会使很多管理人员感到不舒服。也许XP一经实施，就会给项目组带来翻天覆地的变化。如果这样的变化让你感到恐惧，那么请暂时忍耐，你不能肯定这种变化不好，除非你亲眼看到。到那时再决定也不迟。</font> </p>
<p><font face=Verdana size=2>五、慢慢来</font> </p>
<p><font face=Verdana size=2>实施XP的过程不能操之过急。最好的方法是，在部分项目组中先行实施，实施时也不需要同时实施所有实践（但要注意各个实践间的关联问题）。有的时候你会发现，在实施了部分实践后，其它的实践也成为水到渠成的事情。当经过仔细评估，确信XP在项目组中确实有效后，再逐步在企业范围内推广，必要的时候，需要采取自愿的原则，由项目组的成员决定是否需要实施XP。</font> </p>
<p><font face=Verdana size=2>以上即是我在软件工程过程课程中以及平时工作、学习中对XP的一些认识。</font> </p>
<p><br><font face=Verdana size=2>来源：</font> <a href="http://blog.csdn.net/leasun/archive/2006/08/15/1067508.aspx"><font face=Verdana size=2>http://blog.csdn.net/leasun/archive/2006/08/15/1067508.aspx</font> </a></p>
<img src ="http://www.cppblog.com/majianan/aggbug/11728.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-08-26 10:15 <a href="http://www.cppblog.com/majianan/archive/2006/08/26/11728.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iostream 和 iostream.h 的区别 </title><link>http://www.cppblog.com/majianan/archive/2006/08/26/11727.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Sat, 26 Aug 2006 01:49:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/08/26/11727.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/11727.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/08/26/11727.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/11727.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/11727.html</trackback:ping><description><![CDATA[<div align=left><font face=Verdana size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=#0000ff> &lt; iostream &gt; 和 &lt; iostream.h &gt; 的区别</font><br><br>关键词：&lt; iostream &gt; 和 &lt; iostream.h &gt; </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>你写程序的时候，用&lt; iostream &gt;还是&lt; iostream.h &gt;？ </font></div>
<div><font face=Verdana size=2>你知道它们有什么区别么？还是认为他们根本就是一样的？ </font></div>
<div><font face=Verdana size=2>下面听我给你吹（文中纯属个人言论，不涉及国家机密，请放心阅读，若转载请注明出处作者^-^） </font></div>
<div><font face=Verdana size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---majianan </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>其实没有&lt; iostream.h &gt;这样的东西 --- 标准化委员会在简化非C标准头文件时用&lt; iostream &gt; 取代了它。但又没有完全取消&lt; iostream.h &gt;的使用，并且很多编译器都同时支持&lt; iostream &gt;和&lt; iostream.h &gt;，造成现在的局面，老大（标准化委员会）确实有不得已的苦衷。 </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>话说当年，在标准化委员会动手重建新的标准库的时候，遇到了问题。为了避免类名函数名的冲突问题，引入了名字空间std，但无数现有的C++代码都依赖于使用了多年的伪标准库中的功能，例如，声明在&lt; iostream.h &gt;和&lt; complex.h &gt;等头文件中的功能。现有软件没有针对使用名字空间而进行相应的设计或者升级，如果用std来包装标准库导致现有代码不能使用，那手底下的小弟（程序员）是不会同意的。 </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>标准化委员会为了拉拢人心，吸引更多的人入会，决定为包装了std的那部分标准库构建新的头文件名。将现有C++头文件名中的.h去掉，所以就出现了&lt; iostream.h&gt;和&lt; iostream &gt;等很多双胞胎。对于C头文件，采用同样方法但在每个名字前还要添加一个C，所以C的&lt;string.h&gt;变成了&lt;cstring&gt;。 </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>旧的C++头文件是官方明确反对使用的，但旧的C头文件则没有（以保持对C的兼容性）。其实编译器制造商不会停止对客户现有软件提供支持，所以在可以预计的将来，旧的C++头文件还会嚣张一段时间。 </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>如果能明白字符串头文件的使用，举一反三，其他的也差不多会用了。 </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>&lt;string.h&gt;是旧的C头文件，对应的是基于char*的字符串处理函数； </font></div>
<div><font face=Verdana size=2>&lt;string&gt;是包装了std的C++头文件，对应的是新的strng类； </font></div>
<div><font face=Verdana size=2>&lt;cstring&gt;是对应旧的C头文件的std版本。 </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>好像跑远了，言归正传。如果你的编译器都同时支持&lt; iostream &gt;和&lt; iostream.h &gt;，那使用#include &lt; iostream &gt;，得到的是置于名字空间std下的iostream库的元素；如果使用#include &lt; iostream.h &gt;，得到的是置于全局空间的同样的元素。在全局空间获取元素会导致名字冲突，而设计名字空间的初衷正是用来避免这种名字冲突的发生。还有，打字时&lt; iostream &gt;比&lt; iostream.h &gt;少两个字，所以我会使用&lt; iostream &gt; ^-^ </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>困了，睡了。 </font></div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2></font>&nbsp;</div>
<div><font face=Verdana size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 马嘉楠 </font></div>
<div><font face=Verdana size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2005-12-26 午夜 </font></div>
<img src ="http://www.cppblog.com/majianan/aggbug/11727.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-08-26 09:49 <a href="http://www.cppblog.com/majianan/archive/2006/08/26/11727.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于 sizeof() 的一些思考 </title><link>http://www.cppblog.com/majianan/archive/2006/08/25/11682.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Fri, 25 Aug 2006 01:25:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/08/25/11682.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/11682.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/08/25/11682.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/11682.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/11682.html</trackback:ping><description><![CDATA[
		<div>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#000000">
												<font color="#0000ff" size="3">                                       关于 sizeof() 的一些思考</font> <br />                                                         马嘉楠<br /><br /></font>
										<font color="#000080">关键词：</font>
										<font color="#0000ff">sizeof </font>
								</font>
						</font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#000000">这是网上的一个帖子，最初来自那里已经记不得了，不过我觉得很不错。</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">我对原文做了一些修改，并添加了一些内容。如果有什么错误的地方，请大家指正，谢谢~~ </font>
				</p>
				<p>
						<font face="Verdana" size="2">                       --- majianan 2005-12-19 </font>
				</p>
				<p>
						<strong>
								<font face="Verdana" color="#0000ff" size="2">
								</font>
						</strong> </p>
				<p>
						<font size="2">
								<font face="Verdana">
										<strong>
												<font color="#0000ff">0.关键字</font>
										</strong>：sizeof，字节对齐，类型大小 </font>
						</font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<strong>
												<font color="#0000ff">前向声明：</font>
										</strong>
										<br />    sizeof，一个其貌不扬的家伙，引无数菜鸟竟折腰. </font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">    小虾我当初也没少犯迷糊，秉着“辛苦我一个，幸福千万人”的伟大思想,我决定将其尽可能详细的总结一下。 </font>
				</p>
				<p>
						<br />
						<font face="Verdana" size="2">    但当我总结的时候才发现，这个问题既可以简单，又可以复杂。所以本文有的地方并不适合初学者，甚至都没有必要大作文章。但如果你想“知其然，更知其所以然”的话，那么这篇文章对你或许有所帮助。<br />    </font>
				</p>
				<p>
						<font face="Verdana" size="2">    菜鸟我对C++的掌握尚未深入，其中不乏错误，欢迎各位指正啊 </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<strong>
												<font color="#0000ff">1. 定义：<br /></font>
										</strong>    sizeof是何方神圣？ </font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">    sizeof 乃 C/C++ 中的一个操作符（operator）是也。简单说其作用就是返回一个对象或者类型所占的内存字节数。<br /><br />MSDN上的解释为： </font>
				</p>
				<p>
						<font face="Verdana" size="2">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 face="Verdana" size="2">    其返回值类型为size_t，在头文件stddef.h中定义。这是一个依赖于编译系统的值，一般定义为 </font>
				</p>
				<p>
						<font face="Verdana" size="2">typedef unsigned int size_t; </font>
				</p>
				<p>
						<font face="Verdana" size="2">    世上编译器林林总总，但作为一个规范，它们都会保证char、signed char和unsigned char的sizeof值为1，毕竟char是我们编程能用的最小数据类型。<br /><br /><strong><font color="#0000ff">2. 语法：</font></strong><br />    sizeof有三种语法形式，如下：<br />    1) sizeof( object );    // sizeof( 对象 );<br />    2) sizeof( type_name ); // sizeof( 类型 );<br />    3) sizeof object;       // sizeof 对象; </font>
				</p>
				<p>
						<font face="Verdana" size="2">所以，<br />int i;<br />sizeof( i );     // ok<br />sizeof i;        // ok<br />sizeof( int );   // ok<br />sizeof int;      // error </font>
				</p>
				<p>
						<font face="Verdana" size="2">既然写法2可以用写法1代替，为求形式统一以及减少我们大脑的负担，第2种写法，忘掉它吧！ </font>
				</p>
				<p>
						<font face="Verdana" size="2">实际上，sizeof计算对象的大小也是转换成对对象类型的计算。也就是说，同种类型的不同对象其sizeof值都是一致的。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">这里，对象可以进一步延伸至表达式，即sizeof可以对一个表达式求值。编译器<strong>根据表达式的最终结果类型来确定大小</strong>，一般不会对表达式进行计算。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">例如： </font>
				</p>
				<p>
						<font face="Verdana" size="2">sizeof( 2 );        // 2的类型为int，所以等价于 sizeof( int );<br />sizeof( 2 + 3.14 ); // 3.14的类型为double，2也会被提升成double类型，所以等价于 sizeof( double );<br /><br />    sizeof也可以对一个函数调用求值，其<font color="#0000ff">结果是函数返回类型的大小，函数并不会被调用。</font>我们来看一个完整的例子： </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">char foo()<br />{<br />    printf("foo() has been called.\n");<br />    return 'a';<br />}<br />int main()<br />{<br />    size_t sz = sizeof( foo() );   // foo() 的返回值类型为char，所以sz = sizeof(char)，但函数foo()并不会被调用<br />    printf("sizeof( foo() ) = %d\n", sz);<br />} </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">C99标准规定，函数、不能确定类型的表达式以及位域（bit-field）成员不能被计算sizeof值，即下面这些写法都是错误的： </font>
				</p>
				<p>
						<font face="Verdana" size="2">    sizeof( foo );     // error<br />    void foo2() { }<br />    sizeof( foo2() );  // error<br />    struct S<br />    {<br />        unsigned int f1 : 1;<br />        unsigned int f2 : 5;<br />        unsigned int f3 : 12;<br />    };<br />    sizeof( S.f1 );   // error </font>
				</p>
				<p>
						<br />
						<strong>
								<font size="2">
										<font face="Verdana">
												<font color="#0000ff">3. sizeof的常量性</font>
										</font>
								</font>
						</strong>
				</p>
				<strong>
						<font color="#0000ff">
						</font>
				</strong>
				<p>
						<br />
						<font face="Verdana" size="2">    sizeof的计算发生在编译时刻，所以它可以被当作常量表达式使用。如： </font>
				</p>
				<p>
						<font face="Verdana" size="2">char ary[ sizeof( int ) * 10 ];   // ok </font>
				</p>
				<p>
						<font face="Verdana" size="2">最新的C99标准规定sizeof也可以在运行时刻进行计算。如下面的程序在Dev-C++中可以正确执行： </font>
				</p>
				<p>
						<font face="Verdana" size="2">int n;<br />n = 10;        // n动态赋值<br />char ary[n];   // C99也支持数组的动态定义<br />printf("%d\n", sizeof(ary)); // ok. 输出10 </font>
				</p>
				<p>
						<font face="Verdana" size="2">但在没有完全实现C99标准的编译器中就行不通了，上面的代码在VC6中就通不过编译。所以我们<font color="#0000ff">最好还是认为sizeof是在编译期执行的</font>，这样不会带来错误，让程序的可移植性强些。 </font>
				</p>
				<p>
						<br />
						<strong>
								<font size="2">
										<font face="Verdana">
												<font color="#0000ff">4. 基本数据类型的sizeof</font>
										</font>
								</font>
						</strong>
				</p>
				<p>
						<font face="Verdana" size="2">这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型。由于它们都是和系统相关的，所以在不同的系统下取值可能不同。这务必引起我们的注意，尽量不要在这方面给自己程序的移植造成麻烦。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">一般的，在32位编译环境中，sizeof(int)的取值为4。 </font>
				</p>
				<p>
						<br />
						<strong>
								<font size="2">
										<font face="Verdana">
												<font color="#0000ff">5. 指针变量的sizeof</font>
										</font>
								</font>
						</strong>
				</p>
				<p>
						<font face="Verdana" size="2">学过数据结构的你应该知道指针是一个很重要的概念，它记录了另一个对象的地址。<font color="#0000ff">既然是来存放地址的，那么它当然等于计算机内部地址总线的宽度。</font>所以在32位计算机中，一个指针变量的返回值必定是4（注意结果是以字节为单位）。可以预计，在将来的64位系统中指针变量的sizeof结果为8。 </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">char* pc = "abc";<br />int* pi;<br />string* ps;<br />char** ppc = &amp;pc;<br />void (*pf)(); // 函数指针<br />sizeof( pc ); // 结果为4<br />sizeof( pi ); // 结果为4<br />sizeof( ps ); // 结果为4<br />sizeof( ppc );// 结果为4<br />sizeof( pf ); // 结果为4 </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">指针变量的sizeof值与指针所指的对象没有任何关系，正是由于所有的指针变量所占内存大小相等，所以MFC消息处理函数使用两个参数WPARAM、LPARAM就能传递各种复杂的消息结构（使用指向结构体的指针）。 </font>
				</p>
				<p>
						<br />
						<strong>
								<font size="2">
										<font face="Verdana">
												<font color="#0000ff">6. 数组的sizeof</font>
										</font>
								</font>
						</strong>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">数组的sizeof值等于数组所占用的内存字节数</font>，如： </font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">char a1[] = "abc";<br />int a2[3];<br />sizeof( a1 ); // 结果为4，字符 末尾还存在一个NULL终止符<br />sizeof( a2 ); // 结果为3*4=12（依赖于int） </font>
				</p>
				<p>
						<font face="Verdana" size="2">一些朋友刚开始时把sizeof当作了求数组元素的个数，现在，你应该知道这是不对的。那么应该怎么求数组元素的个数呢？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">Easy，通常有下面两种写法： </font>
				</p>
				<p>
						<font face="Verdana" size="2">int c1 = sizeof( a1 ) / sizeof( char );    // 总长度/单个元素的长度<br />int c2 = sizeof( a1 ) / sizeof( a1[0]);    // 总长度/第一个元素的长度 </font>
				</p>
				<p>
						<br />
						<font face="Verdana" size="2">写到这里，提一问，下面的c3，c4值应该是多少呢？ </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">void foo3(char a3[3])<br />{<br />    int c3 = sizeof( a3 ); // c3 ==<br />}<br />void foo4(char a4[])<br />{<br />    int c4 = sizeof( a4 ); // c4 ==<br />} </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">也许当你试图回答c4的值时已经意识到c3答错了，是的，c3!=3。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">这里函数参数<font color="#0000ff">a3已不再是数组类型，而是蜕变成指针。</font>相当于char* a3，为什么仔细想想就不难明白。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">我们调用函数foo1时，程序会在栈上分配一个大小为3的数组吗？不会！ </font>
				</p>
				<p>
						<font face="Verdana" size="2">数组是“传址”的，调用者只需将实参的地址传递过去，所以a3自然为指针类型（char*），c3的值也就为4。 </font>
				</p>
				<p>
						<br />
						<font size="2">
								<font face="Verdana">
										<strong>
												<font color="#0000ff">7.string的sizeof</font>
										</strong>
										<br />
										<font color="#0000ff">一个string的大小与它所指向的字符串的长度无关</font>。<br /><br /><font color="#0000ff">*********************************************************</font><br />string st1("blog.sina.com.cn");<br />string st2("majianan");<br />string st3;<br />string *ps = &amp;st1;<br />cout &lt;&lt; "st1: " &lt;&lt; sizeof(st1) &lt;&lt; endl;<br />cout &lt;&lt; "st2: " &lt;&lt; sizeof(st2) &lt;&lt; endl;<br />cout &lt;&lt; "st3: " &lt;&lt; sizeof(st3) &lt;&lt; endl;<br />cout &lt;&lt; "ps: " &lt;&lt; sizeof(ps) &lt;&lt; endl;<br />cout &lt;&lt; "*ps: " &lt;&lt; sizeof(*ps) &lt;&lt; endl;<br /><font color="#0000ff">*********************************************************</font><br /><br />输出结果为：<br />st1： 28<br />st2： 28<br />st3： 28<br />ps： 4<br />*ps： 28<br /></font>
						</font>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************<br /></font>对于不同的STL，String类的结构定义会有所不同<br />所以不同的工具，例如VC++，和.NET，结果会有所不同，<br />在VC++6.0中（我的机器）结果是16<br />在.NET2003中结果是28<br />但是对于同一个编译器，那么它的结果都是一定的<br /><br /><br /><font color="#0000ff"><strong>8.引用的sizeof</strong></font><br /><br /></font>
						</font>
						<font size="2">
								<font face="Verdana">
										<font style="BACKGROUND-COLOR: #ffffff" color="#0000ff">sizeof操作符应用在引用类型上的时候，返回的是包含被引用对象所需的内存长度（即被引用对象的大小）<br /></font>
										<br />
										<font color="#0000ff">*********************************************************</font>
										<br />cout &lt;&lt; "short:\t" &lt;&lt; sizeof(short) &lt;&lt; endl;<br />cout &lt;&lt; "short*:\t" &lt;&lt; sizeof(short*) &lt;&lt; endl; <br />cout &lt;&lt; "short&amp;:\t" &lt;&lt; sizeof(short&amp;) &lt;&lt; endl;<br />cout &lt;&lt; "short[4]:\t" &lt;&lt; sizeof(short[4]) &lt;&lt; endl;<br />cout &lt;&lt; "int&amp;:\t" &lt;&lt; sizeof(int&amp;) &lt;&lt; endl;<br /></font>
						</font>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************<br /></font>
										<br />输出结果为：<br />short： 2<br />short*： 4<br />short&amp;： 2<br />short[4]： 8<br />int&amp;： 4<br /><br /><br /><strong><font color="#0000ff">9. 结构体的sizeof</font></strong></font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">这是初学者问得最多的一个问题，所以这里有必要多费点笔墨。让我们先看一个结构体： </font>
				</p>
				<p>
						<font face="Verdana" size="2">struct S1<br />{<br />    char c;<br />    int i;<br />}; </font>
				</p>
				<p>
						<font face="Verdana" size="2">问sizeof(s1)等于多少？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">聪明的你开始思考了，char占1个字节，int占4个字节，那么加起来就应该是5。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">是这样吗？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">你在你机器上试过了吗？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">也许你是对的，但很可能你是错的！ </font>
				</p>
				<p>
						<font face="Verdana" size="2">VC6中按默认设置得到的结果为8。<br /><br />    Why？为什么受伤的总是我？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">请不要沮丧，我们来好好琢磨一下sizeof的定义 —— sizeof的结果等于对象或者类型所占的内存字节数。好吧，那就让我们来看看S1的内存分配情况： </font>
				</p>
				<p>
						<font face="Verdana" size="2">S1 s1 = { 'a', 0xFFFFFFFF }; </font>
				</p>
				<p>
						<font face="Verdana" size="2">定义上面的变量后，加上断点，运行程序，观察s1所在的内存，你发现了什么？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">以我的VC6.0为例，s1的地址为0x0012FF78，其数据内容如下： </font>
				</p>
				<p>
						<font face="Verdana" size="2">0012FF78: 61 CC CC CC FF FF FF FF<br /><br />发现了什么？怎么中间夹杂了3个字节的CC？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">看看MSDN上的说明： </font>
				</p>
				<p>
						<font face="Verdana" size="2">When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment. </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">原来如此，这就是传说中的字节对齐啊！一个重要的话题出现了。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">为什么需要字节对齐？ </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">计算机组成原理教导我们，这样有助于加快计算机的取数速度，否则就得多花指令周期了。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">为此，编译器默认会对结构体进行处理（实际上其它地方的数据变量也是如此），<font color="#0000ff">让宽度为2的基本数据类型（short等）都位于能被2整除的地址上，让宽度为4的基本数据类型（int等）都位于能被4整除的地址上。</font>以此类推，这样，两个数中间就可能需要加入填充字节，所以整个结构体的sizeof值就增长了。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">让我们交换一下S1中char与int的位置： </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">struct S2<br />{<br />    int i;<br />    char c;<br />}; </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">看看sizeof(S2)的结果为多少？怎么还是8。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">再看看内存，原来成员c后面仍然有3个填充字节。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">这又是为什么啊？别着急，下面总结规律。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">    <strong><font color="#0000ff">字节对齐的细节和编译器实现相关，但一般而言，满足三个准则：</font></strong><br />    1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除；<br />    2) 结构体每个成员相对于结构体首地址的偏移量（offset）都是成员大小的整数倍，如有需要编译器会在成员之间加上填充字节（internal adding）；<br />    3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍，如有需要编译器会在最末一个成员之后加上填充字节（trailing padding）。<br /><br />    对于上面的准则，有几点需要说明：<br />1) 前面不是说结构体成员的地址是其大小的整数倍，怎么又说到偏移量了呢？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">因为有了第1点存在，所以我们就可以只考虑成员的偏移量，这样思考起来简单。想想为什么。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得，这个宏也在stddef.h中定义，如下： </font>
				</p>
				<p>
						<font face="Verdana" size="2">#define offsetof(s,m) (size_t)&amp;(((s *)0)-&gt;m) </font>
				</p>
				<p>
						<font face="Verdana" size="2">例如，想要获得S2中c的偏移量，方法为 </font>
				</p>
				<p>
						<font face="Verdana" size="2">size_t pos = offsetof(S2, c);// pos等于4 </font>
				</p>
				<p>
						<br />
						<font face="Verdana" size="2">2) 基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型。这里所说的“数据宽度”就是指其sizeof的大小。由于结构体的成员可以是复合类型，比如另外一个结构体，所以在寻找最宽基本类型成员时，应当包括复合类型成员的子成员，而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">这里叙述起来有点拗口，思考起来也有点挠头，还是让我们看看例子吧（具体数值仍以VC6为例，以后不再说明）： </font>
				</p>
				<p>
						<font face="Verdana" size="2">struct S3<br />{<br />    char c1;<br />    S1 s;<br />    char c2;<br />}; </font>
				</p>
				<p>
						<font face="Verdana" size="2">S1的最宽简单成员的类型为int，S3在考虑最宽简单类型成员时是将S1“打散”看的，所以S3的最宽简单类型为int。这样，通过S3定义的变量，其存储空间首地址需要被4整除，整个sizeof(S3)的值也应该被4整除。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">c1的偏移量为0，s的偏移量呢？这时s是一个整体，它作为结构体变量也满足前面三个准则，所以其大小为8，偏移量为4，c1与s之间便需要3个填充字节，而c2与s之间就不需要了，所以c2的偏移量为12，算上c2的大小为13，13是不能被4整除的，这样末尾还得补上3个填充字节。最后得到sizeof(S3)的值为16。 </font>
				</p>
				<p>
						<br />
						<font face="Verdana" size="2">    通过上面的叙述，我们可以得到一个公式：<br />    <font color="#0000ff"><strong>结构体的大小等于最后一个成员的偏移量加上其大小再加上末尾的填充字节数目，</strong></font>即： </font>
				</p>
				<p>
						<font face="Verdana" size="2">sizeof( struct ) = offsetof( last item ) + sizeof( last item ) + sizeof( trailing padding ) </font>
				</p>
				<p>
						<font face="Verdana" size="2">
						</font> </p>
				<div>
						<font color="#0000ff">
								<font size="2">
										<font face="Verdana">
												<strong>10.类的sizeof</strong>
										</font>
								</font>
						</font>
				</div>
				<div>
						<font face="Verdana" size="2">
						</font> </div>
				<div>
						<font face="Verdana" size="2">类的sizeof值等于类中成员变量所占用的内存字节数。如：<br /></font>
				</div>
				<div>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">****************************************************************</font>
								</font>
						</font>
				</div>
				<div>
						<font face="Verdana" size="2">  </font>
				</div>
				<div>
						<font face="Verdana" size="2">class A<br />{<br /> public:<br />     int b;<br />     float c;<br />     char d;<br />}; </font>
				</div>
				<div>
						<br />
						<font face="Verdana" size="2">int main(void)<br />{<br />  A object;<br />  cout &lt;&lt; "sizeof(object) is " &lt;&lt; sizeof(object) &lt;&lt; endl;<br />  return 0 ;<br />} </font>
				</div>
				<div>
						<font face="Verdana" size="2">
						</font> </div>
				<div>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">***************************************************************</font>
								</font>
						</font>
				</div>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">输出结果为12（我的机器上sizeof(float)值为4，字节对其前面已经讲过）。 </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">不过需要注意的是，如果类中存在静态成员变量，结果又会是什么样子呢？ </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font size="2">
						<font face="Verdana">
								<font color="#0000ff">***************************************************************</font>
						</font>
				</font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">class A<br />{<br /> public:<br />     static int a;<br />     int b;<br />     float c;<br />     char d;<br />}; </font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">int main()<br />{ </font>
		</div>
		<div>
				<font face="Verdana" size="2">  A object;<br />  cout &lt;&lt; "sizeof(object) is " &lt;&lt; sizeof(object) &lt;&lt; endl;<br />  return 0 ;<br />} </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font size="2">
						<font face="Verdana">
								<font color="#0000ff">**************************************************************</font>
						</font>
				</font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">16？不对。结果仍然是12. </font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">因为在程序编译期间，就已经为static变量在静态存储区域分配了内存空间，并且这块内存在程序的整个运行期间都存在。 </font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">而每次声明了类A的一个对象的时候，为该对象在堆上，根据对象的大小分配内存。 </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">如果类A中包含成员函数，那么又会是怎样的情况呢？看下面的例子 </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font size="2">
						<font face="Verdana">
								<font color="#0000ff">*************************************************************</font>
						</font>
				</font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">class A<br />{<br /> public:<br />     static int a;<br />     int b;<br />     float c;<br />     char d;<br />     int add(int x,int y)<br />     {<br />       return x+y;<br />     }<br />}; </font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">int main()<br />{<br />  A object;<br />  cout &lt;&lt; "sizeof(object) is " &lt;&lt; sizeof(object) &lt;&lt; endl;<br />  b = object.add(3,4);<br />  cout &lt;&lt; "sizeof(object) is " &lt;&lt; sizeof(object) &lt;&lt; endl;<br />  return 0 ;<br />} </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font size="2">
						<font face="Verdana">
								<font color="#0000ff">***************************************************************</font>
						</font>
				</font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">结果仍为12。<font color="#0000ff"></font></font>
		</div>
		<div>
				<font face="Verdana" color="#0000ff" size="2">
				</font>
		</div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">因为只有非静态类成员变量在新生成一个object的时候才需要自己的副本。 </font>
				</span>
		</div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">所以每个非静态成员变量在生成新object需要内存，而function是不需要的。 </font>
				</span>
		</div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">
						</font>
				</span> </div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">
						</font>
				</span> </div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">注：C++中的多态和虚继承也是非常重要的东西，不过比较复杂，编译器不同，细节也有所不同。（以后慢慢研究，哈哈）<br /></font>
				</span>
		</div>
<img src ="http://www.cppblog.com/majianan/aggbug/11682.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-08-25 09:25 <a href="http://www.cppblog.com/majianan/archive/2006/08/25/11682.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>生活感悟</title><link>http://www.cppblog.com/majianan/archive/2006/07/17/10172.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Mon, 17 Jul 2006 14:14:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/07/17/10172.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/10172.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/07/17/10172.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/10172.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/10172.html</trackback:ping><description><![CDATA[
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
						<p align="left">
								<font face="Verdana" size="2">辛辛苦苦,过舒服日子;<br />舒舒服服,过辛苦日子!</font>
						</p>
				</blockquote>
		</blockquote>
<img src ="http://www.cppblog.com/majianan/aggbug/10172.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-07-17 22:14 <a href="http://www.cppblog.com/majianan/archive/2006/07/17/10172.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>厚道</title><link>http://www.cppblog.com/majianan/archive/2006/07/17/10147.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Mon, 17 Jul 2006 01:13:00 GMT</pubDate><guid>http://www.cppblog.com/majianan/archive/2006/07/17/10147.html</guid><wfw:comment>http://www.cppblog.com/majianan/comments/10147.html</wfw:comment><comments>http://www.cppblog.com/majianan/archive/2006/07/17/10147.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/majianan/comments/commentRss/10147.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/majianan/services/trackbacks/10147.html</trackback:ping><description><![CDATA[
		<ul>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">锲诃夫说：有教养不是吃饭不洒汤，是别人洒汤的时候别去看他。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">有一个相似的美国俗语说：犯过错不是稀奇的事，稀奇的是别人犯错的时候别去讥笑他。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">“别去看他”和“别去讥笑他”是一种做人风范，在中国叫做“厚道”。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">厚道不是方法，虽然也可以当方法训练自己。它是人的本性。厚道之于人，是在什么也没做之中做了很大的事情，锲诃夫称之为“教养”。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">如果美德分为显性与隐性，厚道具有隐性特征。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">厚道不是愚钝，很多时候像愚钝。所谓“贵人话语迟”，迟在对一个人一件事的评价沉着，君子讷于言。尤其在别人蒙羞之际，“迟”的评价保全了别人的面子。真正的愚钝是不明曲直，而厚道乃是明白而又心存善良，以宽怀给别人一个补救的机会。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">厚道者能沉得住气。厚道不一定得到厚道的回报，但厚道之为厚道就在不图回报，随他去。急功近利的人远离厚道。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">在人际交往上，厚道是基石。它并非一时一事的犀利，是别人经过回味的赞赏。处世本无方法，也总有一些高明超越方法，那就是品格。品格可以发光，方法只是工具。厚道是经得起考验的高尚品格。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">厚道是冰水深层的劲流，它有力量，但表面不起波浪。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">厚道的人有主张。和稀泥，做好人，是乖巧之表现，与“厚”无关。无准则，无界限，是糊涂之表现，与“道”无关。</font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">厚道的人也有可能倔强，也可能不入俗流，宁可憨，而不巧。 </font>
						</div>
				</li>
				<li>
						<div class="postbody">
								<font face="Verdana" size="2">厚，是长麦子的土壤之厚，墙体挡风之厚。厚德尔后载物，做人达到这样的境界，已然得道。 </font>
						</div>
				</li>
		</ul>
<img src ="http://www.cppblog.com/majianan/aggbug/10147.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/majianan/" target="_blank">马嘉楠</a> 2006-07-17 09:13 <a href="http://www.cppblog.com/majianan/archive/2006/07/17/10147.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>