﻿<?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++博客-Sunshine Alike-随笔分类-转摘</title><link>http://www.cppblog.com/sunshinealike/category/9965.html</link><description>半完美主义</description><language>zh-cn</language><lastBuildDate>Sun, 11 Apr 2010 04:09:58 GMT</lastBuildDate><pubDate>Sun, 11 Apr 2010 04:09:58 GMT</pubDate><ttl>60</ttl><item><title>一个小故事：老师在毕业典礼上的讲话</title><link>http://www.cppblog.com/sunshinealike/archive/2010/04/10/112153.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Sat, 10 Apr 2010 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/04/10/112153.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/112153.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/04/10/112153.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/112153.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/112153.html</trackback:ping><description><![CDATA[   其一，“世界上第一高峰是哪座山?”大家哄堂大笑：“珠穆朗玛峰!”老师追问：“第二高峰呢?”同学们面面相觑，无人应声。老师在黑板上写：“屈居第二与默默无闻毫无区别。 ” <br />  <br />   其二，“有人要烧壶开水，等生好火发现柴不够，他该怎么办?”有的说赶快去找，有的说去借、去买。老师说：“为什么不把壶里的水倒掉一些?”大家一听，表示佩服。 <br />  <br />   其三，“古代有一人，想学立身的本领。经过反复比较，决心去学屠龙之技。他拜名师，日夜苦练，终有所成。他会怎么样呢?“同学们兴致勃勃，说他能成为英雄、明星，受世人崇拜。老师摇头：“这个人一定会潦倒一生，因为世上根本就没有龙。” <br />  <br />   你们应该要学会“如何做人、做事、做学问”：<b><br />   做人要力求出色，勇争第一，这样别人才能发现你、记住你；<br />   做事要敢于创新，方法灵活，千万不可墨守成规；<br />   做学问要学以致用，要懂得将知识转化为效益，闭门造车没有路。</b><img src ="http://www.cppblog.com/sunshinealike/aggbug/112153.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-04-10 12:23 <a href="http://www.cppblog.com/sunshinealike/archive/2010/04/10/112153.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转来一篇好文，学习一下</title><link>http://www.cppblog.com/sunshinealike/archive/2009/12/14/103148.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Sun, 13 Dec 2009 16:24:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2009/12/14/103148.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/103148.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2009/12/14/103148.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/103148.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/103148.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/sunshinealike/archive/2009/12/14/103148.html'>阅读全文</a><img src ="http://www.cppblog.com/sunshinealike/aggbug/103148.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2009-12-14 00:24 <a href="http://www.cppblog.com/sunshinealike/archive/2009/12/14/103148.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] 金山高管：热钱要有冷思考，运营远比研发烦</title><link>http://www.cppblog.com/sunshinealike/archive/2009/09/23/97048.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Wed, 23 Sep 2009 14:27:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2009/09/23/97048.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/97048.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2009/09/23/97048.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/97048.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/97048.html</trackback:ping><description><![CDATA[在最近这一个月里，总计有四拨人跟我谈过关于游戏创业的话题。他们都是震惊于游戏行业的光环，炫目于史玉柱大爷”没有比网游更赚钱的行业”、丁磊大叔”网络游戏这行睡着了都能赚钱”的观点，怀揣着大把热钱，热情洋溢并焦灼地向我询问：怎么搞？怎么搞才能赚大钱？<p>他
们共同的特点是：以前从事传统行业赚到了钱。有一位是我以前在上海认识的朋友，当时在上海卢湾区政府做宣传干事，后来下海去了深圳，开了个木吉它工厂，五
年赚了2个亿。从年初美国音乐爱好者把买吉它的钱都留在腰包里准备买面包开始，他的厂子慢慢也就关张了。总觉得以前做吉它太辛苦，总得盯着，质量问题关税
问题麻烦得紧，这不就揣上了2000万RMB，准备认认真真地考虑投入游戏行业的问题。</p><p>但这几位款爷对游戏行业都不了解，有的从来没玩过游
戏，有的只玩过空当接龙或扫雷，还有的仍然抱着游戏就是玩物丧志的观点。在我向他们普及游戏行业知识的时候，我觉得，对于这些热钱，最重要的就是要有冷思
考，把运营与研发分开。要一上来就准备把俩事一起办了，那太TM难了，估计2000万玩不转，得2亿。</p><p>这不，今儿在美国德州奥斯丁市的游戏
开发者大会上，暴雪的副总裁Frank Pearce也说了：运营一款游戏，比开发一款游戏要麻烦得多。原文是：”<font color="#ff0000">Operating an
online game is about more than just game
development.</font>”他的感慨是基于魔兽世界这款游戏而发的。对于这款游戏的研发和运营，分而看之，就非常有启发意义了。</p><p>在研发方面，WoW共有<font color="#ff1493">310人</font>。分别：</p><p>* <font color="#800080">游戏设计与策划团队，共有37人。</font>从这个系列游戏十年前开始开发至今，他们致力于建设这个虚拟世界，包括7万个技能/法术和4万个NPC。还有3个资料片加起来近8000个任务。暴雪还请了两位专职作家，专门负责撰写魔兽世界观相关的小说，故事，档案，等等。</p><p><br />* <font color="#ff0000">程序开发团队共有32个人</font>，负责引擎、系统、工具、游戏设置、服务器端技术，以及用户界面。迄今总计已经写了了<font color="#ff0000">550万</font>行代码。</p><p><br />*<font color="#ff0000"><font color="#800080">美术团队共有51人</font></font>，包括原画，人物，场景，副本，与美术相关的支持岗位。他们已制作了150万个美术资产。</p><p><br />* <font color="#800080">CG部门则专门负责游戏动画与视频的制作，以及音乐音效，共有123人</font>。音乐音效合起来总计时长已达27小时。</p><p><br />* <font color="#800080">质量控制（测试）部门有67人</font>，从游戏开发至今，总计跟踪和解决了18万个BUG。</p><p>而在运营方面呢？猜猜看……<b><font size="5">整个运营团队加起来有4600人</font></b>。包括但不限于：</p><p>* 平台服务：245<br />* 国际联络：1724<br />* 支付事项管理：340<br />* 游戏客服与GM：2056<br />* 财务部门：240<br />* 技术支持：121<br />* 网络技术：149</p><p>----------------------------------------------------------------</p><p>这个差别，太大了吧，超出我的相像  Orz ×2</p><p>难道游戏行业里的coding貌似很轻松啊，才30来个人就搞定了 &gt;_&lt;<br /></p><p>-----------------------------------------------------------------<br /></p><p>Frank Pearce也说了，正是研发体系与运营体系的通力合作，才造就了WoW在世界范围内的成功。</p><p>不
管怎么说，游戏研发相对来说简单一些；一帮热爱游戏并且卓有才华的年轻人，只要懂得合作，就有保障。说白了就是自己和自己叫劲。而运营则复杂多了，要与玩
家叫劲，要与服务器叫劲（暴雪的运维人员总计监控着13250台刀片服务器，包括75000个CPU，还有112.5个T的RAM。），和市场环境及政策
叫劲。Pearce介绍说，WoW目前有10个语言版本，要在其他语种的国家运营WoW的决心可不能轻易下。麻烦事儿多了去了，比如在中国，跟丁大叔合作
一起，也搞不定中国政府。</p><p>那对于想进入中国网游行业的热钱来说，到底是搞运营还是研发呢？说白了，两个都不好搞。搞运营初始投入的资金大，
你要么有用户，要么有资金。象蔡文胜那般，先搞4399小游戏，聚齐了人气再去搞Webgame运营平台。<b><font size="4">搞研发，象巨人的刘伟说的，门槛并不高；能让三
五十个人专心快乐工作，那就够了。但千万别一上来就研发和运营一起搞，摊子铺得巨大，那困难重重。</font></b>象我的入门老师王峰大叔的蓝港，听说比较困难。</p><p>当然，归根结底，有钱不算啥，关键还在于人才。你要有合适的人，做运营做研发甚至研发运营双头并进，都没啥问题。世上的事儿最难搞的就是人事。一个人在这里有才，在那里才华未必能显现出来；跟这个配合挺好，跟那个未必能有啥成绩。玄之又玄啊，用人之道。</p><p>所以，现在这个行业普遍开始尊重人的劣根性了。陈天桥开始18了，史玉柱开始赢在巨人还内部改制了，张朝阳和王滔开始祈宝了……我们都知道，人在给自己干事儿的时候，心情才会更开心。</p><p>于
是，当这几位款爷依旧对我所讲的运营与研发之别云山雾罩的时候，我感到这个深奥的话题不能再继续了。于是就转而开说人才。当我对人才难觅深感头痛的时候，
他们却颇不以为然。那我就问了：你是准备向史玉柱学习，给开发团队分他51%干股吗？这四位在四个不同的时间做出四个相同的表情：不会吧，这行业这么过份？</p><p>（本文部分内容为编译，原文地址：http://www.gamasutra.com/php-bin/news_index.php?story=25307）</p><img src ="http://www.cppblog.com/sunshinealike/aggbug/97048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2009-09-23 22:27 <a href="http://www.cppblog.com/sunshinealike/archive/2009/09/23/97048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从MFC与ATL的男女关系说起[转]</title><link>http://www.cppblog.com/sunshinealike/archive/2009/08/03/92102.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Mon, 03 Aug 2009 14:53:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2009/08/03/92102.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/92102.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2009/08/03/92102.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/92102.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/92102.html</trackback:ping><description><![CDATA[
		<p style="text-indent: 2em;">
				<u>                </u>
				<u>写的很有意思，转摘了                         </u>
				<br />
		</p>
		<p style="text-indent: 2em;">我从大三开始学习MFC，对于一个学软件的学生来说算是有点晚，到现在差不多有3个年头了。
我在大四进入公司实习开始学习COM，接触到ATL并用它来做开发。我在大二冬天开始恋爱，到现在为止第一段爱情走过3个半年头终于到了末路。这些对于我
来说都算初尝，尝之有味所以写一点胡言乱语。 </p>
		<p style="text-indent: 2em;">
				<strong>男女关系</strong>
		</p>
		<p style="text-indent: 2em;">如果从哲学的观点来看，这大概要说是一种辩证关系了!</p>
		<p style="text-indent: 2em;">首先谈谈男人。男人与男孩的区别在于责任，对于一个男人来说，他的肩膀永远有负担，他要解决
生活中遇到的所有问题，可以为妻儿带来幸福生活，可以赡养父母，可以做一些成就来创一番事业。所以男人不要轻生，因为你垮下就意味着你的负担没有了支撑，
也就是你不负责任。男人的这种责任体现了一种刚性，打不倒压不垮，坎坎坷坷一路走来即使没有扬名立万但是肩膀上的负担始终没有落下。铮铮铁骨、铁血男儿、
阳刚之美都是对男人的赞美，一个家庭男人是顶梁柱，这就是责任。</p>
		<p style="text-indent: 2em;">再谈谈女人。女人与女孩的区别在于柔情，少了撒娇和任性，多了体贴和温柔。女人是生活的调剂品，少了她尽管可以填抱肚皮、补充营养但食之无味。女人天生就是善于交际的，这本身体现的就是一种柔性，就像太极一样，以柔克刚，借助刚性体现柔美。</p>
		<p style="text-indent: 2em;">用建筑来形容男女关系，男人就像钢筋水泥搭建起来的框架承受着外力，女人则是对框架填补装修
使其美观，不同的男人有着不同的建筑风格，不同的女人可以使建筑呈现不同的美。成功的男人背后都有一个女人，钢筋水泥加上精心装饰让人体会到设计之美，至
于谁重要次要，谁表谁里都不是关键，关键的是刚柔的结合。</p>
		<p style="text-indent: 2em;">
				<font size="4">
						<b>MFC与ATL</b>
				</font>
		</p>
		<p style="text-indent: 2em;">MFC是一个男人，从Microsoft C/C++ version
7.0到Visual Stduio.net
2005一直承担着软件框架设计的角色，风风雨雨路不回头，屹立在软件设计大道，为开发者提供便利，著名的BCG库和XTREME库都是在MFC源码基础
上的改进。它大而繁杂，曲折通幽，粗旷豪放。它必须承担责任，提供软件设计的一套解决方案，而且背负着历史包袱，所以难免带有一些成熟男人的深邃而不被人
理解。如果你还一味的去批判它，那只能说你不懂男人的心，不理解一个男人难言之苦。 ATL</p>
		<p style="text-indent: 2em;">ATL是一个女人，小巧灵活讨人喜爱，它作为COM思想的实现而拿出来解决软件协作的问题。它可以不具体实现功能而只留出一些接口，接口两端相通并且随时拔插，多么完美一个女人!为一个C++对象配备一个ATL对象你可以想象有什么结果嘛?</p>
		<p style="text-indent: 2em;">软件设计中的MFC与ATL</p>
		<p style="text-indent: 2em;">以前我一直以为ATL就是做控件、构造插件接口体系的，而MFC就是用来做界面功能。它们属于不同体系，在功能级别上存在差异，所以只是在纵向上结合而没有尝试横向的结合。人类社会是自然的，软件社会也应该是自然的。自然代表一种随和，亲近，协调。</p>
		<p style="text-indent: 2em;">提到MFC，八九不离十就涉及到软件界面开发。目前来说软件复用需求越来越高，而软件功能的
不确定因素越来越大，一个特定的界面行为可能不确定。MFC是一个男人，用它可以做任何想做的界面，这就是它的刚性。但是我们到底是要去做什么还是告诉别
人我们可以做什么呢?如果我们一味的做，那我们充其量只是一个莽夫，是吕布有勇无谋。我告诉你我有一个MFC对象，还告诉你它可以做什么，这样不就够了。</p>
		<p style="text-indent: 2em;">MFC是男人天生缺乏沟通能力，所以无法告知外界它自身的行为，只有它自己知道。这时候就需
要一个管子插到对象内部去了解它，而ATL刚好提供了一个接口，将其一段插入MFC对象内部而露出另一端以便告知外界MFC对象内部的行为。这样的界面是
可解释的界面，它具有做事情的能力，但是它不去做，而成为可复用界面。</p>
<img src ="http://www.cppblog.com/sunshinealike/aggbug/92102.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2009-08-03 22:53 <a href="http://www.cppblog.com/sunshinealike/archive/2009/08/03/92102.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sizeof终极无惑 (转)</title><link>http://www.cppblog.com/sunshinealike/archive/2009/03/27/78046.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Fri, 27 Mar 2009 08:53:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2009/03/27/78046.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/78046.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2009/03/27/78046.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/78046.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/78046.html</trackback:ping><description><![CDATA[
		<p>
				<font size="2">转自：<a href="/andxie99/archive/2006/10/26/14230.html">http://www.cppblog.com/andxie99/archive/2006/10/26/14230.html</a><br /><br />1. 定义：<br />sizeof是C/C++中的一个操作符（operator），简单的说其作用就是返回一个对象或者类型所占的内存字节数。<br />MSDN上的解释为：<br />The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). <br />This keyword returns a value of type size_t.<br />其返回值类型为size_t，在头文件stddef.h中定义。这是一个依赖于编译系统的值，一般定义为<br />typedef unsigned int size_t;<br />世上编译器林林总总，但作为一个规范，它们都会保证char、signed char和unsigned char的sizeof值为1，毕竟char是我们编程能用的最小数据类型。 </font>
		</p>
		<p>
				<font size="2">
				</font> </p>
		<p>
				<font size="2">2. 语法：<br />sizeof有三种语法形式，如下：<br />1) sizeof( object ); // sizeof( 对象 );<br />2) sizeof( type_name ); // sizeof( 类型 );<br />3) sizeof object; // sizeof 对象;<br />所以，<br />int i;<br />sizeof( i ); // ok<br />sizeof i; // ok<br />sizeof( int ); // ok<br />sizeof int; // error<br />既然写法3可以用写法1代替，为求形式统一以及减少我们大脑的负担，第3种写法，忘掉它吧！<br />实际上，sizeof计算对象的大小也是转换成对对象类型的计算，也就是说，同种类型的不同对象其sizeof值都是一致的。这里，对象可以进一步延伸至表达式，即sizeof可以对一个表达式求值，编译器根据表达式的最终结果类型来确定大小，一般不会对表达式进行计算。如：<br />sizeof( 2 );// 2的类型为int，所以等价于 sizeof( int );<br />sizeof( 2 + 3.14 ); // 3.14的类型为double，2也会被提升成double类型，所以等价于 sizeof( double );<br />sizeof也可以对一个函数调用求值，其结果是函数返回类型的大小，函数并不会被调用，我们来看一个完整的例子：<br />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 />}<br />C99标准规定，函数、不能确定类型的表达式以及位域（bit-field）成员不能被计算sizeof值，即下面这些写法都是错误的：<br />sizeof( foo );// error</font>
		</p>
		<p>
				<font size="2">void foo2() { }<br />sizeof( foo2() );// error</font>
		</p>
		<p>
				<font size="2">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 />
				<font size="2">3. sizeof的常量性<br />sizeof的计算发生在编译时刻，所以它可以被当作常量表达式使用，如：<br />char ary[ sizeof( int ) * 10 ]; // ok<br />最新的C99标准规定sizeof也可以在运行时刻进行计算，如下面的程序在Dev-C++中可以正确执行：<br />int n;<br />n = 10; // n动态赋值<br />char ary[n]; // C99也支持数组的动态定义<br />printf("%d\n", sizeof(ary)); // ok. 输出10<br />但在没有完全实现C99标准的编译器中就行不通了，上面的代码在VC6中就通不过编译。所以我们最好还是认为sizeof是在编译期执行的，这样不会带来错误，让程序的可移植性强些。</font>
		</p>
		<p>
				<br />
				<font size="2">4. 基本数据类型的sizeof<br />这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型，由于它们都是和系统相关的，所以在不同的系统下取值可能不同，这务必引起我们的注意，尽量不要在这方面给自己程序的移植造成麻烦。<br />一般的，在32位编译环境中，sizeof(int)的取值为4。</font>
		</p>
		<p>
				<br />
				<font size="2">5. 指针变量的sizeof<br />学过数据结构的你应该知道指针是一个很重要的概念，它记录了另一个对象的地址。既然是来存放地址的，那么它当然等于计算机内部地址总线的宽度。所以在32位计算机中，一个指针变量的返回值必定是4（注意结果是以字节为单位），可以预计，在将来的64位系统中指针变量的sizeof结果为8。<br />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<br />指针变量的sizeof值与指针所指的对象没有任何关系，正是由于所有的指针变量所占内存大小相等，所以MFC消息处理函数使用两个参数WPARAM、LPARAM就能传递各种复杂的消息结构（使用指向结构体的指针）。</font>
		</p>
		<p>
				<br />
				<font size="2">6. 数组的sizeof<br />数组的sizeof值等于数组所占用的内存字节数，如：<br />char a1[] = "abc";<br />int a2[3];<br />sizeof( a1 ); // 结果为4，字符串末尾还存在一个NULL终止符<br />sizeof( a2 ); // 结果为3*4=12（依赖于int）<br />一些朋友刚开始时把sizeof当作了求数组元素的个数，现在，你应该知道这是不对的，那么应该怎么求数组元素的个数呢？Easy，通常有下面两种写法：<br />int c1 = sizeof( a1 ) / sizeof( char ); // 总长度/单个元素的长度<br />int c2 = sizeof( a1 ) / sizeof( a1[0] ); // 总长度/第一个元素的长度<br />写到这里，提一问，下面的c3，c4值应该是多少呢？<br />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 />}也许当你试图回答c4的值时已经意识到c3答错了，是的，c3!=3。这里函数参数a3已不再是数组类型，而是蜕变成指针，相当于char* a3，为什么？仔细想想就不难明白，我们调用函数foo1时，程序会在栈上分配一个大小为3的数组吗？不会！数组是“传址”的，调用者只需将实参的地址传递过去，所以a3自然为指针类型（char*），c3的值也就为4。</font>
		</p>
		<p>
				<font size="2">7. 结构体的sizeof<br />这是初学者问得最多的一个问题，所以这里有必要多费点笔墨。让我们先看一个结构体：<br />struct S1<br />{<br />char c;<br />int i;<br />};<br />问sizeof(s1)等于多少？聪明的你开始思考了，char占1个字节，int占4个字节，那么加起来就应该是5。是这样吗？你在你机器上试过了吗？也许你是对的，但很可能你是错的！VC6中按默认设置得到的结果为8。<br />Why？为什么受伤的总是我？<br />请不要沮丧，我们来好好琢磨一下sizeof的定义——sizeof的结果等于对象或者类型所占的内存字节数，好吧，那就让我们来看看S1的内存分配情况：<br />S1 s1 = { 'a', 0xFFFFFFFF };<br />定义上面的变量后，加上断点，运行程序，观察s1所在的内存，你发现了什么？<br />以我的VC6.0为例，s1的地址为0x0012FF78，其数据内容如下：<br />0012FF78:? 61 CC CC CC FF FF FF FF<br />发现了什么？怎么中间夹杂了3个字节的CC？看看MSDN上的说明：<br />When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment.<br />原来如此，这就是传说中的字节对齐啊！一个重要的话题出现了。<br />为什么需要字节对齐？计算机组成原理教导我们这样有助于加快计算机的取数速度，否则就得多花指令周期了。为此，编译器默认会对结构体进行处理（实际上其它地方的数据变量也是如此），让宽度为2的基本数据类型（short等）都位于能被2整除的地址上，让宽度为4的基本数据类型（int等）都位于能被4整除的地址上，以此类推。这样，两个数中间就可能需要加入填充字节，所以整个结构体的sizeof值就增长了。<br />让我们交换一下S1中char与int的位置：<br />struct S2<br />{<br />int i;<br />char c;<br />};<br />看看sizeof(S2)的结果为多少，怎么还是8？再看看内存，原来成员c后面仍然有3个填充字节，这又是为什么啊？别着急，下面总结规律。<br /><br />字节对齐的细节和编译器实现相关，但一般而言，满足三个准则：<br />1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除；<br />2) 结构体每个成员相对于结构体首地址的偏移量（offset）都是成员大小的整数倍，如有需要编译器会在成员之间加上填充字节（internal adding）；<br />3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍，如有需要编译器会在最末一个成员之后加上填充字节（trailing padding）。<br />对于上面的准则，有几点需要说明：<br />1) 前面不是说结构体成员的地址是其大小的整数倍，怎么又说到偏移量了呢？因为有了第1点存在，所以我们就可以只考虑成员的偏移量，这样思考起来简单。想想为什么。<br />结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得，这个宏也在stddef.h中定义，如下：<br />#define offsetof(s,m)?? (size_t)&amp;(((s *)0)-&gt;m)<br />例如，想要获得S2中c的偏移量，方法为<br />size_t pos = offsetof(S2, c);// pos等于4<br />2) 基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型，这里所说的“数据宽度”就是指其sizeof的大小。由于结构体的成员可以是复合类型，比如另外一个结构体，所以在寻找最宽基本类型成员时，应当包括复合类型成员的子成员，而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。<br />这里叙述起来有点拗口，思考起来也有点挠头，还是让我们看看例子吧（具体数值仍以VC6为例，以后不再说明）：<br />struct S3<br />{<br />char c1;<br />S1 s;<br />char c2<br />};<br />S1的最宽简单成员的类型为int，S3在考虑最宽简单类型成员时是将S1“打散”看的，所以S3的最宽简单类型为int，这样，通过S3定义的变量，其存储空间首地址需要被4整除，整个sizeof(S3)的值也应该被4整除。<br />c1的偏移量为0，s的偏移量呢？这时s是一个整体，它作为结构体变量也满足前面三个准则，所以其大小为8，偏移量为4，c1与s之间便需要3个填充字节，而c2与s之间就不需要了，所以c2的偏移量为12，算上c2的大小为13，13是不能被4整除的，这样末尾还得补上3个填充字节。最后得到sizeof(S3)的值为16。<br />通过上面的叙述，我们可以得到一个公式：<br />结构体的大小等于最后一个成员的偏移量加上其大小再加上末尾的填充字节数目，即：<br />sizeof( struct ) = offsetof( last item ) + sizeof( last item ) + sizeof( trailing padding )<br /><br />到这里，朋友们应该对结构体的sizeof有了一个全新的认识，但不要高兴得太早，有一个影响sizeof的重要参量还未被提及，那便是编译器的pack指令。它是用来调整结构体对齐方式的，不同编译器名称和用法略有不同，VC6中通过#pragma pack实现，也可以直接修改/Zp编译开关。#pragma pack的基本用法为：#pragma pack( n )，n为字节对齐数，其取值为1、2、4、8、16，默认是8，如果这个值比结构体成员的sizeof值小，那么该成员的偏移量应该以此值为准，即是说，结构体成员的偏移量应该取二者的最小值，公式如下：<br />offsetof( item ) = min( n, sizeof( item ) )<br />再看示例：<br />#pragma pack(push) // 将当前pack设置压栈保存<br />#pragma pack(2)// 必须在结构体定义之前使用<br />struct S1<br />{<br />char c;<br />int i;<br />};<br />struct S3<br />{<br />char c1;<br />S1 s;<br />char c2<br />};<br />#pragma pack(pop) // 恢复先前的pack设置<br />计算sizeof(S1)时，min(2, sizeof(i))的值为2，所以i的偏移量为2，加上sizeof(i)等于6，能够被2整除，所以整个S1的大小为6。<br />同样，对于sizeof(S3)，s的偏移量为2，c2的偏移量为8，加上sizeof(c2)等于9，不能被2整除，添加一个填充字节，所以sizeof(S3)等于10。<br />现在，朋友们可以轻松的出一口气了，:)<br /><br />还有一点要注意，“空结构体”（不含数据成员）的大小不为0，而是1。试想一个“不占空间”的变量如何被取地址、两个不同的“空结构体”变量又如何得以区分呢？于是，“空结构体”变量也得被存储，这样编译器也就只能为其分配一个字节的空间用于占位了。如下：<br />struct S5 { };<br />sizeof( S5 ); // 结果为1<br /></font>
		</p>
		<p>
				<font size="2">8. 含位域结构体的sizeof<br />前面已经说过，位域成员不能单独被取sizeof值，我们这里要讨论的是含有位域的结构体的sizeof，只是考虑到其特殊性而将其专门列了出来。<br />C99规定int、unsigned int和bool可以作为位域类型，但编译器几乎都对此作了扩展，允许其它类型类型的存在。<br />使用位域的主要目的是压缩存储，其大致规则为：<br />1) 如果相邻位域字段的类型相同，且其位宽之和小于类型的sizeof大小，则后面的字段将紧邻前一个字段存储，直到不能容纳为止；<br />2) 如果相邻位域字段的类型相同，但其位宽之和大于类型的sizeof大小，则后面的字段将从新的存储单元开始，其偏移量为其类型大小的整数倍；<br />3) 如果相邻的位域字段的类型不同，则各编译器的具体实现有差异，VC6采取不压缩方式，Dev-C++采取压缩方式；<br />4) 如果位域字段之间穿插着非位域字段，则不进行压缩；<br />5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。<br /><br />还是让我们来看看例子。<br />示例1：<br />struct BF1<br />{<br />char f1 : 3;<br />char f2 : 4;<br />char f3 : 5;<br />};<br />其内存布局为：<br />|_f1__|__f2__|_|____f3___|____|<br />|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|<br /><br />位域类型为char，第1个字节仅能容纳下f1和f2，所以f2被压缩到第1个字节中，而f3只能从下一个字节开始。因此sizeof(BF1)的结果为2。<br />示例2：<br />struct BF2<br />{<br />char f1 : 3;<br />short f2 : 4;<br />char f3 : 5;<br />};<br />由于相邻位域类型不同，在VC6中其sizeof为6，在Dev-C++中为2。<br />示例3：<br />struct BF3<br />{<br />char f1 : 3;<br />char f2;<br />char f3 : 5;<br />};<br />非位域字段穿插在其中，不会产生压缩，在VC6和Dev-C++中得到的大小均为3。<br /></font>
		</p>
		<p>
				<font size="2">9. 联合体的sizeof<br />结构体在内存组织上是顺序式的，联合体则是重叠式，各成员共享一段内存，所以整个联合体的sizeof也就是每个成员sizeof的最大值。结构体的成员也可以是复合类型，这里，复合类型成员是被作为整体考虑的。<br />所以，下面例子中，U的sizeof值等于sizeof(s)。<br />union U<br />{<br />int i;<br />char c;<br />S1 s;<br />};</font>
		</p>
<img src ="http://www.cppblog.com/sunshinealike/aggbug/78046.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2009-03-27 16:53 <a href="http://www.cppblog.com/sunshinealike/archive/2009/03/27/78046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>