﻿<?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++博客-记录代码点滴</title><link>http://www.cppblog.com/tuantuan/</link><description>WEB开发,高性能服务器开发,网络编程,游戏开发 跌跌撞撞中寻找未来</description><language>zh-cn</language><lastBuildDate>Tue, 14 Apr 2026 23:08:33 GMT</lastBuildDate><pubDate>Tue, 14 Apr 2026 23:08:33 GMT</pubDate><ttl>60</ttl><item><title>做事</title><link>http://www.cppblog.com/tuantuan/archive/2009/10/15/98673.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Thu, 15 Oct 2009 04:30:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2009/10/15/98673.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/98673.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2009/10/15/98673.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/98673.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/98673.html</trackback:ping><description><![CDATA[<p>第一：不要认为停留在心灵的舒适区域内是可以原谅的。 <br>　　 <br>　　每个人都有一个舒适区域，在这个区域内是很自我的，不愿意被打扰，不愿意被push，不愿意和陌生的面孔交谈，不愿意被人指责，不愿意按照规定的时限做事，不愿意主动的去关心别人，不愿意去思考别人还有什么没有想到。这在学生时代是很容易被理解的，有时候这样的同学还跟&#8220;冷酷&#8221;&#8220;个性&#8221;这些字眼沾边，算作是褒义。然而相反，在工作之后，你要极力改变这一现状。否则，你会很快变成鸡尾酒会上唯一没有人理睬的对象，或是很快因为压力而内分泌失调。但是，如果你能很快打破之前学生期所处的舒适区域，比别人更快的处理好业务、人际、舆论之间的关系，那就能很快的脱颖而出。 <br>　　 <br>　　在会议上，一个停留在心灵舒适区域的人会消极的听取领导的话语，消极的待命，很死的完成上级交给的事情，但从来不关心此事以外的任何事情，更不会想到多做一步，让接下来的别人的工作更加容易上手。而敢于打破这个舒适区域的人，敢于在适当的时候提出自己的看法和不理解，并在得到上级认可和指点之后把手头的工作尽快的完成，并随时接受别人的批评和调整。（注意：永远不要等待别人把你的想法说出来，这是典型的前者） <br>　　 <br>　　 <br>　　 <br>　　在工作上，当前者遇到一名新的同事，他会装作没有看见，继续自己的工作。殊不知新来的同事不久就变成了自己的上司。而后者则大方客气的自我介绍，并了解对方和自己的关系。 <br>　　 <br>　　在聚会上，前者总是等待别人发言，并喜欢私下里评论对方的言语；如果这个桌子上没有人发言，那直到用餐结束，也没有人认识你。而后者是勇敢的和一同吃饭的开始介绍和闲谈，这看起来很困难，有时候会有失面子，但往往你会发现，对方是多么希望能和你说几句话。 <br>　　 <br>　　以上只是很小的几个例子，但是要说明的是，大学生在走出校园的同时就要在工作上把校园中的&#8220;随意性&#8221;从身边赶走，尽早的冲出自己的舒适区域，开始做好和这个社会交流的准备。 <br>　　 <br>　　 <br>　　 <br>　　第二：不要把&#8220;好像&#8221;；&#8220;有人会&#8230;&#8230;&#8221;；&#8220;大概&#8221;；&#8220;晚些时候&#8221;；&#8220;或者&#8221;；&#8220;说不定&#8221;之类放在嘴边。尤其是和上级谈论工作的时候。 <br>　　 <br>　　我十分痛恨听到的一句话是：&#8220;我晚些时候会把这个文件发给所有的人&#8221;；因为这往往预示着我必须时刻提醒他不要忘记。同样，以下这些言辞也会让人觉得厌恶至极： <br>　　&#8220;到时候有人会把那些东西都准备好&#8221; <br>　　&#8220;大概是明天&#8221; <br>　　&#8220;明天或者后天客户会过来拜访&#8221; <br>　　&#8220;好像他说&#8230;&#8230;&#8221; <br>　　 <br>　　一般是人都会这样说话的，因为这样第一给自己留下了广阔的余地，第二也不会给别人造成很大的压迫感，好像什么事情一定要弄个水落石出似的。说实话大学里面再用功的人都有一半是混的。一个人要么是在课堂上是混的，要么下课之后是混的。两个都没有带有混的色彩的人，要么是超级牛人，要么是神经病。所以，就因为人人都在混的，所以校园是一个浪漫的地方，校园也容易让人单纯。所以学生社团的工作往往是效率很低的，我现在 <br>　　 <br>　　回想起学校里做的工作，当时还觉得挺卖力的，但工作了之后才开始感觉到什么是效率。 <br>　　 <br>　　当你进入了用金钱计算时间的地方之后，你要尽可能的避免在学校里养成的这种习惯。如果上级问你什么时候能实施你给他的承诺，而你回答&#8220;今晚或者明天早上&#8221;这样的答案对于他来说完全等同于你没有回答，并且还给他留下了一个坏印象。（当然，这样的回答往往在学校社团，学生会工作中是常见的） <br>　　 <br>　　有一个寓言故事，一只小老鼠刚刚出世不久，老鼠妈妈问小老鼠：你现在能看见了吗？ 小老鼠说：能。 老鼠妈妈说：那你能看到那块红薯吗？ 小老鼠说：是的。老鼠妈妈说：那是一块石头，这说明你不但还看不见东西，你连嗅觉都还没有。 <br>　　 <br>　　似是而非的应答往往一样会暴露出你更多的弱点。可能是以下中的一个或几个： <br>　　1.你之前没有想到这个工作，或者一直在拖延。 <br>　　2.你没有责任心，认为这些并不重要。 <br>　　3.你应付上级。 <br>　　4.你不敢说真话。 <br>　　5.你喜欢逞能，答应一些做不到的事情。 <br>　　6.你不能独立工作。 <br>　　当你的上级在以上选项中怀疑的时候，潜意识中你已经同时具备了以上所有的弱点了。 <br>　　 <br>　　 <br>　　 <br>　　相反的看来，这样的回答，总是让上司恼火。 <br>　　第一，他的问题没有得到回答，只是起到了提醒你的作用。 <br>　　第二，他依然需要记住提醒你，因为他不知道你是否真正已经落实了工作。 <br>　　第三，他不知道有多少你已经做了的事情中，都是这样没有落实的。（这点非常致命）　　　第四，往往因为没有得到满意的答案，上司自己的计划不得不被耽搁或推迟或不能给出明朗的结束时间。 <br>　　 <br>　　所以--------- <br>　　甲问：你什么时候能把要这个漏洞修好？ <br>　　乙说：我已经通知他们了，他们大概明天就会来修的。 <br>　　一天后 <br>　　甲问：维修公司什么时候回来，你找的是哪家维修公司？ <br>　　乙说：好像他们说安排不出人来，如果可以的话，今天晚上或者明天下午就能过来。 <br>　　一天后 <br>　　甲问：漏洞怎么还没有修好？ <br>　　乙说：我晚点再问问他们。 <br>　　甲说：今天下午之前不解决，明天不用来上班了。 <br>　　 <br>　　 <br>　　第三：不要拖延工作 <br>　　 <br>　　很多人喜欢在学习和玩耍之间先选择后者，然后在最后时间一次性赶工把考试要复习的东西突击完成。但是在工作中请不要养成这样的习惯，因为工作是永远做不完的，容不得你&#8220;突击&#8221;。又或者，当你在徘徊和彷徨如何实施的时候，你的领导已经看不下去，自己去做了。----这是一个危险的信号。 <br>　　 <br>　　往往我们总是想把事情从头到尾全部想好了，才开始走第一步-----就摔倒了。 <br>　　 <br>　　举个例子： 我小学的时候第一次给我一个喜欢的女孩子打电话的时候，想象了各种情况-------1，她接电话的时候在做作业。2，她在做作业，她妈妈接的电话。3.她也很无聊，很想找人说话。4.她正在被父母训斥。 5.她正在想另外一个男孩。6.她父亲接电话。 7.她家正好来了什么亲戚，亲戚接了电话。 8.她接了电话，但父母就在身边，说话不方便。。。。。等等等等。我整整想了一个下午，想好了各种情况的心理准备和应对的策略。然后勇敢的拿起电话机，按下了那几个按钮。结果-------她不在家。 <br>　　 <br>　　所以，当你徘徊不前而手足无措的时候，你要意识到你正在拖延工作。徘徊是因为害怕这个事情可能发生的后果需要自己承担或应付。工作的时候需要一种起码的自信，相信自己有能力，不管下一步是什么状况，我都能把它引导到我需要的那条线上去的。另外，告诉自己，不要想太多时间，如果不知道，就赶快求助，或想办法，苦恼和忧虑会给你更多的压力也会把剩下的时间蚕食殆尽。 <br>　　 <br>　　另外，警告一下：永远不要想，我知道了，先把上级派的事情放一下，等这集《越狱》看完再说。----90%的情况下，你会忘记，或者来不及，因为这件事需要比你原先想象要更多的时间。说做就做，一直是很好的习惯。 <br>　　 <br>　　第四：不要认为理论上可以实施就大功告成了！ <br>　　 <br>　　这点太重要了，往往当真正实施的人开始做了才会发现计划完全等于鬼话。如果不亲自实践，做计划的人会早晚被实施的鄙视。永远需要提升自己的办实事的能力，而不是空谈。 <br>　　 <br>　　首先，如果你是做办公室工作的，或者做策划和计划的。请千万不要把你自己都认为不太可能或者很难做到的事情，让别人试试看。比如，用一个下午的时间在人流量很少的地方举办露天歌唱会。这会让执行的人觉得你在玩他，拿他做实验。没错，理论上，在任何地方都能举办歌唱会，但是，在不同的地方，执行的人的心情是不一样的。 <br>　　 <br>　　其次，和执行的人讨论你的安排。比如，新来的你的下属，你可以安排她坐在任何地方，但是如果那是一个很难和大家接触的角落，这可能比你什么都不安排更差。的确，理论上一个人要坐下来，需要的只是空间。但事实上远远不止那些。 <br>　　 <br>　　再次，不要奢望一切会随着你的计划进行。理论上这个会议会持续两个小时，但是，这是&#8220;不考虑在开场后的30分钟全场都在调试话筒&#8221;，或者&#8220;场下没有提出如此尖锐的问题&#8221;的前提下的状态。 大学生已经习惯了把事情做到 "理论上看上去很美"的程度了。 论文，ppt讲演，考试，辩论赛&#8230;&#8230; 这些校园智商大比拼，都是教我们如何完美的做好&#8220;纸上谈兵&#8221;的功夫。 你一定要相信自己能&#8220;搞定&#8221;事情的能力比想象的弱。 <br>　　 <br>　　如果你是在学校的学生，测试一下自己，能否能搞定以下这些状况： <br>　　1.学校要制作一套校服，由你去寻找供应商，砍价，至少有三家公司的报价。 <br>　　2.学校保安抓住一个学生偷窃，怎么处理？ <br>　　3.学校的一个很重要路段的路灯坏了，你能否让它三天内继续亮起来。 <br>　　4.食堂需要请一位专门烧清真菜的厨师，一周内到岗位。 <br>　　 <br>　　当你开始思考以上这样的问题的时候，你会发现，你的思路和&#8220;看过去两年这个公司的业绩趋向，做出一个下个季度的市场策划方案&#8221;要相差极大。你会发现后者只要你做到&#8220;看上去很完美&#8221;，没有人知道按照你这样做结果会怎样。而上述的工作你只要一想，就会体会到不少的压力。因为你不处理好，结果就是明显的失败更大的问题就会相继发生。 <br>　　对了，这种感觉就是&#8220;工作&#8221;给你的感觉！这就是&#8220;工作&#8221;和&#8220;纸上谈兵&#8221;的差别！ <br>　　　 <br>　　第五：不要让别人等你 <br>　　 <br>　　在任何情况下都不要让别人放下手头的工作来等你。在大学中可能只是同寝室的人的几句半开玩笑的抱怨，在工作上很可能导致你的潜在合作伙伴的丢失。 <br>　　你在做一个工作的同时要知道别人的进度，而永远不要落后。这不像是在考试，你比别人做的慢，别人可以先交卷，你到时间了做不完你自己承受扣分。在工作中的情况是这样的：这是一场没有人能做完的考试，所有的人，都分配做一张试卷的不同部分，有的人分到的是阅读理解，有的人做的是完形填空，有的人做的是语法&#8230;&#8230; 然后大家做完了相互抄，这样，所有人都做完了。 如果大家都把各自的部分做完了，而你却还在没有做完，那么做得快的别人会开始做你的那部分题目，然后也是相互抄。慢慢地，大家会发现你的工作量完全可以由另外人来代替，整个团队中可以不需要你，这个时候，没有人从你这里得到试卷的答案，也没有人会给你他们的答案--------很不幸，你已经没有利用价值了。 <br>　　 <br>　　请一定记住这个例子。 <br>　　　 <br>　　 <br>　　第六：不要认为细节不重要 <br>　　 <br>　　在大学里，往往做事粗枝大叶，看看差不多就行了。相反，在企业里管理的精髓就在于将简单的事情做到细节。一个慌忙寻找保险箱钥匙的动作就很有可能丧失你晋升财务主管的机会。 <br>　　 <br>　　公司的管理，其实需要的并不是把很难的事情做到90%----比如，优化管理层的核心工作流程、改变公司在当地政府面前的形象，提高产品质量，改善工作环境&#8230;&#8230; 而管理要做的是把每个简单的事情做到100%-----比如，把公司的每个人的档案都按照一定的规律整齐的存放起来、在门卫设立一个外来人员的签到台、把会议室多余的椅子拿走、和电视台讲好下个礼拜三来公司做采访、把试用装送到客户手里、在生产的咖啡上加一个口子、给下一期的封面人物拍照&#8230;&#8230;等等如此。 如果你能把所有细节的问题都如实做到，那你才有开口升职的本钱。 <br>　　很多人在毕业的时候不知道自己将来要做什么，于是就和自己说：我以后做管理吧！做管理？问一下自己，如果，公司资产被偷窃了，所有员工士气低下，办公室杂乱无章，公司电梯又坏了，打印机没墨了，采购计划超支了，产品滞销了，客户迟到了&#8230;&#8230;你愿意解决这样的问题，并从小事开始做起吗？想好了这些再考虑是否把管理看得太空洞了。 <br>　　 <br>　　第七：不要表现得消极，仅仅因为你所做的事情不是你的兴趣所在。 <br>　　 <br>　　很显然，在学生时代，当做到自己喜欢的时候，我们会pay200%的精力去创造，但如果是枯燥的事务，我们便懒得理睬，最好能有办法应付过去。但在工作上80%你所做的事情都是繁琐而看似机械的，如果仅仅为此而表现的闷闷不乐，那么你会郁闷更久。要知道你的上司已经为这个项目够烦恼了，你还想让他看到你的表情吗？ <br>　　 <br>　　学会喜欢自己的工作，并把注意力放在日常工作能学到些什么上去。如果现在你努力的抱怨工作，那么接下来你就是努力的寻找工作。尽量少用&#8220;有趣&#8221;，&#8220;好奇&#8221;之类的词语来描述自己想要的工作，而是&#8220;充实&#8221;，&#8220;有成就感&#8221;，&#8220;乐意&#8221;之类。 <br>　　想想以下职位，你会发现生活中很多工作不是在等你有很好的状态下让你做的很有趣的事情： <br>　　1.高速公路收费口的收费员：一天都是面对一个小窗口，把一张卡片送出去，这样要持续好几年。 <br>　　2.学校食堂厨师：永远在烧大排和鸡腿。烧一年。 <br>　　3.作家：交稿期要到了，我还在孕育灵感，两个星期没吃早饭了。 <br>　　4.外科医生：刚刚睡着，马上叫我做一个3小时的手术。这样至少一周一次。 <br>　　5.门市部销售：产品不好卖，8点上班来就坐在店门口，一个人，坐到晚上6点，今天没有一个人来，和昨天一样。 <br>　　6.公交司机：我开车不用你指挥。这条线路我开了三年了。 <br>　　7.宠物商店店员：生意不好，还要一早就过来听着20条狗的叫声一整天，听一年。 <br>　　8.公司职员：晚上两点下班，第二天还要8点上班。关键是路上还要一小时。这样已经一个月了。 <br>　　 <br>　　再想想自己是不是只是接触了这个工作一个月或者才碰到没几个困难，这个时候抱怨的声音最大。 <br>　　千万不要想着去选择一个有趣的职业，因为没有那样的工作存在。没有哪一&#8220;种&#8221;行业是开心的，因为如果有，那所有人都去干那个了。最多试着问问自己本身的兴趣吧。self exploration。 <br>　　 <br>　　第八：绝对不要把改善工作能力仅寄托在公司培训上 <br>　　 <br>　　人绝对不可能经过一次培训就脱胎换骨。相反，集体培训上学到的东西往往是最用不上的信息。 就像食堂烧大锅菜一样，总没有你最想吃的菜，因为这样做容易，并且不容易得罪人。 <br>　　 <br>　　很多学生很看重所选的公司有没有培训，这说明，你不但不知道这个公司做什么，你甚至不知道怎样学习这些技能。 <br>　　我的感悟是如果你不知道怎么学你想要的知识，也不知道你想要的知识是什么，你只会做出两种行为：1。等待别人来教你，并且等待别人发现你不知道的地方。2.寻找现成的答案并且拷贝。期待公司培训的人，就很大概率上是第一种人（不排除极少真正优秀的公司培训） <br>　　 <br>　　许多的同学有这样的习惯思维： <br>　　因为，这个公司的培训能结束达到多少多少的程度 <br>　　又因为，这个程度正好是我想达到的 <br>　　所以我尽力进这家公司 <br>　　因为我进了这家公司 <br>　　所以它自然会使我达到了这个期望的程度。 <br>　　 <br>　　我们把参加培训和达到效果很幼稚的画上了等号。其实往往集体培训上所得到的信息是最没有实际操作价值的。永远不要期望单靠听课，靠老师把同样的东西给所有的人，你会得到比别人更多。把更多的心思放在观察和思考自己的需要上，找到问题的所在再通过观察和实践得到的答案才是真正的知识。 <br>　　 <br>　　所以，刚刚开始工作，什么都不会，不要认为那样是正常的，因为公司还没有培训过呢！等我接受培训了之后，我就全都会了。如果你一无所知还等待别人会可怜你的无知而施舍你知识，那你会为你的无知而付出更多的智商。 <br>　　 <br>　　 <br>　　第九：不要推卸责任 <br>　　 <br>　　推卸责任是害怕的条件反射。不要认为别人看不出这点。 　　我记得我小学里的一件事情。我一次作业没有带来，老师要训斥我，说：你怎么老是作业不带？ <br>　　我当时说：不是。。。。 当我正要支支吾吾时候，老师说：什么不是？你带来了没有？ <br>　　我说：没有 <br>　　老师说：那不就是没有带！什么不是！就是！ <br>　　之后我就发现，我只是害怕承担责任而条件反射似的就说了&#8220;不是&#8221;，仔细观察一下周围，你会发现，身边有无数的人在用&#8220;不是&#8221;作为被责问之后的第一反应。 <br>　　其实现在很多人面对工作也是这样，当上级责问的时候，很条件反射的就做出了推卸动作，然而这样的动作，接下来往往是无力的辩解，以及一些很粗糙的借口。这样会让上司感到你这个人很难沟通，并且很不真实。 <br>　　外一种情况，就是无论什么情况下，我指责一个人，他永远是强调客观。其实这点才是学生最典型的特征。这说明他太容易受到其他事物的影响，并受它们决定。如果你和上司之间会出现以下类型的对话，想想是不是需要改一下你的处事方法。 <br>　　 <br>　　甲：为什么到现在还没有给副总看你的报告！ <br>　　乙：刚才c在打印，我在等他结束，现在他大概好了吧，我去看看 <br>　　乙：还有点东西要修改 <br>　　乙：b也要把东西给副总，我因为等他 <br>　　乙：a他说我报告不用给副总看（a是乙的同级同事） <br>　　乙：不知道副总在不在哦，他的门关着。 <br>　　乙：d他叫我帮他打印文件！怪他！（d是乙的同级同事） <br>　　乙：我的杯子突然找不到了，在找杯子。 <br>　　 <br>　　 <br>　　不愿意负责任的人的不利在于他会让上司怀疑他的忠诚程度，因为上司给他的命令往往会因为一个小事情而被搁置或者打折执行，转而被他人的意识所改变。 <br>　　 <br>　　 <br>　　 <br>　　第十：不要对自己说&#8220;我是大学生&#8221; <br>　　 <br>　　这点包涵了很多信息。 <br>　　1.不要认为自己有多清高 <br>　　2.不要仍然以学生的标准要求自己 <br>　　3.不要感觉低人一等 <br>　　4.不要等待别人的关怀 <br>　　5.不要把这个作为犯错误自我安慰的借口 <br>　　6.不要忘记搞清楚，公司究竟给自己的待遇是多少，老练些，这不是在做志愿者。 <br>　　 <br>　　品格是处理好人际关系的基础，也是确保人际关系质量的关键。除此之外，人际交往的技巧也是尤为重要的。有些人做好事会让人感激一辈子，而有些人帮了别人却可能费力不讨好，不但得不到感激和回报，还让人心存嫉恨。将同样的产品以相同的价格推销给同一个客户，有些业务员可能被粗暴地赶出门，有些业务员却可能签到大单，甚至被客户奉为上宾。 <br>　　人际交往的技巧是一个非常庞杂的话题，囿于篇幅，在这里只能结合我的切身体会做一些 <br>　　 <br>　　简单的列举，挂一漏万在所难免了。 <br>　　1. 多给别人鼓励和表扬，尽量避免批评、指责和抱怨，不要逼别人认错。 <br>　　2. 要学会倾听。不要说得太多，想办法让别人多说。 <br>　　3. 如果你要加入别人的交谈，先要弄清楚别人究竟在说什么。 <br>　　4. 交谈之前尽量保持中立、客观。表明自己的倾向之前先要弄清楚对方真实的倾向。 <br>　　5. 注意对方的社交习惯并适当加以模仿。 <br>　　6. 不要轻易打断、纠正、补充别人的谈话。 <br>　　7. 别人有困难时，主动帮助，多多鼓励。 <br>　　8. 不要因为对方是亲朋好友而不注意礼节。 <br>　　9. 尽可能谈论别人想要的，教他怎样去得到他想要的。 <br>　　10. 始终以微笑待人。 <br>　　11. 做一个有幽默感的人。但是在讲笑话的时候千万不要只顾着自己笑。 <br>　　12. 做一个脱离低级趣味的人。 <br>　　13. 跟别人说话的时候尽量看着对方的眼睛，不管你是在说还是在听。 <br>　　14. 转移话题要尽量不着痕迹。 <br>　　15. 要学会聆听对方的弦外之音。也要学会通过弦外之音来委婉地表达自己的意思。 <br>　　16. 拜访别人一定要事先通知。 <br>　　17. 不要在别人可能忙于工作或者休息的时候打电话过去。除非是非常紧急的事情。 <br>　　18. 给别人打电话的时候，先问对方是否方便通话。 <br>　　19. 一件事情让两个人知道就不再是秘密。 <br>　　20. 你在背后说任何人的坏话都迟早有一天传入这个人的耳朵。 <br>　　21. 不要说尖酸刻薄的话。 <br>　　22. 牢记他人的名字。养成偶尔翻看名片簿、电话本的习惯。 <br>　　23. 尝试着跟你讨厌的人交往。 <br>　　24. 一定要尊重对方的隐私，不管是朋友还是夫妻。 <br>　　25. 很多人在一起的时候，当你与其中某个人交谈，请不要无视其他人的存在。 <br>　　26. 要勇于认错。 <br>　　27. 以谦卑的姿态面对身边的每一个人。 <br>　　28. 给予他人同情和谅解。 <br>　　29. 尽可能用&#8220;建议&#8221;取代&#8220;命令&#8221;。 <br>　　30. 不要轻易做出承诺。承诺的事情就一定要尽可能做到。</p>
<p><br>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/amj0622/archive/2009/10/08/4641906.aspx">http://blog.csdn.net/amj0622/archive/2009/10/08/4641906.aspx</a></p>
<img src ="http://www.cppblog.com/tuantuan/aggbug/98673.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2009-10-15 12:30 <a href="http://www.cppblog.com/tuantuan/archive/2009/10/15/98673.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pthread_create用法</title><link>http://www.cppblog.com/tuantuan/archive/2009/08/02/91970.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Sun, 02 Aug 2009 09:36:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2009/08/02/91970.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/91970.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2009/08/02/91970.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/91970.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/91970.html</trackback:ping><description><![CDATA[今天开始学习linux下用C开发多线程程序，Linux系统下的多线程遵循POSIX线程接口，称为pthread。<br>
<p>
<table class=allBorders cellSpacing=0 cellPadding=5 rules=none border=1>
    <tbody>
        <tr>
            <td class=docTableCell vAlign=top align=left>
            <pre>#include &lt;pthread.h&gt;<br><br>int pthread_create(pthread_t *restrict <span class=docEmphItalicAlt>tidp</span>,<br>                   const pthread_attr_t *restrict <span class=docEmphItalicAlt>attr</span>,<br>                   void *(*<span class=docEmphItalicAlt>start_rtn</span>)(void), <br>                   void *restrict <span class=docEmphItalicAlt>arg</span>);<br></pre>
            </td>
        </tr>
        <tr>
            <td class=docTableCell vAlign=top align=right>
            <p class=docText>Returns: 0 if OK, error number on failure</p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>C99 中新增加了 restrict 修饰的指针： 由 restrict 修饰的指针是最初唯一对指针所指向的对象进行存取的方法，仅当第二个指针基于第一个时，才能对对象进行存取。对对象的存取都限定于基于由 restrict 修饰的指针表达式中。 由 restrict 修饰的指针主要用于函数形参，或指向由 malloc() 分配的内存空间。restrict 数据类型不改变程序的语义。 编译器能通过作出 restrict 修饰的指针是存取对象的唯一方法的假设，更好地优化某些类型的例程。 </p>
第一个参数为指向线程标识符的指针。<br>第二个参数用来设置线程属性。<br>第三个参数是线程运行函数的起始地址。<br>最后一个参数是运行函数的参数。<br><br>下面这个程序中，我们的函数<code><span style="COLOR: rgb(0,0,0)">thr_fn<span style="COLOR: rgb(0,0,204)"></span></span></code>不需要参数，所以最后一个参数设为空指针。第二个参数我们也设为空指针，这样将生成默认属性的线程。当创建线程成功时，函数返回0，若不为0则说明创建线程失败，常见的错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线程，例如线程数目过多了；后者表示第二个参数代表的线程属性值非法。创建线程成功后，新创建的线程则运行参数三和参数四确定的函数，原来的线程则继续运行下一行代码。
<table style="BORDER-COLLAPSE: collapse" borderColor=#e99999 cellSpacing=0 cellPadding=0 width="95%" bgColor=#f1f1f1 border=1>
    <tbody>
        <tr>
            <td>
            <p style="MARGIN: 5px; LINE-HEIGHT: 150%"><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,204)">#</span><span style="COLOR: rgb(255,0,0)">include</span><span style="COLOR: rgb(0,0,204)">&lt;</span>stdio<span style="COLOR: rgb(0,0,204)">.</span>h<span style="COLOR: rgb(0,0,204)">&gt;</span><br><span style="COLOR: rgb(0,0,204)">#</span><span style="COLOR: rgb(255,0,0)">include</span><span style="COLOR: rgb(0,0,204)">&lt;</span>pthread<span style="COLOR: rgb(0,0,204)">.</span>h<span style="COLOR: rgb(0,0,204)">&gt;<br></span></span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,204)">#</span><span style="COLOR: rgb(255,0,0)">include</span><span style="COLOR: rgb(0,0,204)">&lt;</span>string<span style="COLOR: rgb(0,0,204)">.</span>h<span style="COLOR: rgb(0,0,204)">&gt;<br>#</span><span style="COLOR: rgb(255,0,0)">include</span><span style="COLOR: rgb(0,0,204)">&lt;</span>sys/types<span style="COLOR: rgb(0,0,204)">.</span>h<span style="COLOR: rgb(0,0,204)">&gt;<br>#</span><span style="COLOR: rgb(255,0,0)">include</span><span style="COLOR: rgb(0,0,204)">&lt;</span>unistd<span style="COLOR: rgb(0,0,204)">.</span>h<span style="COLOR: rgb(0,0,204)">&gt;</span></span></code><br><code><span style="COLOR: rgb(0,0,0)"><br><span style="COLOR: rgb(255,0,0)">pthread_t</span> ntid<span style="COLOR: rgb(0,0,204)">;</span><br><br><span style="COLOR: rgb(0,0,255)">void</span> printids<span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,255)">const</span> <span style="COLOR: rgb(0,0,255)">char</span> <span style="COLOR: rgb(0,0,204)">*</span>s<span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">{</span><br><span style="COLOR: rgb(255,0,0)">pid_t</span> pid<span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(255,0,0)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(255,0,0)"> pthread_t</span> tid<span style="COLOR: rgb(0,0,204)">;</span><br><br></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"> pid <span style="COLOR: rgb(0,0,204)">=</span> getpid<span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">;</span><br></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"> tid <span style="COLOR: rgb(0,0,204)">=</span> pthread_self<span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(255,0,0)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(255,0,0)"> printf</span><span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(255,0,255)">"%s pid %u tid %u (0x%x)\n"</span><span style="COLOR: rgb(0,0,204)">,</span>s<span style="COLOR: rgb(0,0,204)">,</span><span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,255)">unsigned</span> <span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,204)">)</span>pid<span style="COLOR: rgb(0,0,204)">,</span><span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,255)">unsigned</span> <span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,204)">)</span>tid<span style="COLOR: rgb(0,0,204)">,</span><span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,255)">unsigned</span> <span style="COLOR: rgb(0,0,255)"><br>int</span><span style="COLOR: rgb(0,0,204)">)</span>tid<span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(0,0,204)">}</span><br><br><span style="COLOR: rgb(0,0,255)">void</span> <span style="COLOR: rgb(0,0,204)">*</span>thr_fn<span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,255)">void</span> <span style="COLOR: rgb(0,0,204)">*</span><span style="COLOR: rgb(255,0,0)">arg</span><span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">{</span><br></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"> printids<span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(255,0,255)">"new thread:"</span><span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(0,0,255)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,255)"> return</span> <span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,255)">void</span> <span style="COLOR: rgb(0,0,204)">*</span><span style="COLOR: rgb(0,0,204)">)</span>0<span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(0,0,204)">}</span><br><br><span style="COLOR: rgb(0,0,255)">int</span> main<span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">{</span><br><span style="COLOR: rgb(0,0,255)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,255)"> int</span> err<span style="COLOR: rgb(0,0,204)">;</span><br><br></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"> err <span style="COLOR: rgb(0,0,204)">=</span> <span style="COLOR: rgb(255,0,0)">pthread_create</span><span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(0,0,204)">&amp;</span>ntid<span style="COLOR: rgb(0,0,204)">,</span><span style="COLOR: rgb(255,0,0)">NULL</span><span style="COLOR: rgb(0,0,204)">,</span>thr_fn<span style="COLOR: rgb(0,0,204)">,</span><span style="COLOR: rgb(255,0,0)">NULL</span><span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(0,0,255)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,255)"> if</span><span style="COLOR: rgb(0,0,204)">(</span>err <span style="COLOR: rgb(0,0,204)">!</span><span style="COLOR: rgb(0,0,204)">=</span> 0<span style="COLOR: rgb(0,0,204)">)</span></span></code><code><span style="COLOR: rgb(0,0,0)"></span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,204)">{</span><br><span style="COLOR: rgb(255,0,0)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(255,0,0)"> printf</span><span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(255,0,255)">"can't create thread: %s\n"</span><span style="COLOR: rgb(0,0,204)">,</span>strerror(err<span style="COLOR: rgb(0,0,204)">))</span><span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(0,0,255)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,255)"> return</span> 1<span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(0,0,204)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,204)"> }</span><br><br></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"> printids<span style="COLOR: rgb(0,0,204)">(</span><span style="COLOR: rgb(255,0,255)">"main thread:"</span><span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(255,0,0)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(255,0,0)"> sleep</span><span style="COLOR: rgb(0,0,204)">(</span>1<span style="COLOR: rgb(0,0,204)">)</span><span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(0,0,255)"></span></span></code><code><span style="COLOR: rgb(0,0,0)">&nbsp;</span></code><code><span style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,255)"> return</span> 0<span style="COLOR: rgb(0,0,204)">;</span><br><span style="COLOR: rgb(0,0,204)">}</span><br></span></code></p>
            </td>
        </tr>
    </tbody>
</table>
把APUE2上的一个程序修改一下，然后编译。<br>结果报错:<code><span style="COLOR: rgb(0,0,0)"><br>pthread.c:(.text+0x85)：对&#8216;pthread_create&#8217;未定义的引用</span></code><br><br>由于pthread库不是Linux系统默认的库，连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时，在编译中要加-lpthread参数:<br><code><span style="COLOR: rgb(0,0,0)">gcc -o pthread -lpthread pthread.c</span></code><br>
<img src ="http://www.cppblog.com/tuantuan/aggbug/91970.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2009-08-02 17:36 <a href="http://www.cppblog.com/tuantuan/archive/2009/08/02/91970.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>void指针 </title><link>http://www.cppblog.com/tuantuan/archive/2009/08/02/91968.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Sun, 02 Aug 2009 09:17:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2009/08/02/91968.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/91968.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2009/08/02/91968.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/91968.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/91968.html</trackback:ping><description><![CDATA[指针有两个属性:指向变量/对象的<font style="LINE-HEIGHT: 1.3em" color=#ff0000>地址</font><wbr>和<font style="LINE-HEIGHT: 1.3em" color=#ff0000>长度</font><wbr> <br>但是指针只存储地址,长度则取决于指针的类型 <br>编译器根据指针的类型从指针指向的地址向后寻址 <br>指针类型不同则寻址范围也不同,比如: <br>int*从指定地址向后寻找4字节作为变量的存储单元 <br>double*从指定地址向后寻找8字节作为变量的存储单元 <br><br>1.void指针是一种特别的指针 <br>&nbsp;&nbsp; void *vp <br>&nbsp;&nbsp;//说它特别是因为它没有类型 <br>&nbsp;&nbsp;//或者说这个类型不能判断出指向对象的长度 <br><br>2.任何指针都可以赋值给void指针 <br>&nbsp;&nbsp;type *p; <br>&nbsp;&nbsp;vp=p; <br>&nbsp;&nbsp;//不需转换 <br>&nbsp;&nbsp;//只获得变量/对象地址而不获得大小 <br><br>3.void指针赋值给其他类型的指针时都要进行转换 <br>&nbsp;&nbsp; type *p=(type*)vp; <br>&nbsp;&nbsp; //转换类型也就是获得指向变量/对象大小 <br>转:http://icoding.spaces.live.com/blog/cns!209684E38D520BA6!130.entry <br><br>4.void指针不能复引用 <br>&nbsp;&nbsp;*vp//错误 <br>&nbsp;&nbsp;因为void指针只知道,指向变量/对象的起始地址 <br>&nbsp;&nbsp;而不知道指向变量/对象的大小(占几个字节)所以无法正确引用 <br><br>5.void指针不能参与指针运算,除非进行转换 <br>&nbsp;&nbsp; (type*)vp++; <br>&nbsp;&nbsp;//vp==vp+sizeof(type)<br><br><br><br>#include&lt;iostream&gt;<br>#include&lt;stdlib.h&gt;<br>#include&lt;string&gt;<br>using namespace std;<br>typedef struct tag_st <br>{ <br>char id[10];<br>float fa[2];<br>}ST; <br>//我在程序里面这样使用的 <br>int main()<br>{<br>ST * P=(ST *)malloc(sizeof(ST));<br>strcpy(P-&gt;id,"hello!");<br>P-&gt;fa[0]=1.1;<br>P-&gt;fa[1]=2.1;<br><br>ST * Q=(ST *)malloc(sizeof(ST));<br>strcpy(Q-&gt;id,"world!");<br>Q-&gt;fa[0]=3.1;<br>Q-&gt;fa[1]=4.1;<br>void ** plink=(void **)P;<br>*((ST *)(plink)) = * Q; //<font style="LINE-HEIGHT: 1.3em" color=#ff0000>plink要先强制转换一下,目的是为了让它先知道要覆盖的大小.</font><wbr><br>&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 style="LINE-HEIGHT: 1.3em" color=#ff0000>P的内容竟然给Q的内容覆盖掉了.</font><wbr><br>cout&lt;&lt;P-&gt;id&lt;&lt;" "&lt;&lt;P-&gt;fa[0]&lt;&lt;" "&lt;&lt;P-&gt;fa[1]&lt;&lt;endl;<br>return 0;<br>} 
<img src ="http://www.cppblog.com/tuantuan/aggbug/91968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2009-08-02 17:17 <a href="http://www.cppblog.com/tuantuan/archive/2009/08/02/91968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux操作系统线程同步：互斥量（mutex）</title><link>http://www.cppblog.com/tuantuan/archive/2009/08/02/91964.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Sun, 02 Aug 2009 08:57:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2009/08/02/91964.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/91964.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2009/08/02/91964.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/91964.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/91964.html</trackback:ping><description><![CDATA[互斥量从本质上说就是一把锁, 提供对共享资源的保护访问。 <br>　　1. 初始化: <br>　　在Linux下, 线程的互斥量数据类型是pthread_mutex_t. 在使用前, 要对它进行初始化: <br>　　对于静态分配的互斥量, 可以把它设置为PTHREAD_MUTEX_INITIALIZER, 或者调用pthread_mutex_init. <br>　　对于动态分配的互斥量, 在申请内存(malloc)之后, 通过pthread_mutex_init进行初始化, 并且在释放内存(free)前需要调用pthread_mutex_destroy. <br>　　原型: <br>　　int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restric attr); <br>　　int pthread_mutex_destroy(pthread_mutex_t *mutex); <br>　　头文件: <br>　　返回值: 成功则返回0, 出错则返回错误编号. <br>　　说明: 如果使用默认的属性初始化互斥量, 只需把attr设为NULL. 其他值在以后讲解。 <br>　　2. 互斥操作: <br highlighted="2">　　对共享资源的访问, 要对互斥量进行<zmkey class=zoomino-searchword offset="19" path="body > div:eq(0) > div:eq(3) > table:eq(2) > tbody:eq(0) > tr:eq(0) > td:eq(0) > div:eq(0) > #content:eq(0) > br:eq(11)" anchorType="previous" jQuery1249203190531="6">加锁<span class=zoominoBgImage></span></zmkey>, 如果互斥量已经上了锁, 调用线程会阻塞, 直到互斥量被<zmkey class=zoomino-searchword offset="29" path="body > div:eq(0) > div:eq(3) > table:eq(2) > tbody:eq(0) > tr:eq(0) > td:eq(0) > div:eq(0) > #content:eq(0) > br:eq(11)" anchorType="previous" jQuery1249203190531="7">解锁<span class=zoominoBgImage></span></zmkey>. 在完成了对共享资源的访问后, 要对互斥量进行解锁。 <br>　　首先说一下加锁函数: <br>　　头文件: <br>　　原型: <br>　　int pthread_mutex_lock(pthread_mutex_t *mutex); <br>　　int pthread_mutex_trylock(pthread_mutex_t *mutex); <br>　　返回值: 成功则返回0, 出错则返回错误编号. <br>　　说明: 具体说一下trylock函数, 这个函数是非阻塞调用模式, 也就是说, 如果互斥量没被锁住, trylock函数将把互斥量加锁, 并获得对共享资源的访问权限; 如果互斥量被锁住了, trylock函数将不会阻塞等待而直接返回EBUSY, 表示共享资源处于忙状态。 <br>　　再说一下解所函数: <br>　　头文件: <br>　　原型: int pthread_mutex_unlock(pthread_mutex_t *mutex); <br>　　返回值: 成功则返回0, 出错则返回错误编号. <br>　　3. 死锁: <br>　　死锁主要发生在有多个依赖锁存在时, 会在一个线程试图以与另一个线程相反顺序锁住互斥量时发生. 如何避免死锁是使用互斥量应该格外注意的东西。 <br>　　总体来讲, 有几个不成文的基本原则: <br>　　对共享资源操作前一定要获得锁。 <br>　　完成操作以后一定要释放锁。 <br>　　尽量短时间地占用锁。 <br>　　如果有多锁, 如获得顺序是ABC连环扣, 释放顺序也应该是ABC。 <br>　　线程错误返回时应该释放它所获得的锁。
<img src ="http://www.cppblog.com/tuantuan/aggbug/91964.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2009-08-02 16:57 <a href="http://www.cppblog.com/tuantuan/archive/2009/08/02/91964.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用代码记录</title><link>http://www.cppblog.com/tuantuan/archive/2009/03/31/78458.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Tue, 31 Mar 2009 06:03:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2009/03/31/78458.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/78458.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2009/03/31/78458.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/78458.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/78458.html</trackback:ping><description><![CDATA[<span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::iterator&nbsp;it&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;ve.begin();&nbsp;it&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;ve.end();)<br></span><span id=Codehighlighter1_278_347_Open_Text><span style="COLOR: #000000"><br></span></span>
<img src ="http://www.cppblog.com/tuantuan/aggbug/78458.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2009-03-31 14:03 <a href="http://www.cppblog.com/tuantuan/archive/2009/03/31/78458.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工作很无聊,寻求新环境,寻求新方向</title><link>http://www.cppblog.com/tuantuan/archive/2008/12/28/70566.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Sun, 28 Dec 2008 08:18:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2008/12/28/70566.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/70566.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2008/12/28/70566.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/70566.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/70566.html</trackback:ping><description><![CDATA[工作很无聊,寻求新环境,寻求新方向，最后期限09年5月
<img src ="http://www.cppblog.com/tuantuan/aggbug/70566.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2008-12-28 16:18 <a href="http://www.cppblog.com/tuantuan/archive/2008/12/28/70566.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>强大的网络传输工具cURL和libcurl </title><link>http://www.cppblog.com/tuantuan/archive/2008/06/23/54416.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Mon, 23 Jun 2008 15:24:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2008/06/23/54416.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/54416.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2008/06/23/54416.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/54416.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/54416.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: cURL是一个利用URL语法的文件传输工具,是基于libcurl的前端命令行工具。它支持很多协议：FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及 LDAP。 它同样支持HTTPS认证，HTTP POST方法, HTTP PUT方法, FTP上传, kerberos认证, HTTP上传, 代理服务器, cookies, 用户名/密码认证, 下载文件断点续传, 上载文件断点续传, http代理服务器管道（ proxy tunneling）, 甚至它还支持IPv6, socks5代理服务器,通过http代理服务器上传文件到FTP服务器等等，功能十分强大。&nbsp;&nbsp;<a href='http://www.cppblog.com/tuantuan/archive/2008/06/23/54416.html'>阅读全文</a><img src ="http://www.cppblog.com/tuantuan/aggbug/54416.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2008-06-23 23:24 <a href="http://www.cppblog.com/tuantuan/archive/2008/06/23/54416.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏官网的运营</title><link>http://www.cppblog.com/tuantuan/archive/2008/06/23/54415.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Mon, 23 Jun 2008 15:19:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2008/06/23/54415.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/54415.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2008/06/23/54415.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/54415.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/54415.html</trackback:ping><description><![CDATA[<p>游戏官网是游戏推广的一个重要途径。<br></p>
<p><br>待完善&nbsp;</p>
<img src ="http://www.cppblog.com/tuantuan/aggbug/54415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2008-06-23 23:19 <a href="http://www.cppblog.com/tuantuan/archive/2008/06/23/54415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++资源之不完全导引（完整版）</title><link>http://www.cppblog.com/tuantuan/archive/2008/06/23/54414.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Mon, 23 Jun 2008 15:16:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2008/06/23/54414.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/54414.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2008/06/23/54414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/54414.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/54414.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 无数次听到“我要开始学习C++!”的呐喊，无数次听到“C++太复杂了，我真的<br>学不会”的无奈。Stan Lippman先生曾在《C++ Primer》一书中指出“C++是最为难<br>学的高级程序设计语言之一”，人们常将“之一”去掉以表达自己对C++的敬畏。诚<br>然，C++程序设计语言对于学习者的确有很多难以逾越的鸿沟，体系结构的庞大，应<br>接不暇并不断扩充的特性……除此之外，参考资料之多与冗杂使它的学习者望而却<br>步，欲求深入者苦不堪言。希望这一份不完全导引能够成为您C++学习之路上的引路<br>灯。<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/tuantuan/archive/2008/06/23/54414.html'>阅读全文</a><img src ="http://www.cppblog.com/tuantuan/aggbug/54414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2008-06-23 23:16 <a href="http://www.cppblog.com/tuantuan/archive/2008/06/23/54414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏Entity设计不完全整理</title><link>http://www.cppblog.com/tuantuan/archive/2008/06/23/54413.html</link><dc:creator>谢岱唛</dc:creator><author>谢岱唛</author><pubDate>Mon, 23 Jun 2008 15:09:00 GMT</pubDate><guid>http://www.cppblog.com/tuantuan/archive/2008/06/23/54413.html</guid><wfw:comment>http://www.cppblog.com/tuantuan/comments/54413.html</wfw:comment><comments>http://www.cppblog.com/tuantuan/archive/2008/06/23/54413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tuantuan/comments/commentRss/54413.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tuantuan/services/trackbacks/54413.html</trackback:ping><description><![CDATA[<div>
<p><span><span><span>在游戏引擎中，</span><span>Entity</span><span>通常被翻译成实体，也常用诸如</span><span>GameObject</span><span>、</span><span>Actor</span><span>、</span><span>SimulationObject</span><span>、</span><span>Unit</span><span>、</span><span>Character</span><span>等名字。相比于对图像声音引擎的热情，</span><span>Entity</span><span>层多年来一直备受冷遇，但最近几年随着大型游戏的发展，</span><span>Entity</span><span>层设计的重要性已经达到和图像声音的同等水平，而且已经出现了多种通用型</span><span>Entity</span><span>架构。当然，这里伴随着争议和分歧。</span></p>
<h3><span>直接模式（</span><span>The C Approach</span><span>）</span></h3>
<p><span>这是最早、最简单、也是任何人都能直接想到的模式。这种方式下一个</span><span>Entity</span><span>就是一个简单的</span><span>struct:</span></p>
<p><span>struct Mob<br>{<br>int level, hp, mp, attack, &#8230;;<br>};</span></p>
<p><span>这种情况下往往需要对不同类型的</span><span>Entity</span><span>定义不同的</span><span>struct</span><span>，比如</span><span>Player</span><span>、</span><span>Mob</span><span>、</span><span>Item</span><span>、</span><span>Doodad</span><span>等。</span><span>Entity</span><span>的数据库可以直接使用现成的数据库系统或者从数据文件读取，比如</span><span>csv</span><span>文件。一般会选择</span><span>Excel</span><span>编辑数据库，然后导出</span><span>csv</span><span>。</span><span>Excel</span><span>的强大表格和统计计算功能是调节游戏数据平衡的得力工具。以致这种最古老而简单的</span><span>Entity</span><span>模式以强大的生命力一直活到现在。</span></p>
<p><span>那么为什么</span><span>Developers</span><span>会要去探索其他方式呢？最大的问题是这种方式下各种</span><span>Entity</span><span>完全不同质。比如</span><span>Player</span><span>、</span><span>Mob</span><span>、</span><span>Doodad</span><span>都有位置，都要做碰撞检测，但他们却是不同的类型，不能使用同一份代码；</span><span>Player</span><span>和</span><span>Mob</span><span>都有</span><span>hp</span><span>和</span><span>mp</span><span>，也有基本相同的处理逻辑&#8230;&#8230;当然，这个可以用</span><span>hack</span><span>的方法解决：只要各个</span><span>struct</span><span>前若干个成员类型和顺序完全相同，就可以将指针</span><span>cast</span><span>成统一的一个</span><span>Entity</span><span>类型来处理。不过，任何人都能想到更好的办法，用类！</span></p>
<h3><span>继承模式（</span><span>Inheritage</span><span>）</span></h3>
<p><span>这也是</span><span>Entity</span><span>、</span><span>GameObject</span><span>等这些名字的由来，他们就是基类。于是我们可以得到一颗继承关系树，例如：</span></p>
<p><span>Entity</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Character</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Player</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Mob</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Missile</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Laser</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GuidedMissile</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Item</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;</span></p>
<p><span>Entity</span><span>对象的逻辑大多也是直接包含在类里的。但也有人采用了数据对象和逻辑对象的分离，其好处是对相同的数据可以替换不同的逻辑。不过，个人比较怀疑这种分离是否值得，因为类的派生本身就是可以拥有不同的逻辑。</span></p>
<p><span>另外，</span><span>Entity</span><span>间的交互除了用标准的直接访问方式外，经常使用消息模式。消息模式和</span><span>Windows</span><span>的消息模式类似，</span><span>Entity</span><span>间通过消息交互。虽说窗口编程画了多年时间才摆脱了当年肥大的</span><span>switch</span><span>的消息处理模式，在</span><span>Entity</span><span>层使用消息模式还是有意义的，因为消息很容易广播且可以直接在网络上发送。执着于</span><span>OO</span><span>的人会将消息写成</span><span>Command</span><span>对象，但原理仍然是一样的。</span></p>
<p><span>同时，联网游戏出现，指针不能在不同的机器上标识对象，我们必须用稳定的</span><span>ID</span><span>来标识对象，于是我们有了</span><span>EntityManager</span><span>来分配</span><span>ID</span><span>和管理对象集合，或者叫</span><span>GameObjectManager</span><span>、</span><span>ObjectManager</span><span>等。这在一段时期内几乎成了完美的方案。</span></p>
<p><span>随着游戏内容的丰富性的迅速膨胀，传统的由程序员来实现游戏逻辑功能的模式也越来越力不从心。脚本语言的集成将大部分创意性工作从程序员的担子上拿了下来，交还给游戏设计人员。为了给脚本提供足够的控制权，</span><span>Entity</span><span>结构上必须有充分的灵活性。</span></p>
<h3><span>数据驱动（</span><span>Data-Driven</span><span>）</span></h3>
<p><span>现在有句很流行的话，&#8220;唯一不变的是变化。（</span><span>The only constant is change.</span><span>）&#8221;数据驱动使得变化对引擎的影响最小化。数据驱动不能算是一种独立的</span><span>Entity</span><span>模式，不如说它是一种设计思想，其目的就是将内容制作和游戏引擎的制作分离开来。与上面所说的填充</span><span>Entity</span><span>属性数据库的不同之处在于，它还要能通过数据来设计游戏逻辑。</span></p>
<p><span>游戏设计人员需要的一项最基本功能就是自定义人物属性，所以与其在类里写死属性成员，不如使用属性表（</span><span>Attributes/Properties</span><span>）。通常使用一个哈希表（</span><span>Hashtable</span><span>），或者</span><span>std::map</span><span>，或者</span><span>Dictionary</span><span>，或者就是个数组，随个人喜好，其实就是要一个</span><span>key-value</span><span>的映射表。然后为脚本和编辑器提供对属性表的操作。</span></p>
<p><span>动态的逻辑主要就靠脚本了，必须为脚本提供足够的事件和方法。个人推荐用</span><span>Lua</span><span>脚本，因为它是在游戏领域内用得最多的通用脚本语言，其引擎很小、速度很快、易于集成，尽管语法过于松散。不要迷信宣传去用庞大、极慢、难于集成的</span><span>Python</span><span>。为脚本提供事件，其实也就是调用脚本里的函数，这里如果使用了前面所述的消息模式，那么就只要调用一个脚本方法，传递不同的消息参数就行了。当然也有人觉得这样很丑陋而更愿意为不同的事件注册不同的函数。</span></p>
<p><span>当有了数据驱动后，</span><span>Entity</span><span>的继承树就基本失去意义了，因为一个</span><span>Entity</span><span>是什么已经不是程序里决定的了，而是通过数据和脚本设计出来的。但数据和脚本又不是全部，一个</span><span>Entity</span><span>的核心内容和需要高效处理的部分，如碰撞检测，还是要程序来完成。于是我们需要重新设计</span><span>Entity</span><span>类，困难的局面也就由此开始。</span></p>
<p><span>一个直观的想法是一个统一且唯一的</span><span>Entity</span><span>类，它包含了所有的基本功能，如显示、碰撞检测、运动、背包等，然后由数据决定哪些组件被启用。比如一个玩家角色可能会启用绝大部分组件，而一颗树只启用显示和碰撞检测组件。但也伴随着缺点：一、这个类太大了；二、对于树木等一些简单的</span><span>Entity</span><span>也要浪费其他组件的私有数据所占的内存。那么一个简单的折中是部分使用继承、部分使用数据定制。例如</span><span>Entity</span><span>只提供最基本的组件，再派生出</span><span>CharactorEntity</span><span>提供足够人物角色使用的组件。</span></p>
<h3><span>组件模式（</span><span>Component-Based Entity</span><span>）</span></h3>
<p><span>提到组件，那么很自然的就过渡到组件模式，就是把显示、运动、攻击、背包、队伍、声音等基本功能都做成独立的组件，由数据来决定向</span><span>Entity</span><span>里添加哪些组件。由此可以得到另外一个扩展，就是既然可以有引擎内置的组件，那就也可以有脚本制作的组件，实现脚本模块的复用。这种模式在</span><span>GDC2002</span><span>正式提出，到现在主流的引擎都有这种设计。</span></p>
<p><span>这种模式在理论上很完美，但实践上还是有不少疑问。最常见的问题就是组件间的依赖关系。理想情况下，各个组件是完全独立的，但实践中必然有所依赖。比如运动速度、攻击强度等和角色的基本属性有关，运动组件需要角色的包围盒来测试是否碰撞，</span><span>AI</span><span>组件需要分析角色当前状态和发出运动、攻击命令，角色动作状态变化时改变显示组件属性，攻击组件需要访问队伍信息组件以禁止攻击队友等等。处理这种依赖关系主要要解决两个问题：</span></p>
<p>&lt;!--[if !supportLists]--&gt;<span><span>一、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span>谁依赖谁。比如是敏捷属性改变而去修改移动速度，还是运动组件读取敏捷属性来计算移动速度。如果要游戏设计人员自由定义基本属性的话，就要选择前者，因为基本属性组件会是脚本组件。</span></p>
<p>&lt;!--[if !supportLists]--&gt;<span><span>二、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span>如何取得另一组件的指针</span><span>/</span><span>引用。常见的方法是给每个组件类型一个唯一</span><span>ID</span><span>，然后用该</span><span>ID</span><span>在</span><span>Entity</span><span>上查询注册了的组件，如果找到返回其指针</span><span>/</span><span>引用，否则返回</span><span>null</span><span>。当然，每次访问都做这个查询会很浪费</span><span>CPU</span><span>，如果</span><span>Entity</span><span>的组件不会在运行时动态添加删除的话（除非在编辑器里，否则很少有人会这么做），可以在</span><span>Entity</span><span>初始化后让每个组件缓存它所要用的其他组件指针。那么当所依赖的组件不存在怎么办，一般情况下都是无声地忽略。</span></p>
<p><span>当</span><span>Entity</span><span>由很多组件组成后，交互的消息需要发给每一个组件。这里又一次体现出消息机制的优势，你不需要在</span><span>Entity</span><span>里为每一个事件函数写一个</span><span>loop</span><span>来调用组件的相应事件函数。但这里也出现了一个问题，消息到达各个组件的顺序。很多时候这个顺序不会有什么影响，但个别时候不同的顺序会导致完全不同的逻辑发展方向。</span></p>
<p><span>此外，</span><span>Entity</span><span>的序列化存储也变得比较复杂，经典的</span><span>Excel</span><span>导出</span><span>csv</span><span>的模式难以奏效，因为这里需要结构化的存储，所以需要结构化的数据文件如</span><span>XML</span><span>来存储，或者完全用脚本来包含所有数据和构造</span><span>Entity</span><span>。</span></p>
<p><span>据个人经验，使用数据驱动的继承模式时很是向往组件模式，感觉上它一个非常自然的扩展方向，但顾忌其引入的额外的复杂性，尤其是需要游戏设计人员具有一定的编程能力，所以一直不敢全盘接过使用。但退一步，在引擎里仍然使用组件思想，但</span><span>Entity</span><span>的组件构成在编译时固定，可以达到某种妥协，这和采用继承与数据驱动的折中类似。</span></p>
<h3><span>混入模式（</span><span>Mix-in</span><span>）</span></h3>
<p><span>这是又一种常见的折中模式，即使用</span><span>C++</span><span>的多重继承，将各个组件类混入一个</span><span>Entity</span><span>类。如：</span></p>
<p><span>class Mob: public GameObject, public Renderable, public Movable, public Attackable<br>{<br>&#8230;<br>}</span></p>
<p><span>这种方法因其简单而且非常符合多重继承设计思想而被很多引擎采用。当然缺点也是只能在支持多重继承的语言里使用，而且当组件很丰富时，</span><span>dynamic_cast</span><span>就变成一个代价高昂的操作。</span><span> <br></span></p>
<h3><span>功能性与复杂性（</span><span>Functionality vs Complexity</span><span>）</span></h3>
<p><span>编程领域最古老的原则之一就是要&#8220;简单快速&#8221;。但随着问题的复杂化，程序也随之变得越来越复杂。好的方法应该能有效的降低或隐藏复杂性。但是，没有不带副作用的药（</span><span>No silver bullet.</span><span>），在取得更强大的功能的同时总会带来额外的复杂性。我们需要做出权衡，在必要时牺牲一些功能，也就是要估算性价比。</span><br></p>
<p><span>一般游戏内容制作人员不会或不太会编程，编程人员也不善于游戏的内容创造和数值平衡，过于复杂的系统会导致需要两面兼顾的人才，会大大增加做出一款游戏的难度。</span></p>
</span></span></div>
<img src ="http://www.cppblog.com/tuantuan/aggbug/54413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tuantuan/" target="_blank">谢岱唛</a> 2008-06-23 23:09 <a href="http://www.cppblog.com/tuantuan/archive/2008/06/23/54413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>