<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4063622103172507649</id><updated>2011-05-18T22:55:26.818+08:00</updated><category term='lang-c'/><category term='linux-drivers-char'/><category term='lang-bash'/><category term='linux-drivers-net'/><category term='linux-generic'/><category term='lang-cpp'/><category term='science-physics'/><category term='miscs'/><category term='data-structure'/><category term='linux-net-core'/><category term='bootloader-redboot'/><category term='linux-drivers-gpio'/><category term='linux-block'/><category term='linux-openwrt'/><category term='linux-drivers-scsi'/><category term='linux-arch-arm'/><category term='lang-html'/><category term='group-szlug'/><title type='text'>Edwick</title><subtitle type='html'>在你的主页里，梦想应该永远置顶。
关注linux, android, google, game dev, 编程, 初创。</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>55</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-9219659864819851262</id><published>2011-05-18T22:53:00.003+08:00</published><updated>2011-05-18T22:55:26.851+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='group-szlug'/><title type='text'>2011年5月17日 SZLUG 月度聚会</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;这次聚会的主题是 ubuntu release party，除了展示 Ubuntu Natty 的变革，Unity 桌面&lt;br /&gt;的特性外，我们在现场还动手安装了 Ubuntu on LiveUSB 系统，另外还讨论了 SZLUG 的发&lt;br /&gt;展和现行出现的问题。&lt;br /&gt;&lt;a href="http://groups.google.com/group/szlug/browse_thread/thread/797a61acaef04db8" class="external free" rel="nofollow"&gt;&lt;br /&gt;&lt;/a&gt;相册集：&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/62891604@N02/sets/72157626599796761/" class="external free" rel="nofollow"&gt;http://www.flickr.com/photos/62891604@N02/sets/72157626599796761/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt; &lt;span id=".E4.B8.BB.E9.A2.98" class="mw-headline"&gt; 主题 &lt;/span&gt;&lt;/h2&gt;&lt;h3&gt; &lt;span id="SZLUG_.E5.8E.86.E5.8F.B2.E3.80.81.E5.8F.91.E5.B1.95.E4.B8.8E.E7.8E.B0.E7.8A.B6.2C_by_Wick" class="mw-headline"&gt; SZLUG 历史、发展与现状, by Wick&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ol&gt;&lt;li&gt; Wick个人介绍&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 为什么是我&lt;br /&gt;&lt;/li&gt;&lt;li&gt; SZLUG 历史&lt;br /&gt;&lt;/li&gt;&lt;li&gt; SZLUG 发展&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 问题探讨&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 和我们保持联系&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h3&gt; &lt;span id=".E4.BB.8B.E7.BB.8D_Ubuntu_Natty.2C_by_Wick" class="mw-headline"&gt; 介绍 Ubuntu Natty, by Wick &lt;/span&gt;&lt;/h3&gt;&lt;ol&gt;&lt;li&gt; 快速介绍Ubuntu历史&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 我与Ubuntu&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Ubuntu Natty 的改进与变革&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Unity桌面环境&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Banshee&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Office gets more libre!&lt;br /&gt;&lt;/li&gt;&lt;li&gt; linux 2.6.38, and a killer patch!&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 2D unity 接口&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 改进的 Ubuntu One 界面&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 改进的软件中心&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 拥抱QT&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; 增强体验： Unity小技巧&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Unity Plugin in Compiz&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Ubuntu Tweak 选项微调&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt; &lt;span id="Ubuntu_installfest" class="mw-headline"&gt; Ubuntu installfest &lt;/span&gt;&lt;/h3&gt;&lt;ol&gt;&lt;li&gt; 展示 Ubuntu LiveUSB 的安装和使用&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt; &lt;span id=".E8.87.AA.E7.94.B1.E8.AE.A8.E8.AE.BA.E9.98.B6.E6.AE.B5" class="mw-headline"&gt; 自由讨论阶段 &lt;/span&gt;&lt;/h3&gt;&lt;ol&gt;&lt;li&gt; Anders: SZLUG 发展的建议&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 黄略: 嵌入式合作开发项目&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 海波： 深圳 Linux 软件平台&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-9219659864819851262?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/9219659864819851262/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/05/2011517-szlug.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/9219659864819851262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/9219659864819851262'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/05/2011517-szlug.html' title='2011年5月17日 SZLUG 月度聚会'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-4840468396463889390</id><published>2011-05-18T22:32:00.001+08:00</published><updated>2011-05-18T22:32:40.932+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-generic'/><title type='text'>Kernel Module Loading Order</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&amp;gt; Is there any way to find out the module loading order? Who decide which module&lt;div class='no'&gt;&amp;gt; is loaded first?&lt;br/&gt;&lt;br/&gt;&lt;/div&gt;&lt;div class='level3'&gt;It's random and there is no way to specify the order unless you make one&lt;br /&gt;module a dependancy of the other. &lt;a rel='nofollow' title='http://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-May/001730.html' class='urlextern' href='http://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-May/001730.html'&gt;&lt;br/&gt;&lt;/a&gt;&lt;p&gt;&lt;a rel='nofollow' title='http://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-May/001730.html' class='urlextern' href='http://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-May/001730.html'&gt;http://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-May/001730.html&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-4840468396463889390?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/4840468396463889390/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/05/kernel-module-loading-order.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/4840468396463889390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/4840468396463889390'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/05/kernel-module-loading-order.html' title='Kernel Module Loading Order'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-692360770433498462</id><published>2011-05-18T22:17:00.004+08:00</published><updated>2011-05-18T22:21:25.221+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>五一节假日汕头之行 Shantou Tour on May Day Holiday</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;div class="level2"&gt;4/30-5/2 南澳自驾游&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;&lt;a id="行程" name="行程"&gt;行程&lt;/a&gt;&lt;/h3&gt;&lt;div class="level3"&gt;&lt;ul&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; Day 1. 汕头地区&lt;/div&gt;&lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 5h30m 路程，从罗湖到达汕头&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 早餐： 粿条，非常新鲜呐&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 休息，喝茶&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 10:00 午饭： 海鲜大餐&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 13:30 莱芜客运码头&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 14:10 乘风破浪，登陆南澳岛&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 关帝庙，展南亭，清澳湾洗浴&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 00:30 夜宿展南亭&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; Day 2. 南澳岛&lt;/div&gt;&lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 8：30 起床。户外洗漱&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 早饭&amp;amp;午饭： 丰富的县城小吃，白粥，粿条&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 后宅镇，前江码头，云澳村，青澳湾&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 青澳度假村，享受美丽海岸&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 雄镇关古城墙&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 风能发电站观景台&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 龙滨路大吃大排档。丁螺，薄壳，海瓜子，鱿鱼仔&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 回到后宅镇旅馆冲凉&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 再宿展南亭&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; Day 3. 南澳岛，回程&lt;/div&gt;&lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 8：30 起床。水土不服，拉肚子啦&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 沮丧，汽车熄火，南澳推车一日游&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 南澳环岛公路北段，黄花山森林公园，九尖山&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 13：30 离开南澳岛&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 午饭大餐： 海生大排档&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 汕头市区行： 购置海特产&lt;/div&gt;&lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; 21：30 离开汕头&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h3&gt;&lt;a id="感受" name="感受"&gt;感受&lt;/a&gt;&lt;/h3&gt;&lt;h3&gt;&lt;a id="感受" name="感受"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;h3&gt;&lt;a id="感受" name="感受"&gt;&lt;/a&gt;&lt;/h3&gt;事实上，汕头并不是想象中一个荒僻的小岛。实际它是广东唯一一个海岛县，八千年前就早有人存在，海岛上有金银岛，宋井，雄镇关等等历史古迹，所以南澳游会很像一个人文景观丰富的小岛。&lt;br /&gt;&lt;br /&gt;&lt;div class="level3"&gt;因此，南澳是一个可以待段日子的地方，贝类海鲜非常丰富，管你吃个新鲜吃个饱；而且可以有很多逛的地方： 风能发电厂，青澳湾等等都是非常优美的免费景点。海滩更是随处可见，这对于城市人来说特别奢侈。&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h3&gt;&lt;a id="遗憾" name="遗憾"&gt;遗憾&lt;/a&gt;&lt;/h3&gt;&lt;h3&gt;&lt;a id="遗憾" name="遗憾"&gt;&lt;/a&gt;&lt;/h3&gt;首先，南澳人都特别排外。这种源于小作坊小工厂的意识形态，在对待外地人时候更加严重。&lt;br /&gt;&lt;br /&gt;比如定旅馆，这里的价格高的离谱，双人标间给叫到200以上，南澳宾馆的标间打到540，而且不爱打理；海鲜排挡对外人来说甚至不给杀价；真是郁闷。&lt;br /&gt;&lt;br /&gt;&lt;div class="level3"&gt;其次，天气也让人很扫兴。我们在南澳的两个整天，都是大雾弥漫，空气湿热，气压很高，除了影响心情。对于拍友是个天杀的遗憾。天气不作美，再好的片子也出不来。&lt;br /&gt;&lt;br /&gt;最后，南澳岛环保意识非常之薄弱，走完全岛几乎都没有什么垃圾桶，更没有人定点清理。要知道很多景点都是收费的，那么收费之后谁来管理呢。要重点批驳一下，就是厕所实在太少了，岛上很多野生地点环境太糟糕，完全影响县城形象。&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-692360770433498462?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/692360770433498462/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/05/shantou-tour-on-may-day-holiday.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/692360770433498462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/692360770433498462'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/05/shantou-tour-on-may-day-holiday.html' title='五一节假日汕头之行 Shantou Tour on May Day Holiday'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2911378581351388136</id><published>2011-04-27T23:23:00.001+08:00</published><updated>2011-04-27T23:23:06.201+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-openwrt'/><title type='text'>HOWTO disable failsafe mode in Openwrt</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt; &lt;a rel='nofollow' title='https://forum.openwrt.org/viewtopic.php?id=28227' class='urlextern' href='https://forum.openwrt.org/viewtopic.php?id=28227'&gt;https://forum.openwrt.org/viewtopic.php?id=28227&lt;/a&gt; &lt;/p&gt;  &lt;p&gt; $ edit package/base-files/files/lib/preinit/30_failsafe_wait &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;script src='https://gist.github.com/944446.js'&gt; &lt;/script&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;and make ...&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=c986e721-318b-88cd-b4ab-917a857fa57a' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2911378581351388136?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2911378581351388136/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/04/howto-disable-failsafe-mode-in-openwrt.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2911378581351388136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2911378581351388136'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/04/howto-disable-failsafe-mode-in-openwrt.html' title='HOWTO disable failsafe mode in Openwrt'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2567168856468255440</id><published>2011-04-27T23:15:00.002+08:00</published><updated>2011-04-27T23:17:37.511+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-bash'/><title type='text'>intersection and union： find the difference between two directories</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;h2&gt;&lt;a id="intersection_and_union_find_the_difference_between_two_directories" name="intersection_and_union_find_the_difference_between_two_directories"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;a id="intersection_and_union_find_the_difference_between_two_directories" name="intersection_and_union_find_the_difference_between_two_directories"&gt;&lt;br /&gt;&lt;div class="level2"&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/944426.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Usage: ./cmpdir d1 d2&lt;br /&gt;&lt;br /&gt;`sort' just sort the lines alphabetically. the key is uniq&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="zemanta-pixie"&gt;&lt;img src="http://img.zemanta.com/pixy.gif?x-id=8e653c0a-7913-8e41-b660-c8d7acc96ee0" alt="" class="zemanta-pixie-img" /&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2567168856468255440?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2567168856468255440/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/04/intersection-and-union-find-difference.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2567168856468255440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2567168856468255440'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/04/intersection-and-union-find-difference.html' title='intersection and union： find the difference between two directories'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-7687254069705195532</id><published>2011-04-27T23:08:00.002+08:00</published><updated>2011-04-27T23:54:51.012+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='group-szlug'/><title type='text'>SZLUG April monthly meeting</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;h3&gt;&lt;a id="bring_up_vxworks_on_a_mips_core_by_rockins_chen" name="bring_up_vxworks_on_a_mips_core_by_rockins_chen"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;a id="bring_up_vxworks_on_a_mips_core_by_rockins_chen" name="bring_up_vxworks_on_a_mips_core_by_rockins_chen"&gt;  &lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a id="bring_up_vxworks_on_a_mips_core_by_rockins_chen" name="bring_up_vxworks_on_a_mips_core_by_rockins_chen"&gt;There are three main topics during the meeting.&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a id="bring_up_vxworks_on_a_mips_core_by_rockins_chen" name="bring_up_vxworks_on_a_mips_core_by_rockins_chen"&gt;Rockins's topic is a very good starting-point, even including the study case, TP-LINK's hiring ads. &lt;/a&gt;&lt;/p&gt;&lt;a id="bring_up_vxworks_on_a_mips_core_by_rockins_chen" name="bring_up_vxworks_on_a_mips_core_by_rockins_chen"&gt;  &lt;/a&gt;&lt;h3&gt;&lt;a id="bring_up_vxworks_on_a_mips_core_by_rockins_chen" name="bring_up_vxworks_on_a_mips_core_by_rockins_chen"&gt;&lt;/a&gt;&lt;a id="bring_up_vxworks_on_a_mips_core_by_rockins_chen" name="bring_up_vxworks_on_a_mips_core_by_rockins_chen"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;&lt;h3&gt;&lt;a name="bring_up_vxworks_on_a_mips_core_by_rockins_chen" id="bring_up_vxworks_on_a_mips_core_by_rockins_chen"&gt;Bring up Vxworks on a MIPS core, by Rockins Chen&lt;/a&gt;&lt;/h3&gt; &lt;div class="level3"&gt; &lt;ul&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; why vxworks: see pro and con below&lt;/div&gt; &lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; pro: simplicity, high quality code, document everything&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; con: proprietary, less existed package, inactive community&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; basic:&lt;/div&gt; &lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; multi-tasking&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; inter-task&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; communication&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; mm(first-fit)&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; IO system, UNIX-like file/dir/device, POSIX AIO …&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; fs: dosFs, rawFs, tapeFs, cdromFs, TSFs, TrueFFS for flash devices&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; network: TCP/IP, 802.1x, IPSec, NAT/NAPT, OSPF, Firewall, PPP …&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; A glance of VxWorks&lt;/div&gt; &lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; libdrv.a, libnet.a, libarch.a, libos.a, libwind.a&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; all = libxxx.a + BSP = libxxx.a + bootcode + basic device driver&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; bootcode: arch dependent code&lt;/div&gt; &lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; Cache, TLB, GRs in CPU, CP0's regs, PLL, DDR&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; watchdog, Exception/Interrupt, RTC, GPIO&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; case 1: slow loop on SPI flash&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; case 2: busy stuck of interrupt&lt;/div&gt; &lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; MIPS CPU has 4 general purpose timer&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; case 3: load delay shot on MIPS R3000&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; case 4: stochastically stuch when jumping to vxworks&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; case 5: stochastically soft reboot failure due to PLL switch&lt;/div&gt; &lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; resolution x3&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; importance of bsp:&lt;/div&gt; &lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; availablity&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; reliability&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; stability&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; performance&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; things bsp engineer need to know (!!!)&lt;/div&gt; &lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; arch: Instuctions, Pipeline, cache, exception/interrupt&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; Mem: SDRAM, DDR, NOR/NAND&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; Bus: UART, JTAG, SPI&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; Misc: PLL, Timer, GPIO, watchdog, DMA&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; &lt;acronym title="Operating System"&gt;OS&lt;/acronym&gt; &amp;amp; toolchain&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; Debug: ICE, debugger&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; Time for questions:&lt;/div&gt; &lt;ol&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; cache coherency&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; SoC problem&lt;/div&gt; &lt;/li&gt;&lt;li class="level2"&gt;&lt;div class="li"&gt; how and how hard to be a bsp engineer&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;/ul&gt;  &lt;/div&gt;&lt;h3&gt;&lt;a id="szlug_and_the_cloud_computing_platform_by_haibo_zhang" name="szlug_and_the_cloud_computing_platform_by_haibo_zhang"&gt;SZLUG and the cloud computing platform, by Haibo Zhang&lt;/a&gt;&lt;/h3&gt; &lt;div class="level3"&gt;  &lt;/div&gt;  &lt;h3&gt;&lt;a id="and_qnap_system_image_by_sniperpr" name="and_qnap_system_image_by_sniperpr"&gt;6281 and QNAP system image, by sniperpr&lt;/a&gt;&lt;/h3&gt; &lt;div class="level3"&gt; &lt;ul&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; Market positioning of 6281&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; Collaborative development with a Shanghai guy&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; Introduction of QNAP image&lt;/div&gt; &lt;/li&gt;&lt;/ul&gt;  &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="zemanta-pixie"&gt;&lt;img src="http://img.zemanta.com/pixy.gif?x-id=294edb0b-d092-88d5-987f-fc3fd66cea13" alt="" class="zemanta-pixie-img" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-7687254069705195532?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/7687254069705195532/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/04/szlug-april-monthly-meeting.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7687254069705195532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7687254069705195532'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/04/szlug-april-monthly-meeting.html' title='SZLUG April monthly meeting'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-6302662208605885670</id><published>2011-04-12T23:35:00.002+08:00</published><updated>2011-04-12T23:40:25.360+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-block'/><title type='text'>IOWAIT - 测试IO性能的标尺</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;有个客户给我发邮件，告知我，他们曾对自己的板子和现在正在测试的 Marvell 6281 主板 进行对比测试。发现磁盘I/O操作时候的CPU空闲时间有出入。询问是否是6281的IO效率太低 了。   &lt;p&gt; mpstat 数据如下：  &lt;/p&gt; &lt;pre class="code"&gt;Marvell 6281&lt;br /&gt;CPU %usr %nice %sys %iowait %irq %soft %idle&lt;br /&gt;all 0.00 0.00 5.98 93.69 0.00 0.33 0.00&lt;br /&gt;all 0.00 0.00 3.65 96.01 0.00 0.33 0.00&lt;br /&gt;all 0.66 0.00 7.97 89.37 0.00 1.99 0.00&lt;br /&gt;M5000&lt;br /&gt;CPU %usr %nice %sys %iowait %irq %soft %idle&lt;br /&gt;all 17.67 0.00 22.33 0.00 0.00 0.00 60.00 &lt;br /&gt;all 11.33 0.00 22.00 0.00 0.00 0.00 66.67&lt;br /&gt;all 7.33 0.00 16.33 0.00 0.00 0.00 76.33 &lt;/pre&gt;  &lt;p&gt;  客户认为M5000的 iowait 为0，那么CPU等待IO完成的时间是没有的，因此他的磁盘性能很 好，CPU不去干预；而6281的iowait%太高，CPU都在等，磁盘效率低下。 &lt;/p&gt;    &lt;h3&gt;&lt;a id="误区_cpu在_iowait_的时候傻等" name="误区_cpu在_iowait_的时候傻等"&gt;误区：CPU在 iowait 的时候傻等&lt;/a&gt;&lt;/h3&gt; &lt;div class="level3"&gt;  &lt;p&gt; 这里最要命的就是 iowait 概念。参考 mpstat 手册 &lt;/p&gt;  &lt;p&gt; CPU 的时间片在 mpstat 眼中划分为很多种类，在UP(unique processor)系统中 &lt;/p&gt;  &lt;p&gt; %usr + %nice + %sys + %iwoait + %irq + %soft + %steal + %guest + %idle = 100%  &lt;/p&gt; &lt;ul&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; %usr,  CPU 运行用户程序的时间比&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; %nice, CPU 运行修改过进程优先级的用户程序时间比&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; %sys， CPU 运行内核程序的时间比&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; %iowait, 显示CPU在拥有磁盘I/O请求时候的_空闲_时间比&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; …&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; %idle，现实CPU没有磁盘I/O请求时候的_空闲_时间比&lt;/div&gt; &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;  而其中的 %usr + %nice + %sys 是真正CPU在忙的时间，而其他都属于空闲期。 由上可知， 6281 在磁盘测试的时候使用了 0+0+5.98 = 5.98% 的CPU时间来处理I/O请求， 而 M5000 则使用了 17.63+0+22.33 = 40%，很明显 M5000 的磁盘IO更加占用CPU时间。 &lt;/p&gt;  &lt;/div&gt;  &lt;h3&gt;&lt;a id="iowait_指标" name="iowait_指标"&gt;iowait 指标&lt;/a&gt;&lt;/h3&gt; &lt;div class="level3"&gt;  &lt;p&gt; %iowait 同样也属于空闲期，但是细分成了属于等待磁盘I/O完成的空闲时间，CPU不会傻等 。一旦CPU有其他请求，他会立刻响应。 &lt;/p&gt;  &lt;p&gt; 高的 iowait 代表 CPU早早完成了IO请求的处理而等待磁盘IO的完成。一旦 iowait 逼近 100%，则代表CPU够闲的同时磁盘IO性能过低，总结为磁盘IO成了系统瓶颈。 &lt;/p&gt;  &lt;p&gt; 而M5000 花费了 40% 的CPU 时间来处理请求，这个时候IO传输已经完成，他根本没有等待 时间。这显得 CPU 性能相对磁盘IO反而心力不足，在密集型IO请求的系统中 CPU 会显得 很吃力。 &lt;/p&gt;  &lt;/div&gt;  &lt;h3&gt;&lt;a id="调校_io_性能" name="调校_io_性能"&gt;调校 IO 性能&lt;/a&gt;&lt;/h3&gt; &lt;div class="level3"&gt;  &lt;p&gt; IO性能的调校有超多的方法 &lt;/p&gt; &lt;ol&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; 硬件形成磁盘阵列 raidx&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; hdparm 微调磁盘性能&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; 选用合适的 IO scheduler (/sys/block/sda/queue/scheduler)&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;  同样也可以配合以下工具来试试 &lt;/p&gt; &lt;ol&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; mpstat，适用于 SMP 系统下的监控工具，包含在 sysstat&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; iostat，可以察看IO都写请求的次数等详细数据，包含在sysstat&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; sar, 可以查看网络 IO 性能数据&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; oprofile，可定制的系统微调工具，工作方式类似与 systemtap&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; fio&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; nmon&lt;/div&gt; &lt;/li&gt;&lt;li class="level1"&gt;&lt;div class="li"&gt; iozone&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="zemanta-pixie"&gt;&lt;img src="http://img.zemanta.com/pixy.gif?x-id=fe2a6c80-0c92-8df9-bd5a-d0fefae0dc44" alt="" class="zemanta-pixie-img" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-6302662208605885670?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/6302662208605885670/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/04/iowait-io.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6302662208605885670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6302662208605885670'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/04/iowait-io.html' title='IOWAIT - 测试IO性能的标尺'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-7315903191601067838</id><published>2011-03-24T00:54:00.001+08:00</published><updated>2011-03-24T00:54:40.780+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='science-physics'/><title type='text'>物理简史 之 爱因斯坦相对论</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;div class='level2'&gt;  &lt;p&gt; 注明： 略微看了一下物理简史，算是一个科普吧。  &lt;/p&gt;  &lt;/div&gt; &lt;div class='secedit'&gt;&lt;form method='post' class='button btn_secedit'/&gt;&lt;/div&gt; &lt;h3&gt;&lt;a id='背景介绍' name='背景介绍'&gt;背景介绍&lt;/a&gt;&lt;/h3&gt; &lt;div class='level3'&gt;  &lt;p&gt; 二十世纪两大理论，是对牛顿力学的革命 &lt;/p&gt; &lt;ol&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 量子论&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 相对论&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;  光波有介质吗？以太的存在？ &lt;/p&gt; &lt;ol&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 波动说，需要介质，christian huygens&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 微粒说，不需要介质，newton&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 电磁说，麦克斯韦，赫兹&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 光子说，解释了电磁说中的光电效应，爱因斯坦&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;  爱因斯坦1905四部论文 &lt;/p&gt; &lt;ol&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 光电效应的解释，引入光子概念 NOBEL&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 利用统计力学来解释布朗运动，证明了原子的存在&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 狭义相对论&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 质能方程式&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;  爱因斯坦1907长篇论文 &lt;/p&gt; &lt;ol&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 运动中的质量会变大，速度越大，加速度越小，这样没有超越光速的可能&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 质能方程式 E=mc^2&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;/div&gt; &lt;div class='secedit'&gt;&lt;form method='post' class='button btn_secedit'/&gt;&lt;/div&gt; &lt;h3&gt;&lt;a id='狭义相对论' name='狭义相对论'&gt;狭义相对论&lt;/a&gt;&lt;/h3&gt; &lt;div class='level3'&gt;  &lt;p&gt; 狭义相对论原理（公理） by Einstein in 1905  &lt;/p&gt; &lt;ol&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 相对性原理： 所有“惯性参考架构”，对物理而言，无主从之别&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 光速不变远离： 真空中的光速，在任何“惯性参考架构”中皆是同值&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;  所谓“惯性参考架构”，适用于牛顿力学中则指重力世界，但是架构不指有一个。狭义相对 论的推导成果有：  &lt;/p&gt; &lt;ol&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 否定以太，因为没有绝对静止和绝对速度&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 不能测得的量，不能称之为物理量，也不能成为物理研究的对象&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 推导出洛仁兹转换式&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; “四度空间”。时间和空间是实在的，并且可以有限度的转换，不能截然分别&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 物体不可以追上光，光速是所有速度的极限&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;  等效原理： 局部（短时间、小范围）而言，重力场与参考架构的加速度是等效的 &lt;/p&gt;  &lt;/div&gt; &lt;div class='secedit'&gt;&lt;form method='post' class='button btn_secedit'/&gt;&lt;/div&gt; &lt;h3&gt;&lt;a id='广义相对论' name='广义相对论'&gt;广义相对论&lt;/a&gt;&lt;/h3&gt; &lt;div class='level3'&gt;  &lt;p&gt; 广义相对论 by Einstein in 1915 &lt;/p&gt; &lt;ol&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 爱因斯坦方程式 Guv = kMuv&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 弯曲的时空&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 重力场&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; 光之红位移与光之偏折&lt;/div&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;  狭义相对性原理虽然把伽利略相对性原理推广到了整个物理领域，但并不能包括非惯性参考 系。爱因斯坦把相对性原理推广到一切参考系。 &lt;/p&gt;  &lt;/div&gt; &lt;div class='secedit'&gt;&lt;form method='post' class='button btn_secedit'/&gt;&lt;/div&gt; &lt;h3&gt;&lt;a id='资料' name='资料'&gt;资料&lt;/a&gt;&lt;/h3&gt; &lt;div class='level3'&gt; &lt;ul&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; &lt;a rel='nofollow' title='http://zh.wikipedia.org/wiki/' class='urlextern' href='http://zh.wikipedia.org/wiki/'&gt;http://zh.wikipedia.org/wiki/&lt;/a&gt;光&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; &lt;a rel='nofollow' title='http://zh.wikipedia.org/wiki/' class='urlextern' href='http://zh.wikipedia.org/wiki/'&gt;http://zh.wikipedia.org/wiki/&lt;/a&gt;相对论&lt;/div&gt; &lt;/li&gt;&lt;li class='level1'&gt;&lt;div class='li'&gt; &lt;a rel='nofollow' title='http://www.phy.ncu.edu.tw/dcc/History/HeaderHist.htm' class='urlextern' href='http://www.phy.ncu.edu.tw/dcc/History/HeaderHist.htm'&gt;http://www.phy.ncu.edu.tw/dcc/History/HeaderHist.htm&lt;/a&gt;&lt;/div&gt; &lt;/li&gt;&lt;/ul&gt;  &lt;/div&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=0d304d03-0d8d-859d-a343-f76756ecc389' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-7315903191601067838?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/7315903191601067838/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/03/blog-post_4636.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7315903191601067838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7315903191601067838'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/03/blog-post_4636.html' title='物理简史 之 爱因斯坦相对论'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-6773427111972170754</id><published>2011-03-22T11:45:00.001+08:00</published><updated>2011-03-22T11:45:47.080+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>2011 磨房深圳百公里体验</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;有幸能够在2011年参加闻名遐迩的深圳百公里活动。百公里是一个涉及参赛者，义工，公&lt;br/&gt;安，组织者，医护人员的庞大项目，参加这样的活动意义非凡。&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;big&gt;百公里的具体安排&lt;/big&gt;&lt;/b&gt;&lt;br/&gt;百公里的活动时间是3月19日19:00至3月20日19:00，签到节点是深圳湾体育中心-红岭路口-&lt;br/&gt;梧桐山村-大梅沙海滨公园-溪涌驿站-官湖驿站-金沙湾大酒店。其中深圳湾体育中心作为A&lt;br/&gt;组起点，而大梅沙海滨公园作为B组起点，全长为96.3KM。大约有来自社会的三千多人参加&lt;br/&gt;了活动。&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;big&gt;我的经历&lt;/big&gt;&lt;/b&gt;&lt;br/&gt;我并没有跑完全程，和tommy两人奋发图强，只是达成了从A组起点到盐田关的50KM。&lt;br/&gt;节点1，红岭路口，小腿开始发酸。靠红牛觉得还能撑住。&lt;br/&gt;节点2，梧桐山村，脚掌酸痛，而且疼痛积聚到大腿处，并且开始了痛苦的石板路历程。&lt;br/&gt;节点3，从盐田关坐车到达大梅沙海滨公园，其实也是放弃了前行。脚掌刺痛完全无法移动。&lt;br/&gt;节点6，直接坐车到达了金沙湾终点站，顺便领略大牛的风采。&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;big&gt;我的消耗&lt;/big&gt;&lt;/b&gt;&lt;br/&gt;右腿护膝，临时购买&lt;br/&gt;左边绑腿 from Tommy&lt;br/&gt;头灯 from 苏打&lt;br/&gt;红牛 x4 from 官方赠饮&lt;br/&gt;一碗西红柿鸡蛋面&lt;br/&gt;一盒巧克力豆&lt;br/&gt;少量零食&lt;br/&gt;&lt;br/&gt;&lt;b&gt;&lt;big&gt;百公里的最大敌人&lt;/big&gt;&lt;/b&gt;&lt;br/&gt;脚掌疼痛 -- 大部分人无法避免，这需要你更换不同的袜子，鞋垫(甚至鞋子)，定点休息抬脚让血液回流&lt;br/&gt;大小腿酸痛 -- 必须加强平时锻炼，比如磨房22KM，38KM和一些长途拉练&lt;br/&gt;脚趾间的摩擦起泡 -- 女孩多遇此问题，这需要给每个脚趾做包扎&lt;br/&gt;装备 -- 护膝，护踝，必不可少，最好有背带，眼睛，帽子&lt;br/&gt;体力 -- 这并不是一个大问题。保持一个星期的正常休眠即可&lt;br/&gt;困顿 -- 只要不停下来就不会有难题，因为红牛赞助商不尽的补助&lt;br/&gt;技巧 -- 变换动作可以减缓持续单调运动的磨损，用上你可以用到的所有静走技巧吧&lt;br/&gt;背负 -- 当然越少越好&lt;br/&gt;&lt;br/&gt;官方论坛 &lt;a href='http://www.doyouhike.net/forum/sz100km/'&gt;http://www.doyouhike.net/forum/sz100km/&lt;/a&gt;&lt;br/&gt;路线大图 &lt;a href='http://dl.doyouhike.net/sz100km/2011/2011_100km.jpg'&gt;http://dl.doyouhike.net/sz100km/2011/2011_100km.jpg&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-6773427111972170754?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/6773427111972170754/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/03/2011.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6773427111972170754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6773427111972170754'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/03/2011.html' title='2011 磨房深圳百公里体验'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-7760545068722315211</id><published>2011-03-18T10:54:00.004+08:00</published><updated>2011-03-18T11:03:49.786+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='group-szlug'/><title type='text'>SZLUG 月度聚会，一月讨论张乐的谷歌Offer</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;时间：2011年1月16日 星期六 下午2点－5点&lt;br /&gt;地点：深圳清华研究生院 CI-101 教室&lt;br /&gt;议题：张乐－我如何拿到的google offer&lt;br /&gt;报名：https://groups.google.com/group/szlug/browse_thread/thread/0c5f22cb97b510f1&lt;br /&gt;&lt;br /&gt;实到：本次聚会有25人到场(合照人数加上我)，但是没人登记，我无法列出名字了。&lt;br /&gt;&lt;br /&gt;由于本次聚会主题只有张乐的offer一个，我觉得当然他来作自然比较合适。但是因为被批&lt;br /&gt;作笔记很勤力，麻哥告诉我要作个summary，我就姑且充数叙述一下。&lt;br /&gt;&lt;br /&gt;张乐终于拿到谷歌总部的Offer，这种Offer对中国开发者看起来几乎是要一步踏进国安局一&lt;br /&gt;样不可思议。因此这次会议的主题就只有张乐来讲述：到底使如何拿到谷歌Offer的。&lt;br /&gt;&lt;br /&gt;张乐讲演的时间达到2:30小时，期间的议题非常多，我先列个总表。&lt;br /&gt;&lt;br /&gt;=== 主题 ===&lt;br /&gt;- 简介SRE, Site Reliability Engineering&lt;br /&gt;  * 职责：系统维护，保证软件服务的正常稳定运行&lt;br /&gt;  * 一要兼顾系统管理，二要精通软件编程&lt;br /&gt;- 如何拿到 Google Offer&lt;br /&gt;  * LinkedIn，这是一个很好的开始&lt;br /&gt;  * 无征兆之下接到猎头联系电话&lt;br /&gt;- 面试经历&lt;br /&gt;  * 2010/8，联系和第一次面试。&lt;br /&gt;  * 2010/9月初，电话面试 with a Google SRE&lt;br /&gt;  * 2010/10/1，很正式的美国总部面试 at SanFrancisco!!!&lt;br /&gt;  * 附加面试。 Hiring Committee ...&lt;br /&gt;  * 最后的录用。 Execution Committee ...&lt;br /&gt;  * 薪水问题。 张乐：我们有glassdoor.com&lt;br /&gt;- 前往美国&lt;br /&gt;  * 办理护照和签证，H1-B，H4&lt;br /&gt;  * 谷歌的行程安排，机票，酒店，出租车，吃饭……&lt;br /&gt;  * 痛苦的时差问题&lt;br /&gt;- 乐少开始宣传邪恶的美帝&lt;br /&gt;  * 美国税务，住宿，买车买房&lt;br /&gt;  * 美国绿卡的拿到，H1-B的6年期限&lt;br /&gt;  * 硅谷游： San Jose，Stanford 大学，Oracle，Apple，Cisco ...&lt;br /&gt;- 提问题时间&lt;br /&gt;  * 国内IT的前景  -  做出别人无法替代的东西&lt;br /&gt;  * 张乐的内核之路&lt;br /&gt;  * 英语学习之道&lt;br /&gt;  * 香港IT环境如何？&lt;br /&gt;  * 顺带关注同行业界。 newsycombinator@twitter&lt;br /&gt;- Working in IT industry is a bless&lt;br /&gt;  * 催促大家努力，IT有个很好的明天&lt;br /&gt;  * 榜样： 程任全同学(already in Cisco)，张乐同学...&lt;br /&gt;&lt;br /&gt;下面重点讲述谷歌面试题&lt;br /&gt;&lt;br /&gt;=== 谷歌面试题简述 ===&lt;br /&gt;- 第一次电话面试&lt;br /&gt;    * 自我评价，给自己评级。从1到10给自己打分&lt;br /&gt;  * 简单问题: 比如面向对象……&lt;br /&gt;- 第二次电话面试 with a Google SRE&lt;br /&gt;  * 具体文本在 google docs&lt;br /&gt;  * 口述程序分析结果: fork前后安插print语句&lt;br /&gt;  * 分析程序:  ping 过程，揭示从shell执行、DNS code、socket……到打印结果一系列过程&lt;br /&gt;- 正式的美国总部面试 at SanFrancisco&lt;br /&gt;  * 1/5 系统管理问题: Linux API，信号&lt;br /&gt;  * 2/5 脚本语言: ，自选语言实现pkill和tail&lt;br /&gt;  * 3/5 trouble shooting: ?&lt;br /&gt;  * 4/5 C编程: 分析程序，自己编写一个myopen（考点：LD_PRELOAD）&lt;br /&gt;  * 5/5 数据库问题: 提取100w个执行最多的SQL语句（external merge sort）&lt;br /&gt;- 附加面试&lt;br /&gt;  * C编程: 判断字符串是否为UTF-8&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;作为一个中国小公司的IT行业者，显然会被SRE这样的名词搞蒙，但是看起来出题并不是太&lt;br /&gt;难，事实上SRE是一个着重光度的一个职位。以后可以多多注重这些方面，相信对将来面试&lt;br /&gt;一定会有帮助。&lt;br /&gt;&lt;br /&gt;更大层面上，如何树立方向才是重要的事情。如何如所述那样做出别人无法复制的东西，自&lt;br /&gt;然自己也是无法替代。记住这个目标吧，中国的IT行业者。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-7760545068722315211?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/7760545068722315211/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/03/slug-offer_18.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7760545068722315211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7760545068722315211'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/03/slug-offer_18.html' title='SZLUG 月度聚会，一月讨论张乐的谷歌Offer'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2424648634873861646</id><published>2011-03-18T10:51:00.001+08:00</published><updated>2011-03-18T10:51:57.459+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='group-szlug'/><title type='text'>SZLUG 年底小聚，迎接jserv先生</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;这次讨论组的聚会安排在了12月26日，西方圣诞节后的第一个星期日，这天是为了迎接一个&lt;br/&gt;台湾的大牛，他就是来自台湾 0xlab 公司的黄敬群 先生。&lt;br/&gt;&lt;br/&gt;黄敬群(Jim Huang)，又称 Jserv，涉足非常多的自由软件领域。非常出名的项目有： 台湾&lt;br/&gt;芯Andes，OpenMoko项目，LXDE项目，0xdroid 维护人，Android贡献者等。主页介绍&lt;br/&gt;  * http://jserv.sayya.org/&lt;br/&gt;  * http://blog.linux.org.tw/jserv/&lt;br/&gt;  * http://tw.linkedin.com/in/job4jserv&lt;br/&gt;  * http://wiki.debian.org.tw/User:jserv&lt;br/&gt;&lt;br/&gt;其实这次只是见面小觑，jserv并没有作任何讨论主题的准备，因此大家就瞎聊海聊。因此&lt;br/&gt;场面很热闹，星巴克当时的人也超多。因为星巴克的员工告知不允许拍照和录像，因此不能&lt;br/&gt;提供录像上传了。&lt;br/&gt;&lt;br/&gt;其他讨论的主题有&lt;br/&gt;  - OpenMoko 停止开发？ jserv: 原因保密&lt;br/&gt;  - Oppo Real 新方案？ jserv: 保密&lt;br/&gt;  - 深圳和台湾有什么区别？ jserv: PCB华强北直接卖？台湾做不到&lt;br/&gt;  - linux_pro： 6281项目？ 我也作！还有MV 78100，Freesale，atheros &lt;br/&gt;  - 山寨平板跑 Android，这货太让人吃惊了！&lt;br/&gt;  - Linux 厂商的生态系统 with Anders Ma, linux_pro ...&lt;br/&gt;  - 乐少要去谷歌总部了！&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2424648634873861646?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2424648634873861646/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/03/szlug-jserv_18.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2424648634873861646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2424648634873861646'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/03/szlug-jserv_18.html' title='SZLUG 年底小聚，迎接jserv先生'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2006711614727730447</id><published>2011-03-18T10:07:00.007+08:00</published><updated>2011-03-18T10:53:04.672+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>Syntax Highlighter Test</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;TEST, all test&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/875519.js?file=this.c"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;via http://www.bloggermint.com/2010/02/how-to-add-syntax-highlighter-for-bloggerblogspot/&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2006711614727730447?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2006711614727730447/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2011/03/syntax-highlighter-test_18.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2006711614727730447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2006711614727730447'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2011/03/syntax-highlighter-test_18.html' title='Syntax Highlighter Test'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-5825951841096371300</id><published>2009-03-27T09:38:00.001+08:00</published><updated>2011-03-06T11:11:06.934+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-net-core'/><title type='text'>Ifconfig 如何获得流量统计信息</title><content type='html'>&lt;!-- Page published by Emacs Muse begins here --&gt; &lt;p&gt;本文旨在讲解 Ifconfig 流量信息的获得。将通过 Ifconfig 代码阅读来跟踪流量统计的来 源，这将贯通网络模块，proc文件系统，到硬件设备驱动来探寻这些信息的来源和流向。&lt;/p&gt;  &lt;h2&gt;Ifconfig&lt;/h2&gt;  &lt;p class="first"&gt;Ifconfig是 net-tools的一个组件。 net-tools 为 GNU/Linux 提供控制网络子系统的很多 重要工具(arp, ifconfig, netstat...)，他几乎成为所有发行版必备的软件。&lt;/p&gt;  &lt;p&gt;来看他的输出情况。包含了基本的网卡信息，内核网络配置。除此之外，还包括了流量统计 信息。笔者开始就抱有非常疑惑的信息，Ifconfig是如何做到这一点的？这样一个高层的应 用程序难道和网卡紧密相连么？正是由于这样的疑问，我才开始了阅读代码的过程。&lt;/p&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--     --&gt;&lt;/style&gt;wick@ ~: sudo ifconfig eth0&lt;br /&gt;eth0      Link encap:以太网  硬件地址 00:e0:4c:43:d4:8d&lt;br /&gt;         inet 地址:192.168.16.91  广播:192.168.16.255  掩码:255.255.255.0&lt;br /&gt;         inet6 地址: fe80::2e0:4cff:fe43:d48d/64 Scope:Link&lt;br /&gt;         UP BROADCAST RUNNING MULTICAST  MTU:1500  跃点数:1&lt;br /&gt;         接收数据包:20825 错误:0 丢弃:0 过载:0 帧数:0&lt;br /&gt;         发送数据包:35057 错误:0 丢弃:0 过载:0 载波:0&lt;br /&gt;         碰撞:0 发送队列长度:1000&lt;br /&gt;         接收字节:2225064 (2.2 MB)  发送字节:50827282 (50.8 MB)&lt;br /&gt;         中断:23 基本地址:0xb800&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;本篇实例讲解使用到了 —- net-tools-1.60 源码，可以在官方网站找到&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://packages.debian.org/sid/net-tools"&gt;http://packages.debian.org/sid/net-tools&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;linux-2.6.29 代码&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://kernel.org/"&gt;http://kernel.org&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;h2&gt;net-tools/ifconfig.c&lt;/h2&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .makefile-targets {         /* makefile-targets */         color: #87cefa;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="variable-name"&gt;NET_LIB&lt;/span&gt; = $(&lt;span class="variable-name"&gt;NET_LIB_PATH&lt;/span&gt;)/lib$(&lt;span class="variable-name"&gt;NET_LIB_NAME&lt;/span&gt;).a&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="makefile-targets"&gt;ifconfig&lt;/span&gt;:    $(&lt;span class="variable-name"&gt;NET_LIB&lt;/span&gt;) ifconfig.o&lt;br /&gt;       $(&lt;span class="variable-name"&gt;CC&lt;/span&gt;) $(&lt;span class="variable-name"&gt;LDFLAGS&lt;/span&gt;) -o ifconfig ifconfig.o $(&lt;span class="variable-name"&gt;NLIB&lt;/span&gt;) $(&lt;span class="variable-name"&gt;RESLIB&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt; 来自 net-tools 的Makefile告诉我们，ifconfig工具的链接很简单。除了一个库文件以外， 只需要ifconfig.o。默认情况下，没有指明 obj 文件生成方式的，都只是需要单个同名的C 源码文件 ifconfig.c。   &lt;p&gt;尽快找寻main文件中的参数选项，我们只需要找到列举 eth0 信息的选项分支，其他赶快跳 过。在ifconfig.c:288后以下段落，是我们关注的参数解析过程。&lt;/p&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .comment {         /* font-lock-comment-face */         color: #ff7f24;       }       .comment-delimiter {         /* font-lock-comment-delimiter-face */         color: #ff7f24;       }       .constant {         /* font-lock-constant-face */         color: #7fffd4;       }       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .string {         /* font-lock-string-face */         color: #ffa07a;       }       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;    &lt;span class="comment-delimiter"&gt;/* &lt;/span&gt;&lt;span class="comment"&gt;Create a channel to the NET kernel. &lt;/span&gt;&lt;span class="comment-delimiter"&gt;*/&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; ((skfd = sockets_open(0)) &lt; 0) {&lt;br /&gt;       perror(&lt;span class="string"&gt;"socket"&lt;/span&gt;);&lt;br /&gt;       exit(1);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span class="comment-delimiter"&gt;/* &lt;/span&gt;&lt;span class="comment"&gt;Do we have to show the current setup? &lt;/span&gt;&lt;span class="comment-delimiter"&gt;*/&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (argc == 0) {&lt;br /&gt;       &lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="variable-name"&gt;err&lt;/span&gt; = if_print((&lt;span class="type"&gt;char&lt;/span&gt; *) &lt;span class="constant"&gt;NULL&lt;/span&gt;);&lt;br /&gt;       (&lt;span class="type"&gt;void&lt;/span&gt;) close(skfd);&lt;br /&gt;       exit(err &lt; 0);&lt;br /&gt;   }&lt;br /&gt;   &lt;span class="comment-delimiter"&gt;/* &lt;/span&gt;&lt;span class="comment"&gt;No. Fetch the interface name. &lt;/span&gt;&lt;span class="comment-delimiter"&gt;*/&lt;/span&gt;&lt;br /&gt;   spp = argv;&lt;br /&gt;   safe_strncpy(ifr.ifr_name, *spp++, IFNAMSIZ);&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (*spp == (&lt;span class="type"&gt;char&lt;/span&gt; *) &lt;span class="constant"&gt;NULL&lt;/span&gt;) {&lt;br /&gt;       &lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="variable-name"&gt;err&lt;/span&gt; = if_print(ifr.ifr_name);&lt;br /&gt;       (&lt;span class="type"&gt;void&lt;/span&gt;) close(skfd);&lt;br /&gt;       exit(err &lt; 0);&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt; 首先，调用NET_LIB中的 sockets_open 函数创建 socket 链接；然后在无参数的情况下， if_print 打印所有网络接口信息；如果有参数，则将参数作为接口名称，将会打印对应接 口信息。后者将是我们 `ifconfig eth0' 的参数情况，而 if_print 是唯一调用函数。  &lt;p&gt;同一个文件(ifconfig.c)就可以看到if_print函数，看起来很简洁。&lt;/p&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .function-name {         /* font-lock-function-name-face */         color: #87cefa;       }       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .negation-char {       }       .string {         /* font-lock-string-face */         color: #ffa07a;       }       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="function-name"&gt;if_print&lt;/span&gt;(&lt;span class="type"&gt;char&lt;/span&gt; *&lt;span class="variable-name"&gt;ifname&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="variable-name"&gt;res&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (ife_short)&lt;br /&gt;   printf(_(&lt;span class="string"&gt;"Iface   MTU Met    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg\n"&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (&lt;span class="negation-char"&gt;!&lt;/span&gt;ifname) {&lt;br /&gt;   res = for_all_interfaces(do_if_print, &amp;amp;opt_a);&lt;br /&gt;   } &lt;span class="keyword"&gt;else&lt;/span&gt; {&lt;br /&gt;   &lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;interface&lt;/span&gt; *&lt;span class="variable-name"&gt;ife&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   ife = lookup_interface(ifname);&lt;br /&gt;   res = do_if_fetch(ife);&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (res &gt;= 0)&lt;br /&gt;       ife_print(ife);&lt;br /&gt;   }&lt;br /&gt;   &lt;span class="keyword"&gt;return&lt;/span&gt; res;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; 首先，如果ife_short有效，则打印表头。这是网络接口信息的简洁模式，使用`ifconfig -s'的效果正式如此，`-s'将设置 ife_short = 1，这在main函数解析参数时候已经完成。 然后，分析参数，我们这里的ifname就是"eth0"，因此进入else分支。  &lt;p&gt;下面深入到lookup_interfaces (lib/interfaces.c) &lt;/p&gt;&lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .constant {         /* font-lock-constant-face */         color: #7fffd4;       }       .function-name {         /* font-lock-function-name-face */         color: #87cefa;       }       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;interface&lt;/span&gt; *&lt;span class="function-name"&gt;lookup_interface&lt;/span&gt;(&lt;span class="type"&gt;char&lt;/span&gt; *&lt;span class="variable-name"&gt;name&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;interface&lt;/span&gt; *&lt;span class="variable-name"&gt;ife&lt;/span&gt; = &lt;span class="constant"&gt;NULL&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (if_readlist_proc(name) &lt; 0)&lt;br /&gt;       &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;NULL&lt;/span&gt;;&lt;br /&gt;   ife = add_interface(name);&lt;br /&gt;   &lt;span class="keyword"&gt;return&lt;/span&gt; ife;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;紧跟着是 if_readlist_proc 和 add_interface，一个个来。 &lt;/p&gt;&lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .comment {         /* font-lock-comment-face */         color: #ff7f24;       }       .comment-delimiter {         /* font-lock-comment-delimiter-face */         color: #ff7f24;       }       .constant {         /* font-lock-constant-face */         color: #7fffd4;       }       .function-name {         /* font-lock-function-name-face */         color: #87cefa;       }       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .negation-char {       }       .preprocessor {         /* font-lock-preprocessor-face */         color: #b0c4de;       }       .string {         /* font-lock-string-face */         color: #ffa07a;       }       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="function-name"&gt;if_readlist_proc&lt;/span&gt;(&lt;span class="type"&gt;char&lt;/span&gt; *&lt;span class="variable-name"&gt;target&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="variable-name"&gt;proc_read&lt;/span&gt;;&lt;br /&gt;   &lt;span class="type"&gt;FILE&lt;/span&gt; *&lt;span class="variable-name"&gt;fh&lt;/span&gt;;&lt;br /&gt;   &lt;span class="type"&gt;char&lt;/span&gt; &lt;span class="variable-name"&gt;buf&lt;/span&gt;[512];&lt;br /&gt;   &lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;interface&lt;/span&gt; *&lt;span class="variable-name"&gt;ife&lt;/span&gt;;&lt;br /&gt;   &lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="variable-name"&gt;err&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (proc_read)&lt;br /&gt;       &lt;span class="keyword"&gt;return&lt;/span&gt; 0;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (&lt;span class="negation-char"&gt;!&lt;/span&gt;target)&lt;br /&gt;       proc_read = 1;&lt;br /&gt;&lt;br /&gt;   fh = fopen(_PATH_PROCNET_DEV, &lt;span class="string"&gt;"r"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (&lt;span class="negation-char"&gt;!&lt;/span&gt;fh) {&lt;br /&gt;       fprintf(stderr, _(&lt;span class="string"&gt;"Warning: cannot open %s (%s). Limited output.\n"&lt;/span&gt;),&lt;br /&gt;           _PATH_PROCNET_DEV, strerror(errno));&lt;br /&gt;       &lt;span class="keyword"&gt;return&lt;/span&gt; if_readconf();&lt;br /&gt;   }&lt;br /&gt;   fgets(buf, &lt;span class="keyword"&gt;sizeof&lt;/span&gt; buf, fh);    &lt;span class="comment-delimiter"&gt;/* &lt;/span&gt;&lt;span class="comment"&gt;eat line &lt;/span&gt;&lt;span class="comment-delimiter"&gt;*/&lt;/span&gt;&lt;br /&gt;   fgets(buf, &lt;span class="keyword"&gt;sizeof&lt;/span&gt; buf, fh);&lt;br /&gt;&lt;br /&gt;&lt;span class="preprocessor"&gt;#if&lt;/span&gt; 0                &lt;span class="comment-delimiter"&gt;/* &lt;/span&gt;&lt;span class="comment"&gt;pretty, but can't cope with missing fields &lt;/span&gt;&lt;span class="comment-delimiter"&gt;*/&lt;/span&gt;&lt;br /&gt;   fmt = proc_gen_fmt(_PATH_PROCNET_DEV, 1, fh,&lt;br /&gt;              &lt;span class="string"&gt;"face"&lt;/span&gt;, &lt;span class="string"&gt;""&lt;/span&gt;,    &lt;span class="comment-delimiter"&gt;/* &lt;/span&gt;&lt;span class="comment"&gt;parsed separately &lt;/span&gt;&lt;span class="comment-delimiter"&gt;*/&lt;/span&gt;&lt;br /&gt;              &lt;span class="string"&gt;"bytes"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"packets"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"errs"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"drop"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"fifo"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"frame"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"compressed"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"multicast"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"bytes"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"packets"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"errs"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"drop"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"fifo"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"colls"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"carrier"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="string"&gt;"compressed"&lt;/span&gt;, &lt;span class="string"&gt;"%lu"&lt;/span&gt;,&lt;br /&gt;              &lt;span class="constant"&gt;NULL&lt;/span&gt;);&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (&lt;span class="negation-char"&gt;!&lt;/span&gt;fmt)&lt;br /&gt;   &lt;span class="keyword"&gt;return&lt;/span&gt; -1;&lt;br /&gt;&lt;span class="preprocessor"&gt;#else&lt;/span&gt;&lt;br /&gt;   procnetdev_vsn = procnetdev_version(buf);&lt;br /&gt;&lt;span class="preprocessor"&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   err = 0;&lt;br /&gt;   &lt;span class="keyword"&gt;while&lt;/span&gt; (fgets(buf, &lt;span class="keyword"&gt;sizeof&lt;/span&gt; buf, fh)) {&lt;br /&gt;   &lt;span class="type"&gt;char&lt;/span&gt; *&lt;span class="variable-name"&gt;s&lt;/span&gt;, &lt;span class="variable-name"&gt;name&lt;/span&gt;[IFNAMSIZ];&lt;br /&gt;   s = get_name(name, buf);&lt;br /&gt;   ife = add_interface(name);&lt;br /&gt;   get_dev_fields(s, ife);&lt;br /&gt;   ife-&gt;statistics_valid = 1;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (target &amp;amp;&amp;amp; &lt;span class="negation-char"&gt;!&lt;/span&gt;strcmp(target,name))&lt;br /&gt;       &lt;span class="keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;   }&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (ferror(fh)) {&lt;br /&gt;   perror(_PATH_PROCNET_DEV);&lt;br /&gt;   err = -1;&lt;br /&gt;   proc_read = 0;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;span class="preprocessor"&gt;#if&lt;/span&gt; 0&lt;br /&gt;   free(fmt);&lt;br /&gt;&lt;span class="preprocessor"&gt;#endif&lt;/span&gt;&lt;br /&gt;   fclose(fh);&lt;br /&gt;   &lt;span class="keyword"&gt;return&lt;/span&gt; err;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; 一大长串，这该是我们现在遇到的最长的函数了，但是这个方法远远比想象的要简单的多， 文件I/O就占据了老长。这个方法就是读取网络接口的列表，从那儿读取呢？我们一眼就看 到了 ———— &lt;center&gt; &lt;p&gt;fh = fopen(_PATH_PROCNET_DEV, "r");&lt;/p&gt; &lt;/center&gt;  &lt;p&gt;在 lib/pathnames.h 中看到其芳踪 &lt;/p&gt;&lt;center&gt; &lt;p&gt;#define _PATH_PROCNET_DEV        "/proc/net/dev"&lt;/p&gt; &lt;/center&gt;  &lt;p&gt;首先，探测是否已经检测过 网络接口列表，咱们不作浪费时间的无用功。 然后读取 /proc/net/dev，跳过文件的前两行。为啥？自己瞅瞅就知道了。 &lt;/p&gt;&lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--     --&gt;&lt;/style&gt;wick@ ~: cat /proc/net/dev&lt;br /&gt;Inter-|   Receive                                                |  Transmit&lt;br /&gt;face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed&lt;br /&gt;   lo:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0&lt;br /&gt; eth0: 3342410   31393    0    0    0     0          0         0 76194593   52347    0    0    0     0       0          0&lt;br /&gt; eth1:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;接着解析参数，将得到的所有接口加入到列表中去（add_interface），然后依据格式填充 ife结构体(get_dev_fields)。这个结构体是自定义的，可以看到这个结构体是一个链表结 构。get_dev_fields方法填充的是其中一个成员结构体，他在人群中是那么的耀眼： &lt;/p&gt;&lt;center&gt; &lt;p&gt;struct user_net_device_stats stats;&lt;/p&gt; &lt;/center&gt;  &lt;p&gt;他包含的就是统计信息数据，这些数据的来源就是/proc/net/dev。我们作的仅仅是读取这 个文件信息而已……&lt;/p&gt;  &lt;p&gt;你要问，还有其他的信息呢？诸如IP地址，MAC地址，ifconfig如何知道我的网卡是无线有 线的呢？你就需要去看 if_fetch 函数了。从中你可以看到大量的ioctl调用，一切豁然开 朗。&lt;/p&gt;    &lt;h2&gt;linux/net/core/dev.c&lt;/h2&gt;  &lt;p class="first"&gt;立刻来到内核的领地。&lt;/p&gt;  &lt;p&gt;以上总结到统计数据信息的位置坐落于 /proc/net/dev，他是被谁写入的呢？要理解这个问 题，你得先理解 PROC 文件系统。介于时间和能力原因，我只能大概解释， PROC 是内核和 用户空间通讯的又一个接口，PROC fs是一个由软件创建的文件系统，我们需要追根溯源到 创建 /proc/net/dev 的代码文件。&lt;/p&gt;  &lt;p&gt;如果要问我是如何找到创建软件的代码？我不知道。我只知道最蠢的方法，google 和 grep。&lt;/p&gt;  &lt;p&gt;好吧我是直接grep的……于是找到了 /net/core/dev.c。&lt;/p&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .comment {         /* font-lock-comment-face */         color: #ff7f24;       }       .comment-delimiter {         /* font-lock-comment-delimiter-face */         color: #ff7f24;       }       .function-name {         /* font-lock-function-name-face */         color: #87cefa;       }       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .string {         /* font-lock-string-face */         color: #ffa07a;       }       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="comment-delimiter"&gt;/*&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;*    Called from the PROCfs module. This now uses the new arbitrary sized&lt;br /&gt;*    /proc/net interface to create /proc/net/dev&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="function-name"&gt;dev_seq_show&lt;/span&gt;(&lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;seq_file&lt;/span&gt; *&lt;span class="variable-name"&gt;seq&lt;/span&gt;, &lt;span class="type"&gt;void&lt;/span&gt; *&lt;span class="variable-name"&gt;v&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (v == SEQ_START_TOKEN)&lt;br /&gt;       seq_puts(seq, &lt;span class="string"&gt;"Inter-|   Receive                            "&lt;/span&gt;&lt;br /&gt;                 &lt;span class="string"&gt;"                    |  Transmit\n"&lt;/span&gt;&lt;br /&gt;                 &lt;span class="string"&gt;" face |bytes    packets errs drop fifo frame "&lt;/span&gt;&lt;br /&gt;                 &lt;span class="string"&gt;"compressed multicast|bytes    packets errs "&lt;/span&gt;&lt;br /&gt;                 &lt;span class="string"&gt;"drop fifo colls carrier compressed\n"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;       dev_seq_printf_stats(seq, v);&lt;br /&gt;   &lt;span class="keyword"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; 我们直接看到这段，注释就包含了 /proc/net/dev 信息，由此可见，友好详细的注释是多 么多么的重要啊…… 直接看方法，dev_seq_show 是文件中定义的struct seq_operations dev_seq_ops的成员， 这就提到了 proc提供的seq接口，他使用简单的迭代器方法，使用 seq_open -&gt; read_proc 就可以直接输出 proc文件的接口信息。如果你不熟悉 PROCfs 和 seq_file 接口，这一部 分会有点凹口。  &lt;p&gt;简单来说，当你使用open等系统调用打开 /proc/net/dev 的时候，系统将调用 seq_open 函数；相似的，当你使用read时，内核会使用 seq_show 来将实际数据传递到用户空间。我 们的 `cat /proc/net/dev' 输出，就是这里的 dev_seq_show 打印的。&lt;/p&gt;  &lt;p&gt;接着，是 dev_seq_show 中调用的 dev_seq_printf_stats 方法，他仅仅使用到了一个函数。 不用多说，继续深入到dev_get_stats，他将是core模块此行的终点。&lt;/p&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .constant {         /* font-lock-constant-face */         color: #7fffd4;       }       .doc {         /* font-lock-doc-face */         color: #ffa07a;       }       .function-name {         /* font-lock-function-name-face */         color: #87cefa;       }       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="doc"&gt;/**&lt;br /&gt;*    dev_get_stats    - get network device statistics&lt;br /&gt;*    &lt;/span&gt;&lt;span class="doc"&gt;&lt;span class="constant"&gt;@dev&lt;/span&gt;&lt;/span&gt;&lt;span class="doc"&gt;: device to get statistics from&lt;br /&gt;*&lt;br /&gt;*    Get network statistics from device. The device driver may provide&lt;br /&gt;*    its own method by setting dev-&gt;netdev_ops-&gt;get_stats; otherwise&lt;br /&gt;*    the internal statistics structure is used.&lt;br /&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;const&lt;/span&gt; &lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;net_device_stats&lt;/span&gt; *&lt;span class="function-name"&gt;dev_get_stats&lt;/span&gt;(&lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;net_device&lt;/span&gt; *&lt;span class="variable-name"&gt;dev&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="keyword"&gt;const&lt;/span&gt; &lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;net_device_ops&lt;/span&gt; *&lt;span class="variable-name"&gt;ops&lt;/span&gt; = dev-&gt;netdev_ops;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (ops-&gt;ndo_get_stats)&lt;br /&gt;       &lt;span class="keyword"&gt;return&lt;/span&gt; ops-&gt;ndo_get_stats(dev);&lt;br /&gt;   &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;       &lt;span class="keyword"&gt;return&lt;/span&gt; &amp;amp;dev-&gt;stats;&lt;br /&gt;}&lt;br /&gt;EXPORT_SYMBOL(dev_get_stats);&lt;br /&gt;&lt;/pre&gt; 多么有爱的注释啊……如果定义了设备驱动的 get_stats 方法，就调用 get_stats 调用获 得信息，如果没有，直接返回设备写好的数据结构。  &lt;p&gt;在这里真的需要强调注释的好处，简短的两句话，可以让代码的可读性激增啊！&lt;/p&gt;  &lt;p&gt;感动之后，我们进入驱动，我现在使用的网卡是8139，相关的驱动是 8139too.c。&lt;/p&gt;   &lt;h2&gt;linux/drivers/net/8139too.c&lt;/h2&gt;  &lt;p class="first"&gt;8139too 驱动直接包含在内核里了，我们立刻去关怀他的 get_stats 函数。 &lt;/p&gt;&lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .preprocessor {         /* font-lock-preprocessor-face */         color: #b0c4de;       }       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="keyword"&gt;const&lt;/span&gt; &lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;net_device_ops&lt;/span&gt; &lt;span class="variable-name"&gt;rtl8139_netdev_ops&lt;/span&gt; = {&lt;br /&gt;   .ndo_open        = rtl8139_open,&lt;br /&gt;   .ndo_stop        = rtl8139_close,&lt;br /&gt;   .ndo_get_stats        = rtl8139_get_stats,&lt;br /&gt;   .ndo_validate_addr    = eth_validate_addr,&lt;br /&gt;   .ndo_set_mac_address     = eth_mac_addr,&lt;br /&gt;   .ndo_start_xmit        = rtl8139_start_xmit,&lt;br /&gt;   .ndo_set_multicast_list    = rtl8139_set_rx_mode,&lt;br /&gt;   .ndo_do_ioctl        = netdev_ioctl,&lt;br /&gt;   .ndo_tx_timeout        = rtl8139_tx_timeout,&lt;br /&gt;&lt;span class="preprocessor"&gt;#ifdef&lt;/span&gt; CONFIG_NET_POLL_CONTROLLER&lt;br /&gt;   .ndo_poll_controller    = rtl8139_poll_controller,&lt;br /&gt;&lt;span class="preprocessor"&gt;#endif&lt;/span&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;哦，简单直接，rtl8139_get_stats &lt;/p&gt;&lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .function-name {         /* font-lock-function-name-face */         color: #87cefa;       }       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;net_device_stats&lt;/span&gt; *&lt;span class="function-name"&gt;rtl8139_get_stats&lt;/span&gt; (&lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;net_device&lt;/span&gt; *&lt;span class="variable-name"&gt;dev&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="keyword"&gt;struct&lt;/span&gt; &lt;span class="type"&gt;rtl8139_private&lt;/span&gt; *&lt;span class="variable-name"&gt;tp&lt;/span&gt; = netdev_priv(dev);&lt;br /&gt;   &lt;span class="type"&gt;void&lt;/span&gt; &lt;span class="variable-name"&gt;__iomem&lt;/span&gt; *ioaddr = tp-&gt;mmio_addr;&lt;br /&gt;   &lt;span class="type"&gt;unsigned&lt;/span&gt; &lt;span class="type"&gt;long&lt;/span&gt; &lt;span class="variable-name"&gt;flags&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;if&lt;/span&gt; (netif_running(dev)) {&lt;br /&gt;       spin_lock_irqsave (&amp;amp;tp-&gt;lock, flags);&lt;br /&gt;       dev-&gt;stats.rx_missed_errors += RTL_R32 (RxMissed);&lt;br /&gt;       RTL_W32 (RxMissed, 0);&lt;br /&gt;       spin_unlock_irqrestore (&amp;amp;tp-&gt;lock, flags);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;return&lt;/span&gt; &amp;amp;dev-&gt;stats;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; 这个函数实体只是重写了 dev-&gt;stats.rx_missed_errors，其他的信息我们直接 return。 网卡状态信息 struct net_device_stats 已经在网卡驱动的其他操作方法中即时更新了。   &lt;h2&gt;总结&lt;/h2&gt;  &lt;p class="first"&gt;Ifconfig 使用了简单的文件I/O控制，读取 /proc/net/dev 文件来打印流量统计信息。此 文件是 PROCfs 的一个组成，他的操作方法在代码 net/core/dev.c 中，其中 seq 接口的 show 方法可能调用了网卡设备驱动的 get_status 驱动方法来获得网卡信息。这些信息在 网卡操作中会即时更新。&lt;/p&gt;    &lt;!-- Page published by Emacs Muse ends here --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-5825951841096371300?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/5825951841096371300/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2009/03/ifconfig.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/5825951841096371300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/5825951841096371300'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2009/03/ifconfig.html' title='Ifconfig 如何获得流量统计信息'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-8816554410753779044</id><published>2009-03-17T17:35:00.012+08:00</published><updated>2011-03-06T11:07:07.252+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-drivers-scsi'/><title type='text'>SCSI和SATA</title><content type='html'>&lt;h1&gt;SCSI&lt;/h1&gt;        &lt;h3&gt;概念&lt;/h3&gt;  &lt;p class="first"&gt;Small Computer System Interface, 它是一组在电脑和外围设备间实现物理连接和数据传 输的标准集合。SCSI标准定义了命令、协议、电子和光学接口，它可以连接大量的外围设备。&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;SCSI 隐藏了物理设备接口的复杂性，算是一种智能设备&lt;/li&gt;&lt;li&gt;SCSI 是一个并行设备，可以将 8-16个SCSI设备连接到一根单独的总线&lt;/li&gt;&lt;li&gt;SCSI 是带缓冲的接口，使用了设备间的握手信号，支持出错检查&lt;/li&gt;&lt;li&gt;SCSI 是一个点对点设备，协议已经定义了三组标准：主机对主机，主机对外围设备，外 围设备对外围设备&lt;/li&gt;&lt;/ul&gt;  （&lt;span style="font-style: italic;"&gt;两个SCSI连接器，via wikipedia&lt;/span&gt;）&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/Sb9wqpAnsNI/AAAAAAAAFso/RO4VhBEsz9c/s1600-h/180px-Scsi-1_gehaeuse.jpg"&gt;&lt;img style="cursor: pointer; width: 180px; height: 135px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/Sb9wqpAnsNI/AAAAAAAAFso/RO4VhBEsz9c/s320/180px-Scsi-1_gehaeuse.jpg" alt="" id="BLOGGER_PHOTO_ID_5314089963185746130" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt; SCSI历史&lt;/h3&gt;  &lt;ol&gt;&lt;li&gt;SCSI SPI，SCSI是个很老的协议（1981），至今经历了三代协议变换，也定义了三套标 准SCSI1, 2, 3，SPI是对并行SCSI接口的统称。到了2008年，SPI开始被SAS所取代&lt;/li&gt;&lt;li&gt;SSA，现行的串行SCSI标准有三个，SSA，FC-AL，SAS，他们从SPI中独立出来，使用串 口传输。&lt;/li&gt;&lt;li&gt;SAS, Serial Attached SCSI 是串行标准中最具活力的一个&lt;/li&gt;&lt;li&gt;iSCSI，在此不做讨论&lt;/li&gt;&lt;/ol&gt;    &lt;h2&gt;ATA/ATAPI&lt;/h2&gt;  &lt;h3&gt;概念&lt;/h3&gt;  &lt;p class="first"&gt;AT Attachment / AT Attachment Packet Interface (ATA/ATAPI) 是一套专门连接大容量 存储介质的标准集合，这些设备包括有硬盘、固态硬盘、光驱等等。&lt;/p&gt;&lt;h3&gt;ATA/ATAPI历史&lt;/h3&gt;  &lt;ol&gt;&lt;li&gt;IDE(ATA-1), 1994年，ANSI统一了IDE接口，诞生了ATA-1&lt;/li&gt;&lt;li&gt;EIDE(ATA-2), 西部电子公布了EIDE标准，催生出1996的ATA-2标准&lt;/li&gt;&lt;li&gt;ATAPI 是ATA标准的里程碑，它定义了一系列拓展命令，大大加强了ATA接口。他更可回 应SCSI命令，被称之为"会说话的SCSI"。这个协议也叫"ATA/ATAPI-4"&lt;/li&gt;&lt;li&gt;Parell ATA, 2003年，SATA诞生了，由于他的出现，我们把以前的ATA称之为PATA。 ATA标准要求电缆长度最大为46cm，这限制了计算机存储技术的发挥。&lt;/li&gt;&lt;li&gt;Serial ATA, 2007年度，SATA已经全面取代PATA，它是现行ATA接口市场上的主流。 注意，此时的Serial ATA的规范中就包含了SCSI SAS部分&lt;/li&gt;&lt;/ol&gt;（&lt;span style="font-style: italic;"&gt;7孔SATA缆线和主板SATA接口，via Wikipedia&lt;/span&gt;）&lt;br /&gt; &lt;img style="cursor: pointer; width: 150px; height: 164px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/Sb9yq1E481I/AAAAAAAAFs4/w4wM703yYE8/s320/150px-SATA_Data_Cable.jpg" alt="" id="BLOGGER_PHOTO_ID_5314092165448135506" border="0" /&gt;&lt;span style="text-decoration: underline;"&gt; &lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/Sb9yqyyyjMI/AAAAAAAAFtA/kBk5B4malVk/s1600-h/200px-SATA_ports.jpg"&gt;&lt;img style="cursor: pointer; width: 200px; height: 178px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/Sb9yqyyyjMI/AAAAAAAAFtA/kBk5B4malVk/s320/200px-SATA_ports.jpg" alt="" id="BLOGGER_PHOTO_ID_5314092164835347650" border="0" /&gt;&lt;/a&gt;&lt;h3&gt;SCSI和SATA&lt;/h3&gt;  &lt;p class="first"&gt;SCSI和SATA相比，速率要快上一些，但是其总线结构很复杂，自然成本也较高。SCSI总线支 持多个驱动器连接（多个通道，一个通道连接7-15个设备）。而SATA只支持一对一，除非使 用端口倍加器。&lt;/p&gt;  &lt;p&gt;性能上看，SATA 3Gb/s 提供了 300MB/s 的传输速率，而SCSI可以达到 320MB/s，而且SCSI 驱动器可以提供更高的持久式吞吐量；兼容性上看，SATA 一般保留了向 SAS 的兼容性，而 SCSI 是不能直连到SATA总线上的。&lt;/p&gt;  &lt;p&gt;总体上看，SATA总线更简单，保留了向SAS的兼容性，而且仍旧保持较高速率。SCSI的功能 更强，拓展性更高，但其成本也较高。&lt;/p&gt;     &lt;h2&gt;索引&lt;/h2&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/SCSI"&gt;http://en.wikipedia.org/wiki/SCSI&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/AT_Attachment"&gt;http://en.wikipedia.org/wiki/AT_Attachment&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Serial_ATA"&gt;http://en.wikipedia.org/wiki/Serial_ATA&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.ata-atapi.com/sata.html"&gt;http://www.ata-atapi.com/sata.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-8816554410753779044?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/8816554410753779044/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2009/03/scsisata.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/8816554410753779044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/8816554410753779044'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2009/03/scsisata.html' title='SCSI和SATA'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Kb-lr4qFtj4/Sb9wqpAnsNI/AAAAAAAAFso/RO4VhBEsz9c/s72-c/180px-Scsi-1_gehaeuse.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-3673742475233236909</id><published>2009-03-10T17:51:00.001+08:00</published><updated>2011-03-06T11:24:20.639+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-c'/><title type='text'>翻阅 C99 标准</title><content type='html'>&lt;p&gt;自从C89之后，C语言就没有经过大的改变。相比之下，C++的特性却是一天一个样儿，作为C 语言的超集，C++至今拥有了大量的特性，和多家库支持。为使C一样与时俱进，ISO 在99年 制定了ISO/IEC 9899:1999，被后来称之为C99。&lt;/p&gt;  &lt;p&gt;C99的重要更新有：&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;inline 方法&lt;/li&gt;&lt;li&gt;不一定需要在代码块开始位置定义变量&lt;/li&gt;&lt;li&gt;更多的类型支持：比如 long long int等扩展整形，复数类型等&lt;/li&gt;&lt;li&gt;支持变长数组&lt;/li&gt;&lt;li&gt;使用&amp;quot;//&amp;quot;但行注释&lt;/li&gt;&lt;li&gt;新的库函数，比如snprintf&lt;/li&gt;&lt;li&gt;新的头文件，比如stdbool.h&lt;/li&gt;&lt;li&gt;引入通用类型的数学方法，（tgmath.h, 包含math.h和complex.h，两者通吃）&lt;/li&gt; &lt;li&gt;改进的IEEE浮点支持&lt;/li&gt;&lt;li&gt;制定的初始化方法&lt;/li&gt;&lt;li&gt;混合迭代器&lt;/li&gt;&lt;li&gt;variadic 宏支持(不清楚)&lt;/li&gt;&lt;li&gt;restrict 支持，允许更深的代码优化&lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;尽管C99也已经过去了10年，在我第一次摸的时候还是感觉很凹口和生疏，一方面自己的基 础还是很薄弱，一方面标准性的文档往往追求经准而晦涩难懂。相信随着以后的学习，那些 诸如multibyte char之类的字眼还会出现在我面前。&lt;/p&gt;  &lt;p&gt;WIKIPEDIA: &lt;/p&gt;&lt;blockquote&gt; &lt;p class="quoted"&gt;&lt;a href="http://en.wikipedia.org/wiki/c99"&gt;http://en.wikipedia.org/wiki/c99&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Open-Std 标准文档： &lt;/p&gt;&lt;blockquote&gt; &lt;p class="quoted"&gt;&lt;a href="http://www.open-std.org/JTC1/SC22/WG14/www/standards.html#9899"&gt;http://www.open-std.org/JTC1/SC22/WG14/www/standards.html#9899&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;GCC C99 Status: &lt;/p&gt;&lt;blockquote&gt; &lt;p class="quoted"&gt;&lt;a href="http://gcc.gnu.org/c99status.html"&gt;http://gcc.gnu.org/c99status.html&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-3673742475233236909?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/3673742475233236909/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2009/03/c99.html#comment-form' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/3673742475233236909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/3673742475233236909'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2009/03/c99.html' title='翻阅 C99 标准'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2836938948770447759</id><published>2009-02-20T17:48:00.004+08:00</published><updated>2011-03-06T11:09:28.104+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-drivers-gpio'/><category scheme='http://www.blogger.com/atom/ns#' term='linux-arch-arm'/><title type='text'>EP93xx GPIO interface</title><content type='html'>&lt;h3&gt;名词&lt;/h3&gt;  &lt;p class="first"&gt;AMBA是EP93xx采用的内部总线结构，他包含一个高速总线(AHB)和一个低速总线(APB)。&lt;/p&gt;  &lt;p&gt;AHB (Advanced High-Performance Bus)，包含一个高速内部总线时钟，用来同步协处理 器、MMU、cache、DMA控制器和其他内存模块。&lt;/p&gt;  &lt;p&gt;APB (Advanced Peripheral Bus)，此总线就来连接一些低速并行设备，比如UART和GPIO。 AHB 和 APB 使用 AMBA 架构中的 AHB/APB 总线连接，&lt;/p&gt;  &lt;p&gt;GPIO (General Purpose I/O)，GPIO在EP93xx中是APB的一个子模块，他提供简单的LED控制， 可实现非常基础的调试功能（相当于printk?）。&lt;/p&gt;  &lt;p class="image"&gt;&lt;img src="http://www.cirrus.com/en/images/product_diagrams/9302blkdiag_mag.gif" alt="" /&gt;&lt;/p&gt;   &lt;h3&gt;GPIO&lt;/h3&gt;  &lt;p class="first"&gt;GPIO 包含两种类型和8个接口。&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;标准GPIO (port C, D, E, G, H)。每个端口包含两组寄存器  &lt;ol&gt;&lt;li&gt;data reg x1&lt;/li&gt;&lt;li&gt;data direction reg x1&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;增强型的GPIO（EGPIO, port A, B, F)，包含三种寄存器  &lt;ol&gt;&lt;li&gt;data reg x1&lt;/li&gt;&lt;li&gt;data direction reg x1&lt;/li&gt;&lt;li&gt;intr reg and status regs x?&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;p&gt;标准GPIO的每个端口都包含一个8位数据寄存器（data regs）和另外的8位数据方向寄存器 (datadirection regs)。而EGPIO还会多包含一组8位中断控制寄存器。&lt;/p&gt;  &lt;p&gt;ABF端口还包括了七个多余的寄存器。&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;GPIO Interrupt Enable registers (GPIOAIntEn, GPIOBIntEn, GPIOFIntEn)&lt;/li&gt;&lt;li&gt;GPIO Interrupt Type 1 registers (GPIOAIntType1, GPIOBIntType1, GPIOFIntType1)&lt;/li&gt;&lt;li&gt;GPIO Interrupt Type 2 registers (GPIOAIntType2, GPIOBIntType2, GPIOFIntType2)&lt;/li&gt; &lt;li&gt;GPIO End-Of-Interrupt registers (GPIOAEOI, GPIOBEOI, GPIOFEOI)&lt;/li&gt;&lt;li&gt;GPIO Debounce registers (GPIOADB, GPIOBDB, GPIOFDB)&lt;/li&gt;&lt;li&gt;Interrupt Status registers (IntStsA, IntStsB, IntStsF)&lt;/li&gt;&lt;li&gt;Raw Interrupt Status registers (RawIntStsA, RawIntStsB, RawIntStsF)&lt;/li&gt; &lt;/ol&gt;   &lt;h3&gt;GPIO 初始化&lt;/h3&gt;  &lt;p class="first"&gt;系统复位的时候，GPIO 会执行初始化。&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;所有端口的 data reg 和 data direction reg 都将清零，设置为 input 方式&lt;/li&gt;&lt;li&gt;Port E[1:0] 用来表示 RDLED 和 GRLED，他们将会被置高，也就是 0x11&lt;/li&gt;&lt;li&gt;Port G[3:2] 用来表示 SLA[1:0] 输出，他们被置低。&lt;/li&gt;&lt;li&gt;Port G[1:0] 用来表示 EEDAT 和 EECLK，设置为 input 方式&lt;/li&gt;&lt;li&gt; 所有的中断控制寄存器和祛抖动寄存器都被清零&lt;/li&gt;&lt;/ul&gt;   &lt;h3&gt;GPIO端口和针脚映射&lt;/h3&gt;  &lt;p class="first"&gt;EP93xx的阵脚情况不一样，后继版本的板子总是多了点，下面只是列出EP9301/EP9302的针 脚映射：&lt;/p&gt;  &lt;table class="muse-table" border="2" cellpadding="5"&gt;   &lt;thead&gt;     &lt;tr&gt;       &lt;th&gt;主板针脚名称&lt;/th&gt;       &lt;th&gt;位于GPIO模块上的端口&lt;/th&gt;     &lt;/tr&gt;   &lt;/thead&gt;   &lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;EGPIO[7:0]&lt;/td&gt;       &lt;td&gt;Port A&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;EGPIO[15:8]&lt;/td&gt;       &lt;td&gt;Port B&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;GRLED1&lt;/td&gt;       &lt;td&gt;Port E0&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;RDLED2&lt;/td&gt;       &lt;td&gt;Port E1&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;EECLK3&lt;/td&gt;       &lt;td&gt;Port G0&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td&gt;EEDAT4&lt;/td&gt;       &lt;td&gt;Port G1&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt; &lt;/table&gt;   &lt;h3&gt;GPIO 寄存器映射&lt;/h3&gt;  &lt;p class="first"&gt;鉴于GPIO寄存器很多，我也就不列出来了。&lt;/p&gt;  &lt;p&gt;只是说几个要点。&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;PADR ― PHDR，数据寄存器  &lt;ul&gt;&lt;li&gt;读取这些寄存器将会返回GPIO模块输入端口的值（由PXDDR控制），默认情况是缺省端 口映射下的端口状态信息。&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;PEDR，他的bit[1:0]提供了LED 驱动方法，默认是0x11&lt;/li&gt;&lt;li&gt;RAWSTATUSx，共三个寄存器。显示了无关针脚的读取状态&lt;/li&gt;&lt;/ol&gt;   &lt;h3&gt;寄存器索引&lt;/h3&gt;  &lt;p class="first"&gt;略&lt;/p&gt;   &lt;h3&gt;引用&lt;/h3&gt;  &lt;ol&gt;&lt;li&gt;&lt;a href="http://www.cirrus.com/en/products/pro/detail/P1066.html"&gt;EP9302 User's Guide&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2836938948770447759?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2836938948770447759/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2009/02/ep93xx-gpio-interface.html#comment-form' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2836938948770447759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2836938948770447759'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2009/02/ep93xx-gpio-interface.html' title='EP93xx GPIO interface'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-30821229767102903</id><published>2009-02-17T21:39:00.002+08:00</published><updated>2011-03-06T11:27:02.524+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>新章： 试用LXDE Desktop Environment</title><content type='html'>&lt;h3&gt;闲聊&lt;/h3&gt;  &lt;p class="first"&gt;好了，很长时间没写字，我都不知道如何动笔了。&lt;/p&gt;  &lt;p&gt;其实不是不想写，也非过年过皮实了，而是这些天都在忙活。从过年来，天天加班到九点， 回到家里还要折腾自己的小窝，面对邪恶的加菲，我在家里几乎无所事事。但是我也没闲着， 天天折腾到两三点，至于我干什么？我在折腾这两年累计的东西呢。&lt;/p&gt;  &lt;p&gt;就说今天干了什么吧。&lt;/p&gt;   &lt;h3&gt;新手接触 LXDE&lt;/h3&gt;  &lt;p class="first"&gt;我今天测试了一下新的桌面环境LXDE，这是来自彼岸的台湾同胞洪任谕开发的（他同时也是 PC Man文件管理器的作者）。LXDE是非常小巧的羽量级桌面环境，他的桌面组建加载的很少， 这样本身的代码量就比较小（加起来总共只有9M左右），这样运行起来就很快很快。&lt;/p&gt;  &lt;p&gt;LXDE采用了openbox作为窗口管理器，这个东西也是非常的迅速。使用的文件浏览器是看家 的 pcmanfm，一些官方维护的组件如下：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;PCManFM，文件管理器，类似于Nautilus&lt;/li&gt;&lt;li&gt;LXLauncher，一个快速启动面板&lt;/li&gt;&lt;li&gt;LXPanel，简洁的桌面面板，类似于 gnome-panel&lt;/li&gt;&lt;li&gt;LXSession，会话管理器&lt;/li&gt;&lt;li&gt;LXAppearance，主题管理器&lt;/li&gt;&lt;li&gt;LXSessionEdit，进化的任务管理器&lt;/li&gt;&lt;li&gt;Leafpad，默认的记事本&lt;/li&gt;&lt;li&gt;Xarchiver，内嵌的归档管理器&lt;/li&gt; &lt;li&gt;GPicView&lt;/li&gt;&lt;li&gt;LXTerminal&lt;/li&gt;&lt;li&gt;LXTask&lt;/li&gt;&lt;li&gt;LXNM&lt;/li&gt;&lt;li&gt;Openbox&lt;/li&gt;&lt;li&gt;LXRandr，屏幕管理器，可以管理多个屏幕的分辨率，刷新频率等等，大赞！&lt;/li&gt;&lt;li&gt;LXShortCut，用来快捷方式&lt;/li&gt;&lt;li&gt;LXMusic&lt;/li&gt;&lt;li&gt;LXDE Common&lt;/li&gt;&lt;li&gt;GtkNetCat&lt;/li&gt;&lt;/ul&gt;   &lt;h3&gt;希望&lt;/h3&gt;  &lt;p class="first"&gt;目前的LXDE还是太少，跟树大根深的GNOME自然无法比，但是LXDE有着很多的先天优势。对 于我来说，LXDE还需要改进的是：一个快捷键管理工具，虽然你可以手动编辑 ~/.config/openbox/lxde-rc.xml；一个很好的桌面字体渲染引擎；采用更多的轻量级应用 软件，比如Office，画图等等；增强PCMan文件管理器功能，当然这要建立在不牺牲速度和 性能的基础之上，毕竟这是LXDE的设计哲学。&lt;/p&gt;  &lt;p&gt;安装 LXDE 请看：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://en.gentoo-wiki.com/wiki/LXDE"&gt;http://en.gentoo-wiki.com/wiki/LXDE&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;追踪 LXDE 社区线索：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.lxde.org/join_lxde_community"&gt;http://www.lxde.org/join_lxde_community&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;截图&lt;/h3&gt;&lt;br /&gt;&lt;p class="mobile-photo"&gt;&lt;a href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SZq-CM_ytSI/AAAAAAAAFWY/8TOy_O90lmY/s1600-h/Screenshot-lxde-760306.png"&gt;&lt;img src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SZq-CM_ytSI/AAAAAAAAFWY/8TOy_O90lmY/s320/Screenshot-lxde-760306.png" alt="" id="BLOGGER_PHOTO_ID_5303760456239985954" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="mobile-photo"&gt;&lt;a href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SZq-CP_vjkI/AAAAAAAAFWg/5HvOMO13a0w/s1600-h/Screenshot-lxlauncher-760659.png"&gt;&lt;img src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SZq-CP_vjkI/AAAAAAAAFWg/5HvOMO13a0w/s320/Screenshot-lxlauncher-760659.png" alt="" id="BLOGGER_PHOTO_ID_5303760457045085762" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-30821229767102903?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/30821229767102903/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2009/02/lxde-desktop-environment.html#comment-form' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/30821229767102903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/30821229767102903'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2009/02/lxde-desktop-environment.html' title='新章： 试用LXDE Desktop Environment'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Kb-lr4qFtj4/SZq-CM_ytSI/AAAAAAAAFWY/8TOy_O90lmY/s72-c/Screenshot-lxde-760306.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-1804814116543149254</id><published>2009-01-18T17:33:00.013+08:00</published><updated>2011-03-17T16:20:56.388+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>游历深圳博物馆 (Shenzhen Museum)</title><content type='html'>深圳博物馆位于福田区市民中心的东部，新馆于12月25日开馆，由此免费向公众开放。&lt;br /&gt;&lt;br /&gt;博物馆主题重要的有三个，古代深圳、近代深圳和深圳民俗文化，以此分别设置三个主题展&lt;br /&gt;厅。这三个展厅相当相当的长，里面的玩意儿非常之多，很对得起2.4亿的造价啊。。。&lt;br /&gt;&lt;br /&gt;我和大黄俊丽三人浩浩荡荡的来到深圳博物馆，开始长游，因为展品繁多，地形复杂。我只&lt;br /&gt;说说几个非常重要的 ————&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;中国国家典藏精品展览&lt;/span&gt;&lt;br /&gt;先是一楼，中国国家典藏精品展览。你可以看到很多在历史书里翻看到的东西，包括四羊方&lt;br /&gt;尊、战神之鸟、铜面具、青瓷莲花尊等等等等。未能想到在这里就见到我朝思暮想的宝贝啊～&lt;br /&gt;&lt;br /&gt;四羊方尊，在历史书籍里的出境率非常之高。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL4gAWInxI/AAAAAAAADd0/z_X7q9QDiB8/s1600-h/IMG_4275.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL4gAWInxI/AAAAAAAADd0/z_X7q9QDiB8/s320/IMG_4275.JPG" alt="" id="BLOGGER_PHOTO_ID_5292565740846096146" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;战神之鸟，基本看不出来是只鸟。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL4gYU3aYI/AAAAAAAADd8/oooGPiGLZcE/s1600-h/IMG_4278.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL4gYU3aYI/AAAAAAAADd8/oooGPiGLZcE/s320/IMG_4278.JPG" alt="" id="BLOGGER_PHOTO_ID_5292565747283224962" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;编钟，1952年中国首次使用编钟演奏了《东方红》。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXL4gsNLpwI/AAAAAAAADeE/TnDYCCYPv_c/s1600-h/IMG_4294.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXL4gsNLpwI/AAAAAAAADeE/TnDYCCYPv_c/s320/IMG_4294.JPG" alt="" id="BLOGGER_PHOTO_ID_5292565752619706114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;兵马俑，让我想起了The Mummy!&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SXL4g-FbDfI/AAAAAAAADeM/pNk0j0TLKx4/s1600-h/IMG_4304.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SXL4g-FbDfI/AAAAAAAADeM/pNk0j0TLKx4/s320/IMG_4304.JPG" alt="" id="BLOGGER_PHOTO_ID_5292565757418999282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;金缕玉衣，大黄坏坏的给了这样一个特写。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXL4g-MG-HI/AAAAAAAADeU/Zsho2UCc6Y0/s1600-h/IMG_4310.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXL4g-MG-HI/AAAAAAAADeU/Zsho2UCc6Y0/s320/IMG_4310.JPG" alt="" id="BLOGGER_PHOTO_ID_5292565757447043186" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;重点的重点啊！青瓷莲花尊的做工非常精美呐，介绍词给的非常庄严——涅磐之舟！&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SXL9_9CsPMI/AAAAAAAADec/NnTcryfsUOs/s1600-h/IMG_4314.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SXL9_9CsPMI/AAAAAAAADec/NnTcryfsUOs/s320/IMG_4314.JPG" alt="" id="BLOGGER_PHOTO_ID_5292571787273190594" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;民俗文化厅&lt;/span&gt;&lt;br /&gt;然后是二楼，民俗文化展厅，里面展示深圳古色古香的民俗风情。里面大多来自清朝和近代&lt;br /&gt;的一些民间情景，其中各个情景中的泥偶人物非常逼真。第一次看到的时候吓我一跳:(&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SXL-ABgLH1I/AAAAAAAADek/WJ12rcEn1i8/s1600-h/IMG_4333.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SXL-ABgLH1I/AAAAAAAADek/WJ12rcEn1i8/s320/IMG_4333.JPG" alt="" id="BLOGGER_PHOTO_ID_5292571788470591314" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;官员展示农耕的场景。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXL-AQrs9yI/AAAAAAAADes/OBzEiMPA6qA/s1600-h/IMG_4335.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXL-AQrs9yI/AAAAAAAADes/OBzEiMPA6qA/s320/IMG_4335.JPG" alt="" id="BLOGGER_PHOTO_ID_5292571792545478434" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL-Aw2Bp3I/AAAAAAAADe0/GJMHOYuWZsY/s1600-h/IMG_4354.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL-Aw2Bp3I/AAAAAAAADe0/GJMHOYuWZsY/s320/IMG_4354.JPG" alt="" id="BLOGGER_PHOTO_ID_5292571801178711922" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SXL-BNVWXCI/AAAAAAAADe8/vSa7b9Q6RZQ/s1600-h/IMG_4358.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SXL-BNVWXCI/AAAAAAAADe8/vSa7b9Q6RZQ/s320/IMG_4358.JPG" alt="" id="BLOGGER_PHOTO_ID_5292571808826285090" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;古代展厅&lt;/span&gt;&lt;br /&gt;这个似乎在说深圳的悠长历史，可是我印象中这是深圳的薄弱之处。抱歉，我这里没有好的&lt;br /&gt;素材。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SXL_XO-Xt8I/AAAAAAAADfE/IqqxHTXXgNk/s1600-h/IMG_4381.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SXL_XO-Xt8I/AAAAAAAADfE/IqqxHTXXgNk/s320/IMG_4381.JPG" alt="" id="BLOGGER_PHOTO_ID_5292573286735525826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;近代展厅&lt;/span&gt;&lt;br /&gt;此展厅讲述深圳从鸦片战争以来的发展历史。&lt;br /&gt;&lt;br /&gt;民国时期的成绩单，看看那时候的科目：国语，算术，历史，自然，地理，图画，美术等等&lt;br /&gt;……&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL_Xf1fBTI/AAAAAAAADfM/lfFjW6ifYNc/s1600-h/IMG_4363.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL_Xf1fBTI/AAAAAAAADfM/lfFjW6ifYNc/s320/IMG_4363.JPG" alt="" id="BLOGGER_PHOTO_ID_5292573291261658418" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;旧式缝纫机。我真的不觉得很旧，因为老妈还有一个缝纫机，形状神似。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL_Xk0eTNI/AAAAAAAADfU/27WBz7Q6-vs/s1600-h/IMG_4364.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL_Xk0eTNI/AAAAAAAADfU/27WBz7Q6-vs/s320/IMG_4364.JPG" alt="" id="BLOGGER_PHOTO_ID_5292573292599594194" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;罗湖火车站的旧景。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXL_X7OqNII/AAAAAAAADfc/wamPO48tslw/s1600-h/IMG_4365.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXL_X7OqNII/AAAAAAAADfc/wamPO48tslw/s320/IMG_4365.JPG" alt="" id="BLOGGER_PHOTO_ID_5292573298615006338" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;抗日战争中使用的武器，我总以为解放军最先进的是驳壳枪……&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXMq1350lLI/AAAAAAAADgk/ZMoIkXI8vCI/s1600-h/IMG_4372.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXMq1350lLI/AAAAAAAADgk/ZMoIkXI8vCI/s320/IMG_4372.JPG" alt="" id="BLOGGER_PHOTO_ID_5292621092118369458" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;现代展厅&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;深圳所具备的魅力，毫无疑问被定格在了现代。作为改革开放的试点城市，深圳引进外资，&lt;br /&gt;对外开放，成就了神话般的成长速度。这个地方看到的东西就非常新奇了。&lt;br /&gt;&lt;br /&gt;恨死这家伙，把我照片拍的血肉模糊……&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXMA2V760mI/AAAAAAAADf0/BQJtkd1fAzE/s1600-h/IMG_4397.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXMA2V760mI/AAAAAAAADf0/BQJtkd1fAzE/s320/IMG_4397.JPG" alt="" id="BLOGGER_PHOTO_ID_5292574920691864162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;模拟的深圳特区全景，包括了关内的四个区。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SXMA2mxHTcI/AAAAAAAADf8/BhH2ftvyeQI/s1600-h/IMG_4402.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SXMA2mxHTcI/AAAAAAAADf8/BhH2ftvyeQI/s320/IMG_4402.JPG" alt="" id="BLOGGER_PHOTO_ID_5292574925209947586" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;超级乐高机器人！太太太酷了，我还在szlug里贴给他们看呐，只可惜我不能碰它:P&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SXMA3P4xmrI/AAAAAAAADgE/oAyLD-LCFRU/s1600-h/IMG_4404.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SXMA3P4xmrI/AAAAAAAADgE/oAyLD-LCFRU/s320/IMG_4404.JPG" alt="" id="BLOGGER_PHOTO_ID_5292574936247933618" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;展示深圳金融系统推出的各种卡：银穗卡，一卡通，信用卡。教条内容：2000年深圳率先建&lt;br /&gt;立以银行、证券、保险为主体，其他类型金融机构并存的现代金融体系。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXMA3V5zEcI/AAAAAAAADgM/71GHlkiYNGY/s1600-h/IMG_4408.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXMA3V5zEcI/AAAAAAAADgM/71GHlkiYNGY/s320/IMG_4408.JPG" alt="" id="BLOGGER_PHOTO_ID_5292574937862836674" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;深圳湾码头，被大堆的集装箱所淹没。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXMBYkjts-I/AAAAAAAADgU/67CJwZBzJJU/s1600-h/IMG_4410.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXMBYkjts-I/AAAAAAAADgU/67CJwZBzJJU/s320/IMG_4410.JPG" alt="" id="BLOGGER_PHOTO_ID_5292575508732425186" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;这一切的始作俑者，邓公。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXMBY2rJAvI/AAAAAAAADgc/lKVSY4uBim4/s1600-h/IMG_4417.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SXMBY2rJAvI/AAAAAAAADgc/lKVSY4uBim4/s320/IMG_4417.JPG" alt="" id="BLOGGER_PHOTO_ID_5292575513595413234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;谢谢欣赏。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-1804814116543149254?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/1804814116543149254/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2009/01/shenzhen-museum.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1804814116543149254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1804814116543149254'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2009/01/shenzhen-museum.html' title='游历深圳博物馆 (Shenzhen Museum)'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Kb-lr4qFtj4/SXL4gAWInxI/AAAAAAAADd0/z_X7q9QDiB8/s72-c/IMG_4275.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2360385552716311095</id><published>2009-01-09T18:19:00.002+08:00</published><updated>2011-03-17T16:24:50.705+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-bash'/><title type='text'>初学sed</title><content type='html'>&lt;!-- Page published by Emacs Muse begins here --&gt; &lt;p&gt;sed, awk等等UNIX下的工具初看显得晦涩又难用，就些命令行搞那么复杂干哈子呀。&lt;/p&gt;  &lt;p&gt;不过一旦掌握以后就能发现给日常操作带来很大好处，那些简洁高效的命令行可都有着悠久 的历史了……&lt;/p&gt;  &lt;p&gt;因此在学习他们之前，告诫自己：Don't get confuSed~&lt;br /&gt;&lt;/p&gt;&lt;p&gt;这里的例子全部来自ibm developerworks。 &lt;a href="http://www.ibm.com/developerworks/linux/library/l-sed1.html"&gt;&lt;br /&gt;http://www.ibm.com/developerworks/linux/library/l-sed1.html&lt;/a&gt;&lt;/p&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .comment {         /* font-lock-comment-face */         color: #ff7f24;       }       .comment-delimiter {         /* font-lock-comment-delimiter-face */         color: #ff7f24;       }       .string {         /* font-lock-string-face */         color: #ffa07a;       }     --&gt;&lt;/style&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;基本篇&lt;br /&gt;&lt;/span&gt;sed -e &lt;span class="string"&gt;'d'&lt;/span&gt; /etc/services &lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;删除所有行，因此没有输出&lt;br /&gt;&lt;/span&gt;sed -e &lt;span class="string"&gt;'1d'&lt;/span&gt; /etc/services | more &lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;删除第一行&lt;br /&gt;&lt;/span&gt;sed -e &lt;span class="string"&gt;'1,10d'&lt;/span&gt; /etc/services | more &lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;删除1-10行&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;正则篇&lt;br /&gt;&lt;/span&gt;sed -e &lt;span class="string"&gt;'/^#/d'&lt;/span&gt; /etc/services | more &lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;删除注释&lt;br /&gt;&lt;/span&gt;sed -n -e &lt;span class="string"&gt;'/regexp/p'&lt;/span&gt; /path/to/my/test/file | more &lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;打印匹配regexp的行&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;-n 标示只打印regexp匹配字符，-e针对文本，-f将指定sed 脚本&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;标准的正则符号有&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;^: matches all begin with...&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;$: matches the end of the line...&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;.: matches any single char&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;*: will match zero or more occurences of the previous char&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;[]: matches all the characters inside the []&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;sed -n -e &lt;span class="string"&gt;'/BEGIN/,/END/p'&lt;/span&gt; /my/test/file | more&lt;br /&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;打印一个范围，首行包含BEGIN, 尾行包含END&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;sed -ne &lt;span class="string"&gt;'/main[[:space:]]*(/,/^)/p'&lt;/span&gt; tmp.c&lt;br /&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;打印main函数&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;替换篇&lt;br /&gt;&lt;/span&gt;sed -e &lt;span class="string"&gt;'s/foo/bar/'&lt;/span&gt; myfile.txt &lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;找到第一个foo，替换为bar&lt;br /&gt;&lt;/span&gt;sed -e &lt;span class="string"&gt;'s/foo/bar/g'&lt;/span&gt; myfile.txt &lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;全局替换&lt;br /&gt;&lt;/span&gt;sed -e &lt;span class="string"&gt;'1,10s/foo/bar/g'&lt;/span&gt; myfile.txt&lt;br /&gt;sed -e &lt;span class="string"&gt;'/^$/,/^END/s/foo/bar/g'&lt;/span&gt; myfile.txt&lt;br /&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;以最前的空行为开始，END字符结束&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;sed -e &lt;span class="string"&gt;'s:/usr/local:/usr:g'&lt;/span&gt; myfile.txt&lt;br /&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;改变操作服为`:'&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;sed -e &lt;span class="string"&gt;'s/&lt;[^&gt;]*&gt;//g'&lt;/span&gt; myfile.html&lt;br /&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;原文本: &lt;b&gt;This&lt;/b&gt; is what &lt;b&gt;I&lt;/b&gt; want&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;改变后: This is what I want.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;sed -e &lt;span class="string"&gt;'s/.*/ralph said: &amp;amp;/'&lt;/span&gt; myfile.html&lt;br /&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;在所有首行添加"ralph said: "&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;sed -e &lt;span class="string"&gt;'s/\(.*\) \(.*\) \(.*\)'&lt;/span&gt;/Victor \1-\2 Von \3/&lt;span class="string"&gt;' myfile.txt&lt;br /&gt;#原文本:&lt;br /&gt;# foo bar oni&lt;br /&gt;# eeny meeny miny&lt;br /&gt;#改变后:&lt;br /&gt;# Victor foo-bar Von oni&lt;br /&gt;# Victor eeny-meeny Von miny&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;sed一般用来 (via &lt;a href="http://www.builder.com.cn/2002/1024/72583.shtml"&gt;builder.com&lt;/a&gt;)—&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Double/triple-space a file&lt;/li&gt;&lt;li&gt;转化DOS/UNIX 的新行（newline）&lt;/li&gt;&lt;li&gt;删除前后的空格&lt;/li&gt;&lt;li&gt;在所有/全部行上进行取代操作&lt;/li&gt;&lt;li&gt;删除连续的空行&lt;/li&gt;&lt;li&gt;删除文件开头和结尾的空行&lt;/li&gt;&lt;/ul&gt;  &lt;!-- Page published by Emacs Muse ends here --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2360385552716311095?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2360385552716311095/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2009/01/sed.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2360385552716311095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2360385552716311095'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2009/01/sed.html' title='初学sed'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-6943472367519785684</id><published>2008-12-25T10:55:00.005+08:00</published><updated>2011-03-06T11:00:34.831+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-arch-arm'/><title type='text'>ARM Linux 启动过程 (1)</title><content type='html'>&lt;span style="font-weight: normal;font-size:85%;" &gt;&lt;span style="font-style: italic;"&gt;此系列记录了ARM Linux从Bootloader部分到Linux初始化，然后进入C环境的一段坎坷历程 。作为第一部分，我将从RedBoot开开始。RedBoot是嵌入式中应用广泛的Bootloader，他将作为此系列的序章。&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;RedBoot  (bootloader)&lt;/h2&gt;  &lt;ul&gt;&lt;li&gt;概述&lt;/li&gt;&lt;li&gt;RedBoot所作的工作&lt;/li&gt;&lt;/ul&gt;  &lt;h3&gt;概述&lt;/h3&gt;  &lt;p class="first"&gt;（本示例讲解基于ARM9的Cirrus EP9302） Bootloader 在 ARM 中依然是加电后的第一道程序，其作用简单，相当于 PC 机器上的 BIOS 固件程序。Bootloader 负责完成系统初始化，它将非易失性储存器中的 Linux 内核 拷贝到 RAM 中去，然后跳转到内核的第一道指令，将控制权交给内核。从这个意义上讲， 嵌入式 Bootloader 要做的事情比 x86 等机器多很多。&lt;/p&gt;  &lt;p&gt;一般ARM Linux的第一条指令地址是0x0000_0000，而通常嵌入式系统会将FLASH等存储寄存 器映射到这个地址，而Bootloader就位于该存储器顶端，这保证了Bootloader的顺利执行。&lt;/p&gt;  &lt;p&gt;以 RedBoot for EP93xx 为例，EP93xx 采用 NAND Flash 作为存储介质，在 RedBoot 中可 以罗列存储器的根目录如下：&lt;/p&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--     --&gt;&lt;/style&gt;RedBoot&gt; fis init&lt;br /&gt;Name              FLASH addr  Mem addr    Length      Entry point&lt;br /&gt;RedBoot           0x60000000  0x60000000  0x00040000  0x00000000&lt;br /&gt;RedBoot config    0x60FC0000  0x60FC0000  0x00001000  0x00000000&lt;br /&gt;FIS directory     0x60FE0000  0x60FE0000  0x00020000  0x00000000&lt;br /&gt;zImage            0x60040000  0x00080000  0x00120000  0x00080000&lt;br /&gt;ramdisk           0x60140000  0x00800000  0x00800000  0x00800000&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;这里可以看出在 Flash 文件系统中存储了他的系统文件 RedBoot（内核）、RedBoot config（设置信息）、FIS directory（系统目录），另外就是 Linux 的内核 zImage 和内 存盘 ramdisk.gz。&lt;/p&gt;   &lt;h3&gt;RedBoot做的工作&lt;/h3&gt;  &lt;ol&gt;&lt;li&gt;SDRAM初始化，没有内存，啥东西也玩不转 (cyg/hal/hal_platform_setup.h)&lt;/li&gt;&lt;li&gt;初始化串口 (hal/arch/ARCH/src/hal_diag.c)&lt;/li&gt;&lt;li&gt;检测处理器类型 (宏指定，cdl/hal_ARCH_MACHINE.cdl)&lt;/li&gt;&lt;li&gt;设置Linux启动参数 (hal/ARCH/arch/src/redboot_linux_exec.c)&lt;/li&gt;&lt;li&gt;将Linux内核装载到内存中，跳转执行&lt;/li&gt;&lt;/ol&gt;   &lt;h3&gt;启动内核&lt;/h3&gt;  &lt;p class="first"&gt;启动内核函数do_exec的这段代码在 hal/ARCH/arch/src/redboot_linux_exec.c，最重要的 就是末尾处的内联汇编语句： &lt;/p&gt;&lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .comment {         /* font-lock-comment-face */         color: #ff7f24;       }       .comment-delimiter {         /* font-lock-comment-delimiter-face */         color: #ff7f24;       }       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .preprocessor {         /* font-lock-preprocessor-face */         color: #b0c4de;       }       .string {         /* font-lock-string-face */         color: #ffa07a;       }     --&gt;&lt;/style&gt;    &lt;span class="keyword"&gt;asm&lt;/span&gt; &lt;span class="keyword"&gt;volatile&lt;/span&gt; (&lt;br /&gt;      CYGARC_HAL_MMU_OFF(%5)&lt;br /&gt;      &lt;span class="string"&gt;"__tramp_start__:\n"&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;" cmp %1,%4;\n"&lt;/span&gt;       &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;Default kernel load address. Relocate&lt;br /&gt;&lt;/span&gt;        &lt;span class="string"&gt;" beq 2f;\n"&lt;/span&gt;          &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;kernel image there if necessary, and&lt;br /&gt;&lt;/span&gt;        &lt;span class="string"&gt;" cmp %2,#0;\n"&lt;/span&gt;       &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;if size is non-zero&lt;br /&gt;&lt;/span&gt;        &lt;span class="string"&gt;" beq 2f;\n"&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;"1:\n"&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;" ldr r0,[%1],#4;\n"&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;" str r0,[%4],#4;\n"&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;" subs %2,%2,#4;\n"&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;" bne 1b;\n"&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;"2:\n"&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;" mov r0,#0;\n"&lt;/span&gt;       &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;Set board type&lt;br /&gt;&lt;/span&gt;        &lt;span class="string"&gt;" mov r1,%3;\n"&lt;/span&gt;       &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;Machine type&lt;br /&gt;&lt;/span&gt;        &lt;span class="string"&gt;" mov r2,%6;\n"&lt;/span&gt;       &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;Kernel parameters&lt;br /&gt;&lt;/span&gt;        &lt;span class="string"&gt;" mov pc,%0;\n"&lt;/span&gt;       &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;Jump to kernel&lt;br /&gt;&lt;/span&gt;        &lt;span class="string"&gt;"__tramp_end__:\n"&lt;/span&gt;&lt;br /&gt;      : :&lt;br /&gt;      &lt;span class="string"&gt;"r"&lt;/span&gt;(entry),&lt;br /&gt;      &lt;span class="string"&gt;"r"&lt;/span&gt;(CYGARC_PHYSICAL_ADDRESS(base_addr)),&lt;br /&gt;      &lt;span class="string"&gt;"r"&lt;/span&gt;(length),&lt;br /&gt;      &lt;span class="string"&gt;"r"&lt;/span&gt;(CYGHWR_REDBOOT_ARM_MACHINE_TYPE),&lt;br /&gt;&lt;span class="preprocessor"&gt;#ifdef&lt;/span&gt; CYGHWR_HAL_ARM_EDB93XX_VARIANT&lt;br /&gt;      &lt;span class="string"&gt;"r"&lt;/span&gt;((CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS &amp;amp; 0x3ffffff) +&lt;br /&gt;          ConfigInfo[3]),&lt;br /&gt;&lt;span class="preprocessor"&gt;#else&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;"r"&lt;/span&gt;(CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS),&lt;br /&gt;&lt;span class="preprocessor"&gt;#endif&lt;/span&gt;&lt;br /&gt;      &lt;span class="string"&gt;"r"&lt;/span&gt;(CYGARC_PHYSICAL_ADDRESS(CYGHWR_REDBOOT_ARM_TRAMPOLINE_ADDRESS)),&lt;br /&gt;      &lt;span class="string"&gt;"r"&lt;/span&gt;(CYGARC_PHYSICAL_ADDRESS(CYGHWR_REDBOOT_ARM_LINUX_TAGS_ADDRESS))&lt;br /&gt;      : &lt;span class="string"&gt;"r0"&lt;/span&gt;, &lt;span class="string"&gt;"r1"&lt;/span&gt;&lt;br /&gt;      );&lt;br /&gt;&lt;/pre&gt; 首先关闭MMU，保证代码跳转位置是绝对的物理地址，然后重置内核（如果需要）到entry处， 执行跳转，跳转前保证了：r0置0，r1装载机器类型，r2装载struct tag数组地址。  &lt;p&gt;这样RedBoot结束了其短暂而又伟大的一生，我们进入Linux的世界。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-6943472367519785684?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/6943472367519785684/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/12/arm-linux-1.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6943472367519785684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6943472367519785684'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/12/arm-linux-1.html' title='ARM Linux 启动过程 (1)'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2808358427907561282</id><published>2008-12-12T11:54:00.002+08:00</published><updated>2011-03-06T11:27:02.529+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>优化代码显示的另一个方法</title><content type='html'>&lt;code&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;       printf("Hello, everybody!\n");&lt;br /&gt;}&lt;br /&gt;/* 为啥空出那么多呢？*/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;参考：&lt;br /&gt;&lt;a href="http://klcintw4.blogspot.com/2006/11/blog-post_03.html"&gt;http://klcintw4.blogspot.com/2006/11/blog-post_03.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2808358427907561282?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2808358427907561282/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/12/blog-post.html#comment-form' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2808358427907561282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2808358427907561282'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/12/blog-post.html' title='优化代码显示的另一个方法'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-6183020709259704929</id><published>2008-12-10T10:16:00.006+08:00</published><updated>2011-03-06T11:07:07.257+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-drivers-scsi'/><title type='text'>Linux SCSI子系统</title><content type='html'>&lt;h2&gt;scsi历史&lt;/h2&gt;scsi-1::1979年由SHugart Associates创建，它定义了一种具有5MHz数据时钟的8-bit并行接口。  &lt;p&gt;scsi-2::1985年，10MHz，16位总线。&lt;/p&gt;  &lt;p&gt;scsi-3::1993年，已经成为了一种标准集，它包含一种命名为Ultra的并行scsi标准和基于 串行scsi和基于串行scsi的协议，这些标准通过引入存储网络技术将数据速率拓展到了 1Gb/s。&lt;/p&gt;   &lt;h2&gt;scsi架构基础&lt;/h2&gt;如果你是一位设计师，那么需要从scsi spec下手。而对于软件开发人员来说，你只需要关 注scsi的架构。在深入之前，将scsi架构图牢记于心，对于理解代码是非常重要的。linux scsi位于系统的底层 —&lt;br /&gt;&lt;br /&gt;linux scsi本身是一种三层架构，upper, mid, lower，upper层最为接近内核，包括一组驱 动器（比如块设备SCSI 磁盘和字符设备SCSI generic）；mid实现了common services layer， 接受upper的请求并将其转化为scsi请求，scsi lower层则是紧附硬件之上的硬件驱动。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;索引&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p class="image"&gt;&lt;/p&gt;&lt;p&gt;从ibm developerworks大致了解三层架构：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/linux/l-scsi-subsystem/"&gt;http://www.ibm.com/developerworks/cn/linux/l-scsi-subsystem/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;从这里获得scsi标准的细节：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.t10.org/"&gt;http://www.t10.org/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;我们的目标在于linux的实现(pdf, 321KB)：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://developer.osdl.org/dev/opendrivers/documentation/scsi_design_analysis_2_6_v2.pdf"&gt;http://developer.osdl.org/dev/opendrivers/documentation/scsi_design_analysis_2_6_v2.pdf&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;h2&gt;出发&lt;/h2&gt;  &lt;hr /&gt; 本着记录和总结的目的，深入求实的精神，我开始在日志上记录scsi的看书笔记。scsi的设 备是典型的层次架构，经历过风雨变迁的scsi标准也散发着蓬勃的活力，因此看懂这段代码 很有意义。  &lt;p&gt;笔记目标将会从sd_mod.o起步，清晰中间层（mid），上层（upper）和底层（lower）的大 致架构，最后深入到公司最近正在移植的sata_sil驱动。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-6183020709259704929?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/6183020709259704929/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/12/linux-scsi.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6183020709259704929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6183020709259704929'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/12/linux-scsi.html' title='Linux SCSI子系统'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-6447849029819427555</id><published>2008-11-28T16:27:00.005+08:00</published><updated>2011-03-06T11:25:26.008+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-html'/><title type='text'>使用muse来发布日志</title><content type='html'>使用Emacs是一件实在幸福的事情，它提供了一个又一个强大的拓展，让你的上机活动变的&lt;br /&gt;轻松惬意。很多Linux用户都是以Emacs为中心的。而我现在使用ECB阅读代码，diary-mode&lt;br /&gt;来撰写笔记，org-mode来组织日程规划……这次说到使用muse模式。  &lt;p&gt;muse允许通过简单的样式控制，制作出非常漂亮的网页。&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;控制基本样式&lt;/li&gt;&lt;li&gt;高亮代码&lt;/li&gt;&lt;/ol&gt;  &lt;h3&gt;&lt;a name="kongzhijibenyangshi" id="kongzhijibenyangshi"&gt;&lt;/a&gt;控制基本样式&lt;/h3&gt;  &lt;p class="first"&gt;很简单的，我先给出几个例子。 &lt;/p&gt;&lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--     --&gt;&lt;/style&gt;#title 第一个Wiki页面&lt;br /&gt;* 一级标题&lt;br /&gt;** 二级标题&lt;br /&gt;*** 三级标题&lt;br /&gt;#anchor&lt;br /&gt;段落需要空行两个（至少）&lt;br /&gt;  居中字前只少空四格&lt;br /&gt;----&lt;br /&gt;&lt;br /&gt;这是 *着重* 的文字，这是进一步 **着重** 的文字，这是 ***更进一步的着重*** 的文字&lt;br /&gt;&lt;br /&gt;这是 _下划线_ 文字，这是 =等宽verbatim and monospace= 的文字&lt;br /&gt;*** 列表：&lt;br /&gt;- 无序列表需要以空格和“-”开头&lt;br /&gt;1. 有序列表需要以空格和数字序号开头&lt;br /&gt;字典 :: 名词定义需要以“::”分隔名词和所定义文字&lt;br /&gt;- 列表也可以嵌套&lt;br /&gt;1. 列表嵌套深度按照开头空格的多少来控制&lt;br /&gt;2. 可以继续嵌套不同类型的列表&lt;br /&gt; - 比如这样&lt;br /&gt;*** 表格：&lt;br /&gt;Double bars  || Separate header fields&lt;br /&gt;Single bars   | Separate body fields&lt;br /&gt;Here are more | body fields&lt;br /&gt;Triple bars ||| Separate footer fields&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt; 生成的页面：&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SS-wWFxZq4I/AAAAAAAAC1g/6zU_ka9YV1w/s1600-h/Screenshot.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SS-wWFxZq4I/AAAAAAAAC1g/6zU_ka9YV1w/s320/Screenshot.png" alt="" id="BLOGGER_PHOTO_ID_5273627582227131266" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;a name="gaoliangdaima" id="gaoliangdaima"&gt;&lt;/a&gt;高亮代码&lt;/h3&gt;  &lt;p class="first"&gt;高亮代码是一个比较头疼的问题，大家给出的方案也不一样。在blogger中，你可以使用&lt;br /&gt;Google的&lt;a href="http://popoer.021128.net/2008/07/blogger-bloggerjs-google-code-prettify.html"&gt;prettyprint&lt;/a&gt;方法来实现高亮，但是它支持代码样式很少；同样2maomao也写了一个&lt;br /&gt;&lt;a href="http://www.fayaa.com/code/"&gt;高亮语法的工具&lt;/a&gt;，相对来说总是麻烦点；其实使用emacs高度的拓展性完全可以做到这点。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://pluskid.lifegoo.com/wiki/MuseSrctag.html"&gt;这里&lt;/a&gt;给出了一个使用muse来实现语法高亮的模式，这个方法非常的cool。它将emacs强大的&lt;br /&gt;高亮特性报留下来，嵌入到了html中。&lt;/p&gt;  &lt;p class="verse"&gt; 阅读上面的例子就可以看到，通过很少的字符，就可以实现工整的格式控制，这对于编写繁&lt;br /&gt;杂冗长的标志语言和记住大批的标记来说，是一种极好的替代。muse编写的脚本可以简单的&lt;br /&gt;声称很多种文档发布，包括HTML，Latex，PDF等等，多多使用，也自然可以可以极大提高工&lt;br /&gt;作效率。&lt;br /&gt;&lt;/p&gt;  &lt;center&gt; &lt;p&gt;参考资料&lt;/p&gt; &lt;/center&gt;  &lt;ol&gt;&lt;li&gt;&lt;a href="http://emacswiki.org/"&gt;Emacs Wiki&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mwolson.org/projects/WelcomePage.html"&gt;Emacs muse官方网站&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;    &lt;!-- Page published by Emacs Muse ends here --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-6447849029819427555?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/6447849029819427555/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/11/muse.html#comment-form' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6447849029819427555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6447849029819427555'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/11/muse.html' title='使用muse来发布日志'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Kb-lr4qFtj4/SS-wWFxZq4I/AAAAAAAAC1g/6zU_ka9YV1w/s72-c/Screenshot.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-1461018622771457410</id><published>2008-11-27T17:38:00.001+08:00</published><updated>2011-03-17T16:27:56.370+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bootloader-redboot'/><title type='text'>eCos HAL分析</title><content type='html'>&lt;h2&gt;HAL架构&lt;/h2&gt;  &lt;p class="first"&gt;HAL在eCos中是一个多层次的架构，层级封装了不同的功能，它包括：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;the architecture HAL &lt;blockquote&gt; &lt;p class="quoted"&gt;架构抽象包含基本的CPU架构，比如interrupt，上下文切换，CPU启动等&lt;/p&gt; &lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;the variant HAL &lt;blockquote&gt; &lt;p class="quoted"&gt;变体抽象层专注某一CPU的特性，比如caches，MMU和FPU等，他通常也处理内存和中断 控制器等外设。&lt;/p&gt; &lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;the platform HAL &lt;blockquote&gt; &lt;p class="quoted"&gt;平台抽象层专注于现任的平台特性，比如平台启动，定时器，I/O寄存器访问和中断控 制器等等。&lt;/p&gt; &lt;/blockquote&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;h2&gt;HAL接口&lt;/h2&gt;  &lt;p class="first"&gt;这里讲究HAL实现了哪些接口。&lt;/p&gt;  &lt;h3&gt;architecture characterization&lt;/h3&gt;  &lt;p class="first"&gt;这里包含了CPU基础架构的定义。包括了CPU段文存储格式，上下文切换，bit twiddling， 断点，堆栈大小和地址转换。这些定义位于：&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;cyg/hal/hal_arch.h (arch HAL)&lt;/li&gt;&lt;li&gt;cyg/hal/var_arch.h (var HAL)&lt;/li&gt;&lt;li&gt;cyg/hal/plf_arch.h (plf HAL)&lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;以下为议题细节&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;register save format&lt;/li&gt;&lt;li&gt;thread context initialization&lt;/li&gt;&lt;li&gt;thread context switching&lt;/li&gt;&lt;li&gt;bit indexing&lt;/li&gt;&lt;li&gt;idle thread activity&lt;/li&gt;&lt;li&gt;reorder barrier&lt;/li&gt;&lt;li&gt;breakpoint support&lt;/li&gt;&lt;li&gt;GDB support&lt;/li&gt;&lt;li&gt;setjmp and longjmp support&lt;/li&gt;&lt;li&gt;stack sizes&lt;/li&gt;&lt;li&gt;address translation&lt;/li&gt;&lt;li&gt;global pointer&lt;/li&gt;&lt;/ul&gt;   &lt;h3&gt;interrupt handling&lt;/h3&gt;  &lt;p class="first"&gt;这些接口定义了中断处理相关的定义，包括了异常和中断号，中断允许和屏蔽和实时时钟操 作。这些定义可以位于：&lt;/p&gt;  &lt;blockquote&gt; &lt;p class="quoted"&gt;cyg/hal/hal_intr.h (arch HAL)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;而变体和平台抽象层定义位于：&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;cyg/hal/var_intr.h (var HAL)&lt;/li&gt;&lt;li&gt;cyg/hal/plf_intr.h (plf HAL)&lt;/li&gt;&lt;li&gt;cyg/hal/hal_platform_ints.h (?)&lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;议题细节：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;vector numbers&lt;/li&gt;&lt;li&gt;interrupt state control&lt;/li&gt;&lt;li&gt;ISR and VSR management&lt;/li&gt;&lt;li&gt;interrupt controller management&lt;/li&gt;&lt;li&gt;clock control&lt;/li&gt;&lt;li&gt;microsecond delay&lt;/li&gt;&lt;/ul&gt;   &lt;h3&gt;HAL I/O&lt;/h3&gt;  &lt;p class="first"&gt;此接口定义了对设备控制寄存器的访问支持。&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;cyg/hal/hal_io.h&lt;/li&gt;&lt;li&gt;cyg/hal/var_io.h&lt;/li&gt;&lt;li&gt;cyg/hal/plf_io.h&lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;议题细节有：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;register address&lt;/li&gt;&lt;li&gt;register read&lt;/li&gt;&lt;li&gt;register write&lt;/li&gt;&lt;/ul&gt;   &lt;h3&gt;cache control&lt;/h3&gt;  &lt;p class="first"&gt;此接口定义了CPU caches的控制支持。&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;cyg/hal/hal_cache.h&lt;/li&gt;&lt;li&gt;cyg/hal/var_cache.h&lt;/li&gt;&lt;li&gt;cyg/hal/plf_cache.h&lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;详细议题：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;cache dimensions&lt;/li&gt;&lt;li&gt;global cache control&lt;/li&gt;&lt;li&gt;cache line control&lt;/li&gt;&lt;/ul&gt;   &lt;h3&gt;Linker scripts（连接器脚本，lds）&lt;/h3&gt;  &lt;p class="first"&gt;连接器脚本对于eCos程序来说是必须的，他定义了内存区域，地址和尺寸，代码段和数据段 的放置位置，还有分配不同的编译器声称的段。&lt;/p&gt;  &lt;p&gt;一般lds位于install/lib/target.ld，它事实上是由其他两类文件声称，一个基本的lds和 ldi文件声称的。&lt;/p&gt;  &lt;p&gt;基本lds由arch HAL或者var HAL提供，它由一组lds段组成。ldi由plf HAL提供哦你，它包 含目标平台的的内存布局信息，位于&lt;/p&gt;  &lt;p&gt;pkgconf/mlt_&lt;architecture&gt;_&lt;variant&gt;_&lt;platform&gt;_&lt;startup&gt;.ldi&lt;/p&gt;  &lt;p&gt;这些ldi文件都是由相应的mlt(memory layout tool)脚本生成的。&lt;/p&gt;   &lt;h3&gt;诊断支持&lt;/h3&gt;  &lt;p class="first"&gt;略&lt;/p&gt;   &lt;h3&gt;SMP支持&lt;/h3&gt;  &lt;p class="first"&gt;略&lt;/p&gt;  &lt;hr /&gt; &lt;blockquote&gt; &lt;p class="quoted"&gt;参考资料&lt;/p&gt; &lt;/blockquote&gt;  &lt;ol&gt;&lt;li&gt;&lt;a href="http://ecos.sourceware.org/docs-latest/cdl-guide/overview.html#OVERVIEW.TERMINOLOGY"&gt;eCos component writer's guide &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ecos.sourceware.org/docs-latest/ref/hal-porting-guide.html"&gt;eCos HAL porting guide&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.maihui.net/book/pcb99074.htm"&gt;如何构建eCos嵌入式系统&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-1461018622771457410?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/1461018622771457410/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/11/ecos-hal.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1461018622771457410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1461018622771457410'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/11/ecos-hal.html' title='eCos HAL分析'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-550309995083961435</id><published>2008-11-25T14:19:00.007+08:00</published><updated>2011-03-17T16:27:56.372+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bootloader-redboot'/><category scheme='http://www.blogger.com/atom/ns#' term='linux-arch-arm'/><title type='text'>Cirrus EP9302: 从RedBoot到Linux</title><content type='html'>&lt;h3&gt;Cirrus EP9302&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://www.cirrus.com/"&gt;Cirrus Logic&lt;/a&gt;是美国德州的一家半导体制造商，早在1989年就进入NASDAQ，股票代码是CRUS。&lt;br /&gt;EP93xx是基于ARM920T的主板系列，在官方上你可以看到详尽的EP9302资料。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cirrus.com/en/products/pro/detail/P1066.html"&gt;http://www.cirrus.com/en/products/pro/detail/P1066.html&lt;/a&gt;&lt;/p&gt;  &lt;p class="image"&gt;&lt;img src="http://www.cirrus.com/en/images/product_diagrams/9302blkdiag_mag.gif" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;EP9302和EP9301最大的区别就在于，CPU核心加入了一个浮点运算部件MaverickCrunch。&lt;/p&gt;  &lt;p&gt;我在开始的时候曾经说过，eCos支持&lt;a href="http://ecos.sourceware.org/hardware.html"&gt;非常多的架构&lt;/a&gt;，包括ARM， CalmRISC, FR-V, H8,&lt;br /&gt;IA32, M68K, Matsushita AM3x, MIPS, NEC V8xx, PowerPC, SPARC, SuperH。这是eCos非&lt;br /&gt;常值得骄傲的一点，也充分发挥了开源的长处。但是毕竟世界上的主板千千万，从汽车到蓝&lt;br /&gt;牙，无线设备等等等等，eCos开发小组也无法支持所有的主板。如果厂商新推出一个主板，&lt;br /&gt;那多半需要自己拓展eCos来支持自己的新板，我所使用的Cirrus Logic就是一个例子。&lt;/p&gt;  &lt;p&gt;你可以在&lt;a href="http://arm.cirrus.com/"&gt;官方网站&lt;/a&gt;上找到这些工具：&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://arm.cirrus.com/files/linux/releases/linux-2.6/old/cirrus-arm-linux-2.0.8-full.tar.bz2"&gt;cirrus-arm-linux-2.0.8-full.tar.bz2&lt;/a&gt; (Cirrus Linux套件)&lt;/li&gt;&lt;li&gt;&lt;a href="http://arm.cirrus.com/files/tools/arm-elf-gcc-3.2.1-full.tar.bz2"&gt;arm-elf-gcc-3.2.1-full.tar.bz2&lt;/a&gt; (arm-elf-gcc)&lt;/li&gt;&lt;li&gt;&lt;a href="http://arm.cirrus.com/files/tools/arm-linux-gcc-3.4.3-1.0.1.tar.bz2"&gt;arm-linux-gcc-3.4.3-1.0.1.tar.bz2&lt;/a&gt; (arm-linux-gcc)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;h3&gt;搭建工作环境&lt;/h3&gt;  &lt;p class="first"&gt;(此工作环境是在Red Hat Linux 9.0下配置完成，嵌入式开发普遍需要串口支持。)&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;解压arm-elf-gcc-3.2.1-full.tar.bz2得到两个目录，按照目录指引放置文件&lt;/li&gt;&lt;li&gt;在/etc/profile或者~/.bashrc中添加系统环境变量。比如 /etc/profile &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .comment {         /* font-lock-comment-face */         color: #ff7f24;       }       .comment-delimiter {         /* font-lock-comment-delimiter-face */         color: #ff7f24;       }       .keyword {         /* font-lock-keyword-face */         color: #00ffff;       }       .sh-quoted-exec {         /* sh-quoted-exec */         color: #fa8072;       }     --&gt;&lt;/style&gt;&lt;span class="keyword"&gt;if&lt;/span&gt; [ &lt;span class="sh-quoted-exec"&gt;`id -u`&lt;/span&gt; = 0]; &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;br /&gt; pathmunge /sbin&lt;br /&gt; pathmunge /usr/sbin&lt;br /&gt; pathmunge /usr/local/sbin&lt;br /&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;newly added for arm-3.4&lt;br /&gt;&lt;/span&gt;        pathmunge /usr/local/arm/3.4/bin&lt;br /&gt;&lt;span class="keyword"&gt;fi&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;   &lt;h3&gt;配置安装redboot&lt;/h3&gt;  &lt;p class="first"&gt;这步会非常简单。Cirrus几乎把一切工作都做好了，解压cirrus-arm-linux-2.0.8.tar.bz2&lt;br /&gt;进入目录 cirrus-arm-linux-2.0.8/edb9302，直接编译 &lt;/p&gt;&lt;blockquote&gt; &lt;p class="quoted"&gt;cd /path/to/cirrus-arm-linux-2.0.8/edb9302&lt;br /&gt;make redboot&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;然后得到cirrus-arm-linux-2.0.8/edb9302/images/redboot.bin，这就是一个redboot内核，&lt;br /&gt;他使用了ecos的redboot模板，创建针对EP9302主板的ecos内核。安装也是比较方便，这使&lt;br /&gt;用到了cirrus给的download工具（如果没有，你还需要编译）： &lt;/p&gt;&lt;blockquote&gt; &lt;p class="quoted"&gt;../download/download -p 1 images/redboot.bin&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;通常情况下，我们的主板都是不允许FLASH被任意擦写的，这个规定在硬件上被强制实现：&lt;br /&gt;用短路块连接EP9302的JP14的2、3脚。相反接到1、2脚，这个时候Flash会根据写入的协议&lt;br /&gt;向外发布数据，待download侦测到数据时候会进行握手和数据传递。&lt;/p&gt;  &lt;p&gt;然后关闭主板，进入EP9302，则可以进入Redboot命令行。&lt;/p&gt;   &lt;h3&gt;编译烧录linux&lt;/h3&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .builtin {         /* font-lock-builtin-face */         color: #b0c4de;       }       .comment {         /* font-lock-comment-face */         color: #ff7f24;       }       .comment-delimiter {         /* font-lock-comment-delimiter-face */         color: #ff7f24;       }     --&gt;&lt;/style&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;busybox config&lt;br /&gt;&lt;/span&gt;&lt;span class="builtin"&gt;cd&lt;/span&gt; /path/to/cirrus-arm-linux-2.0.8&lt;br /&gt;tar jxf tarballs/busybox-1.1.3.tar.bz2&lt;br /&gt;&lt;span class="builtin"&gt;cd&lt;/span&gt; busybox&lt;br /&gt;make menuconfig&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;compile ramdisk.gz&lt;br /&gt;&lt;/span&gt;&lt;span class="builtin"&gt;cd&lt;/span&gt; /path/to/cirrus-arm-linux-2.0.8/edb9302&lt;br /&gt;make ramdisk&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;compile linux zImage&lt;br /&gt;&lt;/span&gt;make linuxconfig&lt;br /&gt;make linux&lt;br /&gt;&lt;/pre&gt;这样就在/path/to/cirrus-arm-linux-2.0.8/edb9302/images中生成两个文件：&lt;br /&gt;ramdisk.gz和zImage。&lt;br /&gt;&lt;br /&gt;其中busybox和linux都需要对自己需求的理解来进行配置，在这里不再赘述。这里将一下&lt;br /&gt;linux拷贝方法。将Linux内核传递给EP9302，是使用到了tftp(Trival FTP)，首先需要配置&lt;br /&gt;Red Hat 9.0主机的tftp客户端（/etc/xinetd.d/tftp），tftp常常用于无盘工作站。在这&lt;br /&gt;里作为RH和EP9302的通讯协议。&lt;br /&gt;&lt;p&gt;然后进入EP9302 redboot配置主板（主要是网络）。&lt;/p&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .comment {         /* font-lock-comment-face */         color: #ff7f24;       }       .comment-delimiter {         /* font-lock-comment-delimiter-face */         color: #ff7f24;       }     --&gt;&lt;/style&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;---- 主板配置部分 ----&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;Local IP address是EP9302 IP地址&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;Default server IP address是RH9 IP地址&lt;br /&gt;&lt;/span&gt;RedBoot&gt; fcon -i&lt;br /&gt;Initialize non-volatile configuration - continue(y/n)&lt;br /&gt;Run script at boot: true&lt;br /&gt;Boot script:&lt;br /&gt;Enter script, terminate with empty line&lt;br /&gt;&gt;&gt; fis load ramdisk&lt;br /&gt;&gt;&gt; fis load zImage&lt;br /&gt;&gt;&gt; exec -r 0x800000 -s 0x800000&lt;br /&gt;&gt;&gt;&lt;br /&gt;Boot script(1000ms resolution): 1&lt;br /&gt;Use BOOTP for network configuration: false&lt;br /&gt;Gateway IP address: 192.168.16.1&lt;br /&gt;Local IP address: 192.168.16.93&lt;br /&gt;Local IP address mask: 255.255.255.0&lt;br /&gt;Default server IP address: 192.168.16.91&lt;br /&gt;DNS server IP address:&lt;br /&gt;Network hardware address[MAC]:0x78:0x56:0x34:0x12:0x64:0x30&lt;br /&gt;GDB connection port: 9000&lt;br /&gt;Force console for special debug messages: false&lt;br /&gt;Network debug at boot time: false&lt;br /&gt;Update RedBoot non-volatile configuration - continue(y/n)? y&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;---- 拷贝文件部分 ----&lt;br /&gt;&lt;/span&gt;RedBoot&gt; fis init -f&lt;br /&gt;RedBoot&gt; load -v -r -b 0x800000 ramdisk.gz -h 192.168.16.91&lt;br /&gt;RedBoot&gt; fis create -b 0x800000 -l 0x800000 ramdisk&lt;br /&gt;RedBoot&gt; load -v -r -b 0x80000 zImage -h 192.168.16.91&lt;br /&gt;RedBoot&gt; fis create -b 0x80000 -l 0x120000 zImage&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;---- 重启 ----&lt;br /&gt;&lt;/span&gt;RedBoot&gt; re&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;重启EP9302之后，主板开机加载RedBoot，然后执行默认的启动脚本，加载ramdisk和zImage。&lt;br /&gt;就这样我们进入Linux，第一次进入嵌入式Linux的感觉，是不是很奇妙？&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSuZuPqlCOI/AAAAAAAACzA/2J4R9cwg6dc/s1600-h/ep9302-linux-boot.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 148px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSuZuPqlCOI/AAAAAAAACzA/2J4R9cwg6dc/s320/ep9302-linux-boot.png" alt="" id="BLOGGER_PHOTO_ID_5272476808525449442" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="file:///home/wickyl/tmp/ep9302-linux-boot.png" alt="" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-550309995083961435?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/550309995083961435/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/11/cirros-ep9302-redbootlinux.html#comment-form' title='3 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/550309995083961435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/550309995083961435'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/11/cirros-ep9302-redbootlinux.html' title='Cirrus EP9302: 从RedBoot到Linux'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSuZuPqlCOI/AAAAAAAACzA/2J4R9cwg6dc/s72-c/ep9302-linux-boot.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-5803133169553419564</id><published>2008-11-23T23:34:00.005+08:00</published><updated>2011-03-17T16:20:56.390+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>西冲海岸线穿越</title><content type='html'>深圳西冲，因为交通不便、偏离市区等天然原因，成为了深圳市最优美的海岸线。仅仅这一&lt;br /&gt;点，就让俺们心里痒痒太多太多了，于是跟随大家一起到西冲鹅公湾穿越海岸线。&lt;br /&gt;&lt;br /&gt;到了地方才知道，西贡此行比想象的艰难太多了。活动选取了西贡-&gt;鹅公湾这一非常变态的&lt;br /&gt;路线，海岸边的岩石形状大小各异，沟堑无数，深浅不一。在石头间上串下跳，实在是极其&lt;br /&gt;消耗体力的事情，也有部分人受伤。&lt;br /&gt;&lt;br /&gt;从下午一点到达海岸开始，接下来的五个小时都要接受如此费力的考验，同时身负重物，真&lt;br /&gt;是让我苦不堪言；更可惜傍晚涨潮，潮水变凉，没能有机会下水。回来时候也已无力气打字，&lt;br /&gt;只能更新照片来看。（PS:不过海景实在是太美了）&lt;br /&gt;&lt;br /&gt;回头一看，我也在几个月内到访过梧桐山，老虎涧，塘朗山，排牙山，大小梅沙，西冲海&lt;br /&gt;岸……至此，我也几乎整完深圳所有的著名户外景点，我想可能需要转换一下目标了。当然下&lt;br /&gt;个目标是啥？还没有想过。不过类似户外的活动，我将会愈少的参与。&lt;br /&gt;&lt;br /&gt;（&lt;span style="font-weight: bold;"&gt;以下猛击可查看大图&lt;/span&gt;）&lt;br /&gt;---- 登山部分 ----&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSl8hC7lRRI/AAAAAAAACss/FBRxew2y7cI/s1600-h/IMG_3969.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSl8hC7lRRI/AAAAAAAACss/FBRxew2y7cI/s320/IMG_3969.JPG" alt="" id="BLOGGER_PHOTO_ID_5271881745978180882" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl8htq9qFI/AAAAAAAACs0/O7DTQ2pZSrw/s1600-h/IMG_3972.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl8htq9qFI/AAAAAAAACs0/O7DTQ2pZSrw/s320/IMG_3972.JPG" alt="" id="BLOGGER_PHOTO_ID_5271881757451200594" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl8h__cdvI/AAAAAAAACs8/SFzMU-0WV58/s1600-h/IMG_3978.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl8h__cdvI/AAAAAAAACs8/SFzMU-0WV58/s320/IMG_3978.JPG" alt="" id="BLOGGER_PHOTO_ID_5271881762368943858" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSl8iC-2NII/AAAAAAAACtE/rUbb-Ea64lg/s1600-h/IMG_4007.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSl8iC-2NII/AAAAAAAACtE/rUbb-Ea64lg/s320/IMG_4007.JPG" alt="" id="BLOGGER_PHOTO_ID_5271881763171742850" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;---- 海岸线部分 ----&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl8iX4WG5I/AAAAAAAACtM/rkGfqvNmcKA/s1600-h/IMG_4009.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl8iX4WG5I/AAAAAAAACtM/rkGfqvNmcKA/s320/IMG_4009.JPG" alt="" id="BLOGGER_PHOTO_ID_5271881768781618066" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl92A7fjMI/AAAAAAAACtU/m5gXG-e0EkY/s1600-h/IMG_4017.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl92A7fjMI/AAAAAAAACtU/m5gXG-e0EkY/s320/IMG_4017.JPG" alt="" id="BLOGGER_PHOTO_ID_5271883205729815746" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSl92TqFr3I/AAAAAAAACtc/NEO2AM96gFc/s1600-h/IMG_4023.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSl92TqFr3I/AAAAAAAACtc/NEO2AM96gFc/s320/IMG_4023.JPG" alt="" id="BLOGGER_PHOTO_ID_5271883210757091186" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl9267AAQI/AAAAAAAACtk/qW0hBMOjvSU/s1600-h/IMG_4026.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSl9267AAQI/AAAAAAAACtk/qW0hBMOjvSU/s320/IMG_4026.JPG" alt="" id="BLOGGER_PHOTO_ID_5271883221297004802" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSl93HvBChI/AAAAAAAACts/DGWHc6N1Z5s/s1600-h/IMG_4041.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSl93HvBChI/AAAAAAAACts/DGWHc6N1Z5s/s320/IMG_4041.JPG" alt="" id="BLOGGER_PHOTO_ID_5271883224736401938" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSl939ojXJI/AAAAAAAACt0/8y-rHUaAtlI/s1600-h/IMG_4046.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSl939ojXJI/AAAAAAAACt0/8y-rHUaAtlI/s320/IMG_4046.JPG" alt="" id="BLOGGER_PHOTO_ID_5271883239204805778" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SSl-9DIQ4eI/AAAAAAAACt8/LNbZ0wTxRRc/s1600-h/IMG_4051.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SSl-9DIQ4eI/AAAAAAAACt8/LNbZ0wTxRRc/s320/IMG_4051.JPG" alt="" id="BLOGGER_PHOTO_ID_5271884426090963426" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSl-9smXraI/AAAAAAAACuE/1lsvZ1WdSeY/s1600-h/IMG_4060.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSl-9smXraI/AAAAAAAACuE/1lsvZ1WdSeY/s320/IMG_4060.JPG" alt="" id="BLOGGER_PHOTO_ID_5271884437223091618" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;---- 结束部分 ----&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSl--C6GDDI/AAAAAAAACuM/S4ObfmgCo0s/s1600-h/IMG_4065.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSl--C6GDDI/AAAAAAAACuM/S4ObfmgCo0s/s320/IMG_4065.JPG" alt="" id="BLOGGER_PHOTO_ID_5271884443211402290" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSl---J2msI/AAAAAAAACuU/4nMdorITrmQ/s1600-h/IMG_4072.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSl---J2msI/AAAAAAAACuU/4nMdorITrmQ/s320/IMG_4072.JPG" alt="" id="BLOGGER_PHOTO_ID_5271884459115190978" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thx for you time!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-5803133169553419564?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/5803133169553419564/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/11/blog-post_23.html#comment-form' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/5803133169553419564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/5803133169553419564'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/11/blog-post_23.html' title='西冲海岸线穿越'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSl8hC7lRRI/AAAAAAAACss/FBRxew2y7cI/s72-c/IMG_3969.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-4834959050226238720</id><published>2008-11-22T18:50:00.001+08:00</published><updated>2011-03-17T16:27:56.374+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bootloader-redboot'/><title type='text'>eCos，高度自制性的嵌入式操作系统</title><content type='html'>&lt;!-- Page published by Emacs Muse begins here --&gt;eCos, embedded configuratable os. 这个名字很好的说明了这个操作系统的特性，高度可 配置的嵌入式操作系统。他现在是非常流行的嵌入式操作系统，支持很多嵌入式平台（远远 不只是ARM平台），而且配置简单。他原先是由Cygnus开发，后来归于Red Hat旗下。  &lt;h4&gt;安装&lt;/h4&gt;  &lt;p class="first"&gt;你可以按照&lt;a href="http://ecos.sourceware.org/getstart.html"&gt;官方的方&lt;/a&gt;来安装eCos，使用脚本来完成整个下载和安装过程很方便，这个过程安 全但是不可靠。其实本质上需要的就是下载两个包，和一套安装方法。&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="http://ftp.gwdg.de/pub/misc/sources.redhat.com/ecos/releases/ecos-2.0/ecos-2.0.i386linux.tar.bz2"&gt;ecos源码&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="ftp://ftp.gwdg.de/pub/misc/sources.redhat.com/ecos/gnutools/i386linux/ecoscentric-gnutools-i386-elf-1.4-2.i386linux.tar.bz2"&gt;编译工具链(gnutools)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;解压后的目录可以放置在任意位置（例如/opt/redboot），然后在此目录下创建以下脚本— (记住设置系统环境变量ECOS_REPOSITORY) &lt;/p&gt;&lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .builtin {         /* font-lock-builtin-face */         color: #b0c4de;       }       .comment {         /* font-lock-comment-face */         color: #ff7f24;       }       .comment-delimiter {         /* font-lock-comment-delimiter-face */         color: #ff7f24;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;!/bin/sh&lt;br /&gt;&lt;/span&gt;&lt;span class="builtin"&gt;export&lt;/span&gt; &lt;span class="variable-name"&gt;ECOS_DEST&lt;/span&gt;=/opt/redboot&lt;br /&gt;&lt;span class="builtin"&gt;export&lt;/span&gt; &lt;span class="variable-name"&gt;ECOS_REPOSITORY&lt;/span&gt;=$&lt;span class="variable-name"&gt;ECOS_DEST&lt;/span&gt;/ecos-2.0/packages/&lt;br /&gt;&lt;span class="builtin"&gt;export&lt;/span&gt; &lt;span class="variable-name"&gt;PATH&lt;/span&gt;=$&lt;span class="variable-name"&gt;PATH&lt;/span&gt;:$&lt;span class="variable-name"&gt;ECOS_DEST&lt;/span&gt;/gnutools/i386-elf/bin/:$&lt;span class="variable-name"&gt;ECOS_DEST&lt;/span&gt;/ecos-2.0/tools/bin&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;rm build -rf&lt;br /&gt;mkdir build&lt;br /&gt;&lt;span class="builtin"&gt;cd&lt;/span&gt; build&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;ecosconfig new TARGET [template [version]]&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;-- create a configuration file: ecos-2.0/packages/ecos.ecc&lt;br /&gt;&lt;/span&gt;ecosconfig new pc redboot&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;ecosconfig import&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;-- import additional config info&lt;br /&gt;&lt;/span&gt;ecosconfig import ${&lt;span class="variable-name"&gt;ECOS_DEST&lt;/span&gt;}/ecos-2.0/packages/hal/i386/pc/v2_0/misc/redboot_FLOPPY.ecm&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;ecosconfig tree&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;-- create a build tree&lt;br /&gt;&lt;/span&gt;ecosconfig tree&lt;br /&gt;make&lt;br /&gt;&lt;/pre&gt; 这样就得到一个裸露的内核redboot.bin，可以制作一个启动软盘，来在虚拟机里测试它。   &lt;h4&gt;ecos术语&lt;/h4&gt;  &lt;h5&gt;package&lt;/h5&gt;  &lt;p&gt;parcket关键字对应一组完成独立功能的代码包，他可以内嵌cdl脚本，来容纳更小的单位， 如cdl_option和cdl_component。 option和component是更小的代码元素，在解析之后将会成为C语言的宏。比如：&lt;/p&gt;  &lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="type"&gt;cdl_option CYGSEM_REDBOOT_DEFAULT_NO_BOOTP&lt;/span&gt; {&lt;br /&gt;  &lt;span class="variable-name"&gt;user_value&lt;/span&gt; 1&lt;br /&gt;&lt;span class="variable-name"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;生成在.h文件，就是 &lt;a name="define" id="define"&gt;&lt;/a&gt; CYGSEM_REDBOOT_DEFAULT_NO_BOOTP 1&lt;/p&gt;   &lt;h5&gt;target&lt;/h5&gt;  &lt;p&gt;target指定某种目标架构，关键字下将会定义很多的packet，来设置需要的组建和代码包。 &lt;/p&gt;&lt;pre class="src" style="background-color: rgb(85, 85, 85); color: rgb(245, 222, 179);"&gt;&lt;style type="text/css"&gt;&lt;!--       .string {         /* font-lock-string-face */         color: #ffa07a;       }       .type {         /* font-lock-type-face */         color: #98fb98;       }       .variable-name {         /* font-lock-variable-name-face */         color: #eedd82;       }     --&gt;&lt;/style&gt;&lt;span class="type"&gt;target edb9302&lt;/span&gt; {&lt;br /&gt; &lt;span class="variable-name"&gt;alias&lt;/span&gt;       { &lt;span class="string"&gt;"Cirrus Logic EDB9302 evaluation board"&lt;/span&gt; ep9302 }&lt;br /&gt; &lt;span class="type"&gt;packages&lt;/span&gt;    { CYGPKG_HAL_ARM&lt;br /&gt;               &lt;span class="variable-name"&gt;CYGPKG_HAL_ARM_ARM9&lt;/span&gt;&lt;br /&gt;               &lt;span class="variable-name"&gt;CYGPKG_HAL_ARM_ARM9_EP93XX&lt;/span&gt;&lt;br /&gt;               &lt;span class="variable-name"&gt;CYGPKG_DEVS_FLASH_STRATA&lt;/span&gt;&lt;br /&gt;               &lt;span class="variable-name"&gt;CYGPKG_DEVS_FLASH_EDB9301&lt;/span&gt;&lt;br /&gt;               &lt;span class="variable-name"&gt;CYGPKG_DEVS_ETH_ARM_EP93XX&lt;/span&gt;&lt;br /&gt;     &lt;span class="variable-name"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;description&lt;/span&gt; &lt;span class="string"&gt;"&lt;br /&gt;The EDB9302 target provides the packages needed to run eCos on the Cirrus Logic&lt;br /&gt;EP9302 based development boards."&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;set_value&lt;/span&gt; CYGHWR_HAL_ARM_EDB93XX_VARIANT &lt;span class="string"&gt;"EP9302"&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;此target旨在建立edb9302，他会包含packets中指明的packet，并且设置宏 &lt;a name="define" id="define"&gt;&lt;/a&gt; CYGHWR_HAL_ARM_EDB93XX_VARIANT "EP9302"&lt;/p&gt;   &lt;h5&gt;template&lt;/h5&gt;  &lt;p&gt;template是指为某种目的build而建立的相应模板配置，比如选取一些包，配置一些选项等 等。在目录 ecos-2.0/package/templates 下面有一些模板的目录。&lt;/p&gt;   &lt;h5&gt;文件 ecos.db&lt;/h5&gt;  &lt;p&gt;ecos-2.0/packages/ecos.db是ecos的选项总表，是维系整个ecos代码的数据库。他定义了 全部的target和target所需要packets。ecosconfig将从中获取信息，构建ecos.ecc，从而 完成代码树的构建。&lt;/p&gt;   &lt;h5&gt;文件 ecos.ecc&lt;/h5&gt;  &lt;p&gt;由ecosconfig声称的目标代码的设置文件，他包括了生成目标代码所需的所有选项配置，包 括了template, option，component等等等等。ecos.ecc有可能包含有冲突的部分，你需要 解决这些冲突，然后ecosconfig tree 声称代码树。&lt;/p&gt;   &lt;h5&gt;解释刚才的redboot.sh脚本&lt;/h5&gt;  &lt;p&gt;ecosconfig new pc redboot &lt;/p&gt;&lt;blockquote&gt; &lt;p class="quoted"&gt;此命令来创建一个针对target pc的ecc脚本，他将选取redboot作为模板。根据模板和 ecos.db，ecosconfig会向ecos.ecc脚本放置所有可能的组建，选项和包集合。&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;ecosconfig import ${ECOS_DEST}/ecos-2.0/packages/hal/i386/pc/v2_0/misc/redboot_FLOPPY.ecm &lt;/p&gt;&lt;blockquote&gt; &lt;p class="quoted"&gt;引入ecm设置，表明我们选择的启动媒体是软盘，你也可以选择其他介质。&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;ecosconfig tree &lt;/p&gt;&lt;blockquote&gt; &lt;p class="quoted"&gt;根据ecos.ecc来生成代码集合，之后make，完成编译安装。&lt;/p&gt; &lt;/blockquote&gt;    &lt;h4&gt;eCos架构&lt;/h4&gt;  &lt;p class="image"&gt;&lt;img src="file:///home/wickyl/tmp/ecos.jpg" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSfkYFBoCVI/AAAAAAAACgg/owOO1YQHMjQ/s1600-h/ecos.jpg"&gt;&lt;img style="cursor: pointer; width: 298px; height: 320px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSfkYFBoCVI/AAAAAAAACgg/owOO1YQHMjQ/s320/ecos.jpg" alt="" id="BLOGGER_PHOTO_ID_5271432991177443666" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这是一个ecos的系统框图，框图重点突出了Hardware Abstraction Layer在eCos中的重要作 用。如果要领悟这些，还需要参看eCos代码。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSfkYWAKxKI/AAAAAAAACgo/Tc6DwJwBvpQ/s1600-h/redboot.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 232px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSfkYWAKxKI/AAAAAAAACgo/Tc6DwJwBvpQ/s320/redboot.jpg" alt="" id="BLOGGER_PHOTO_ID_5271432995734733986" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt; &lt;p class="quoted"&gt;&lt;img src="file:///home/wickyl/tmp/redboot.jpg" alt="" /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;这里重点表述了redboot模板的eCos系统架构，redboot相当于是一个bootloader，但是他的 作用远远不只是启动内核那么简单。除了提供网络功能，他还包括了硬件初始化，调试，文 件系统等等功用。是嵌入式中应用非常广泛的bootloader。&lt;/p&gt;  &lt;p&gt;有空下次聊聊eCos的源代码架构。&lt;/p&gt;   &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/ecos"&gt;http://en.wikipedia.org/wiki/ecos&lt;/a&gt; &lt;a href="http://ecos.sourceware.org/"&gt;&lt;br /&gt;http://ecos.sourceware.org/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ecoscentric.com/ecos/ecospro.shtml"&gt;http://www.ecoscentric.com/ecos/ecospro.shtml&lt;/a&gt;&lt;/p&gt;     &lt;!-- Page published by Emacs Muse ends here --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-4834959050226238720?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/4834959050226238720/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/11/ecos.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/4834959050226238720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/4834959050226238720'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/11/ecos.html' title='eCos，高度自制性的嵌入式操作系统'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSfkYFBoCVI/AAAAAAAACgg/owOO1YQHMjQ/s72-c/ecos.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-1606575326293097255</id><published>2008-11-17T20:31:00.009+08:00</published><updated>2011-03-17T16:20:56.393+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>脚踏排牙山顶</title><content type='html'>这次活动去了排牙山，排牙山位于深圳龙岗区的大鹏半岛，这里也是深圳的最东边。大约也&lt;br /&gt;是深圳最后一片未开发的原始森林。这里保持了古森林的特色，大鹏半岛三面环海，景色非&lt;br /&gt;常秀丽，山下是大亚湾，坐落着出名的大亚湾核电站。不过要欣赏美景就要付出代价，排牙&lt;br /&gt;山上没有护栏和石阶，为开发的山路会考验你的脚力，而且排牙山山脉险峻，个别路段陡峭，&lt;br /&gt;给出行带来很大难度。&lt;br /&gt;&lt;br /&gt;组织：17爬爬吧&lt;br /&gt;领队：阿文，黄瓜，阿鹏&lt;br /&gt;合作：朗森户外&lt;br /&gt;报名：91人&lt;br /&gt;难度：标准+&lt;br /&gt;地图：&lt;a href="http://maps.google.com/maps/ms?ie=UTF&amp;amp;msa=0&amp;amp;msid=102563878911537749872.00045b8abc72a0e6ca675"&gt;点击这里&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSFq8ZPE-VI/AAAAAAAACeg/QiNz8kqOPTc/s1600-h/mt_paiya.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSFq8ZPE-VI/AAAAAAAACeg/QiNz8kqOPTc/s320/mt_paiya.jpg" alt="" id="BLOGGER_PHOTO_ID_5269610624799013202" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;前面罗嗦了很多，讲的就是此行的意义：能够在艰难的环境中披荆斩棘，会当绝顶，领略到&lt;br /&gt;大鹏美景，这毫无疑问是最有成就感的。排牙山旅途将会经历险要的山路，连绵的山峦，似&lt;br /&gt;乎是在牙齿顶端上下起伏，相信这也是排牙山得名的由来。&lt;br /&gt;（&lt;span style="font-weight: bold;"&gt;猛击图片查看大图&lt;/span&gt;）&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSFmjapBjaI/AAAAAAAACc4/DZU9FVRK-rI/s1600-h/img_3839.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSFmjapBjaI/AAAAAAAACc4/DZU9FVRK-rI/s320/img_3839.jpg" alt="" id="BLOGGER_PHOTO_ID_5269605797633035682" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFmkeCaPXI/AAAAAAAACdI/VQeULqCb6cc/s1600-h/img_3862.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFmkeCaPXI/AAAAAAAACdI/VQeULqCb6cc/s320/img_3862.jpg" alt="" id="BLOGGER_PHOTO_ID_5269605815724686706" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFqi3XYRuI/AAAAAAAACeY/1GByXaFa8nc/s1600-h/img_3869.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFqi3XYRuI/AAAAAAAACeY/1GByXaFa8nc/s320/img_3869.jpg" alt="" id="BLOGGER_PHOTO_ID_5269610186210297570" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSFmkoKs9cI/AAAAAAAACdQ/TuESuMFyYfY/s1600-h/sta_3887.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SSFmkoKs9cI/AAAAAAAACdQ/TuESuMFyYfY/s320/sta_3887.jpg" alt="" id="BLOGGER_PHOTO_ID_5269605818443822530" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;经历山顶的起伏，这一路真是险象环生，有部分人中途退出，也有体力透支情况出现。可以&lt;br /&gt;想象排牙山的难度。如果各位朋友要征服排牙山，那定要足够的体力和意志。多人出行需要&lt;br /&gt;作足准备，从登山鞋到活络油不一而足。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFmlCfzM_I/AAAAAAAACdY/EI4qtOCSWqA/s1600-h/img_3871.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFmlCfzM_I/AAAAAAAACdY/EI4qtOCSWqA/s320/img_3871.jpg" alt="" id="BLOGGER_PHOTO_ID_5269605825511633906" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSFpAo1f4QI/AAAAAAAACdg/UbiFOQyVI0k/s1600-h/img_3901.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSFpAo1f4QI/AAAAAAAACdg/UbiFOQyVI0k/s320/img_3901.jpg" alt="" id="BLOGGER_PHOTO_ID_5269608498682913026" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SSFpBNAMrzI/AAAAAAAACdo/ckJyFP6MF2Y/s1600-h/img_3908.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SSFpBNAMrzI/AAAAAAAACdo/ckJyFP6MF2Y/s320/img_3908.jpg" alt="" id="BLOGGER_PHOTO_ID_5269608508391468850" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFpBp7R_NI/AAAAAAAACdw/irJ_M2k4hvo/s1600-h/img_3914.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFpBp7R_NI/AAAAAAAACdw/irJ_M2k4hvo/s320/img_3914.jpg" alt="" id="BLOGGER_PHOTO_ID_5269608516155473106" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;下山段也绝对不轻松，很多地方陡峭而且土质疏松。有朋友在这里摔跤和抽筋。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFpCAFn7bI/AAAAAAAACd4/ectBnps_n1A/s1600-h/img_3916.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSFpCAFn7bI/AAAAAAAACd4/ectBnps_n1A/s320/img_3916.jpg" alt="" id="BLOGGER_PHOTO_ID_5269608522104434098" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSFpC7IyFqI/AAAAAAAACeA/JxacXeKcMws/s1600-h/img_3918.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSFpC7IyFqI/AAAAAAAACeA/JxacXeKcMws/s320/img_3918.jpg" alt="" id="BLOGGER_PHOTO_ID_5269608537955374754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSFqh8S2AnI/AAAAAAAACeI/vJ7rv4FEHhU/s1600-h/img_3919.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSFqh8S2AnI/AAAAAAAACeI/vJ7rv4FEHhU/s320/img_3919.jpg" alt="" id="BLOGGER_PHOTO_ID_5269610170353582706" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SSFqiqmGU6I/AAAAAAAACeQ/BOmXSe9oJRU/s1600-h/img_3937.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SSFqiqmGU6I/AAAAAAAACeQ/BOmXSe9oJRU/s320/img_3937.jpg" alt="" id="BLOGGER_PHOTO_ID_5269610182782374818" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;这次旅程在艰险中度过，除了放弃以外，还有中途退出，体力透支，小腿抽筋等意外情况发&lt;br /&gt;生。在后半段过程因为抄近路的原因，领队选择了一段溯溪线路，这段路途很有难度，而且&lt;br /&gt;在六点半钟情况攀爬岩石，大家着实受了苦头。&lt;br /&gt;&lt;br /&gt;最后和同行聊天才得知，这次是一次商业性的组织活动，朗森是东莞的一家专门组织户外互&lt;br /&gt;动的公司，本次活动公召集81人参与报名，预计实际参与人数在75人左右。而领队大约只有&lt;br /&gt;6人，而且分布不足，介于人数过多，在旅途中很少得到周围的援助，毕竟认识的人不多，&lt;br /&gt;而且领队都远远的跑在了前面，所以登山之旅实在有些焦躁。如果下次仍旧有此类活动，我&lt;br /&gt;当考虑参与队伍的规模和组织形式。&lt;br /&gt;&lt;br /&gt;最后的图片，容易让人产生遐想：&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSF6h9pc4UI/AAAAAAAACfM/dP0AyUGlvPE/s1600-h/img_3892.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SSF6h9pc4UI/AAAAAAAACfM/dP0AyUGlvPE/s320/img_3892.jpg" alt="" id="BLOGGER_PHOTO_ID_5269627762902884674" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;_&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-1606575326293097255?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/1606575326293097255/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/11/17-91-8175-6.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1606575326293097255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1606575326293097255'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/11/17-91-8175-6.html' title='脚踏排牙山顶'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Kb-lr4qFtj4/SSFq8ZPE-VI/AAAAAAAACeg/QiNz8kqOPTc/s72-c/mt_paiya.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-1238821733200040054</id><published>2008-11-16T00:12:00.004+08:00</published><updated>2009-03-17T15:27:25.000+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>正版软件距离我们多远</title><content type='html'>最近喧闹的微软黑屏事件影响力可谓波涛汹涌，各方都对此事表达自己的观点。其实形式如&lt;br /&gt;何，大家心知肚明。然而无论是为自己使用盗版谋权力的个人用户，还是正版用户的铁杆支&lt;br /&gt;持者，都对国家的软件产业抱有怀疑态度——正版推广，真的很难。&lt;br /&gt;&lt;br /&gt;前些天，深圳&lt;span style="font-weight: bold;"&gt;第一现场&lt;/span&gt;也对此事进行了报道，文中表达了自己对微软黑屏事件的看法：&lt;br /&gt;&lt;br /&gt;首先是加大正版软件使用力度，维护软件开发人员和发布厂商权益。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SR725vQnsNI/AAAAAAAACOE/cd7gGxY5X0w/s1600-h/IMG_3799.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SR725vQnsNI/AAAAAAAACOE/cd7gGxY5X0w/s320/IMG_3799.JPG" alt="" id="BLOGGER_PHOTO_ID_5268920085869211858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;另一方面是减少对单向软件的依赖度。且拿Linux的发布版本Ubuntu为例，推介软件用户除&lt;br /&gt;微软产品以外的更多选择（这里的Ubuntu还打印错了……）。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SR7258qB3MI/AAAAAAAACOM/87JIwEF9c9Q/s1600-h/IMG_3801.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SR7258qB3MI/AAAAAAAACOM/87JIwEF9c9Q/s320/IMG_3801.JPG" alt="" id="BLOGGER_PHOTO_ID_5268920089465445570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;还有一方面，是加大国有软件的扶植力度，培养有竞争力的自身软件产业。这个例子选取了&lt;br /&gt;最近推出的个人免费版本的WPS国产办公软件。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SR726iA-b7I/AAAAAAAACOU/iI2G3Is-HBg/s1600-h/IMG_3802.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SR726iA-b7I/AAAAAAAACOU/iI2G3Is-HBg/s320/IMG_3802.JPG" alt="" id="BLOGGER_PHOTO_ID_5268920099493801906" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;不过在我看来，国家和媒体对软件权益的认知都建立在软件版权的基础之上，这个出生于微&lt;br /&gt;软之手的概念为微软等软件商带来丰厚的利润。大家可以尝试一下&lt;a href="http://www.gnu.org/"&gt;&lt;span style="font-weight: bold;"&gt;GNU系列软件&lt;/span&gt;&lt;/a&gt;，他立志于&lt;br /&gt;推广自由软件产业，也尝试保护开发者的权益。Linux就是GNU旗下软件，遵循GPL条例。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-1238821733200040054?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/1238821733200040054/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/11/blog-post_16.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1238821733200040054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1238821733200040054'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/11/blog-post_16.html' title='正版软件距离我们多远'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Kb-lr4qFtj4/SR725vQnsNI/AAAAAAAACOE/cd7gGxY5X0w/s72-c/IMG_3799.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-1668053023528251385</id><published>2008-11-02T22:35:00.007+08:00</published><updated>2011-03-17T16:20:56.395+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>山清水秀塘朗山</title><content type='html'>这次户外活动选择了塘朗山，塘朗山位于南山北部，是宝安和南山的北部分界线；拥有西丽&lt;br /&gt;水库和梅林水库两个水源，山水秀丽，而且攀爬容易，属于休闲娱乐级别。可谓是居家旅&lt;br /&gt;游，避暑游乐之必选之地……&lt;br /&gt;&lt;br /&gt;组织：狼行天涯③(Q群 63191237)&lt;br /&gt;领队：wolf, 小雨&lt;br /&gt;说明：桃源村，螳螂山顶，东部穿越到梅林水库&lt;br /&gt;地图：&lt;br /&gt;&lt;a href="http://maps.google.com/maps/ms?ie=UTF&amp;amp;msa=0&amp;amp;msid=102563878911537749872.00045ab3e58dd543dec97"&gt;http://maps.google.com/maps/ms?ie=UTF&amp;amp;msa=0&amp;amp;msid=102563878911537749872.00045ab3e58dd543dec97&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;废话不说，启程带你们领略秀丽的山水咯~&lt;br /&gt;&lt;br /&gt;这里是桃源村的塘朗山入口。进入正门之后就可以上东边坡路，这条道路开发的非常好！阶&lt;br /&gt;梯让攀爬更加容易。深圳城市这一点让人很是欣慰，梧桐山，大南山等大约所有的景点开发&lt;br /&gt;的非常不错。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ29I5R6fOI/AAAAAAAAB_E/qQVDNnMv5PE/s1600-h/IMG_3650.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ29I5R6fOI/AAAAAAAAB_E/qQVDNnMv5PE/s320/IMG_3650.JPG" alt="" id="BLOGGER_PHOTO_ID_5264071499978538210" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ29JaYYokI/AAAAAAAAB_M/_Z4BruCzTvg/s1600-h/IMG_3652.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ29JaYYokI/AAAAAAAAB_M/_Z4BruCzTvg/s320/IMG_3652.JPG" alt="" id="BLOGGER_PHOTO_ID_5264071508864049730" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;桃源村这一段路，难度不高。因为路程短暂，不消一会儿，就可以到达山顶。在这里可以看&lt;br /&gt;到深圳梅林一代的城市景观。早上的雾气和蹩脚的技术，让照片技术打了折扣。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQ29JsplJQI/AAAAAAAAB_U/CdELZg4yCmg/s1600-h/IMG_3656.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQ29JsplJQI/AAAAAAAAB_U/CdELZg4yCmg/s320/IMG_3656.JPG" alt="" id="BLOGGER_PHOTO_ID_5264071513768011010" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQ29J_kA7RI/AAAAAAAAB_c/gFEuAbxUatg/s1600-h/IMG_3657.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQ29J_kA7RI/AAAAAAAAB_c/gFEuAbxUatg/s320/IMG_3657.JPG" alt="" id="BLOGGER_PHOTO_ID_5264071518844939538" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;12点后开始东移，沿着塘朗山脉起伏升降，三、四十人的队伍也是够壮观的。我们在一个平&lt;br /&gt;台处开始吃午饭，中途有家伙开始打牌。扑克……平民化的艺术！&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ29KEJJ0YI/AAAAAAAAB_k/mJKgEefes_w/s1600-h/IMG_3714.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ29KEJJ0YI/AAAAAAAAB_k/mJKgEefes_w/s320/IMG_3714.JPG" alt="" id="BLOGGER_PHOTO_ID_5264071520074453378" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQ3AqLOPxmI/AAAAAAAACAE/pRDxTOWYwhU/s1600-h/IMG_3702.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQ3AqLOPxmI/AAAAAAAACAE/pRDxTOWYwhU/s320/IMG_3702.JPG" alt="" id="BLOGGER_PHOTO_ID_5264075370265560674" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;梅林段的地势开始恶劣起来……山道变的崎岖，沿着溪流而下，甚至有了溯溪的感觉。大家都&lt;br /&gt;没有任何准备，路途变得缓慢艰难。不少人失身于此。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQ3Aqo_M00I/AAAAAAAACAM/tSV2vEaVo7U/s1600-h/IMG_3731.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQ3Aqo_M00I/AAAAAAAACAM/tSV2vEaVo7U/s320/IMG_3731.JPG" alt="" id="BLOGGER_PHOTO_ID_5264075378255516482" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQ3ArAyWbJI/AAAAAAAACAU/kTiD6Q9N244/s1600-h/IMG_3737.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQ3ArAyWbJI/AAAAAAAACAU/kTiD6Q9N244/s320/IMG_3737.JPG" alt="" id="BLOGGER_PHOTO_ID_5264075384644070546" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;到达一个小瀑布的时候，路途的艰难程度达到最大，山路陡峭。但这也是后半段景色嘴秀丽&lt;br /&gt;的位置，可谓是RPG的小高潮。好在大家团结一心，没有人受伤。如果各位有打算经历此路&lt;br /&gt;程，一点要有心理准备。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3ArjjKb7I/AAAAAAAACAc/BmAHiFLZYpc/s1600-h/IMG_3749.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3ArjjKb7I/AAAAAAAACAc/BmAHiFLZYpc/s320/IMG_3749.JPG" alt="" id="BLOGGER_PHOTO_ID_5264075393975611314" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3AsMlYtuI/AAAAAAAACAk/SntVwUVeX14/s1600-h/IMG_3752.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3AsMlYtuI/AAAAAAAACAk/SntVwUVeX14/s320/IMG_3752.JPG" alt="" id="BLOGGER_PHOTO_ID_5264075404990789346" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;到达山脚，天堑变通途！走起来轻松之极，脚步也轻快多了。短时间之后，立刻看到本次行&lt;br /&gt;动的终点，梅林水库大坝。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DJcjHTVI/AAAAAAAACAs/F-7sVzkDTsA/s1600-h/IMG_3757.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DJcjHTVI/AAAAAAAACAs/F-7sVzkDTsA/s320/IMG_3757.JPG" alt="" id="BLOGGER_PHOTO_ID_5264078106515688786" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DLLc07DI/AAAAAAAACA0/8JNF4rMyDVs/s1600-h/IMG_3758.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DLLc07DI/AAAAAAAACA0/8JNF4rMyDVs/s320/IMG_3758.JPG" alt="" id="BLOGGER_PHOTO_ID_5264078136285654066" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;这里的景色真是非常美丽，这些天让俺们郁闷的情绪一扫而光。就赖在这里多多拍了几张。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DLgA-hAI/AAAAAAAACA8/_o33IipM_S4/s1600-h/IMG_3763.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DLgA-hAI/AAAAAAAACA8/_o33IipM_S4/s320/IMG_3763.JPG" alt="" id="BLOGGER_PHOTO_ID_5264078141805986818" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DMGEwIwI/AAAAAAAACBE/ZbpuVNrK91M/s1600-h/IMG_3760.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DMGEwIwI/AAAAAAAACBE/ZbpuVNrK91M/s320/IMG_3760.JPG" alt="" id="BLOGGER_PHOTO_ID_5264078152022369026" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;梅林水库的大坝上面，没啥好说的了。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DMVRkpMI/AAAAAAAACBM/tY6yU0Nsad4/s1600-h/IMG_3765.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ3DMVRkpMI/AAAAAAAACBM/tY6yU0Nsad4/s320/IMG_3765.JPG" alt="" id="BLOGGER_PHOTO_ID_5264078156102673602" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ3EvVoMlNI/AAAAAAAACBU/JNtqMRDZd64/s1600-h/IMG_3772.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ3EvVoMlNI/AAAAAAAACBU/JNtqMRDZd64/s320/IMG_3772.JPG" alt="" id="BLOGGER_PHOTO_ID_5264079857004614866" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;最后是大家的集体照，希望各位读者多多参加户外运动，陶冶情操，多多益善:)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ3EvzqKysI/AAAAAAAACBc/iKQj3r80-5g/s1600-h/IMG_3747.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ3EvzqKysI/AAAAAAAACBc/iKQj3r80-5g/s320/IMG_3747.JPG" alt="" id="BLOGGER_PHOTO_ID_5264079865065949890" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;谢谢大家的时间:)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-1668053023528251385?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/1668053023528251385/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/11/blog-post.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1668053023528251385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1668053023528251385'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/11/blog-post.html' title='山清水秀塘朗山'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQ29I5R6fOI/AAAAAAAAB_E/qQVDNnMv5PE/s72-c/IMG_3650.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-252897152658013218</id><published>2008-10-31T00:15:00.007+08:00</published><updated>2011-03-17T16:20:56.397+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>万圣节在世界之窗</title><content type='html'>公司加班到六点半，我就找理由逃脱了。周总说了：可以，我也在下棋呢！呵呵。&lt;br /&gt;&lt;br /&gt;晚上有洪洪和曾胖组织的世界之窗活动，借助优惠券，我们可以在世界之窗享受廉价的万圣&lt;br /&gt;节。感谢洪洪，感谢曾胖，感谢老外，嘿嘿。&lt;br /&gt;&lt;br /&gt;万圣节又名鬼节，在西方是非常活跃的节日。最重要的标志，就是孩子们挨家挨户的要糖果，&lt;br /&gt;这点我们可以在《老友记》中可以感受其气氛（因为被孩子哄的团团转，Rachel把糖果全部&lt;br /&gt;给了一个小女孩）。另外你也可以看到Phoebe的超人服。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQniA5IkKzI/AAAAAAAABu4/CzNdrc-hjCU/s1600-h/73135bdaefe784d6b7fd4875.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQniA5IkKzI/AAAAAAAABu4/CzNdrc-hjCU/s320/73135bdaefe784d6b7fd4875.jpg" alt="" id="BLOGGER_PHOTO_ID_5262986144523758386" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;今天在世界之窗，你完全感受到另类的中国式万圣节。灰长灰长的热闹！中国人就是多，头&lt;br /&gt;顶上带个犄角，更有各式各样的妖魔鬼怪齐聚这里。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQne-O1RSvI/AAAAAAAABtQ/CZmUSd4PHwE/s1600-h/img_3569.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQne-O1RSvI/AAAAAAAABtQ/CZmUSd4PHwE/s320/img_3569.jpg" alt="" id="BLOGGER_PHOTO_ID_5262982800273918706" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQngfz6J0_I/AAAAAAAABuI/JIq7D0NQeVk/s1600-h/img_3570.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQngfz6J0_I/AAAAAAAABuI/JIq7D0NQeVk/s320/img_3570.jpg" alt="" id="BLOGGER_PHOTO_ID_5262984476673823730" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;我是第一次进世界之窗，这里你可以看到很多很多的世界之窗。由于在夜间，没有像曾胖同&lt;br /&gt;志那样注意技巧。如果你想学摄影，可以找&lt;a href="http://twitter.com/zengli"&gt;曾胖&lt;/a&gt;。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQne-iyOaNI/AAAAAAAABtg/Nh28sMRoDVA/s1600-h/img_3574.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQne-iyOaNI/AAAAAAAABtg/Nh28sMRoDVA/s320/img_3574.jpg" alt="" id="BLOGGER_PHOTO_ID_5262982805629855954" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQne_ZES1WI/AAAAAAAABtw/8FeuxBpkRnU/s1600-h/img_3579.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQne_ZES1WI/AAAAAAAABtw/8FeuxBpkRnU/s320/img_3579.jpg" alt="" id="BLOGGER_PHOTO_ID_5262982820201157986" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQne_CXgksI/AAAAAAAABto/3V1qnoMM5ds/s1600-h/img_3575.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SQne_CXgksI/AAAAAAAABto/3V1qnoMM5ds/s320/img_3575.jpg" alt="" id="BLOGGER_PHOTO_ID_5262982814107734722" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQngejV0xQI/AAAAAAAABt4/mt9x6_7E7DY/s1600-h/img_3582.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQngejV0xQI/AAAAAAAABt4/mt9x6_7E7DY/s320/img_3582.jpg" alt="" id="BLOGGER_PHOTO_ID_5262984455046612226" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;这里是精简版本的曼哈顿，你也可以看到已经米稀的双子楼。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQngfmiNpEI/AAAAAAAABuA/p3QthpZ-xT4/s1600-h/img_3608.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQngfmiNpEI/AAAAAAAABuA/p3QthpZ-xT4/s320/img_3608.jpg" alt="" id="BLOGGER_PHOTO_ID_5262984473083749442" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;恐怖活动是主题，到处是南瓜头。在僵尸峡谷还可以看到专业级别的女鬼。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQne-ey6K2I/AAAAAAAABtY/ebpmhvq0ftk/s1600-h/img_3584.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQne-ey6K2I/AAAAAAAABtY/ebpmhvq0ftk/s320/img_3584.jpg" alt="" id="BLOGGER_PHOTO_ID_5262982804558981986" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQnggMtSUJI/AAAAAAAABuQ/8aHrfKMmcKk/s1600-h/img_3590.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQnggMtSUJI/AAAAAAAABuQ/8aHrfKMmcKk/s320/img_3590.jpg" alt="" id="BLOGGER_PHOTO_ID_5262984483330740370" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;最后是万圣节party，不太专业的乐队，不太哈皮的派对。到最后出现赶鬼行动，用纸团相&lt;br /&gt;互攻击。其实最后被群鬼完全吓跑。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQnggsh_mZI/AAAAAAAABuY/5k56Mafh-QA/s1600-h/img_3626.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQnggsh_mZI/AAAAAAAABuY/5k56Mafh-QA/s320/img_3626.jpg" alt="" id="BLOGGER_PHOTO_ID_5262984491873311122" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQnh_-JP5hI/AAAAAAAABuw/HUXRX00U8Lk/s1600-h/img_3633.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQnh_-JP5hI/AAAAAAAABuw/HUXRX00U8Lk/s320/img_3633.jpg" alt="" id="BLOGGER_PHOTO_ID_5262986128688932370" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;最后是龙套小鬼，祝福大家异类的万圣节快乐。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQnhly6X9wI/AAAAAAAABuo/_pKw8vb6L7g/s1600-h/img_3612.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SQnhly6X9wI/AAAAAAAABuo/_pKw8vb6L7g/s320/img_3612.jpg" alt="" id="BLOGGER_PHOTO_ID_5262985678997157634" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;_&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-252897152658013218?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/252897152658013218/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_31.html#comment-form' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/252897152658013218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/252897152658013218'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_31.html' title='万圣节在世界之窗'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Kb-lr4qFtj4/SQniA5IkKzI/AAAAAAAABu4/CzNdrc-hjCU/s72-c/73135bdaefe784d6b7fd4875.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-3122920551591976361</id><published>2008-10-30T00:08:00.000+08:00</published><updated>2011-03-17T16:23:06.174+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>心诚则灵</title><content type='html'>&lt;p class="first"&gt;经过接近三个月的离职期之后，我最近得以 &lt;strong&gt;光荣上岗&lt;/strong&gt;。&lt;/p&gt;  &lt;p&gt;回顾这三个月，似乎经历了松山湖之行，&lt;a href="http://hi.baidu.com/wickyl/blog/item/f9fb1bdfb754d715622798f2.html"&gt;回乡历程&lt;/a&gt;，孤单的七夕节，八月北京奥运，经济的&lt;br /&gt;冰冻期;几经周折，我也完成了助学贷款，习惯了泡图书馆的日子，参与&lt;a href="http://tieba.baidu.com/f?kw=17%C5%C0%C5%C0"&gt;17爬爬吧&lt;/a&gt;的活动(&lt;a href="http://hi.baidu.com/wickyl/blog/item/8bfade2a1d8f449d023bf6fd.html"&gt;1&lt;/a&gt;，&lt;br /&gt;&lt;a href="http://hi.baidu.com/wickyl/blog/item/772edd2a63cfba2bd52af110.html"&gt;2&lt;/a&gt;，&lt;a href="http://hi.baidu.com/wickyl/blog/item/1ea9c0806c82bdd19023d9fc.html"&gt;3&lt;/a&gt;) 烦躁的求职生活。&lt;/p&gt;  &lt;p&gt;这段时间也正是痛苦和快乐并重，有次扁桃体发炎，疼到吞咽困难也坚持不去看医生；多个&lt;br /&gt;公司下遭遇闭门羹，&lt;a href="http://hi.baidu.com/wickyl/blog/item/efe39d0aa0a05d1994ca6ba8.html"&gt;面试题&lt;/a&gt;更是折磨的我苦不堪言；我和莹莹经历了最严重的争吵，甚至有&lt;br /&gt;放弃感情的念头……&lt;/p&gt;  &lt;p&gt;不过也终究过来了，我觉得生活还就这样，我也还就这样，2008年也就这样过来了。我总是&lt;br /&gt;对这样苦中作乐的日子念念不忘，我还会回头想起高考的日子，踏上深圳的每一步。我甚至&lt;br /&gt;可以一直这样慢悠悠的闲廷信步，一直等到花光手上所有积蓄，需要到必胜客去打钟点工来&lt;br /&gt;找足乐子。尽管这样随性的性格伤害了一些好朋友。&lt;/p&gt;  &lt;p&gt;上个星期回家，老妈告诉我家里的情况很乱。一般家里和游子总是处于“报喜不报忧”的状态&lt;br /&gt;之中，假设他们不告诉家中的情形，那你得总怀揣着担忧的心思；而家人支支吾吾甚至直接&lt;br /&gt;告知情况糟糕的时候，家里一定乱成一团糟了。因此找份工作仍旧是重中之重，回家过年也&lt;br /&gt;会挂上日程。&lt;/p&gt;  &lt;p&gt;现在的工作是在一家工控公司作嵌入式开发，公司名称保密。他们会为一些厂家作外包，来&lt;br /&gt;实现一些工控，自动化设施的嵌入式主板，他们也有了PCB设计师，调板工，唯独让人郁闷&lt;br /&gt;的是：除了经理以外，没有开发人员。很显然这个公司还处于起步阶段，办公室位于33层&lt;br /&gt;（最高层），主板扔的到处都是，每个房间都有包装盒堆成的小山，室内环境比清华信息港&lt;br /&gt;差上几个档次。最重要的是——在这个公司， &lt;em&gt;加班时间将成为家常便饭&lt;/em&gt;，而且没有加班费。&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;于是我进入了这样一个阶段：&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;始终拒绝加班的我，将会把加班作为一种享受&lt;/li&gt;&lt;li&gt;仍旧为成为一个顶级的软件工程师而努力&lt;/li&gt;&lt;li&gt;我将来的一段时间内，必须把工作放在第一位&lt;/li&gt;&lt;li&gt;那个小小的梦想还将被搁置&lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;心诚则灵，收起邋遢随性的性格，为将来努力吧！&lt;/p&gt;  &lt;p&gt;&lt;em&gt;得知一大票人口在我和莹莹就职后也开始找到工作，恭喜你们，也祝愿全球金融冰冻期早日&lt;br /&gt;结束。&lt;/em&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-3122920551591976361?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/3122920551591976361/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_30.html#comment-form' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/3122920551591976361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/3122920551591976361'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_30.html' title='心诚则灵'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-6198331465657388141</id><published>2008-10-25T12:31:00.001+08:00</published><updated>2009-03-17T15:23:59.669+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>微软黑屏和盗版权益</title><content type='html'>&lt;div class="cnt"&gt; &lt;p&gt;自从微软发布WGA更新以后，中国网民的抗议声音不绝于耳： &lt;a href="http://tech.dzwww.com/synr/kjfd/200810/t20081024_4029671.htm"&gt;微软黑屏引发威胁百倍于熊猫烧香&lt;/a&gt;，&lt;a href="http://tech.163.com/08/1024/23/4P2COK60000915BD.html"&gt;微软黑屏引发国家安全话题&lt;/a&gt;，国家版权局将会对此事件 表态。真实情况将会怎样呢？是中国一家之言，还是全球群起反对？是网友过激，还是捍卫 安全呢？&lt;/p&gt; &lt;p&gt;环顾四周，我们才发现，微软黑屏是一个全球性的政策，然而对其他国家来说远远未像中国 那样表现过激，&lt;a href="http://tech.qq.com/a/20081025/000012.htm"&gt;就连香港也对此冷漠&lt;/a&gt;。很多普及正版的国家和地区，人民是可以支付正版价 格的；而对于大多数发展中国家来说，他们也有更多的选择。&lt;/p&gt; &lt;p&gt;而就技术方面来说，微软只是针对盗版用户投放信息，现在没有任何组织和个人可以拿出证 据说微软控制电脑和数据。如果你说强制黑屏可以指明微软控制用户的计算机，我觉得这是 捕风捉影。操作系统本身具有利用硬件资源提供服务的功用，而在正常情况下，微软将会根 据&lt;a href="http://en.wikipedia.org/wiki/EULA"&gt;EULA&lt;/a&gt;，在用户同意后才可以使用，更改任何用户数据，并通知处理用户信息的目的。但是 因为EULA的争议性，中国大陆还在考虑其是否适用。&lt;/p&gt; &lt;p&gt;如果中国官方现在考虑，那我建议微软黑屏和控制电脑之间需要更多的证据。当然我觉得更 值得考虑的事情是：1)盗版用户和软件制作商之间基于什么样的权力关系。2)国家如何扶植 操作系统和办公软件，用以改变对Windows和Office过度依赖的现状。3)如何发展本国自由 软件技术和提高重要机构的信息安全。&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-6198331465657388141?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/6198331465657388141/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_25.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6198331465657388141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6198331465657388141'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_25.html' title='微软黑屏和盗版权益'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-7997721796463100627</id><published>2008-10-22T09:25:00.000+08:00</published><updated>2011-03-17T16:23:49.312+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>我把事情搞砸了</title><content type='html'>事情得回溯到六月底，我一个人在康科办公室里，翻看着APUE的源码，我会很满足的告诉自&lt;br /&gt;己：我在忙碌，我像一个有志向，发奋图强的年轻人一样在学习。但是面对着眼前的烂摊子&lt;br /&gt;我就傻眼了————加拿大随时会发来稀奇古怪的需求，需要你改动一点点小玩意，在晚上下班&lt;br /&gt;之前提交上去。&lt;br /&gt;&lt;br /&gt;我讨厌了这样的工作，别人的软件让我在其之上修改一些小的界面，或者使用简单的汇编语&lt;br /&gt;句取得一些硬件信息；完成之后我还要钻到实验室里，花费两天时间来测试效果。想起为了&lt;br /&gt;完成新主板的MAPPING，我要投身两个星期来分析完芯片初期数据，那个经历真是糟糕透了。&lt;br /&gt;&lt;br /&gt;我宁愿去看Linux内核，那是一个有创意的，有前途的东西，让我学习了一些硬件知识是如&lt;br /&gt;何应用到操作系统设计之上的。后来我发现手头的工作极其枯燥，而且无法腾出时间来看内&lt;br /&gt;核代码，我义无反顾的提交了辞呈。老板对于我的第二次辞呈没有发表太多意见，在一个月&lt;br /&gt;后（七月底），我在一片静寂之中离开了付出两年汗水的公司。&lt;br /&gt;&lt;br /&gt;八月初，我回到家乡，我见到了很多亲人老友，他们对我的经历一无所知，辞职的事情除了&lt;br /&gt;老哥以外，我没有告诉任何人。家里有压在我心头的几块石头，完成这些琐碎之事以后，我&lt;br /&gt;匆忙的回到了深圳，开始了漫长的求职时期。&lt;br /&gt;&lt;br /&gt;我得说，我从没想过，求职期如此的漫长和烦躁，这让我生活的周边都显得更加煎熬。&lt;br /&gt;&lt;br /&gt;我在八九月发出了超过30条求职信，而回复者寥寥无几。我认为这开始并不是什么稀奇事情，&lt;br /&gt;很多人告诉我八到十月是招聘淡季，我对这些措辞不以为然，我不相信什么淡季，依据我的&lt;br /&gt;能力，找到一个适合的工作没有大问题。现在回想起来，我对自己的自信慢慢感觉到羞愧！&lt;br /&gt;&lt;br /&gt;九月份我的回复得到了稍许回应，我接到了几个公司的面试申请。于是我开始一一品尝面试&lt;br /&gt;的滋味，腾讯公司，开源通讯公司，深信服公司，深圳傲天通讯，研祥科技大厦……这其中带&lt;br /&gt;有趣味，然而更多的是苦痛。&lt;br /&gt;&lt;br /&gt;在经历过如此多的面试之后，我得说，我根本不了解我工作的这一行是个什么样的状况，甚&lt;br /&gt;至可以说，我根本没有对自己的工作做一个很好的评估————根本不知道自己要作什么。&lt;br /&gt;&lt;br /&gt;想起毕业的时候我选择报一本《JAVA编程思想》南下找工作的情景，我觉得从理念上看，现&lt;br /&gt;在和那个时候没有什么本质分别：我依然自信满满的认为我可以作自己要的工作，可对这一&lt;br /&gt;份工作的概念都是模糊的。&lt;br /&gt;&lt;br /&gt;我想作Linux程序员，但是来到人才招聘网上，我看到Linux程序员都有什么要求呢：&lt;br /&gt;1) Linux驱动编程&lt;br /&gt;2) Linux嵌入式开发&lt;br /&gt;3) Linux后台开发&lt;br /&gt;&lt;br /&gt;在这样的职位需求面前，我傻眼了，如果佯装是一个Linux程序员去面试职位，你几乎必须&lt;br /&gt;面对以下问题之一：&lt;br /&gt;1) Linux内核裁减&lt;br /&gt;2) Linux驱动程序编写和移植&lt;br /&gt;3) 嵌入式CPU架构和编程环境&lt;br /&gt;4) Linux网络编程&lt;br /&gt;&lt;br /&gt;如果你没有以上经验，那么你几乎没有和人事部经理谈话的资格，在技术面试官前就会被淘&lt;br /&gt;汰。可是我就没有，全部NO，如我所说，80%的面试官都不会接受我的。&lt;br /&gt;&lt;br /&gt;剩下20%是通过面试题来测试的，我得说，我是一个应试型的人才，面对考试不以为然。但&lt;br /&gt;是在答复一些笔试题时候，我仍然深受打击————我的专业功底显得那么的不堪一击！我经历&lt;br /&gt;过的面试题浩如烟海，他们覆盖了计算机知识绝大多数部分：&lt;br /&gt;1. C/C++语言功底，C++庞大的语言特性，Shell高级编程&lt;br /&gt;2. UNIX环境编程，Socket编程，多线程编程&lt;br /&gt;3. UNIX网络编程，tcp/ip，http协议&lt;br /&gt;4. 数据结构和算法设计，一些查找和排序算法&lt;br /&gt;5. CPU架构，x96, Power, MIPS架构知识&lt;br /&gt;&lt;br /&gt;要从理论上学习这些，我起码要看完手头的大堆书籍。他们包括：&lt;br /&gt;Thinking in C++&lt;br /&gt;Effective C++&lt;br /&gt;UNIX环境编程 APUE&lt;br /&gt;UNIX网络编程 UNP&lt;br /&gt;编程艺术&lt;br /&gt;算法设计&lt;br /&gt;Linux设备驱动&lt;br /&gt;深入理解Linux内核&lt;br /&gt;... ...&lt;br /&gt;&lt;br /&gt;顿时我觉得自己非常渺小，经过的两年工作时间在眼前化为乌有。&lt;br /&gt;&lt;br /&gt;如果没有什么奇迹发生的话，我仍将领教上面所说的面试和笔试问题，我将再次面临自己薄&lt;br /&gt;弱的知识和经验积累，我还会在离职的深渊中不断轮回。因此这样一个明显的选择摆在我的&lt;br /&gt;面前：要么尝试其他低阶的工作甚至换行，要么就要费劲心力来补齐自己的不足。更要命的&lt;br /&gt;是，我花费这么长的时间才发觉这个问题，那么离职时我在做什么呢？一年前呢？哦～这让&lt;br /&gt;我实在难受————&lt;br /&gt;&lt;br /&gt;天呐！我把事情搞砸了！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-7997721796463100627?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/7997721796463100627/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_22.html#comment-form' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7997721796463100627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7997721796463100627'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_22.html' title='我把事情搞砸了'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2243250616084892997</id><published>2008-10-22T00:34:00.004+08:00</published><updated>2011-03-06T11:09:28.110+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-drivers-char'/><title type='text'>[LDD] C3. Character Device driver</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;代码阅读 &amp;lt;Linux Device Driver&amp;gt; v3&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Chapter 3. Character Device Driver&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、scull介绍 Simple Chracter Utility for Loading Localities&lt;/span&gt;&lt;br /&gt;scull是一个操作内存区域的字符设备。&lt;br /&gt;&lt;br /&gt;scull源码实现的设备有：&lt;br /&gt;scull0 ~ scull3&lt;br /&gt;这四个设备分别由一个全局且持久的内存区域组成。&lt;br /&gt;scullpipe0 ~ scullpipe3&lt;br /&gt;这四个FIFO与管道类似。一个进程读取由另一个进程写入的数据。如果多个进程读&lt;br /&gt;取同一个设备，它们就会为数据发生竞争。scullpipe的内部实现将说明在不借助&lt;br /&gt;于中断的情况下如何实现阻塞式和非阻塞式读写操作。&lt;br /&gt;scullsingle&lt;br /&gt;scullpriv&lt;br /&gt;sculluid&lt;br /&gt;scullwuid&lt;br /&gt;这些设备与scull0相似，但在何时允许open操作方面有一些限制。&lt;br /&gt;scullsingle，一次只允许一个进程使用该驱动程序。&lt;br /&gt;scullpriv，它对每个虚拟控制台是私有的。因为控制台进程会获取不痛的内存区。&lt;br /&gt;sculluid和scullwuid可以被多次打开，但是每次只能由一个用户打开；如果另一&lt;br /&gt;个用户锁定该设备，sculluid则返回“Device Busy”错误，而scullwuid则实现了阻&lt;br /&gt;塞式open。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、设备编号&lt;/span&gt;&lt;br /&gt;对字符设备的访问是通过文件系统内的设备文件进行的，这些设备文件通常位于/dev。而这&lt;br /&gt;些文件包含两个重要数据，主设备号和次设备号。&lt;br /&gt;&lt;br /&gt;主设备号表示对应的驱动程序，现代的Linux允许多个驱动程序共享主设备号，但一般仍旧&lt;br /&gt;遵循“一个主设备号对应一个驱动程序”的原则。&lt;br /&gt;&lt;br /&gt;次设备号由内核使用，用于正确确定设备文件指定的设备。&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;MAJOR(dev_t dev);        /* 返回主设备号 */&lt;br /&gt;MINOR(dev_t dev);        /* 返回次设备号 */&lt;br /&gt;MKDEV(int major, int minor);    /* 由主次设备得到dev_t类型的设备编号 */&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;关于分配和释放设备编号，系统在linux/fs.h中声明了以下函数：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/* 获得一个或者多个设备编号 */&lt;br /&gt;int register_chrdev_region(dev_t first, unsigned int, char *name);&lt;br /&gt;&lt;br /&gt;/* 运行过程中，使用以下函数会为我们恰当分配所需要的设备号 */&lt;br /&gt;int alloc_chrdev_region(dev_t *dev, unsigned int firstminor,&lt;br /&gt;            unsigned int count, char *name);&lt;br /&gt;&lt;br /&gt;/* 应该用以下函数释放这些设备编号 */&lt;br /&gt;void unregister_chrdev_region(dev_t first, unsigned int count);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;三、重要数据结构&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#include &amp;lt;linux/fs.h&amp;gt;&lt;br /&gt;struct inode {&lt;br /&gt;struct hlist_node    i_hash;&lt;br /&gt;struct list_head    i_list;&lt;br /&gt;struct list_head    i_sb_list;&lt;br /&gt;struct list_head    i_dentry;&lt;br /&gt;unsigned long        i_ino;&lt;br /&gt;atomic_t        i_count;&lt;br /&gt;unsigned int        i_nlink;&lt;br /&gt;uid_t            i_uid;&lt;br /&gt;gid_t            i_gid;&lt;br /&gt;dev_t            i_rdev;&lt;br /&gt;u64            i_version;&lt;br /&gt;loff_t            i_size;&lt;br /&gt;#ifdef __NEED_I_SIZE_ORDERED&lt;br /&gt;seqcount_t        i_size_seqcount;&lt;br /&gt;#endif&lt;br /&gt;struct timespec        i_atime;&lt;br /&gt;struct timespec        i_mtime;&lt;br /&gt;struct timespec        i_ctime;&lt;br /&gt;unsigned int        i_blkbits;&lt;br /&gt;blkcnt_t        i_blocks;&lt;br /&gt;unsigned short          i_bytes;&lt;br /&gt;umode_t            i_mode;&lt;br /&gt;spinlock_t        i_lock;    /* i_blocks, i_bytes, maybe i_size */&lt;br /&gt;struct mutex        i_mutex;&lt;br /&gt;struct rw_semaphore    i_alloc_sem;&lt;br /&gt;const struct inode_operations    *i_op;&lt;br /&gt;const struct file_operations    *i_fop;    /* former -&amp;gt;i_op-&amp;gt;default_file_ops */&lt;br /&gt;struct super_block    *i_sb;&lt;br /&gt;struct file_lock    *i_flock;&lt;br /&gt;struct address_space    *i_mapping;&lt;br /&gt;struct address_space    i_data;&lt;br /&gt;#ifdef CONFIG_QUOTA&lt;br /&gt;struct dquot        *i_dquot[MAXQUOTAS];&lt;br /&gt;#endif&lt;br /&gt;struct list_head    i_devices;&lt;br /&gt;union {&lt;br /&gt;    struct pipe_inode_info    *i_pipe;&lt;br /&gt;    struct block_device    *i_bdev;&lt;br /&gt;    struct cdev        *i_cdev;&lt;br /&gt;};&lt;br /&gt;/* ... */&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct file {&lt;br /&gt;/*&lt;br /&gt; * fu_list becomes invalid after file_free is called and queued via&lt;br /&gt; * fu_rcuhead for RCU freeing&lt;br /&gt; */&lt;br /&gt;union {&lt;br /&gt;    struct list_head    fu_list;&lt;br /&gt;    struct rcu_head     fu_rcuhead;&lt;br /&gt;} f_u;&lt;br /&gt;struct path        f_path;&lt;br /&gt;#define f_dentry    f_path.dentry&lt;br /&gt;#define f_vfsmnt    f_path.mnt&lt;br /&gt;const struct file_operations    *f_op;&lt;br /&gt;atomic_t        f_count;&lt;br /&gt;unsigned int         f_flags;&lt;br /&gt;mode_t            f_mode;&lt;br /&gt;loff_t            f_pos;&lt;br /&gt;struct fown_struct    f_owner;&lt;br /&gt;unsigned int        f_uid, f_gid;&lt;br /&gt;struct file_ra_state    f_ra;&lt;br /&gt;&lt;br /&gt;u64            f_version;&lt;br /&gt;#ifdef CONFIG_SECURITY&lt;br /&gt;void            *f_security;&lt;br /&gt;#endif&lt;br /&gt;/* needed for tty driver, and maybe others */&lt;br /&gt;void            *private_data;&lt;br /&gt;&lt;br /&gt;/* ... */&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct file_operations {&lt;br /&gt;struct module *owner;&lt;br /&gt;loff_t (*llseek) (struct file *, loff_t, int);&lt;br /&gt;ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);&lt;br /&gt;ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);&lt;br /&gt;ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);&lt;br /&gt;ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);&lt;br /&gt;int (*readdir) (struct file *, void *, filldir_t);&lt;br /&gt;unsigned int (*poll) (struct file *, struct poll_table_struct *);&lt;br /&gt;int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);&lt;br /&gt;long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);&lt;br /&gt;long (*compat_ioctl) (struct file *, unsigned int, unsigned long);&lt;br /&gt;int (*mmap) (struct file *, struct vm_area_struct *);&lt;br /&gt;int (*open) (struct inode *, struct file *);&lt;br /&gt;int (*flush) (struct file *, fl_owner_t id);&lt;br /&gt;int (*release) (struct inode *, struct file *);&lt;br /&gt;int (*fsync) (struct file *, struct dentry *, int datasync);&lt;br /&gt;int (*aio_fsync) (struct kiocb *, int datasync);&lt;br /&gt;int (*fasync) (int, struct file *, int);&lt;br /&gt;int (*lock) (struct file *, int, struct file_lock *);&lt;br /&gt;ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);&lt;br /&gt;unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);&lt;br /&gt;int (*check_flags)(int);&lt;br /&gt;int (*dir_notify)(struct file *filp, unsigned long arg);&lt;br /&gt;int (*flock) (struct file *, int, struct file_lock *);&lt;br /&gt;ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);&lt;br /&gt;ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);&lt;br /&gt;int (*setlease)(struct file *, long, struct file_lock **);&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/* 自定义结构 */&lt;br /&gt;struct scull_qset {&lt;br /&gt;void **data;&lt;br /&gt;struct scull_qset *next;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct scull_dev {&lt;br /&gt;struct scull_qset *data;&lt;br /&gt;int quantum;&lt;br /&gt;int qset;&lt;br /&gt;unsigned long size;&lt;br /&gt;unsigned int access_key;&lt;br /&gt;struct semaphore sem;&lt;br /&gt;struct cdev cdev;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;struct inode ————&lt;br /&gt;内核使用inode结构在内部表示文件，因此它和file结构不同，后者表示打开的文件描述符。&lt;br /&gt;对单个文件，可能会有许多个表示打开的文件描述符的file结构，但他们都指向单个inode&lt;br /&gt;结构。&lt;br /&gt;&lt;br /&gt;inode包含大量节点文件信息。而此驱动只是用到了以下两个字段：&lt;br /&gt;dev_t i_rdev;  // 对于表示设备的inode结构，该字段包含真正的设备编号&lt;br /&gt;struct cdev *i_cdev;  // 对于表示字符设备的inode结构，此字段包含struct cdev指针&lt;br /&gt;&lt;br /&gt;另外，开发者可以通过两个宏来获取主次设备编号：&lt;br /&gt;unsigned int iminor(struct inode *inode);&lt;br /&gt;unsigned int imajor(struct inode *inode);&lt;br /&gt;&lt;br /&gt;struct file ————&lt;br /&gt;file结构代表一个打开的文件，系统中任何一个打开的文件都有一个对应的file结构，他由&lt;br /&gt;内核在open时候创建，并传递给在文件上的所有函数，知道最后的close函数。在文件实例&lt;br /&gt;关闭之后，内核会释放这个结构。用到的字段有：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;struct path        f_path;&lt;br /&gt;#define f_dentry    f_path.dentry        // 目录项结构&lt;br /&gt;const struct file_operations    *f_op;&lt;br /&gt;unsigned int         f_flags;    // 标志，是否阻塞&lt;br /&gt;mode_t            f_mode;        // 权限检查&lt;br /&gt;loff_t            f_pos;        // 当前读写位置&lt;br /&gt;/* needed for tty driver, and maybe others */&lt;br /&gt;void            *private_data;    // 跨系统调用时候保存状态信息&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;struct file_operations ————&lt;br /&gt;file_operations用来建立驱动程序操作和驱动设备编号之间的连接，他包含了一组函数指&lt;br /&gt;针，这些函数和某些系统调用相关联。程序员可以视此结构为面向对象的C编程的一个例证。&lt;br /&gt;&lt;br /&gt;file_operations的函数指针必须指向驱动程序实现特定操作的函数，对于不支持的操作，&lt;br /&gt;对应的字段被赋值NULL，这种情况下，内核的处理行为是不尽相同的。&lt;br /&gt;在本例中，我们实现了以下操作：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;struct file_operations scull_fops = {&lt;br /&gt;.owner =    THIS_MODULE,&lt;br /&gt;.llseek =   scull_llseek,&lt;br /&gt;.read =     scull_read,&lt;br /&gt;.write =    scull_write,&lt;br /&gt;.ioctl =    scull_ioctl,&lt;br /&gt;.open =     scull_open,&lt;br /&gt;.release =  scull_release,&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;四、scull内存使用&lt;/span&gt;&lt;br /&gt;两个函数 ————&lt;br /&gt;void *kmalloc(size_t size, gfp_t flags);&lt;br /&gt;void kfree(void *ptr);&lt;br /&gt;这个两个函数定义在linux/stab.h中，是内核中非常重要的两个内存操作函数。用kmalloc&lt;br /&gt;函数分配，然后用kfree释放，同时也注意不应该把非kmalloc返回的指针传递给kfree。&lt;br /&gt;（但是将NULL传递给kfree是合法的）&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SP4GhYPQNEI/AAAAAAAABXg/-Egw_LA1agc/s1600-h/ldd3-3-1.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SP4GhYPQNEI/AAAAAAAABXg/-Egw_LA1agc/s320/ldd3-3-1.png" alt="" id="BLOGGER_PHOTO_ID_5259648585327195202" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;scull驱动中，每一个scull设备（scull_dev）都是一个链表头，他的指针指向scull_qset&lt;br /&gt;结构的链表。而每一个scull_qset则是典型的链表结构，包含了一个4000bytes * 1000的内&lt;br /&gt;存区域，这里的每一个区域就被称为是一个量子（quantum）。&lt;br /&gt;4000和1000的尺寸，由宏SCULL_QUANTUM和SCULL_QSET定义。当然，你也可以设置为模块参&lt;br /&gt;数，也可以在运行时使用ioctl来更改。&lt;br /&gt;&lt;br /&gt;由于scull设备是虚拟的内存区域，所以我们的read/write操作也将是对内存的操作，顶多&lt;br /&gt;的麻烦是跨越内核空间和用户空间的拷贝而已。这让实现变的非常容易。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;五、实现&lt;/span&gt;&lt;br /&gt;初始化和清理函数&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;int scull_init_module(void)&lt;br /&gt;{&lt;br /&gt;int result, i;&lt;br /&gt;dev_t dev = 0;&lt;br /&gt;&lt;br /&gt;if (scull_major) {&lt;br /&gt;    dev = MKDEV(scull_major, scull_minor);&lt;br /&gt;    result = register_chrdev_region(dev, scull_nr_devs, "scull");&lt;br /&gt;} else {&lt;br /&gt;    result = alloc_chrdev_region(&amp;amp;dev, scull_minor, scull_nr_devs,&lt;br /&gt;                     "scull");&lt;br /&gt;    scull_major = MAJOR(dev);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (result &amp;lt; 0) {&lt;br /&gt;    printk(KERN_WARNING "scull: can't get major %d\n", scull_major);&lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* allocate the devices -- we can't have them static, as the number&lt;br /&gt; * can be specified at load time.&lt;br /&gt; */&lt;br /&gt;scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL);&lt;br /&gt;if (!scull_devices) {&lt;br /&gt;    result = -ENOMEM;&lt;br /&gt;    goto fail;&lt;br /&gt;}&lt;br /&gt;memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));&lt;br /&gt;&lt;br /&gt;/* initialize each device */&lt;br /&gt;for (i = 0; i &amp;lt; scull_nr_devs; i++) {&lt;br /&gt;    scull_devices[i].quantum = scull_quantum;&lt;br /&gt;    scull_devices[i].qset = scull_qset;&lt;br /&gt;    init_MUTEX(&amp;amp;scull_devices[i].sem);&lt;br /&gt;    scull_setup_cdev(&amp;amp;scull_devices[i], i);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;    /* At this point call the init function for any friend device */&lt;br /&gt;dev = MKDEV(scull_major, scull_minor + scull_nr_devs);&lt;br /&gt;//    dev += scull_p_init(dev);&lt;br /&gt;//    dev += scull_access_init(dev);&lt;br /&gt;&lt;br /&gt;#ifdef SCULL_DEBUG /* only when debugging */&lt;br /&gt;//    scull_create_proc();&lt;br /&gt;#endif&lt;br /&gt;printk(KERN_INFO "init scull successful\n");&lt;br /&gt;return 0; /* succeed */&lt;br /&gt;&lt;br /&gt;fail:&lt;br /&gt;scull_cleanup_module();&lt;br /&gt;return result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void scull_cleanup_module(void)&lt;br /&gt;{&lt;br /&gt;int i;&lt;br /&gt;dev_t devno = MKDEV(scull_major, scull_minor);&lt;br /&gt;&lt;br /&gt;/* Get rid of our char dev entries */&lt;br /&gt;if (scull_devices) {&lt;br /&gt;    for (i = 0; i &amp;lt; scull_nr_devs; i++) {&lt;br /&gt;        scull_trim(scull_devices + i);&lt;br /&gt;        cdev_del(&amp;amp;scull_devices[i].cdev);&lt;br /&gt;    }&lt;br /&gt;    kfree(scull_devices);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#ifdef SCULL_DEBUG /* use proc only if debugging */&lt;br /&gt;scull_remove_proc();&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;/* cleanup_module is never called if registering failed */&lt;br /&gt;unregister_chrdev_region(devno, scull_nr_devs);&lt;br /&gt;&lt;br /&gt;/* and call the cleanup functions for friend devices */&lt;br /&gt;//    scull_p_cleanup();&lt;br /&gt;//    scull_access_cleanup();&lt;br /&gt;printk(KERN_INFO "cleanup scull successful\n");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;init_module过程包括 ————&lt;br /&gt;1) 注册设备&lt;br /&gt;2) 初始化scull_dev设备&lt;br /&gt;3) 初始化其他设备&lt;br /&gt;为了简化设计，此章节没有引入pipe等设备，所以注销了某些方法。&lt;br /&gt;&lt;br /&gt;cleanup_module过程 ————&lt;br /&gt;1）释放scull_dev结构，注销字符设备&lt;br /&gt;2) 注销设备号&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;然后是在file_operations指明的函数，这里重点讲解read和write的实现 ————&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;ssize_t scull_read(struct file *filp, char __user *buf,&lt;br /&gt;       size_t count, loff_t *f_pos)&lt;br /&gt;{&lt;br /&gt;struct scull_dev *dev = filp-&amp;gt;private_data;&lt;br /&gt;struct scull_qset *dptr;&lt;br /&gt;int quantum = dev-&amp;gt;quantum, qset = dev-&amp;gt;qset;&lt;br /&gt;int itemsize = quantum * qset;&lt;br /&gt;int item, s_pos, q_pos, rest;&lt;br /&gt;ssize_t retval = 0;&lt;br /&gt;&lt;br /&gt;if (down_interruptible(&amp;amp;dev-&amp;gt;sem))&lt;br /&gt;    return -ERESTARTSYS;&lt;br /&gt;if(*f_pos &amp;gt;= dev-&amp;gt;size)&lt;br /&gt;    goto out;&lt;br /&gt;if(*f_pos + count &amp;gt; dev-&amp;gt;size)&lt;br /&gt;    count = dev-&amp;gt;size - *f_pos;&lt;br /&gt;&lt;br /&gt;item = (long)*f_pos / itemsize;&lt;br /&gt;rest = (long)*f_pos % itemsize;&lt;br /&gt;s_pos = rest / quantum;&lt;br /&gt;q_pos = rest % quantum;&lt;br /&gt;&lt;br /&gt;dptr = scull_follow(dev, item);&lt;br /&gt;&lt;br /&gt;if (dptr == NULL || !dptr-&amp;gt;data || !dptr-&amp;gt;data[s_pos])&lt;br /&gt;    goto out;&lt;br /&gt;&lt;br /&gt;if (count &amp;gt; quantum - q_pos)&lt;br /&gt;    count = quantum - q_pos;&lt;br /&gt;&lt;br /&gt;if (copy_to_user(buf, dptr-&amp;gt;data[s_pos] + q_pos, count)) {&lt;br /&gt;    retval = -EFAULT;&lt;br /&gt;    goto out;&lt;br /&gt;}&lt;br /&gt;*f_pos += count;&lt;br /&gt;retval = count;&lt;br /&gt;out:&lt;br /&gt;up(&amp;amp;dev-&amp;gt;sem);&lt;br /&gt;return(retval);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ssize_t scull_write(struct file *filp, const char __user *buf,&lt;br /&gt;        size_t count, loff_t *f_pos)&lt;br /&gt;{&lt;br /&gt;struct scull_dev *dev = filp-&amp;gt;private_data;&lt;br /&gt;struct scull_qset *dptr;&lt;br /&gt;int quantum = dev-&amp;gt;quantum, qset = dev-&amp;gt;qset;&lt;br /&gt;int itemsize = quantum * qset;&lt;br /&gt;int item, s_pos, q_pos, rest;&lt;br /&gt;ssize_t retval = 0;&lt;br /&gt;&lt;br /&gt;if (down_interruptible(&amp;amp;dev-&amp;gt;sem))&lt;br /&gt;    return -ERESTARTSYS;&lt;br /&gt;if(*f_pos &amp;gt;= dev-&amp;gt;size)&lt;br /&gt;    goto out;&lt;br /&gt;if(*f_pos + count &amp;gt; dev-&amp;gt;size)&lt;br /&gt;    count = dev-&amp;gt;size - *f_pos;&lt;br /&gt;&lt;br /&gt;item = (long)*f_pos / itemsize;&lt;br /&gt;rest = (long)*f_pos % itemsize;&lt;br /&gt;s_pos = rest / quantum;&lt;br /&gt;q_pos = rest % quantum;&lt;br /&gt;&lt;br /&gt;dptr = scull_follow(dev, item);&lt;br /&gt;&lt;br /&gt;if (dptr == NULL)&lt;br /&gt;    goto out;&lt;br /&gt;if (!dptr-&amp;gt;data) {&lt;br /&gt;    dptr-&amp;gt;data = kmalloc(qset *sizeof(char *), GFP_KERNEL);&lt;br /&gt;    if (!dptr-&amp;gt;data)&lt;br /&gt;        goto out;&lt;br /&gt;    memset(dptr-&amp;gt;data, 0, qset * sizeof(char *));&lt;br /&gt;}&lt;br /&gt;if (!dptr-&amp;gt;data[s_pos]) {&lt;br /&gt;    dptr-&amp;gt;data[s_pos] = kmalloc(quantum, GFP_KERNEL);&lt;br /&gt;    if (!dptr-&amp;gt;data[s_pos])&lt;br /&gt;        goto out;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (count &amp;gt; quantum - q_pos)&lt;br /&gt;    count = quantum - q_pos;&lt;br /&gt;&lt;br /&gt;if (copy_from_user(dptr-&amp;gt;data[s_pos] + q_pos, buf, count)) {&lt;br /&gt;    retval = -EFAULT;&lt;br /&gt;    goto out;&lt;br /&gt;}&lt;br /&gt;*f_pos += count;&lt;br /&gt;retval = count;&lt;br /&gt;&lt;br /&gt;/* 更新文件大小 */&lt;br /&gt;if (dev-&amp;gt;size &amp;lt; *f_pos)&lt;br /&gt;    dev-&amp;gt;size = *f_pos;&lt;br /&gt;out:&lt;br /&gt;up(&amp;amp;dev-&amp;gt;sem);&lt;br /&gt;return(retval);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;scull_read从filp的f_pos处读取count个字节，写到buf中。&lt;br /&gt;首先要作的是，确定f_pos的位置，根据f_pos，我们要确定写的位置，位于第几个item的&lt;br /&gt;第s_pos数组的第q_pos个量子处，然后根据item返回我们要的scull_qset结构体。最后使用&lt;br /&gt;copy_to_user完成读操作。&lt;br /&gt;&lt;br /&gt;写操作和读操作很相似，使用了逆向的copy_from_user函数。&lt;br /&gt;&lt;br /&gt;这两个重要的系统调用实现，都使用了跨越内核和用户空间的写操作：&lt;br /&gt;copy_to_user(void *to, void *from, int count);&lt;br /&gt;copy_from_user(void *to, void *from, int count);&lt;br /&gt;&lt;br /&gt;六、总结&lt;br /&gt;scull_init_module&lt;br /&gt;  * alloc_chrdev_region&lt;br /&gt;  * scull_setup_cdev&lt;br /&gt;   ** cdev_init, cdev_add&lt;br /&gt;   ** scull_fops(llseek, read, write, ioctl, open, release)&lt;br /&gt;  * scull_create_proc&lt;br /&gt;  * scull_p_init&lt;br /&gt;  * scull_access_init&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQUoGor7s3I/AAAAAAAABjI/xfv7x9cyRSE/s1600-h/1.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 198px;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SQUoGor7s3I/AAAAAAAABjI/xfv7x9cyRSE/s320/1.png" alt="" id="BLOGGER_PHOTO_ID_5261655834118304626" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;_&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2243250616084892997?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2243250616084892997/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/ldd-c3-character-device-driver.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2243250616084892997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2243250616084892997'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/ldd-c3-character-device-driver.html' title='[LDD] C3. Character Device driver'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Kb-lr4qFtj4/SP4GhYPQNEI/AAAAAAAABXg/-Egw_LA1agc/s72-c/ldd3-3-1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-9163267682791644659</id><published>2008-10-14T11:40:00.002+08:00</published><updated>2011-03-06T11:24:39.788+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>[TIC++] C13. Dynamic Object Creation</title><content type='html'>&lt;span style="font-weight: bold;font-size:180%;" &gt;代码阅读&amp;lt;Thinking In C++&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Chapter 13. Dynamic Object Creation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、在堆区创建内存&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c13: malloc_class.cpp&lt;br /&gt;// malloc with class objects&lt;br /&gt;#include &amp;lt;cstdlib&amp;gt;&lt;br /&gt;#include &amp;lt;cstring&amp;gt;&lt;br /&gt;#include &amp;lt;cstring&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class obj {&lt;br /&gt;   int i, j, k;&lt;br /&gt;   enum { sz = 100 };&lt;br /&gt;   char buf[sz];&lt;br /&gt;public:&lt;br /&gt;   void initialization() {  // can't use constructors&lt;br /&gt;       cout &amp;lt;&amp;lt; "initialization obj" &amp;lt;&amp;lt; endl;&lt;br /&gt;       i = j = k = 0;&lt;br /&gt;       memset(buf, 0, sz);&lt;br /&gt;   }&lt;br /&gt;   void destroy() {&lt;br /&gt;       cout &amp;lt;&amp;lt; "destroy obj" &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   obj *o = (obj*)malloc(sizeof(obj));&lt;br /&gt;   if (o == 0)&lt;br /&gt;       return -1;&lt;br /&gt;   o-&amp;gt;initialization();&lt;br /&gt;   //sometimes later...&lt;br /&gt;   o-&amp;gt;destroy();&lt;br /&gt;   free(o);&lt;br /&gt;}&lt;br /&gt;/* result:&lt;br /&gt;initialization obj&lt;br /&gt;destroy obj&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;当C++对象创建的时候，将会发生两件事情：&lt;br /&gt;1) 为空间分配内存&lt;br /&gt;2) 调用构造方法来初始化这块内存&lt;br /&gt;&lt;br /&gt;而空间创建问题（1），可以有以下选择：&lt;br /&gt;1) 在程序开始前创建&lt;span style="color: rgb(204, 0, 0);"&gt;静态空间&lt;/span&gt;，位于静态内存区，拥有文件生命期&lt;br /&gt;2) 在执行点处创建&lt;span style="color: rgb(204, 0, 0);"&gt;堆栈空间&lt;/span&gt;，他将在执行跳出方法的时候释放。堆栈的处理是处理器完成&lt;br /&gt;的，自然非常高效&lt;br /&gt;3) 在执行点处创建&lt;span style="color: rgb(204, 0, 0);"&gt;堆空间&lt;/span&gt;(heap)，这被成为动态内存分配(!)。方法必须在运行调用的时候&lt;br /&gt;创建堆空间，这意味着你可以决定任何时候创建，当然也要为释放负&lt;span style="font-weight: bold;"&gt;全权责任&lt;/span&gt;————生命期完&lt;br /&gt;全由程序员掌控。&lt;br /&gt;&lt;br /&gt;上面的例子展示了C处理堆区空间的方法：&lt;br /&gt;这里的obj o对象的创建，没有使用到构造方法！这是非常糟糕的情况，因为你有可能选择&lt;br /&gt;是否初始化，甚至可能忘记，初始化的丢失极为可能带来bug。&lt;br /&gt;&lt;br /&gt;于是C++引入了一种新方法：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c13: new_and_delete.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class tree {&lt;br /&gt;   int height;&lt;br /&gt;public:&lt;br /&gt;   tree(int tree_height): height(tree_height) {}&lt;br /&gt;   ~tree() { cout &amp;lt;&amp;lt; "*"; }&lt;br /&gt;   friend ostream&amp;amp; operator &amp;lt;&amp;lt;(ostream &amp;amp;os, const tree* t) {&lt;br /&gt;       return os &amp;lt;&amp;lt; "tree height is: "&lt;br /&gt;             &amp;lt;&amp;lt; t-&amp;gt;height &amp;lt;&amp;lt; std::endl;&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;   tree *t = new tree(40);&lt;br /&gt;   cout &amp;lt;&amp;lt; t;&lt;br /&gt;   delete t;&lt;br /&gt;}&lt;br /&gt;/* result&lt;br /&gt;tree height is: 40&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;new和delete保证了构造方法的正常调用，甚至还会检查内存申请是否调用成功。&lt;br /&gt;这一切显得像堆栈内存分配一样简单。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、delete void*&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c13: bad_void_pointer_deletion.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class object {&lt;br /&gt;   void *data;&lt;br /&gt;   const int size;&lt;br /&gt;   const char id;&lt;br /&gt;public:&lt;br /&gt;   object(int sz, char c): size(sz), id(c) {&lt;br /&gt;       data = new char[size];&lt;br /&gt;       cout &amp;lt;&amp;lt; "constructing object" &amp;lt;&amp;lt; id&lt;br /&gt;            &amp;lt;&amp;lt; ", size = " &amp;lt;&amp;lt; size &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;   ~object() {&lt;br /&gt;       cout &amp;lt;&amp;lt; "desctructing object " &amp;lt;&amp;lt; id &amp;lt;&amp;lt; endl;&lt;br /&gt;       delete []data; // OK, just release storage;&lt;br /&gt;       // no desctructor calls are necessary;&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt;   object *a = new object(40, 'a');&lt;br /&gt;   delete a;&lt;br /&gt;   void *b = new object(40, 'b');&lt;br /&gt;   delete b;&lt;br /&gt;}&lt;br /&gt;/* result:&lt;br /&gt;constructing objecta, size = 40&lt;br /&gt;desctructing object a&lt;br /&gt;constructing objectb, size = 40&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;object是一个包含 void *data的一个类，在这个类的析构方法中，我们看到使用了delete&lt;br /&gt;来析构data，这没什么问题，因为这里要作的只是释放内存。&lt;br /&gt;&lt;br /&gt;但是在main()中，对于delete来说，对象类型信息就非常必要了。由于delete a知道a是一&lt;br /&gt;个class object，所以他使用到了~object()析构方法，data也被释放了。可是void *b就遇&lt;br /&gt;到麻烦，他无法得知void*的类型信息，就无法调用析构方法，因此data将会永远的丢失，&lt;br /&gt;这是一个&lt;span style="color: rgb(204, 0, 0);"&gt;静静的内存泄&lt;/span&gt;露。&lt;br /&gt;&lt;br /&gt;如果你在C++工程中有内存泄露问题，那就要好好检查你的delete了。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;三、介绍new handler&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c13: new_handler.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;cstdlib&amp;gt;&lt;br /&gt;#include &amp;lt;new&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int count = 0;&lt;br /&gt;&lt;br /&gt;void out_of_memory()&lt;br /&gt;{&lt;br /&gt;   cerr &amp;lt;&amp;lt; "memory exhausted after " &amp;lt;&amp;lt; count &amp;lt;&amp;lt; " allocations" &amp;lt;&amp;lt; endl;&lt;br /&gt;   exit(1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   set_new_handler(out_of_memory);&lt;br /&gt;   while(1) {&lt;br /&gt;       count++;&lt;br /&gt;       new int[1000];&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;当new无法找到一个足够大的堆空间来存放对象，会出现何种情况呢？&lt;br /&gt;这样的情况下，就会调用new-handler。默认的new-handler会抛出异常，当然可以定义新的&lt;br /&gt;new-handler，打印出信息告诉你发生了什么。&lt;br /&gt;&lt;br /&gt;这里就是用&amp;lt;new&amp;gt;的set_new_handler设置了方法，他会打印在经历多少次存储之后耗尽内存。&lt;br /&gt;&lt;br /&gt;_&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-9163267682791644659?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/9163267682791644659/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c13-dynamic-object-creation.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/9163267682791644659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/9163267682791644659'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c13-dynamic-object-creation.html' title='[TIC++] C13. Dynamic Object Creation'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-4836354748915858716</id><published>2008-10-14T11:37:00.001+08:00</published><updated>2011-03-06T11:24:39.793+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>[TIC++] C11. References &amp; the Copy-Constructor</title><content type='html'>&lt;span style="font-weight: bold;font-size:180%;" &gt;代码阅读&amp;lt;Thinking In C++&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Chapter 11. References &amp;amp; the Copy-Constructor&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、再次介绍引用&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// reference.cpp&lt;br /&gt;int *f(int *x)&lt;br /&gt;{&lt;br /&gt;    (*x)++;&lt;br /&gt;    return x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int &amp;amp;g(int &amp;amp;x)&lt;br /&gt;{&lt;br /&gt;    x++;&lt;br /&gt;    return x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int &amp;amp;h()&lt;br /&gt;{&lt;br /&gt;    int q;&lt;br /&gt;//!    return q;    // error&lt;br /&gt;    static int x;&lt;br /&gt;    return x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    int a = 0;&lt;br /&gt;    f(&amp;amp;a);&lt;br /&gt;    g(a);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;reference可以被简单视作一个常量指针，而这个指针会在预编译期间自动被解释掉。&lt;br /&gt;ref最常用到的地方，就是作为参数和返回值使用了。对参数而言，任何形参的改变会作用&lt;br /&gt;到实参；针对返回值，要注意的是返回的东西只是引用，必须保证要返回的内存在返回地可&lt;br /&gt;见。&lt;br /&gt;* 因此，你不能在h()中返回局部变量。&lt;br /&gt;&lt;br /&gt;在介绍copy constructor之前，让我们来看常引用情况 ————&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// const_ref.cpp&lt;br /&gt;void f(int&amp;amp;) {}&lt;br /&gt;void g(const int&amp;amp;) {}&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt;//!    f(1);    //invalid initialization of non-const reference&lt;br /&gt;    g(1);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;当传递1这个实参的时候，编译器会为1分配内存，然后创造一个引用(int&amp;amp;)绑定到这个内存&lt;br /&gt;地址。如果1没有被声明为const，那将是毫无意义的。f(1)将得到一个编译时错误。&lt;br /&gt;&lt;br /&gt;最后是复合化的引用，指向指针的引用 ————&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c11: ref_to_pointer.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;void increment(int* &amp;amp;i) { i++; }&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    int *i = 0;&lt;br /&gt;   &lt;br /&gt;    cout &amp;lt;&amp;lt; "i = " &amp;lt;&amp;lt; i &amp;lt;&amp;lt; endl;&lt;br /&gt;    increment(i);&lt;br /&gt;    cout &amp;lt;&amp;lt; "i = " &amp;lt;&amp;lt; i &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这里阵阵改变的是指针(int*)i，而不是指针指向的值，但是这里传递的i。&lt;br /&gt;在C中要做到这点，那就要使用二级指针了。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、copy-constructor&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c11: howmany.cpp&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;string&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;ofstream out("howmany.out");&lt;br /&gt;&lt;br /&gt;class howmany {&lt;br /&gt;    static int object_cnt;&lt;br /&gt;public:&lt;br /&gt;    howmany() { object_cnt++; }&lt;br /&gt;    static void print(const string&amp;amp; msg = "") {&lt;br /&gt;        if (msg.size() != 0)&lt;br /&gt;            out &amp;lt;&amp;lt; msg &amp;lt;&amp;lt; ": ";&lt;br /&gt;        out &amp;lt;&amp;lt; "object_cnt = " &amp;lt;&amp;lt; object_cnt &amp;lt;&amp;lt; endl;&lt;br /&gt;    }&lt;br /&gt;    ~howmany() {&lt;br /&gt;        object_cnt--;&lt;br /&gt;        print("~howmany()");&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int howmany::object_cnt = 0;&lt;br /&gt;&lt;br /&gt;// pass and return by value:&lt;br /&gt;howmany f(howmany x)&lt;br /&gt;{&lt;br /&gt;    x.print("x argument inside f()");&lt;br /&gt;    return x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    howmany h;&lt;br /&gt;    howmany::print("after construction of h");&lt;br /&gt;    howmany h2 = f(h);&lt;br /&gt;    howmany::print("after call to f()");&lt;br /&gt;}&lt;br /&gt;/* result:&lt;br /&gt;after construction of h: object_cnt = 1&lt;br /&gt;x argument inside f(): object_cnt = 1&lt;br /&gt;~howmany(): object_cnt = 0&lt;br /&gt;after call to f(): object_cnt = 0&lt;br /&gt;~howmany(): object_cnt = -1&lt;br /&gt;~howmany(): object_cnt = -2&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;首先我们构建howmany h，调用构造函数，会得到object_cnt = 1;&lt;br /&gt;然后我们使用f()来构建第二个对象h2 = f(h)，编译器传递h拷贝，并没有使用构造函数来&lt;br /&gt;创建h2。但是意想不到的是，离开f()的时候发生了析构，导致object_cnt = 0。&lt;br /&gt;而最后的两个析构，使得object_cnt得到负数。&lt;br /&gt;&lt;br /&gt;这是为什么呢？&lt;br /&gt;因为在f()内，函数使用了C形式的&lt;span style="font-weight: bold;"&gt;bitcopy&lt;/span&gt;，我们得到的只是一份h的拷贝，他没有调用构造&lt;br /&gt;方法，所以我们没有看到f()中objecgt_cnt = 2。而在后来，C++特性去保证了最后一步析&lt;br /&gt;构，因此出现了object_cnt不升反降的结果。&lt;br /&gt;&lt;br /&gt;C++中为了保证构造的完整性，因此提出了copy-constructor————&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c11: howmany.cpp&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;string&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;ofstream out("howmany2.out");&lt;br /&gt;&lt;br /&gt;class howmany2 {&lt;br /&gt;    string name;&lt;br /&gt;    static int object_cnt;&lt;br /&gt;public:&lt;br /&gt;    howmany2(const string &amp;amp;id = ""): name(id) {&lt;br /&gt;        ++object_cnt;&lt;br /&gt;        print("howmany2()");&lt;br /&gt;    }&lt;br /&gt;    ~howmany2() {&lt;br /&gt;        --object_cnt;&lt;br /&gt;        print("~howmany()");&lt;br /&gt;    }&lt;br /&gt;    howmany2(const howmany2 &amp;amp;h): name(h.name) {&lt;br /&gt;        name += " copy";&lt;br /&gt;        ++object_cnt;&lt;br /&gt;        print("howmany2(const howmany2&amp;amp;)");&lt;br /&gt;    }&lt;br /&gt;    void print(const string&amp;amp; msg = "") const {&lt;br /&gt;        if (msg.size() != 0)&lt;br /&gt;            out &amp;lt;&amp;lt; msg &amp;lt;&amp;lt; endl;&lt;br /&gt;        out &amp;lt;&amp;lt; '\t' &amp;lt;&amp;lt; name &amp;lt;&amp;lt; ": "&lt;br /&gt;            &amp;lt;&amp;lt; "object_cnt = " &amp;lt;&amp;lt; object_cnt &amp;lt;&amp;lt; endl;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int howmany2::object_cnt = 0;&lt;br /&gt;&lt;br /&gt;// pass and return by value:&lt;br /&gt;howmany2 f(howmany2 x)&lt;br /&gt;{&lt;br /&gt;    x.print("x argument inside f()");&lt;br /&gt;    return x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    howmany2 h("h");&lt;br /&gt;    out &amp;lt;&amp;lt; "entering f()" &amp;lt;&amp;lt; endl;&lt;br /&gt;    howmany2 h2 = f(h);&lt;br /&gt;    h2.print("h2 after call to f()");&lt;br /&gt;    out &amp;lt;&amp;lt; "call f(), no return value" &amp;lt;&amp;lt; endl;&lt;br /&gt;    f(h);&lt;br /&gt;    out &amp;lt;&amp;lt; "after call to f()" &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;/*&lt;br /&gt;howmany2()&lt;br /&gt;    h: object_cnt = 1&lt;br /&gt;entering f()&lt;br /&gt;howmany2(const howmany2&amp;amp;)&lt;br /&gt;    h copy: object_cnt = 2&lt;br /&gt;x argument inside f()&lt;br /&gt;    h copy: object_cnt = 2&lt;br /&gt;howmany2(const howmany2&amp;amp;)&lt;br /&gt;    h copy copy: object_cnt = 3&lt;br /&gt;~howmany()&lt;br /&gt;    h copy: object_cnt = 2&lt;br /&gt;h2 after call to f()&lt;br /&gt;    h copy copy: object_cnt = 2&lt;br /&gt;call f(), no return value&lt;br /&gt;howmany2(const howmany2&amp;amp;)&lt;br /&gt;    h copy: object_cnt = 3&lt;br /&gt;x argument inside f()&lt;br /&gt;    h copy: object_cnt = 3&lt;br /&gt;howmany2(const howmany2&amp;amp;)&lt;br /&gt;    h copy copy: object_cnt = 4&lt;br /&gt;~howmany()&lt;br /&gt;    h copy copy: object_cnt = 3&lt;br /&gt;~howmany()&lt;br /&gt;    h copy: object_cnt = 2&lt;br /&gt;after call to f()&lt;br /&gt;~howmany()&lt;br /&gt;    h copy copy: object_cnt = 1&lt;br /&gt;~howmany()&lt;br /&gt;    h: object_cnt = 0&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;我们可以看到，f()传递参数的时候，编译器将会把拷贝传值的过程交给copy-constructor，&lt;br /&gt;同样return返回值，也需要这样的拷贝。&lt;br /&gt;entering f()&lt;br /&gt;howmany2(const howmany2&amp;amp;)&lt;br /&gt;    h copy: object_cnt = 2&lt;br /&gt;x argument inside f()&lt;br /&gt;    h copy: object_cnt = 2&lt;br /&gt;howmany2(const howmany2&amp;amp;)&lt;br /&gt;    h copy copy: object_cnt = 3&lt;br /&gt;&lt;br /&gt;而后离开f()，这需要析构刚才创建的临时变量，保留return的值。&lt;br /&gt;&lt;br /&gt;第二次f()没有返回值，因此情况稍微发生改变。此种调用忽略了返回值，编译器也会聪明&lt;br /&gt;的直接在调用点析构此临时对象。&lt;br /&gt;&lt;br /&gt;三、选择copy-construction&lt;br /&gt;我们来看如何迫使系统自建拷贝构造方法&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c11: default_cc.cpp&lt;br /&gt;// automatic creation of the copy-constructor&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;string&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class withcc {&lt;br /&gt;public:&lt;br /&gt;    withcc() {}&lt;br /&gt;    withcc(const withcc &amp;amp;) {&lt;br /&gt;        cout &amp;lt;&amp;lt; "withcc(withcc &amp;amp;)" &amp;lt;&amp;lt; endl;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class wocc {&lt;br /&gt;    string id;&lt;br /&gt;public:&lt;br /&gt;    wocc(const string &amp;amp;ident = ""): id(ident) {}&lt;br /&gt;    void print(const string &amp;amp;msg = "") const {&lt;br /&gt;        if (msg.size() != 0)&lt;br /&gt;            cout &amp;lt;&amp;lt; msg &amp;lt;&amp;lt; ": ";&lt;br /&gt;        cout &amp;lt;&amp;lt; id &amp;lt;&amp;lt; endl;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class composite {&lt;br /&gt;    withcc tc;&lt;br /&gt;    wocc oc;&lt;br /&gt;public:&lt;br /&gt;    composite(): oc("composite()") {}&lt;br /&gt;    void print(const string &amp;amp;msg = "") const {&lt;br /&gt;        oc.print(msg);&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt;    composite c;&lt;br /&gt;    c.print("content of c");&lt;br /&gt;    cout &amp;lt;&amp;lt; "calling composite copy-constructor" &amp;lt;&amp;lt; endl;&lt;br /&gt;    composite c2 = c;&lt;br /&gt;    c2.print("content of c2");&lt;br /&gt;}&lt;br /&gt;/* reuslt&lt;br /&gt;content of c: composite()&lt;br /&gt;calling composite copy-constructor&lt;br /&gt;withcc(withcc &amp;amp;)&lt;br /&gt;content of c2: composite()&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;我们在这里看到两个案例：&lt;br /&gt;1) class withcc拥有构造方法和拷贝构造方法。一旦包含拷贝构造函数，这就是在告诉编&lt;br /&gt;译器：永远不要再自作主张，自动创建默认构造函数。因此，如果class withcc没有定义&lt;br /&gt;withcc()，编译器会报错——composite中的tc没有办法创建。&lt;br /&gt;&lt;br /&gt;2) class composite拥有构造方法，而没有拷贝构造方法。一旦需要拷贝构造方法，编译器&lt;br /&gt;会为所有的成员对象调用他们的拷贝构造方法。（这通过组合或者继承可以实现composite）&lt;br /&gt;在这里，c2 = c，就强迫调用了withcc和wocc的拷贝构造方法。而wocc没有拷贝构造方法，&lt;br /&gt;因此系统为其自动定义一个，完成bitcopy。&lt;br /&gt;&lt;br /&gt;接下来，通过小技巧来避免赋值拷贝&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: no_cc.cpp&lt;br /&gt;class nocc {&lt;br /&gt;    int i;&lt;br /&gt;    nocc(const nocc &amp;amp;);&lt;br /&gt;public:&lt;br /&gt;    nocc(int ii = 0): i(ii) {}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void f(nocc);&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;    nocc n;&lt;br /&gt;// copy-constructor is private!&lt;br /&gt;//!    f(n);&lt;br /&gt;//!    nocc n2 = n;&lt;br /&gt;//!    nocc n3(n);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;通过将拷贝构造方法设置为私有，来避免赋值拷贝，这是一个非常简单的方法。&lt;br /&gt;在此不用赘述。&lt;br /&gt;_&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-4836354748915858716?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/4836354748915858716/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c11-references-copy-constructor.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/4836354748915858716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/4836354748915858716'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c11-references-copy-constructor.html' title='[TIC++] C11. References &amp; the Copy-Constructor'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2123641905423788643</id><published>2008-10-11T01:20:00.003+08:00</published><updated>2011-03-06T11:24:39.799+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>[TIC++] C10. Name Control</title><content type='html'>&lt;span style="font-weight: bold;font-size:180%;" &gt;代码阅读&amp;lt;Thinking In C++&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Chapter 10. Name Control&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、局部变量作为static&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: static_objects_inside_funcs.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class X {&lt;br /&gt;   int i;&lt;br /&gt;public:&lt;br /&gt;   X(int ii = 0):i(ii) {}&lt;br /&gt;   ~X() { cout &amp;lt;&amp;lt; "X::~X()" &amp;lt;&amp;lt; endl; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void f()&lt;br /&gt;{&lt;br /&gt;   static X x1(47);&lt;br /&gt;   static X x2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   f();&lt;br /&gt;} ///:~&lt;br /&gt;/* result:&lt;br /&gt;X::~X()&lt;br /&gt;X::~X()&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;当局部变量声明为static的时候，此变量将不会放置在堆栈区内，而是放置在程序的静态内&lt;br /&gt;存区。这就意味着static变量：&lt;br /&gt;* 具有全局生命期&lt;br /&gt;* 初始化只进行一次&lt;br /&gt;* 此变量在声明函数外部不可见&lt;br /&gt;&lt;br /&gt;来解析一下静态对象的析构方法：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: static_destructors.cpp&lt;br /&gt;// static object destructors&lt;br /&gt;&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;ofstream out("statdest.out");&lt;br /&gt;&lt;br /&gt;class obj {&lt;br /&gt;   char c;&lt;br /&gt;public:&lt;br /&gt;   obj(char cc): c(cc) {&lt;br /&gt;       out &amp;lt;&amp;lt; "obj::obj() for " &amp;lt;&amp;lt; c &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;   ~obj() {&lt;br /&gt;       out &amp;lt;&amp;lt; "obj::~obj() for " &amp;lt;&amp;lt; c &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;obj a('a');&lt;br /&gt;&lt;br /&gt;void f()&lt;br /&gt;{&lt;br /&gt;   static obj b('b');&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void g()&lt;br /&gt;{&lt;br /&gt;   static obj c('c');&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   out &amp;lt;&amp;lt; "inside main()" &amp;lt;&amp;lt; endl;&lt;br /&gt;   f();&lt;br /&gt;   //g() not called&lt;br /&gt;   out &amp;lt;&amp;lt; "leaving main()" &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;/* statdest.out:&lt;br /&gt;obj::obj() for a&lt;br /&gt;inside main()&lt;br /&gt;obj::obj() for b&lt;br /&gt;leaving main()&lt;br /&gt;obj::~obj() for b&lt;br /&gt;obj::~obj() for a&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;静态变量具有全局生命期，这样静态对象会在main()函数退出时候，或者调用C标准函数&lt;br /&gt;exit()的时候被自动调用析构方法。这意味着：&lt;span style="color: rgb(204, 0, 0);"&gt;如果你在静态对象的析构方法内exit，就会&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;造成一个死循环&lt;/span&gt;。&lt;/span&gt;这是很危险的。另外，调用abort()函数结束程序，将不会自动调用静态&lt;br /&gt;对象的析构方法。&lt;br /&gt;&lt;br /&gt;这个例子解释了一些基本概况，a是全局对象，b是f()内部的静态对象，他们的构造和析构&lt;br /&gt;顺序正好相反:&lt;br /&gt;cons a -&amp;gt; cons b -&amp;gt; des b --&amp;gt; des a&lt;br /&gt;（在C++中，全局静态对象的构造函数是在main()之前被调用的）&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、全局变量为static&lt;/span&gt;&lt;br /&gt;local_extern.cpp -- 第一个模块（main）&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: local_extern.cpp&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   extern int i;&lt;br /&gt;   std::cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; endl;;&lt;br /&gt;}&lt;br /&gt;/* result:&lt;br /&gt;5&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;local_extern2.cpp -- 第二个模块&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: local_extern2.cpp&lt;br /&gt;int i = 5;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;static 和 extern在 C++中是一对反义词。&lt;br /&gt;* 默认全局变量是extern的，extern关键词标明次变量包含外部链接，可以在其他模块中引&lt;br /&gt;用。而static则约束此变量为内部链接，不可外部引用。这对于“非成员”函数也同样适用。&lt;br /&gt;file scope:&lt;br /&gt;1) 全局变量声明默认为extern，而声明为static只会更改可视范围，这样变量只包含内部&lt;br /&gt;链接————它仍旧会位于静态数据区域，无论static还是extern。&lt;br /&gt;&lt;br /&gt;2) 局部变量声明默认为auto，若声明为static则会更改可视范围，并且更改存储区域（从&lt;br /&gt;堆栈区更改到静态数据区）；若声明为extern，则显示此变量位于别的模块。&lt;br /&gt;&lt;br /&gt;3) 方法定义为static/extern，只会改变可视范围。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;三、名字空间 namespaces&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: continuation.cpp&lt;br /&gt;namespace mylib {&lt;br /&gt;   extern int x;&lt;br /&gt;   void f();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;namespace mylib {&lt;br /&gt;   extern int y;&lt;br /&gt;   void g();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main() {}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;* 名字空间的定义&lt;span style="color: rgb(204, 0, 0);"&gt;必须在全局区内，或者被嵌套在其他名字空间内&lt;/span&gt;。&lt;br /&gt;* 定义的末尾没有";"&lt;br /&gt;* 可以在多个头文件里添加名字空间定义（原本看起来像重复定义）&lt;br /&gt;* 名字空间可以被引用为其他名字，比如&lt;br /&gt; namespace bob = bobs_super_duper_library;&lt;br /&gt;* 对名字空间内部数据的引用类似于成员操作&lt;br /&gt;* 你不能使用名字空间建立实例，他根本不是一个类型&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;四、using 指令&lt;/span&gt;&lt;br /&gt;namespace_int.h -- 定义名字空间Int&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: namespace_int.h&lt;br /&gt;#ifndef __NAMESPACEINT_H&lt;br /&gt;#define __NAMESPACEINT_H&lt;br /&gt;&lt;br /&gt;namespace Int {&lt;br /&gt;   enum sign { positive, negative };&lt;br /&gt;   class Integer {&lt;br /&gt;       int i;&lt;br /&gt;       sign s;&lt;br /&gt;   public:&lt;br /&gt;       Integer(int ii = 0): i(ii),&lt;br /&gt;                    s(i &amp;gt;= 0 ? positive : negative)&lt;br /&gt;           {}&lt;br /&gt;       sign get_sign() const { return s; }&lt;br /&gt;       void set_sign(sign sgn) { s = sgn; }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#endif /// __NAMESPACEINT_H&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;namespace_math.h -- 定义名字空间Math&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: namespace_math.h&lt;br /&gt;#ifndef __NAMESPACEMATH_H&lt;br /&gt;#define __NAMESPACEMATH_H&lt;br /&gt;&lt;br /&gt;#include "namespace_int.h"&lt;br /&gt;&lt;br /&gt;namespace Math {&lt;br /&gt;   using namespace int;&lt;br /&gt;   Integer a, b;&lt;br /&gt;   Integer divide(Integer, Integer);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#endif  /// __NAMESPACEMATH_H&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;arithmetic.cpp&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: arithmetic.cpp&lt;br /&gt;#include "namespace_math.h"&lt;br /&gt;void arithmetic()&lt;br /&gt;{&lt;br /&gt;   using namespace Int;&lt;br /&gt;   Integer x;&lt;br /&gt;   x.set_sign(positive);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main() {}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;在arithmetic()的方法中，我们看到了using指令，如果没有他，任何命名空间的内容都需&lt;br /&gt;要全名提供。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;五、C++中的static数据成员&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: static_init.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int x = 100;&lt;br /&gt;&lt;br /&gt;class with_static {&lt;br /&gt;   static int x;&lt;br /&gt;   static int y;&lt;br /&gt;public:&lt;br /&gt;   void print() const {&lt;br /&gt;       cout &amp;lt;&amp;lt; "with_static::x = " &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;       cout &amp;lt;&amp;lt; "with_static::y = " &amp;lt;&amp;lt; y &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int with_static::x = 1;&lt;br /&gt;int with_static::y = x + 1;&lt;br /&gt;// with_static::x not ::x&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   with_static ws;&lt;br /&gt;   ws.print();&lt;br /&gt;}&lt;br /&gt;/*&lt;br /&gt;with_static::x = 1&lt;br /&gt;with_static::y = 2&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;类的static成员存在于一个独立的空间中，无论建立多少个对象，他们的static成员都是共&lt;br /&gt;享的。更重要的是static成员只有在类对象中可见，它也可以受成员访问符约束。&lt;br /&gt;&lt;br /&gt;在此例子中，在没有创建实例的时候，我们就对with_static::x进行初始化，这对于静态成&lt;br /&gt;员是可行的。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: static_array.cpp&lt;br /&gt;class values {&lt;br /&gt;   static const int scsize;// = 100;&lt;br /&gt;   static const long sclong = 100;&lt;br /&gt;&lt;br /&gt;   static const int scints[];&lt;br /&gt;   static const long sclongs[];&lt;br /&gt;   static const float sctable[];&lt;br /&gt;   static const char scletters[];&lt;br /&gt;   static int size;&lt;br /&gt;   static const float scfloat; // differ from tic++&lt;br /&gt;   static float table[];&lt;br /&gt;   static char letters[];&lt;br /&gt;};&lt;br /&gt;int values::scsize = 100;&lt;br /&gt;int values::size = 100;&lt;br /&gt;const float values::scfloat = 1.1;&lt;br /&gt;const int values::scints[] = { 99, 47, 33, 11, 7 };&lt;br /&gt;const long values::sclongs[] = { 99, 47, 33, 11, 7 };&lt;br /&gt;const float values::sctable[] = { 1.1, 2.2, 3.3, 4.4 };&lt;br /&gt;const char values::scletters[] = { 'a','b','c','d','e','f','g','h','i','j',};&lt;br /&gt;float values::table[4] = { 1.1, 2.2, 3.3, 4.4 };&lt;br /&gt;char values::letters[10] = { 'a','b','c','d','e','f','g','h','i','j',};&lt;br /&gt;&lt;br /&gt;int main() { values v; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这里揭示了static初始化的可行性分析：&lt;br /&gt;1) &lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;static&lt;/span&gt; &lt;/span&gt;不可以在类中初始化，必须要求const。&lt;br /&gt;2) &lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;static const 非原子类型&lt;/span&gt;，不可以在类中初始化。&lt;br /&gt;3) &lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;static const 原子类型&lt;/span&gt;，可以而且必须在类中初始化。&lt;br /&gt;&lt;br /&gt;下面来看嵌套类定义和局部类定义中的static情况————&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: local.cpp&lt;br /&gt;// static member &amp;amp; local classes&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;// Nested classes CAN have static data members;&lt;br /&gt;class outer {&lt;br /&gt;   class inner {&lt;br /&gt;       static int i;&lt;br /&gt;   };&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int outer::inner::i = 47;&lt;br /&gt;&lt;br /&gt;//local class can not have static data members;&lt;br /&gt;void f()&lt;br /&gt;{&lt;br /&gt;   class local {&lt;br /&gt;   public:&lt;br /&gt;//!        static int i; // error&lt;br /&gt;// (how could you define i?)&lt;br /&gt;   } x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   outer x;&lt;br /&gt;   f();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;你可以发现嵌套类定义中的static完全可行，但是在局部类定义中却被禁止了。&lt;br /&gt;我们怎么办呢？实际上，局部类定义是很少使用的。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;六、static成员方法&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: static_member_funcs.cpp&lt;br /&gt;class X {&lt;br /&gt;   int i;&lt;br /&gt;   static int j;&lt;br /&gt;public:&lt;br /&gt;   X(int ii = 0): i(ii) {&lt;br /&gt;       // non-static member function can&lt;br /&gt;       // access static member function or data&lt;br /&gt;       j = i;&lt;br /&gt;   }&lt;br /&gt;   int val() const { return i; }&lt;br /&gt;   static int incr() {&lt;br /&gt;       //! i++; // Error: static member function&lt;br /&gt;       // cannot access non-static member data&lt;br /&gt;       return ++j;&lt;br /&gt;   }&lt;br /&gt;   static int f() {&lt;br /&gt;       //! val(); // Error: static member function&lt;br /&gt;       // cannot access non-static member function&lt;br /&gt;       return incr();&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int X::j = 0;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   X x;&lt;br /&gt;   X *xp = &amp;x;&lt;br /&gt;&lt;br /&gt;   x.f();&lt;br /&gt;   xp-&amp;gt;f();&lt;br /&gt;   X::f(); // only works with static members&lt;br /&gt;} ///:~&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;同样，我们在C++中可以像定义成员数据那样定义一个static成员方法，在我们需要创建一&lt;br /&gt;个仅仅作用于类或者对象的方法的时候，我们不希望他在全局区域内造成命名污染，因此，&lt;br /&gt;这个念头就诞生了。&lt;br /&gt;&lt;br /&gt;static方法可以直接被引用调用，不需要建立类实例（就像数据成员初始化一样）。有一点&lt;br /&gt;要注意的是：static成员方法，他&lt;span style="color: rgb(204, 0, 0);"&gt;并不包含this指针&lt;/span&gt;，这注定了它：&lt;br /&gt;&lt;br /&gt;* 不能够访问数据成员，也不能调用成员方法。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: singleton.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class egg {&lt;br /&gt;   static egg e;&lt;br /&gt;   int i;&lt;br /&gt;&lt;br /&gt;   egg(int ii): i(ii) {}&lt;br /&gt;   egg(const egg&amp;amp;); // prevent copy-construction&lt;br /&gt;public:&lt;br /&gt;   static egg* instance() { return &amp;e; }&lt;br /&gt;   int val() const { return i; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;egg egg::e(47);&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;//!    egg x(1); // private constructor&lt;br /&gt;   cout &amp;lt;&amp;lt; egg::instance()-&amp;gt;val() &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这个例子非常有趣，除了egg::e，你将永远无法创造第二个egg对象。&lt;br /&gt;&lt;br /&gt;1) 因为egg的构造函数设置为私有，你无法直接创建私有对象。&lt;br /&gt;2) 使用static成员方法egg::instance()，你可以创建一个实例，这个实例是&lt;br /&gt;  static egg e;&lt;br /&gt;3) 由于egg e本身也是e，那么所有的 instance()调用，都会返回这一个对象。其他对象创&lt;br /&gt;  建不能。&lt;br /&gt;4) 此例还禁用了拷贝构造方法 egg(const egg&amp;amp;)，这意味着，你甚至无法赋值对象，最后&lt;br /&gt;  一条路也被封锁了。&lt;br /&gt;&lt;br /&gt;七、static 初始化依赖 static initialization dependency&lt;br /&gt;initializer.h&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: initializer.h&lt;br /&gt;#ifndef __INITIALIZER_H&lt;br /&gt;#define __INITIALIZER_H&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;extern int x;&lt;br /&gt;extern int y;&lt;br /&gt;&lt;br /&gt;class initializer {&lt;br /&gt;   static int init_count;&lt;br /&gt;public:&lt;br /&gt;   initializer() {&lt;br /&gt;       std::cout &amp;lt;&amp;lt; "initializer()" &amp;lt;&amp;lt; std::endl;&lt;br /&gt;       //initialize first time only&lt;br /&gt;       if (init_count++ == 0) {&lt;br /&gt;           std::cout &amp;lt;&amp;lt; "performing initialization"&lt;br /&gt;                 &amp;lt;&amp;lt; std::endl;&lt;br /&gt;           x = 100;&lt;br /&gt;           y = 200;&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;   ~initializer() {&lt;br /&gt;       std::cout &amp;lt;&amp;lt; "initializer()" &amp;lt;&amp;lt; std::endl;&lt;br /&gt;       //cleanup last time only&lt;br /&gt;       if (--init_count == 0) {&lt;br /&gt;           std::cout &amp;lt;&amp;lt; "performing cleanup"&lt;br /&gt;                 &amp;lt;&amp;lt; std::endl;&lt;br /&gt;           // any necessary cleanup here&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static initializer init;&lt;br /&gt;&lt;br /&gt;#endif//__INITIALIZER_H&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;initializer_defs.cpp -- 已知模块&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: initializer_defs.cpp&lt;br /&gt;#include "initializer.h"&lt;br /&gt;&lt;br /&gt;int x;&lt;br /&gt;int y;&lt;br /&gt;int initializer::init_count;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;initializer.cpp -- 测试模块(main)&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: initializer.cpp&lt;br /&gt;#include "initializer.h"&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   cout &amp;lt;&amp;lt; "inside main()" &amp;lt;&amp;lt; endl;&lt;br /&gt;   cout &amp;lt;&amp;lt; "leaving main()" &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;/* result:&lt;br /&gt;initializer()&lt;br /&gt;performing initialization&lt;br /&gt;initializer()&lt;br /&gt;inside main()&lt;br /&gt;leaving main()&lt;br /&gt;initializer()&lt;br /&gt;initializer()&lt;br /&gt;performing cleanup&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;在extern的初始化过程中，我们会遇到这样的问题：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;   extern std::ofstream out;&lt;br /&gt;   class Oof {&lt;br /&gt;   public:&lt;br /&gt;       Oof() { std::out &amp;lt;&amp;lt; "ouch"; }&lt;br /&gt;   } Oof;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这段代码引用到了其他文件的一个对象ofstream out，如果两个文件位于不同的模块，那么&lt;br /&gt;这意味着out的定义和使用位于两个模块。在编译器编译的时候，往往不能完全决定哪一个&lt;br /&gt;模块先编译，操作系统也没有提供确保初始化顺序的绝对方法。如果是此段代码先编译，那&lt;br /&gt;么面对的问题就是，out还未构造就使用了，这会带来混乱。&lt;br /&gt;这个问题针对的对象是（它们会在main()之前执行初始化）：&lt;br /&gt;1) 全局对象&lt;br /&gt;2) 局部static对象&lt;br /&gt;&lt;br /&gt;为了解决此问题的发生，我们给出&lt;span style="font-weight: bold; color: rgb(204, 0, 0);"&gt;三种方法&lt;/span&gt;：&lt;br /&gt;1) 永远别这样做，避免此类问题发生是最好的选择&lt;br /&gt;2) 如果必须这样做，把静态对象定义放在一个文件里，这样你可以安排预想的编译次序。&lt;br /&gt;3) 如果不可避免的要把静态对象放在不同模块中，可以采用两种技巧来解决此问题。&lt;br /&gt;&lt;br /&gt;本段例子就是技巧1，它是Jerry Schwarz在创建iostream库的时候提出的。&lt;br /&gt;   initializer.h *设计目标&lt;br /&gt;   initializer_defs.cpp *已知模块&lt;br /&gt;   initializer.cpp *已知模块&lt;br /&gt;我们要求的目标是，无论initializer_defs.cpp和initializer.cpp哪一个先初始化，都可&lt;br /&gt;以保证x,y的安全使用。&lt;br /&gt;实现方法：首先在initializer.h中，extern引用x,y，然后定义为x,y专门的初始化类&lt;br /&gt;initializer，根据static成员int_count是否为0，判断x,y是否已经被初始化，如果未初始&lt;br /&gt;化，则实现初始化；否则不要动。以同样的方法定义析构方法。接着在文件末尾添加static&lt;br /&gt;对象initializer init。&lt;br /&gt;最后一步，在x,y对象定义的模块初始化 initializer::init_count = 0;&lt;br /&gt;&lt;br /&gt;由于已知模块都已经包含了initializer.h头文件，那么他们将共同拥有init对象，init对&lt;br /&gt;象保证了对象x,y的初始化；由于class initializer的处理，也将屏蔽x,y的重复初始化。&lt;br /&gt;&lt;br /&gt;下面介绍技巧2————&lt;br /&gt;dependency1.h&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: dependency1.h&lt;br /&gt;#ifndef __DEPENDENCY1_H&lt;br /&gt;#define __DEPENDENCY1_H&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;class dependency1 {&lt;br /&gt;   bool init;&lt;br /&gt;public:&lt;br /&gt;   dependency1(): init(true) {&lt;br /&gt;       std::cout &amp;lt;&amp;lt; "dependency1 construction"&lt;br /&gt;             &amp;lt;&amp;lt; std::endl;&lt;br /&gt;   }&lt;br /&gt;   void print() const {&lt;br /&gt;       std::cout &amp;lt;&amp;lt; "dependency1 init:"&lt;br /&gt;             &amp;lt;&amp;lt; init &amp;lt;&amp;lt; std::endl;&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;#endif//__DEPENDENCY1_H&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;dependency2.h&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: dependency2.h&lt;br /&gt;#ifndef __DEPENDENCY2_H&lt;br /&gt;#define __DEPENDENCY2_H&lt;br /&gt;&lt;br /&gt;#include "dependency1.h"&lt;br /&gt;&lt;br /&gt;class dependency2 {&lt;br /&gt;   dependency1 d1;&lt;br /&gt;public:&lt;br /&gt;   dependency2(const dependency1 &amp;amp;dep1): d1(dep1) {&lt;br /&gt;       std::cout &amp;lt;&amp;lt; "dependency2 construction ";&lt;br /&gt;       print();&lt;br /&gt;   }&lt;br /&gt;   void print() const { d1.print(); }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;#endif//__DEPENDENCY2_H&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;dependency1statfun.h&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: dependency1statfun.h&lt;br /&gt;#ifndef __DEPENDENCY1STATFUN_H&lt;br /&gt;#define __DEPENDENCY1STATFUN_H&lt;br /&gt;&lt;br /&gt;#include "dependency1.h"&lt;br /&gt;extern dependency1 &amp;amp;d1();&lt;br /&gt;&lt;br /&gt;#endif//__DEPENDENCY1STATFUN_H&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;dependency2statfun.h&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: dependency2statfun.h&lt;br /&gt;#ifndef __DEPENDENCY2STATFUN_H&lt;br /&gt;#define __DEPENDENCY2STATFUN_H&lt;br /&gt;&lt;br /&gt;#include "dependency2.h"&lt;br /&gt;extern dependency2 &amp;amp;d2();&lt;br /&gt;&lt;br /&gt;#endif//__DEPENDENCY2STATFUN_H&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;dependency1statfun.cpp&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: dependency1statfun.cpp&lt;br /&gt;#include "dependency1statfun.h"&lt;br /&gt;&lt;br /&gt;dependency1 &amp;amp;d1()&lt;br /&gt;{&lt;br /&gt;   static dependency1 dep1;&lt;br /&gt;   return(dep1);&lt;br /&gt;}///:~&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;dependency2statfun.cpp&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: dependency2statfun.cpp&lt;br /&gt;#include "dependency1statfun.h"&lt;br /&gt;#include "dependency2statfun.h"&lt;br /&gt;&lt;br /&gt;dependency2 &amp;amp;d2()&lt;br /&gt;{&lt;br /&gt;   static dependency2 dep2(d1());&lt;br /&gt;   return(dep2);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;technique2b.cpp&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c10: technique2b.cpp&lt;br /&gt;// (L) dependency1statfun dependency2statfun&lt;br /&gt;&lt;br /&gt;#include "dependency2statfun.h"&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   d2();&lt;br /&gt;}///:~&lt;br /&gt;/* result:&lt;br /&gt;dependency1 construction&lt;br /&gt;dependency2 construction dependency1 init:1&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这个方法显然更加干净清爽:)&lt;br /&gt;   dependency1.h * 已知头文件&lt;br /&gt;   dependency2.h * 已知头文件&lt;br /&gt;   dependency1statfun.h * 设计头文件&lt;br /&gt;   dependency2statfun.h * 设计头文件2&lt;br /&gt;   dependency1statfun.cpp * 设计模块&lt;br /&gt;   dependency2statfun.cpp * 设计模块2&lt;br /&gt;   technique2b.cpp *main函数，用来测试&lt;br /&gt;我们发现class dependency2的对象实例必须通过拷贝构造函数来初始化，而且他需要借助&lt;br /&gt;class dependency1的对象。因此以下的初始化总是可能存在的:&lt;br /&gt;   dependency2 dep2((dependency1)dep1);&lt;br /&gt;如果dep1和此定义不再同一模块中，我们显然要面对静态对象的依赖问题。&lt;br /&gt;&lt;br /&gt;技巧2是这样作的。他通过定义两个模块提供了两个函数d1()和d2()，他们分别包含一个静&lt;br /&gt;态对象dep1和dep2(d1)，如果要创建dependency2对象，只有通过d2()返回得到。实际上，&lt;br /&gt;技巧2正是封锁了初始化方法，迫使初始化按照即定的顺序进行。&lt;br /&gt;dependency2&amp;amp; -&amp;gt; d2() -&amp;gt; dep2(d1()) -&amp;gt; d1() -&amp;gt; dep1 -&amp;gt; dependency1: dependency1()&lt;br /&gt;&lt;br /&gt;总结&lt;br /&gt;&lt;br /&gt;我们看到static带来功能性的同时，也带来了困惑，因为在某些情况下，它用来控制存储位&lt;br /&gt;置，有些时候控制可视范围或者名字的链接属性。&lt;br /&gt;* static存储在静态数据内存区，拥有全局生命域&lt;br /&gt;* 作用在&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;局部变量&lt;/span&gt;上，static使得变量局部可见却拥有全局生命期。&lt;br /&gt;* 作用在&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;全局变量&lt;/span&gt;上，static控制可视范围，仅仅在本模块内可见。&lt;br /&gt;* 作用在&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;类的数据成员&lt;/span&gt;上，static既控制生命期，又限制该标识符仅仅在类中可见。&lt;br /&gt;* 作用在&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;类的成员方法&lt;/span&gt;上，static方法除了保留数据成员特性以外，还去除了指针。这意味&lt;br /&gt;着，静态成员不能访问非static数据成员，也不能调用非static成员方法。&lt;br /&gt;&lt;br /&gt;namespace 同样给予更加灵活的方法，让您在大工程内部控制代码的增加和繁衍。&lt;br /&gt;&lt;br /&gt;class 内部的class是在程序中控制名字的另外一种方法，他不会和全局名字冲突，而在程&lt;br /&gt;序内部享用独立的可视范围和访问控制。这会大大增强你代码的维护性能。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2123641905423788643?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2123641905423788643/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c10-name-control.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2123641905423788643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2123641905423788643'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c10-name-control.html' title='[TIC++] C10. Name Control'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-7558645343738963578</id><published>2008-10-10T16:01:00.012+08:00</published><updated>2011-03-17T16:30:13.759+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>We Are On The Cruise! -- OnePiece 十周年纪念</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SO8Pfex3BjI/AAAAAAAABOw/2t4V_av8A9I/s1600-h/OnePieceLogo.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SO8Pfex3BjI/AAAAAAAABOw/2t4V_av8A9I/s320/OnePieceLogo.png" alt="" id="BLOGGER_PHOTO_ID_5255436323677210162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;财富、名声、力量——曾经拥有这世界上一切男人，海贼王 Gol D. Roger，他在临刑前的一&lt;br /&gt;句话，让全世界的人们趋之若鹜奔向大海：“想要我的财宝吗？想要的话可以全部给你！伟&lt;br /&gt;大航路！我把所有财宝都放在了那里。”于是男子汉们启程前往伟大航路————&lt;br /&gt;大海贼的时代来临了！&lt;br /&gt;----&lt;br /&gt;&lt;br /&gt;这是每次星期天晚上都会听到的话，这一天的早上九点，隔海相望的日本将会定期推出日本&lt;br /&gt;漫画《One Piece》。因此这一天来说，对我总是轻松的一天，可以享受周末的轻松，同样&lt;br /&gt;观看《One Piece》——我从来未曾想过自己会爱上一部动画。&lt;br /&gt;&lt;br /&gt;而最新的373集openning再次更改，启用了10周年版本主题曲&lt;we&gt;，我们在openning动&lt;br /&gt;画中看到了从第一章节至今出现过的主要人物，从Buggy，Arlong，Smoker到Red Foot Zeff，&lt;br /&gt;巨鲸Laboon，Vivi，Mr.2，还有冰山先生，七武海Sir Crocodile，最新的CP9。这才发现&lt;br /&gt;《One Piece》已经度过漫长的10周年～&lt;br /&gt;&lt;br /&gt;One Piece是啥玩意儿呢？对于一些大叔大婶，从来认为动画是小儿科的人们，咱们还是来&lt;br /&gt;普及一下————&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;One Piece介绍&lt;/span&gt;&lt;br /&gt;One Piece是由日本漫画家尾田荣一郎创作的少年漫画，自1997年8月4日起开始在《周刊少&lt;br /&gt;年JUMP》中连载，而漫画每一章节都由株式会社集英社以单行本的方式发行，至今仍在连载。&lt;br /&gt;（OnePiece漫画创刊号）&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8PfgkcccI/AAAAAAAABO4/yODEMRIPzgg/s1600-h/230px-One_Piece,_Volume_1.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8PfgkcccI/AAAAAAAABO4/yODEMRIPzgg/s320/230px-One_Piece,_Volume_1.jpg" alt="" id="BLOGGER_PHOTO_ID_5255436324157813186" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;we&gt;其名字“One Piece”在故事中为“一个大秘宝”之意。One Piece讲述的是一个17岁的男孩，&lt;br /&gt;Monkey D. Luffy，从误食恶魔果实获得超自然力，而后伙同一群勇敢的海贼的冒险故事，&lt;br /&gt;他们的海贼团体叫做“草帽海贼团”。Luffy以获得世界的终极秘宝——One Piece为目标，从而&lt;br /&gt;成为新一代的海贼王。&lt;br /&gt;&lt;br /&gt;我们所听到的译名“海贼王”为台湾中文版发行权转移之后的新代理商“东立出版社”因版权关&lt;br /&gt;系另取的译名。你可以在内地看到以下译名，他都说的是一个动画————One Piece：&lt;br /&gt;海贼王（台湾 大然文化）&lt;br /&gt;航海王（台湾 东立出版社）&lt;br /&gt;海贼王（香港 天下出版社）&lt;br /&gt;&lt;br /&gt;借由1亿4千万的漫画销量，One Piece是《周刊少年JUMP》史上销量第三的漫画作品，同样&lt;br /&gt;One Piece也被认为是最受好评的三大漫画作品之一。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;情节&lt;/span&gt;&lt;br /&gt;听到上面的解说，你还是对One Piece没有概念，因为描述实在乏味，这和打败BOSS拿钥匙&lt;br /&gt;开宝箱的经典剧情没有啥大分别。那我没的办法，因为我无法用三言两语把十年长篇的漫画&lt;br /&gt;说个清楚透彻。&lt;br /&gt;&lt;/we&gt;&lt;br /&gt;&lt;we&gt;One Piece中描述的海贼，显然和大家想象中的不一样，“独木腿、铁钩手、黑眼罩、三角帽&lt;br /&gt;子、提着酒瓶劫掠四方的人”，这种《加勒比海盗》中的海贼形象在One Piece的世界里显得&lt;br /&gt;更加简单但是多元化，我们的几个主角将会是各自背景不同，使命非凡，勇于追逐梦想，极&lt;br /&gt;富自由精神的，乐于向上，将朋友视为生命的海贼，这将传统意义上作恶多端的海贼形象完&lt;br /&gt;全颠覆。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8PfomIwfI/AAAAAAAABPA/1ujAV7KQGPc/s1600-h/4607903.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8PfomIwfI/AAAAAAAABPA/1ujAV7KQGPc/s320/4607903.jpg" alt="" id="BLOGGER_PHOTO_ID_5255436326312395250" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;主线似乎很明了，少年时代的Luffy，被他心目中的英雄“红发Shanks”鼓舞，而起身寻找传&lt;br /&gt;说的大秘宝，这个宝藏可谓是世界财富的集合与象征，更重要的是，它是“海贼王”称号的标&lt;br /&gt;志。为了成为“海贼之王”，Luffy面临的将是世界上最危险，最诡异的海域：伟大航路&lt;br /&gt;（The Grand Line）。&lt;br /&gt;&lt;br /&gt;Luffy在东海位置起步，他面临的首要任务是组织一个草帽海贼团；沿着上一代海贼王，&lt;br /&gt;Gold Roger的足迹，他们将一步步的逼近One Piece秘宝。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;我喜欢的OP&lt;/span&gt;&lt;br /&gt;我在这里说说这部动画的杰出之处。他和其他漫画有啥分别。&lt;br /&gt;&lt;br /&gt;1) &lt;span style="color: rgb(204, 0, 0);"&gt;OP的故事构架太出色了。&lt;/span&gt;&lt;br /&gt;在二十几集的时候和三百多集的时候，我依然抱有同样感觉：海贼王的故事写的太好了！&lt;br /&gt;从四海到伟大航路，再到新世界，这样故事的轮廓非常清晰，而四皇，海军，七武海三大势&lt;br /&gt;力的均衡也很直白，尾田没有在这里隐瞒什么。相反观众和读者的想法都很简单：Luffy是&lt;br /&gt;要朝着新世界去的，在三大势力并存的新世界，草帽海贼团显然不是个旁观者。他将会与这&lt;br /&gt;些恶势力搏斗，最终取得One Piece。&lt;br /&gt;&lt;br /&gt;传统动画上呢？你几乎永远摸索不到故事的主题，当然如果“主角变强变强再变强”也算主题。&lt;br /&gt;（中将Monkey D. Garp介绍四皇）&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SO8PfgEGGrI/AAAAAAAABPI/2WkHhlMnRPg/s1600-h/180px-Yonkou.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SO8PfgEGGrI/AAAAAAAABPI/2WkHhlMnRPg/s320/180px-Yonkou.JPG" alt="" id="BLOGGER_PHOTO_ID_5255436324022131378" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;2) &lt;span style="color: rgb(204, 0, 0);"&gt;OP启用了多元化的叙述方式，让故事显得更加具有立体感。&lt;/span&gt;&lt;br /&gt;大体轮廓确定之后，尾田先生在漫画的主干上面耗费了太多太多的精力，为我们呈现出来极&lt;br /&gt;其精彩的故事。&lt;br /&gt;&lt;br /&gt;我们开始的时候都会知道，Shanks是Luffy的启蒙英雄，由他激励鼓舞，Luffy踏上了海贼王&lt;br /&gt;的征程。那么依据观众的理解，Shanks将来肯定会在伟大航路和Luffy碰面，还会向Luffy提&lt;br /&gt;供帮助和指引。对，没错，不过Shanks后来展现在大家面前的时候还是吓了一跳：他就是在&lt;br /&gt;新世界里君临海上的四皇之一“红发Shanks”。这种落差感，让我们对他们的相遇期待度大增。&lt;br /&gt;&lt;br /&gt;尾田的这种起承的手法用了非常非常的多，包括巨鲸Laboon的约定，Zoro对Mihawk的誓言等&lt;br /&gt;等等等。&lt;br /&gt;&lt;br /&gt;再来说说，第24集动画的时候，Luffy遭遇Sanji，努力想纳入麾下。但是面对的主要矛盾则&lt;br /&gt;是，摆脱红脚Zeff的干扰和努力说服Sanji，但是红脚Zeff可是穿越伟大航路的大海贼，所&lt;br /&gt;以我们开始把视线聚焦到Luffy vs. Zeff的问题上来。但是后来东海霸主Kreig来袭，我们&lt;br /&gt;又确定他才是本场的强敌。不过更恐怖的才来到我们面前，世界第一剑客，同时是七武海之&lt;br /&gt;一的鹰眼Mihawk紧随Kreig来到东海，而又发生Zoro单挑鹰眼的事件。这让观众才和Zoro一&lt;br /&gt;样惊叹：这才是世界第一的力量！这种层层迭加的紧张感觉，更加白热化的场景，实在让海&lt;br /&gt;贼王更加趋近于电影化。&lt;br /&gt;&lt;br /&gt;这样的情节在海贼王屡见不鲜，空岛被迫牵连到本地人的纠纷，司法岛引出Nico Robin离奇&lt;br /&gt;的身世，处处显示出尾田先生的高明。&lt;br /&gt;&lt;br /&gt;3) &lt;span style="color: rgb(204, 0, 0);"&gt;尾田创作的是一部笑着流泪的漫画。&lt;/span&gt;&lt;br /&gt;环顾当今《周年少年JUMP》的三大漫画，OP一定是最为轻松的一个了。Luffy，Usopp和&lt;br /&gt;Chopper本身就是一个超级无敌高效组合……尾田先生在剧情中添加了非常非常多夸张的肢体&lt;br /&gt;语言，可以让猥琐的敌人更加幽默，让恐怖的局势稍显放松。&lt;br /&gt;&lt;br /&gt;然而OP努力在人格刻画上费劲心思，Shanks为拯救Luffy而断臂，Zeff为Sanji忍受饥饿，&lt;br /&gt;Laboon厮守和Brook的约定，Vivi和草帽海贼团的惜别之情。这些OP迷们耳熟能详的场面，&lt;br /&gt;每每重复的时候，仍旧能让大家泪流满面。&lt;br /&gt;&lt;br /&gt;想到动画开始的时候真的是非常痛苦，不明白是制作成本，还是知名度不高的原因，OP动画&lt;br /&gt;的前几十集真的是朴实到“粗糙”，长时间以来人们都称之为“一流漫画，二流动画”。即便是&lt;br /&gt;到后来，OP仍旧没有引用广泛的3d技术，没有神乎其神的PK情景，绚烂的招式噼里啪啦打上&lt;br /&gt;天昏地暗，我才明白，这才是OP，用真情信义感动大家的海贼王。&lt;br /&gt;（草帽一伙与Vivi惜别）&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SO9t0kcfNgI/AAAAAAAABRI/_FZe78Wk3js/s1600-h/One-Piece.jpg"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SO9t0kcfNgI/AAAAAAAABRI/_FZe78Wk3js/s320/One-Piece.jpg" alt="" id="BLOGGER_PHOTO_ID_5255540040068445698" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;we&gt;4) &lt;span style="color: rgb(204, 0, 0);"&gt;OP的场景和角色非常多元化。&lt;/span&gt;&lt;br /&gt;能坚持从头看到今天，我真是对画家佩服的五体投地。十年动画里涌现出来的各式新鲜玩意&lt;br /&gt;儿，实在让人目瞪口呆。&lt;br /&gt;&lt;br /&gt;那么那么多的建筑风格，那么那么多的恶魔果实，那么那么多的珍禽异类，那么那么奇怪的&lt;br /&gt;大叔大婶，那么那么搞笑的敌人。。。尾田脑子里天天在想些什么呢？&lt;br /&gt;&lt;/we&gt;&lt;br /&gt;&lt;we&gt;5) &lt;span style="color: rgb(204, 0, 0);"&gt;OP自始自终保留了故事的神秘美感，这是能够在十年以来保持长久不衰的重要原因。&lt;/span&gt;&lt;br /&gt;当然我在这里就不再讨论七武海是啥能力，四皇最后一位是谁了，那是些论坛上永久不会停&lt;br /&gt;歇的话题（除了尾田直接说出来）。我只说一些重头戏：&lt;br /&gt;&lt;br /&gt;历史文本之谜。空岛的老头曾经说过：“20年前也有一个家伙来到空岛，那家伙真是豪爽阿！&lt;br /&gt;”紧接着，在空岛的历史正文旁边，草帽们发现了海贼王Roger的签名。在之后的水之都章节&lt;br /&gt;里，我们已经发现Nico Robin隐藏着巨大的秘密，这显然印证了青稚所言：那个女人身后的&lt;br /&gt;黑暗不是你们可以理解的。司法岛一战才告诉我们，恶魔之子Nico Robin正是可以读懂历史&lt;br /&gt;正文的最后一人。由此即将揭示的空白历史到底描述了什么呢？&lt;br /&gt;&lt;br /&gt;还有一些热度非常高的未解之谜：Luffy的父亲Dragon到底在进行什么样的事业，海贼王&lt;br /&gt;Roger投降的原因呢？恶魔果实的来源？&lt;br /&gt;&lt;br /&gt;漫画达到10年历程，我们还是被这样的迷题折腾的死去活来，这无疑让One Piece保持着神&lt;br /&gt;秘的美感，延续着它的青春和生命力。&lt;br /&gt;（革命家Dragon一切都是个迷）&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8VYDZjW2I/AAAAAAAABQ4/ddEof52ucA8/s1600-h/200px-Dragon2.jpg"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8VYDZjW2I/AAAAAAAABQ4/ddEof52ucA8/s320/200px-Dragon2.jpg" alt="" id="BLOGGER_PHOTO_ID_5255442793138183010" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;we&gt;6) &lt;span style="color: rgb(204, 0, 0);"&gt;最后，轻松搞笑的海贼王，仍旧具有深度和前瞻性。&lt;/span&gt;&lt;br /&gt;世界政府掩盖历史，无论如何，这都会让人联想到日本政府掩盖真相的事实。这个隐喻不言&lt;br /&gt;而喻，真正的历史是属于人类的，它们一定不会被抹杀。&lt;br /&gt;&lt;br /&gt;在尾田的笔下，人物焕发出来的精神和气质值得当代青年人学习：&lt;br /&gt;这里有Sanji表现出来的骑士精神，Zoro为梦想坚持不懈，永不言放弃，Usopp唯唯诺诺，需&lt;br /&gt;要不断超越自我，Brook作死守誓约的男人，Luffy重视朋友轻易，这一群爱理想的少年焕发&lt;br /&gt;出来的自由注意精神，永远值得我们称道！&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;对海贼王的问候&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;最后在十周年之际，向他们致以问候！&lt;br /&gt;&lt;br /&gt;Monkey D. Luffy，船长。没啥可说的。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJJM27LI/AAAAAAAABPQ/MymBvQuN0tg/s1600-h/250px-Monkey_D_Luffy.png"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJJM27LI/AAAAAAAABPQ/MymBvQuN0tg/s320/250px-Monkey_D_Luffy.png" alt="" id="BLOGGER_PHOTO_ID_5255438138951003314" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;三刀流 Roronoa Zoro，Zoro在OP世界里以传统职业——剑士的身份，通过苦行不断磨练自己，&lt;br /&gt;最终达到终极目标————打败世界第一剑客 Dracule Mihawk！&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJGXHCRI/AAAAAAAABPY/__JO1ctGSUg/s1600-h/230px-Roronoazoro2.jpg"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJGXHCRI/AAAAAAAABPY/__JO1ctGSUg/s320/230px-Roronoazoro2.jpg" alt="" id="BLOGGER_PHOTO_ID_5255438138188695826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;航海士 Nami，在地理位置复杂，气候恶劣的Grand Line，一位杰出的航海士将会是顺利航&lt;br /&gt;行的关键。清纯可爱的Nami对宝箱可是有着天生的直觉。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJsFkOyI/AAAAAAAABPg/F5W093elYyw/s1600-h/230px-Nami_face.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJsFkOyI/AAAAAAAABPg/F5W093elYyw/s320/230px-Nami_face.jpg" alt="" id="BLOGGER_PHOTO_ID_5255438148315659042" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;狙击手 Usopp，他用来完成远程狙击人物，在尾田的笔下，Usopp性格幽默，但身材柔弱，&lt;br /&gt;胆小怕事，这使得Usopp更加趋近于常人，形象具有警世的价值！&lt;br /&gt;值得一提的是，Usopp的声优是非常出名的山口胜平，你可以想象金田一，犬夜叉，怪盗基&lt;br /&gt;德，乱马……实乃声优界的超级大腕。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJqbBagI/AAAAAAAABPo/UUNpSzZAHCc/s1600-h/230px-Usopp_face.jpg"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJqbBagI/AAAAAAAABPo/UUNpSzZAHCc/s320/230px-Usopp_face.jpg" alt="" id="BLOGGER_PHOTO_ID_5255438147868781058" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;厨师 Sanji，在Sanji看来，没有什么比荒岛上饿肚子更加恶劣的体验了。平日里的Sanji，&lt;br /&gt;形象俊朗，见女士腿软，极富“骑士精神”。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJ7YaWxI/AAAAAAAABPw/RGBQbm-GMws/s1600-h/230px-Sanji2.jpg"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SO8RJ7YaWxI/AAAAAAAABPw/RGBQbm-GMws/s320/230px-Sanji2.jpg" alt="" id="BLOGGER_PHOTO_ID_5255438152421235474" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;医师 Tony Tony Chopper，队中唯一的一位动物角色，Chopper极富仁义的天性和羞怯可爱&lt;br /&gt;的性情，使得他胜任医生重要一职。为其献声的因为皮卡秋誉满全球的大谷育江。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8RgKSi82I/AAAAAAAABP4/if8Un5TxpbA/s1600-h/230px-Tony_Tony_Chopper.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8RgKSi82I/AAAAAAAABP4/if8Un5TxpbA/s320/230px-Tony_Tony_Chopper.jpg" alt="" id="BLOGGER_PHOTO_ID_5255438534380286818" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;恶魔之子 Nico Robin，通晓古文字的她可以破解“冥王”之谜，而她黑暗离奇的身世将会在&lt;br /&gt;司法岛章节揭开。从Miss All Sunday到草帽海贼团一员，尾田对于Robin花费了太多的手笔，&lt;br /&gt;Nico Robin 也是我个人最喜欢的动漫女性角色。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SO8RgPvcp8I/AAAAAAAABQA/KJlQYqH0nCs/s1600-h/230px-Robin_f.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SO8RgPvcp8I/AAAAAAAABQA/KJlQYqH0nCs/s320/230px-Robin_f.JPG" alt="" id="BLOGGER_PHOTO_ID_5255438535843686338" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;造船师 Franky，在水之都对草帽海贼团建造新船——万里阳光号，这无疑是给海贼团们进行&lt;br /&gt;了大换血。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8RgAlKBPI/AAAAAAAABQI/eUBk5nwup4I/s1600-h/230px-Franky_One_Piece2.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8RgAlKBPI/AAAAAAAABQI/eUBk5nwup4I/s320/230px-Franky_One_Piece2.jpg" alt="" id="BLOGGER_PHOTO_ID_5255438531773990130" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;音乐家 Brook，拥有88岁的年纪，他将是One Piece的第八个队员。Brook是一个借助恶魔果&lt;br /&gt;实保持生命的骷髅，他有着儒雅的风度，却保留了很龌龊的个性（喜欢问女孩子：可以看一&lt;br /&gt;下内裤吗……）。Brook的目标是绕行伟大航路一周，最后回到双子岬完成50年的约定。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SO8Rgc04ZII/AAAAAAAABQQ/mZJfKzcZ_9s/s1600-h/230px-Brook_Of_One_Piece.jpg"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SO8Rgc04ZII/AAAAAAAABQQ/mZJfKzcZ_9s/s320/230px-Brook_Of_One_Piece.jpg" alt="" id="BLOGGER_PHOTO_ID_5255438539356136578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;第一只船，黄金梅利号（Going Merry），这是来自Usopp相知相识的朋友Kaya赠送给草帽们&lt;br /&gt;的珍贵礼物。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8Rgc9tUSI/AAAAAAAABQY/g2IpqxOSJjw/s1600-h/Going_merry.png"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SO8Rgc9tUSI/AAAAAAAABQY/g2IpqxOSJjw/s320/Going_merry.png" alt="" id="BLOGGER_PHOTO_ID_5255438539393159458" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;we&gt;&lt;br /&gt;第二之船，万里阳光号（Thousand Sunny），在司法岛事件之后，Franky送给草帽海贼团一&lt;br /&gt;件大礼，借助自己无以伦比的造船工艺，新船具有更出色的性能，舒适的船舱和强大的功能。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8RkK-XrbI/AAAAAAAABQg/Pw7psY7I2S8/s1600-h/230px-Thousand_Sunny.jpg"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8RkK-XrbI/AAAAAAAABQg/Pw7psY7I2S8/s320/230px-Thousand_Sunny.jpg" alt="" id="BLOGGER_PHOTO_ID_5255438603283574194" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;we&gt;最后是大神尾田荣一郎，现年33岁。他的画风深受著名画家鸟山明的影响。&lt;br /&gt;&lt;/we&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8Tlg4BvhI/AAAAAAAABQo/-xnFvOQPxFM/s1600-h/oda1.png"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SO8Tlg4BvhI/AAAAAAAABQo/-xnFvOQPxFM/s320/oda1.png" alt="" id="BLOGGER_PHOTO_ID_5255440825365675538" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;OP十周年纪念！&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SO8Zyf2DuWI/AAAAAAAABRA/HZWiDwCofUs/s1600-h/10.jpg"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SO8Zyf2DuWI/AAAAAAAABRA/HZWiDwCofUs/s320/10.jpg" alt="" id="BLOGGER_PHOTO_ID_5255447645497047394" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;we&gt;-----------------&lt;br /&gt;引用：&lt;br /&gt;1. &lt;a href="http://jump.shueisha.co.jp/home.html"&gt;少年JUMP官方网站&lt;/a&gt;：&lt;br /&gt;2. wiki -- &lt;a href="http://en.wikipedia.org/wiki/onepiece"&gt;onepiece&lt;/a&gt;&lt;br /&gt;3. &lt;a href="http://comipress.com/article/2007/05/06/1923"&gt;The Rise and Fall of Weekly Shonen Jump&lt;/a&gt;:&lt;br /&gt;4. &lt;a href="http://www.j-onepiece.com/"&gt;OnePiece官方网站&lt;/a&gt;&lt;br /&gt;&lt;/we&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-7558645343738963578?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/7558645343738963578/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/we-are-on-cruise-onepiece.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7558645343738963578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/7558645343738963578'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/we-are-on-cruise-onepiece.html' title='We Are On The Cruise! -- OnePiece 十周年纪念'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Kb-lr4qFtj4/SO8Pfex3BjI/AAAAAAAABOw/2t4V_av8A9I/s72-c/OnePieceLogo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-1187963282294356094</id><published>2008-10-06T11:46:00.001+08:00</published><updated>2011-03-06T11:24:39.804+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>[TIC++] C9. Inline Functions</title><content type='html'>&lt;span style="font-weight: bold;font-size:180%;" &gt;代码阅读 &amp;lt;Thinking in C++&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Chapter 9. Inline Functions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、什么是Inline&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c09: macro_side_effects.cpp&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;#define BAND(x) (((x) &amp;gt; 5 &amp;amp;&amp;amp; (x) &amp;lt; 10) ? (x) : 0)&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    ofstream out("macro.out");&lt;br /&gt;//    assure(out, "macro.out");&lt;br /&gt;    for (int i = 4; i &amp;lt; 11; i++) {&lt;br /&gt;        int a = i;&lt;br /&gt;        out &amp;lt;&amp;lt; "a = " &amp;lt;&amp;lt; a &amp;lt;&amp;lt; endl &amp;lt;&amp;lt; "\t";&lt;br /&gt;        out &amp;lt;&amp;lt; "BAND(++a)" &amp;lt;&amp;lt; BAND(++a) &amp;lt;&amp;lt; endl;&lt;br /&gt;        out &amp;lt;&amp;lt; "\t a = " &amp;lt;&amp;lt; a &amp;lt;&amp;lt; endl;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;/* macro.out:&lt;br /&gt;a = 4&lt;br /&gt;    BAND(++a)0&lt;br /&gt;     a = 5&lt;br /&gt;a = 5&lt;br /&gt;    BAND(++a)8&lt;br /&gt;     a = 8&lt;br /&gt;a = 6&lt;br /&gt;    BAND(++a)9&lt;br /&gt;     a = 9&lt;br /&gt;a = 7&lt;br /&gt;    BAND(++a)10&lt;br /&gt;     a = 10&lt;br /&gt;a = 8&lt;br /&gt;    BAND(++a)0&lt;br /&gt;     a = 10&lt;br /&gt;a = 9&lt;br /&gt;    BAND(++a)0&lt;br /&gt;     a = 11&lt;br /&gt;a = 10&lt;br /&gt;    BAND(++a)0&lt;br /&gt;     a = 12&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;第一个例子，介绍了宏(macro)带来的负面效应。BAND(x)定义了一个三元运算符，C/C++中&lt;br /&gt;会对选择语句中的与运算和或运算进行优化，(x)&amp;gt;5为false之后，将不会考虑(x)&amp;lt;10，而自&lt;br /&gt;增运算符结合macro会产生预料之外的效果。&lt;br /&gt;&lt;br /&gt;为了消除奇异，避免此类情况发生，我们引入了内联方法——&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c09: inline.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;string&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Point {&lt;br /&gt;    int i, j, k;&lt;br /&gt;public:&lt;br /&gt;    Point(): i(0), j(0), k(0) {}&lt;br /&gt;    Point(int ii, int jj, int kk)&lt;br /&gt;        : i(ii), j(jj), k(kk) {}&lt;br /&gt;    void print(const string &amp;amp;msg = "") const&lt;br /&gt;        {&lt;br /&gt;            if (msg.size() != 0)&lt;br /&gt;                cout &amp;lt;&amp;lt; msg &amp;lt;&amp;lt; endl;&lt;br /&gt;            cout &amp;lt;&amp;lt; "i = " &amp;lt;&amp;lt; i &amp;lt;&amp;lt; ","&lt;br /&gt;                 &amp;lt;&amp;lt; "j = " &amp;lt;&amp;lt; j &amp;lt;&amp;lt; ","&lt;br /&gt;                 &amp;lt;&amp;lt; "k = " &amp;lt;&amp;lt; k &amp;lt;&amp;lt; endl;&lt;br /&gt;        }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    Point p, q(1,2,3);&lt;br /&gt;    p.print("value of p");&lt;br /&gt;    q.print("value of q");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这里和以前并没有什么异常，这证明人的习惯是很可怕的……我们要说的是，以前在类中定义&lt;br /&gt;的所有函数，都是内联函数(inline functions)。内联函数也只是存在于编译期内，编译的&lt;br /&gt;时候，编译器会打开内联函数的代码，直接迭代到调用处。他起到了宏的作用，而且避免了&lt;br /&gt;负面效用。&lt;br /&gt;&lt;br /&gt;考虑一下print(const string&amp;amp;)方法，如果没有内联，那么print代码本身就要将this指针&lt;br /&gt;放入堆栈，并且使用一次汇编语句CALL，大多数机器中，这段代码的长度会比内联展开的代&lt;br /&gt;码量要大，而且花费时间也会更长。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、使用内联&lt;/span&gt;&lt;br /&gt;这个例子包含了三个代码段stash4.h，stash4.cpp，stash4test.cpp。&lt;br /&gt;&lt;br /&gt;stash4.h&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c09: stash4.h&lt;br /&gt;// inline functions&lt;br /&gt;&lt;br /&gt;#ifndef __STASH4_H&lt;br /&gt;#define __STASH4_H&lt;br /&gt;&lt;br /&gt;class stash {&lt;br /&gt;    int size;&lt;br /&gt;    int quantity;&lt;br /&gt;    int next;&lt;br /&gt;    unsigned char *storage;&lt;br /&gt;    void inflate(int increase);&lt;br /&gt;public:&lt;br /&gt;    stash(int sz): size(sz), quantity(0), next(0), storage(0) {}&lt;br /&gt;    stash(int sz, int init_quantity): size(sz), quantity(0), next(0), storage(0)&lt;br /&gt;    {&lt;br /&gt;        inflate(init_quantity);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ~stash()&lt;br /&gt;    {&lt;br /&gt;        if (storage != 0)&lt;br /&gt;            delete []storage;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    void *fetch(int index) const&lt;br /&gt;    {&lt;br /&gt;        if (index &amp;gt;= next)&lt;br /&gt;            return 0;&lt;br /&gt;        return &amp;amp;(storage[index * size]);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // declarations of non-inline functions&lt;br /&gt;    int add(void *element);&lt;br /&gt;    int count() const { return next; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#endif // __STASH4_H&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;stash4.cpp&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c09: stash4.cpp&lt;br /&gt;#include "stash4.h"&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;cassert&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;const int increment = 100;&lt;br /&gt;&lt;br /&gt;int stash::add(void *element)&lt;br /&gt;{&lt;br /&gt;    if (next &amp;gt;= quantity)&lt;br /&gt;        inflate(increment);&lt;br /&gt;    int start_bytes = next * size;&lt;br /&gt;    unsigned char *e = (unsigned char*)element;&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &amp;lt; size; i++)&lt;br /&gt;        storage[start_bytes + i] = e[i];&lt;br /&gt;    next ++;&lt;br /&gt;    return(next -1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void stash::inflate(int increase)&lt;br /&gt;{&lt;br /&gt;    assert(increase &amp;gt;= 0);&lt;br /&gt;    if (increase == 0)&lt;br /&gt;        return;&lt;br /&gt;    int new_quantity = quantity + increase;&lt;br /&gt;    int new_bytes = new_quantity * size;&lt;br /&gt;    int old_bytes = quantity * size;&lt;br /&gt;    unsigned char *b = new unsigned char[new_bytes];&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &amp;lt; old_bytes; i++)&lt;br /&gt;        b[i] = storage[i];&lt;br /&gt;    delete [](storage);&lt;br /&gt;    storage = b;&lt;br /&gt;    quantity = new_quantity;&lt;br /&gt;}&lt;br /&gt;///:~&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;stash4test.cpp&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c09: stash4test.cpp&lt;br /&gt;#include "stash4.h"&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;string&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    stash int_stash(sizeof(int));&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &amp;lt; 100; i++)&lt;br /&gt;        int_stash.add(&amp;amp;i);&lt;br /&gt;    for (int j = 0; j &amp;lt; int_stash.count(); j++)&lt;br /&gt;        cout &amp;lt;&amp;lt; "int_stash.fetch(" &amp;lt;&amp;lt; j &amp;lt;&amp;lt; ") = "&lt;br /&gt;             &amp;lt;&amp;lt; *(int*)int_stash.fetch(j)&lt;br /&gt;             &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;br /&gt;    const int bufsize = 80;&lt;br /&gt;    stash string_stash(sizeof(char) * bufsize, 100);&lt;br /&gt;    ifstream in("stash4test.cpp");&lt;br /&gt;    string line;&lt;br /&gt;    while(getline(in, line))&lt;br /&gt;        string_stash.add((char*)line.c_str());&lt;br /&gt;&lt;br /&gt;    int k = 0;&lt;br /&gt;    char *cp;&lt;br /&gt;    while ((cp = (char*)string_stash.fetch(k++)) != 0)&lt;br /&gt;        cout &amp;lt;&amp;lt; "string_stash.fetch(" &amp;lt;&amp;lt; k &amp;lt;&amp;lt; ") = "&lt;br /&gt;             &amp;lt;&amp;lt; cp &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;/* result: 结果中途省略&lt;br /&gt;int_stash.fetch(0) = 0&lt;br /&gt;int_stash.fetch(1) = 1&lt;br /&gt;int_stash.fetch(2) = 2&lt;br /&gt;int_stash.fetch(3) = 3&lt;br /&gt;...&lt;br /&gt;int_stash.fetch(98) = 98&lt;br /&gt;int_stash.fetch(99) = 99&lt;br /&gt;string_stash.fetch(1) = // c09: stash4test.cpp&lt;br /&gt;string_stash.fetch(2) = #include "stash4.h"&lt;br /&gt;string_stash.fetch(3) = #include &amp;lt;fstream&amp;gt;&lt;br /&gt;string_stash.fetch(4) = #include &amp;lt;iostream&amp;gt;&lt;br /&gt;string_stash.fetch(5) = #include &amp;lt;string&amp;gt;&lt;br /&gt;string_stash.fetch(6) = using namespace std;&lt;br /&gt;string_stash.fetch(7) =&lt;br /&gt;string_stash.fetch(8) = int main()&lt;br /&gt;string_stash.fetch(9) = {&lt;br /&gt;...&lt;br /&gt;string_stash.fetch(31) = }&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;stash中的简单方法在这里用到了inline，他们更加的高效和简洁。但也要留意两个最大的&lt;br /&gt;方法在外部被定义，这样他们就不是inline方法，因为这样作不会带来任何效益。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;三、向前引用特性&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c09: evaluation_order.cpp&lt;br /&gt;// inline evaluation order&lt;br /&gt;&lt;br /&gt;class forward {&lt;br /&gt;    int i;&lt;br /&gt;public:&lt;br /&gt;    forward(): i(0) {}&lt;br /&gt;    // call undeclared function&lt;br /&gt;    int f() const { return g() + 1; }&lt;br /&gt;    int g() const { return 1; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    forward fwd;&lt;br /&gt;    fwd.f();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;注意到，f()在g()声明或者定义之前调用了g()，这在inline函数世界里变得可能了。&lt;br /&gt;_&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-1187963282294356094?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/1187963282294356094/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c9-inline-functions.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1187963282294356094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1187963282294356094'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c9-inline-functions.html' title='[TIC++] C9. Inline Functions'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-93444602245769661</id><published>2008-10-05T10:30:00.003+08:00</published><updated>2011-03-06T11:24:39.809+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>[TIC++] C8. Constants</title><content type='html'>&lt;span style="font-weight: bold;font-size:180%;" &gt;代码阅读&amp;lt;Thinking in C++&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Chapter 8. constants&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、介绍常量&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//safecons.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;const int i = 100;&lt;br /&gt;const int j = i + 10;&lt;br /&gt;long address = (long)&amp;j;&lt;br /&gt;char buf[j + 10];&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;   cout &amp;lt;&amp;lt; "type a character &amp;amp; CR: ";&lt;br /&gt;   const char c  = cin.get();&lt;br /&gt;   const char c2 = c + 'a';&lt;br /&gt;   cout &amp;lt;&amp;lt; c2 &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;1. 宏，它只存在于预编译期(preprocessing)，不占据内存空间，不包含类型信息。&lt;br /&gt;2. 常量，也在编译期被翻译。通常情况下默认为内部链接，并且不会为const分配内存。这&lt;br /&gt;被称为const folding原则。但是这个原则在很多情况下会被打破。&lt;br /&gt;  特例有很多，主要一点就是常量的外部引用。比如extern声明会强制建立外部链接，这&lt;br /&gt;要求修饰的const也要提供地址（内存空间所在位置）。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、常量遭遇指针&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: const_pointer.cpp&lt;br /&gt;const int *u;               // pointer to const int, init not required&lt;br /&gt;int const *v;               // still pointer to const int!&lt;br /&gt;int d = 1;&lt;br /&gt;int * const w = &amp;d;         // const pointer&lt;br /&gt;const int * const x  = &amp;d;  // const pointer to const object&lt;br /&gt;int const * const x2 = &amp;d;&lt;br /&gt;&lt;br /&gt;int main(void){}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;指针也可以被声明常量，这里带来两个歧义：一个是指针指向的东西被声明常量(pointer&lt;br /&gt;to const)；另一个是指针包含的地址本身被定义为常量(const pointer)。&lt;br /&gt;上面的例子就列举了两种定义，还有另外指向常量的常量指针。&lt;br /&gt;1) 指向常量的指针(`const*')&lt;br /&gt;  可以不被初始化&lt;br /&gt;2) 常量型指针(`*const')&lt;br /&gt;  必须初始化&lt;br /&gt;3) 指向常量的常量指针(`const * const')&lt;br /&gt;  必须初始化&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: pointer_assignment.cpp&lt;br /&gt;int d = 1;&lt;br /&gt;const int e = 2;&lt;br /&gt;int *u = &amp;d;&lt;br /&gt;//! int *v = &amp;e;   // illegal -- a const&lt;br /&gt;int *w = (int*)&amp;e; // legal but bad practice&lt;br /&gt;&lt;br /&gt;int main(){}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这里举例说明了指针赋值。&lt;br /&gt;1. 常量不可以再被非常量直接引用(指针和引用均不可以)。&lt;br /&gt;2. 但是他可以被强制转换，转换的安全性需要程序员负责。&lt;br /&gt;3. 不可以在文件域内部对指向常量指针赋值（p2c，cp都不行）&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;三、常量返回值 return consts by value&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: constval.cpp&lt;br /&gt;// return consts by value&lt;br /&gt;// has no meaning for built-in type&lt;br /&gt;int f3() { return 1;}&lt;br /&gt;const int f4() { return 1;}&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;   const int j = f3(); // Works fine&lt;br /&gt;   int k = f4();       // But this works fine too!&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;原子类型之间的赋值，只是拷贝，勿需考虑常量情况。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: const_return_values.cpp&lt;br /&gt;// const return by value&lt;br /&gt;// result cannot be used as an lvalue&lt;br /&gt;&lt;br /&gt;class X {&lt;br /&gt;   int i;&lt;br /&gt;public:&lt;br /&gt;   X(int ii = 0);&lt;br /&gt;   void modify();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;X::X(int ii)&lt;br /&gt;{&lt;br /&gt;   i = ii;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void X::modify()&lt;br /&gt;{&lt;br /&gt;   i++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;X f5()&lt;br /&gt;{&lt;br /&gt;   return X();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;const X f6()&lt;br /&gt;{&lt;br /&gt;   return X();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void f7(const X&amp;amp; x) // pass non-const reference&lt;br /&gt;{&lt;br /&gt;   x.modify();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   f5() = X(1);&lt;br /&gt;   f5().modify();&lt;br /&gt;   // compile-time error&lt;br /&gt;//!    f6() = X(1);&lt;br /&gt;//!    f6().modify();&lt;br /&gt;//!    f7(f5());&lt;br /&gt;//!    f7(f6());        // 29&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;将返回值定义为常量，这对于原子类型来说没有意义。而在自定义类型中，却有很大不同。&lt;br /&gt;NOTE!&lt;br /&gt;如果函数返回一个常量类型的类对象，那么返回的值将不能成为左值（不可被定义和修改）。&lt;br /&gt;而原子类型本身就不能成为左值，所以返回常量原子类型是无意义的。&lt;br /&gt;f5()返回了非常量型，而f6()返回的是常量型的类对象，因此f6()的赋值和修改都是非法的&lt;br /&gt;（f6不可以作为左值）。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;四、传递和返回地址 passing and returning addresses&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: const_pointer2.cpp&lt;br /&gt;&lt;br /&gt;void t(int*) {}&lt;br /&gt;&lt;br /&gt;void u(const int *cip)&lt;br /&gt;{&lt;br /&gt;//!    *cip = 2; // illegal -- modifies value&lt;br /&gt;   int i = *cip; // OK -- copies value&lt;br /&gt;//!    int *ip2 = cip; // illegal: non-const&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;const char *v()&lt;br /&gt;{&lt;br /&gt;   // return address of a static array&lt;br /&gt;   return "result of function v()";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;const int * const w()&lt;br /&gt;{&lt;br /&gt;   static int i;&lt;br /&gt;   return &amp;i;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   int x = 0;&lt;br /&gt;   int *ip = &amp;x;&lt;br /&gt;   const int *cip = &amp;x;&lt;br /&gt;&lt;br /&gt;   // passing addresses&lt;br /&gt;   t(ip);  // non-const* to non-const*&lt;br /&gt;//!    t(cip); // const*     to non-const*&lt;br /&gt;   u(ip);  // non-const* to const*&lt;br /&gt;   u(cip); // const*     to const*&lt;br /&gt;&lt;br /&gt;   // returning addresses&lt;br /&gt;//!    char *cp = v();         // const* to non-const*, not OK&lt;br /&gt;   const char * ccp = v(); // const* to const*&lt;br /&gt;//!    int *ip2 = w();         // const* to non-const*, not OK!&lt;br /&gt;   const int * const ccip = w(); // const* to const*&lt;br /&gt;   const int * cip2 = w();&lt;br /&gt;//!    *w() = 1; // modify consts, not OK&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;无论是传递地址，还是返回地址。从const*到non-const*的传递（或赋值）都是被禁止的，&lt;br /&gt;而如果选择将const转换为non-const，则需要确保转换的安全性。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;五、常量成员的初始化&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: const_init.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Fred {&lt;br /&gt;   const int size;&lt;br /&gt;public:&lt;br /&gt;   Fred(int sz);&lt;br /&gt;   void print();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Fred::Fred(int sz) : size(sz) {}&lt;br /&gt;void Fred::print() { cout &amp;lt;&amp;lt; size &amp;lt;&amp;lt; endl; }&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   Fred a(1), b(2), c(3);&lt;br /&gt;&lt;br /&gt;   a.print(), b.print(), c.print();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这里展示了构造方法的初始化列表的用法。形如：&lt;br /&gt;   Fred::Fred(int sz) : size(sz) {}&lt;br /&gt;函数列表括弧后的单位就是，常量初始化的地方。唯有这里可以将类中定义的常量成员初始&lt;br /&gt;化，实际上，他们是在进入函数体之前就进行了初始化。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;六、const 成员遭遇 static&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: string_stack.cpp&lt;br /&gt;// using static const to create a compile-time constant&lt;br /&gt;// inside a class&lt;br /&gt;#include &amp;lt;cstring&amp;gt;&lt;br /&gt;#include &amp;lt;string&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class string_stack {&lt;br /&gt;   static const int size = 100; // a static constant&lt;br /&gt;   const string *stack[size];&lt;br /&gt;   int index;&lt;br /&gt;public:&lt;br /&gt;   string_stack();&lt;br /&gt;   void push(const string *s);&lt;br /&gt;   const string *pop();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;string_stack::string_stack():index(0)&lt;br /&gt;{&lt;br /&gt;   memset(stack, 0, size * sizeof(string*));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void string_stack::push(const string *s)&lt;br /&gt;{&lt;br /&gt;   if (index &amp;lt; size)&lt;br /&gt;       stack[index++] = s;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;const string *string_stack::pop()&lt;br /&gt;{&lt;br /&gt;   if (index &amp;gt; 0) {&lt;br /&gt;       const string *rv = stack[--index];&lt;br /&gt;       stack[index] = 0;&lt;br /&gt;       return rv;&lt;br /&gt;   }&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;const string icecream[] = {&lt;br /&gt;   "pralines &amp;amp; cream",&lt;br /&gt;   "fudge ripple",&lt;br /&gt;   "jamocha almond fudge",&lt;br /&gt;   "wild mountain blackberry",&lt;br /&gt;   "raspberry sortbet",&lt;br /&gt;   "lemon swirl",&lt;br /&gt;   "rocky road",&lt;br /&gt;   "deep chocolate fudge"&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;const int icsz = sizeof(icecream) / sizeof(*icecream);&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   string_stack ss;&lt;br /&gt;   for(int i = 0; i &amp;lt; icsz; i++)&lt;br /&gt;       ss.push(&amp;amp;icecream[i]);&lt;br /&gt;   const string *cp;&lt;br /&gt;   while((cp = ss.pop()) != 0)&lt;br /&gt;       cout &amp;lt;&amp;lt; *cp &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这里展示了C++ string的强大与方便。但是更重要的是，解释了compile-time constants的&lt;br /&gt;用法。&lt;br /&gt;static类成员意味着，无论用此类建立多少个对象，static成员实例都只会存在一个。&lt;br /&gt;另外static const的特性要求，static const常量(原子型)必须在定义位置初始化。&lt;br /&gt;&lt;br /&gt;从例子中可以看到，push持有const string*参数，pop()则返回const string*，还有&lt;br /&gt;string_stack包含了一个const string*成员。这看来像一个锁链一样，一环套一环。&lt;br /&gt;stack_stack包含const string *stack[]，这要求在pop():&lt;br /&gt;* 中间赋值必须用const传递, const string *rv;&lt;br /&gt;* 返回值类型必须是const.&lt;br /&gt;&lt;br /&gt;const string *icecream也要求push():&lt;br /&gt;* 持有const参数&lt;br /&gt;&lt;br /&gt;三个const约定了字符串以const形式亚栈，而除了push和pop以外，你再也无法更改&lt;br /&gt;成员*stack[]。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;七、const 成员方法&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: const_member.cpp&lt;br /&gt;class X {&lt;br /&gt;   int i;&lt;br /&gt;public:&lt;br /&gt;   X(int ii);&lt;br /&gt;   int f() const; // const member func&lt;br /&gt;   int g();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;X::X(int ii): i(ii) {}&lt;br /&gt;int X::f() const { return i;}&lt;br /&gt;int X::g() {}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   X x1(10);&lt;br /&gt;   const X x2(20);&lt;br /&gt;&lt;br /&gt;   x1.f();&lt;br /&gt;   x2.f();&lt;br /&gt;//!    x2.g(); // discards qualifiers&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;const成员方法，将会告诉编译器，他可以被常量对象调用。而没有被申明常量的方法，将&lt;br /&gt;不可以被常量对象调用！&lt;br /&gt;&lt;br /&gt;const成员方法和const函数(const func)有本质不同：&lt;br /&gt;* const func 是返回一个常量值。&lt;br /&gt;* func const 则是表明此成员方法可以被常量对象调用。他的使用方法是：&lt;br /&gt;&lt;br /&gt;为了强调const方法，编译器强迫在const成员方法的声明和定义处都要加上const。&lt;br /&gt;&lt;br /&gt;接下来细细观察const成员方法和普通成员方法的不同——&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: quoter.cpp&lt;br /&gt;// random quote selection&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;cstdlib&amp;gt;&lt;br /&gt;#include &amp;lt;ctime&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class quoter {&lt;br /&gt;   int lastquote;&lt;br /&gt;public:&lt;br /&gt;   quoter();&lt;br /&gt;   int get_lastquote() const; // const member func&lt;br /&gt;   const char *quote(); // member func which returns a const pointer&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;quoter::quoter()&lt;br /&gt;{&lt;br /&gt;   lastquote = -1;&lt;br /&gt;   srand(time(0));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int quoter::get_lastquote() const&lt;br /&gt;{&lt;br /&gt;   return lastquote;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;const char *quoter::quote()&lt;br /&gt;{&lt;br /&gt;   static const char *quotes[] = {&lt;br /&gt;       "Are we having fun yet?",&lt;br /&gt;       "Doctors always know best",&lt;br /&gt;       "Is it ... Atomic?",&lt;br /&gt;       "Fear is obscene",&lt;br /&gt;       "There is scientific evidence "&lt;br /&gt;       "to support the idea "&lt;br /&gt;       "that life is serious",&lt;br /&gt;       "Things that make us happy, make us wise",&lt;br /&gt;   };&lt;br /&gt;   const int qsize = sizeof quotes / sizeof *quotes;&lt;br /&gt;   int qnum = rand() % qsize;&lt;br /&gt;&lt;br /&gt;   while (lastquote &amp;gt;=0 &amp;amp;&amp;amp; qnum == lastquote)&lt;br /&gt;       qnum = rand() % qsize;&lt;br /&gt;   return quotes[lastquote = qnum];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   quoter q;&lt;br /&gt;   const quoter cq;&lt;br /&gt;&lt;br /&gt;   cq.get_lastquote();&lt;br /&gt;//!    cq.quote(); // 常量型对象无法调用非常量型成员方法&lt;br /&gt;   for (int i = 0; i &amp;lt; 20; i++)&lt;br /&gt;       cout  &amp;lt;&amp;lt; q.quote() &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这里比较了const对象和普通对象处理的区别，另外揭示了const成员方法的条件：&lt;br /&gt;如果成员方法体内更改了数据成员，那么它就不能声明为const。&lt;br /&gt;&lt;br /&gt;比如const char *quoter::quote()更改了成员 lastquote（return语句），它将不能声明&lt;br /&gt;为const；而int quoter::get_lastquote()则没有动，他就可以成为const成员方法，而且&lt;br /&gt;可以被常量对象cq安全调用。&lt;br /&gt;&lt;br /&gt;如果我确实声明了const成员方法，我又确实想更改类成员，我该如何是好？&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;八、bitwise vs. logical const&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: castaway.cpp&lt;br /&gt;class Y {&lt;br /&gt;   int i;&lt;br /&gt;public:&lt;br /&gt;   Y();&lt;br /&gt;   void f() const;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Y::Y(): i(0) {}&lt;br /&gt;&lt;br /&gt;void Y::f() const&lt;br /&gt;{&lt;br /&gt;   //! i++;&lt;br /&gt;   ((Y*)this)-&amp;gt;i++;&lt;br /&gt;   // Better: use C++ explicit cast syntax:&lt;br /&gt;   (const_cast&amp;lt;Y*&amp;gt;(this))-&amp;gt;i++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   const Y yy;&lt;br /&gt;   yy.f();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;bitwise const意思是说，此对象的每一数据比特都是永久不可变的，这样它的任何一部分&lt;br /&gt;都不可改变；而logical const意思是，虽然从概念上说整个对象不可改变，但是可以从成&lt;br /&gt;员基础上更改它本身。&lt;br /&gt;这其实是编译器给const定义的两面性，一方面编译器小心翼翼地确保const对象是bitwise&lt;br /&gt;的，另一方面，它又提供两个路径来通过_const成员函数_来更改数据成员。&lt;br /&gt;&lt;br /&gt;以上就是第一个：转换掉const属性。无论是C还是C++语法，都一样可行。&lt;br /&gt;这样带来的一个问题就是，你无法确认你的更改是否有效。。。&lt;br /&gt;&lt;br /&gt;于是提供了第二个方法：&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: mutable.cpp&lt;br /&gt;class Z {&lt;br /&gt;private:&lt;br /&gt;   int i;&lt;br /&gt;   mutable int j;&lt;br /&gt;public:&lt;br /&gt;   Z();&lt;br /&gt;   void f() const;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Z::Z(): i(0), j(0) {}&lt;br /&gt;&lt;br /&gt;void Z::f() const&lt;br /&gt;{&lt;br /&gt;   //! i++; // error - const mem func&lt;br /&gt;   j++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   const Z zz;&lt;br /&gt;   zz.f();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;mutable 关键词告诉编译器，被定义为mutable的数据成员，在const成员方法内仍旧可以更&lt;br /&gt;改。相对转型，显然mutable更加优雅一点。&lt;br /&gt;&lt;br /&gt;TIC++也提到了只读属性（ROMability），如何指导编译器把const对象放到只读内存中呢？&lt;br /&gt;这个条件比较复杂，任何可以改写数据成员的可能都会阻止只读化：&lt;br /&gt;1) 不包含logical const特性（不能有mutable关键词，也不能有const转型）&lt;br /&gt;2) class或者struct不可以包含任何自定义构造和析构方法&lt;br /&gt;3) 也不可以包含有自定义构造和析构方法的超类和成员对象（子类没有限制）&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;九、volatile和类&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// c08: volatile.cpp&lt;br /&gt;&lt;br /&gt;class comm {&lt;br /&gt;   const volatile unsigned char byte;&lt;br /&gt;   volatile unsigned char flag;&lt;br /&gt;   enum { bufsize = 100 };&lt;br /&gt;   unsigned char buf[bufsize];&lt;br /&gt;   int index;&lt;br /&gt;public:&lt;br /&gt;   comm();&lt;br /&gt;   void isr() volatile;&lt;br /&gt;   char read(int index) const;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;comm::comm(): index(0), byte(0), flag(0) {}&lt;br /&gt;&lt;br /&gt;// only a demo; won't actually work as an interrupt service routine:&lt;br /&gt;void comm::isr() volatile&lt;br /&gt;{&lt;br /&gt;   flag = 0;&lt;br /&gt;   buf[index++] = byte;&lt;br /&gt;   if (index &amp;gt;= bufsize)&lt;br /&gt;       index = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;char comm::read(int index) const&lt;br /&gt;{&lt;br /&gt;   if (index &amp;lt; 0 || index &amp;gt;= bufsize)&lt;br /&gt;       return 0;&lt;br /&gt;   return buf[index];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   volatile comm port;&lt;br /&gt;   port.isr(); // OK&lt;br /&gt;//!    port.read(0); // Error, read() not volatile&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;volatile关键字和const是极其相似的修饰词，只不过他们的意义不同。&lt;br /&gt;通常情况下，编译器会告诉我们：我把此数据读入到了寄存器，但我保证不会再去碰它。下&lt;br /&gt;次需要读取此变量，直接从寄存器中读取即可（而不需要到内存中寻找）。&lt;br /&gt;而volatile告诉编译器：这个数据成员的活动，将会超过编译器的理解范围。如果需要读取&lt;br /&gt;此数据，不要尝试从寄存器中取值，因为内存和寄存器可能已经出现了不同步。&lt;br /&gt;&lt;br /&gt;同const一样，volatile对象也只能调用volatile成员方法。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;十、总结&lt;/span&gt;&lt;br /&gt;const一章的例子比其他章节要多，原因是const类型在C++中遇到了多种繁杂的情况，而且&lt;br /&gt;他们也表现出来各自的特性。总结来说，我们探讨了以下情况：&lt;br /&gt;&lt;br /&gt;* 原子类型申明为const（这里也讨论了const*和*const）&lt;br /&gt; const声明意味着，这意味着该内存为只读属性。const存在于编译期，通常情况下默认为&lt;br /&gt; 内部链接，并且不会为const分配内存，这被称为const folding原则。const类型的局部&lt;br /&gt; 标识符必须在定义时候初始化。&lt;br /&gt; const指针包括了指向常量的指针(const*)和常指针(*const)，const*可以选择是否初始&lt;br /&gt; 化，但是他不可以显性修改指针指向的内存(*x = y illegal)；*const不可以修改指针&lt;br /&gt; 本身((int*)a = (int*)b illegal)。&lt;br /&gt;&lt;br /&gt;* 返回值为const&lt;br /&gt; const返回值将不可作为左值，赋值修改都是非法的。而作为右值时候，const返回值的左&lt;br /&gt; 值必须为const，const到non-const的传递和赋值都是非法的。&lt;br /&gt;&lt;br /&gt;* 传递参数为const&lt;br /&gt; const到non-const的传递仍旧是非法的。要切记这一规则。&lt;br /&gt;&lt;br /&gt;* 成员数据为const&lt;br /&gt; const成员数据不可以在普通成员方法中更改。这里也给出了特例（const_init.cpp）：&lt;br /&gt; 使用构造方法的初始化列表来完成常量数据成员的初始化。&lt;br /&gt;&lt;br /&gt;* 成员数据为static const&lt;br /&gt; static说明所有的成员实例都会共享一个static数据成员。static const额外要求必须在&lt;br /&gt; 定义位置实现初始化。&lt;br /&gt;&lt;br /&gt;* 成员方法为const&lt;br /&gt; 首先，一个const成员方法将永远不会更改类的数据成员。&lt;br /&gt; 再次，声明为const的成员方法允许被const对象调用，而普通成员方法是不允许调用的。&lt;br /&gt;&lt;br /&gt;* 对象为const&lt;br /&gt; const对象表现出两个特性，一个是表面上他的整体不可改变（bitwise const）,另一个&lt;br /&gt; 则是通过某些特殊方法实现更改（logical const）。&lt;br /&gt; logical const的实现有两种方法，一个在const成员方法使用强制类型转换&lt;br /&gt; （castaway.cpp），另一个是在类定义中给想要修改的值添加mutable修饰词&lt;br /&gt; （mutable.cpp）。&lt;br /&gt;_&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-93444602245769661?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/93444602245769661/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c8-constants.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/93444602245769661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/93444602245769661'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c8-constants.html' title='[TIC++] C8. Constants'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2632489744230746716</id><published>2008-10-04T10:35:00.005+08:00</published><updated>2011-03-06T11:24:39.814+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>[TIC++] C7. Function Overloading and Default Arguments</title><content type='html'>&lt;span style="font-weight: bold;font-size:180%;" &gt;代码阅读&amp;lt;Thinking in C++&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Chapter 7. Function Overloading and Default Arguments&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、C++中的union&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//unionclass.cpp&lt;br /&gt;#include &lt;iostream&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;union u {&lt;br /&gt;private:&lt;br /&gt;   int i;&lt;br /&gt;   float f;&lt;br /&gt;public:&lt;br /&gt;   u(int a);&lt;br /&gt;   u(float b);&lt;br /&gt;   ~u();&lt;br /&gt;   int read_int();&lt;br /&gt;   float read_float();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;u::u(int a)&lt;br /&gt;{&lt;br /&gt;   i = a;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;u::u(float b)&lt;br /&gt;{&lt;br /&gt;   f = b;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;u::~u(void)&lt;br /&gt;{&lt;br /&gt;   cout &lt;&lt; "u::~u()\n"; }  int u::read_int(void) {     return i; }  float u::read_float(void) {     return f; }  int main(void) {     u X(12), Y(1.9F);     cout &lt;&lt;&gt;&lt;/pre&gt;&lt;br /&gt;这个例子展示了union的用法。union仍就是C++的关键词，union也和class一样，他也可以&lt;br /&gt;有constructor，destructor，成员方法甚至访问控制。&lt;br /&gt;union和class的不同之处在于：&lt;br /&gt;1. union含有独特的数据存储方式。&lt;br /&gt;2. union不能被继承，这也是由特性1决定的。这使得它在C++里无法大展身手。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、匿名union&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//supervar.cpp&lt;br /&gt;#include &lt;iostream&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class supervar {&lt;br /&gt;   enum {&lt;br /&gt;       character,&lt;br /&gt;       integer,&lt;br /&gt;       floating_point,&lt;br /&gt;   } vartype;&lt;br /&gt;   union {            // anonymous union&lt;br /&gt;       char c;&lt;br /&gt;       int i;&lt;br /&gt;       float f;&lt;br /&gt;   };&lt;br /&gt;public:&lt;br /&gt;   supervar(char ch);&lt;br /&gt;   supervar(int ii);&lt;br /&gt;   supervar(float ff);&lt;br /&gt;   void print();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;supervar::supervar(char ch)&lt;br /&gt;{&lt;br /&gt;   vartype = character;&lt;br /&gt;   c = ch;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;supervar::supervar(int ii)&lt;br /&gt;{&lt;br /&gt;   vartype = integer;&lt;br /&gt;   i = ii;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;supervar::supervar(float ff)&lt;br /&gt;{&lt;br /&gt;   vartype = floating_point;&lt;br /&gt;   f = ff;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void supervar::print(void)&lt;br /&gt;{&lt;br /&gt;   switch (vartype) {&lt;br /&gt;   case character:&lt;br /&gt;       cout &lt;&lt; "character: " &lt;&lt;&gt;&lt;/pre&gt;&lt;br /&gt;1. class supervar定义了一个enum类型，但是没有给此类型标注类型名。因为他只是用此&lt;br /&gt;enum定义了一个变量实例vartype.&lt;br /&gt;2. class supervar定义了一个union类型成员，这是一个匿名union(anonymous union)，这&lt;br /&gt;样在此类的成员中应用union成员，将不必使用成员操作符`.'。&lt;br /&gt;  如果匿名union定义在文件类型，_一定_要声明为static，这样他就有了内部链接。&lt;br /&gt;_&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2632489744230746716?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2632489744230746716/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c7-function-overloading-and-default.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2632489744230746716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2632489744230746716'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/tic-c7-function-overloading-and-default.html' title='[TIC++] C7. Function Overloading and Default Arguments'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-1627496774559083506</id><published>2008-10-02T22:09:00.006+08:00</published><updated>2011-03-17T16:20:56.399+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>国庆第二天-疯狂的南山巡游</title><content type='html'>国庆到达第二天了，没有能出去爬山，也没有太多能力腐败了。想起酝酿许久的自行车旅&lt;br /&gt;行，觉得今天真是个好日子。曾胖花费￥1400的自行车，多好的条件，于是立刻出发！&lt;br /&gt;&lt;br /&gt;地图路线：&lt;br /&gt;&lt;a href="http://maps.google.com/maps/ms?ie=UTF&amp;amp;msa=0&amp;amp;msid=102563878911537749872.0004584479d8054cb6ac0"&gt;http://maps.google.com/maps/ms?ie=UTF&amp;amp;msa=0&amp;amp;msid=102563878911537749872.0004584479d8054cb6ac0&lt;/a&gt;&lt;br /&gt;（注意卫星地图和交通图是不一致的，选择卫星地图）&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOTbHBXOUcI/AAAAAAAABLQ/mjvojck9M2k/s1600-h/google-maps-1002.jpg"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOTbHBXOUcI/AAAAAAAABLQ/mjvojck9M2k/s320/google-maps-1002.jpg" alt="" id="BLOGGER_PHOTO_ID_5252563979092251074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;首先从大新居委会出发，西转到深圳西车站，然后顺着月亮湾大道南下。沿途大部分交通工&lt;br /&gt;具都是货车，在港湾和机场之间来回。不过一会，就来到南山区的西南角——妈湾。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SOTXgxsgMUI/AAAAAAAABKA/chlQLr9HWzc/s1600-h/IMG_3407.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SOTXgxsgMUI/AAAAAAAABKA/chlQLr9HWzc/s320/IMG_3407.JPG" alt="" id="BLOGGER_PHOTO_ID_5252560023516623170" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOTXhJM1AEI/AAAAAAAABKI/bL0Yj0JWlIE/s1600-h/IMG_3409.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOTXhJM1AEI/AAAAAAAABKI/bL0Yj0JWlIE/s320/IMG_3409.JPG" alt="" id="BLOGGER_PHOTO_ID_5252560029826220098" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;接着从妈湾东转到赤湾，这一带是集装箱盛集的地方。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SOTXhdYWBLI/AAAAAAAABKQ/XQ5nLok1DXw/s1600-h/IMG_3414.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SOTXhdYWBLI/AAAAAAAABKQ/XQ5nLok1DXw/s320/IMG_3414.JPG" alt="" id="BLOGGER_PHOTO_ID_5252560035243230386" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOTXhsvwdfI/AAAAAAAABKY/FPTGEbOMj1I/s1600-h/IMG_3415.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOTXhsvwdfI/AAAAAAAABKY/FPTGEbOMj1I/s320/IMG_3415.JPG" alt="" id="BLOGGER_PHOTO_ID_5252560039367964146" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;然后来到赤湾岛部分，伸出的小岛部分被集装箱覆盖。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SOTXiMKcfmI/AAAAAAAABKg/gFTxUl-cZds/s1600-h/IMG_3421.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SOTXiMKcfmI/AAAAAAAABKg/gFTxUl-cZds/s320/IMG_3421.JPG" alt="" id="BLOGGER_PHOTO_ID_5252560047801400930" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SOTZo1nBjEI/AAAAAAAABKo/4WPDbDO-3RI/s1600-h/IMG_3427.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SOTZo1nBjEI/AAAAAAAABKo/4WPDbDO-3RI/s320/IMG_3427.JPG" alt="" id="BLOGGER_PHOTO_ID_5252562361029594178" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;然后进入到赤湾村，我在深圳不知道曾经坐过多少次226和204，这次就来到他们的终点站——&lt;br /&gt;赤湾。赤湾的景点，最出名的就是宋少帝陵。&lt;br /&gt;引自&lt;a href="http://baike.baidu.com/view/1692996.html?tp=1_11"&gt;百度百科&lt;/a&gt;：宋少帝陵位于蛇口赤湾，是广东省境内仅有的黄陵。1278年蒙古入侵，南宋&lt;br /&gt;王朝败退至广东新会，爆发"崖海大战"．南宋政权军队被歼始尽，危急关头，宰相陆秀夫背&lt;br /&gt;负仅８岁的少帝跳海殉国．少帝陵处还有陆秀夫背帝的石像．&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOTZo0POQqI/AAAAAAAABKw/0QahnYfAlAk/s1600-h/IMG_3425.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOTZo0POQqI/AAAAAAAABKw/0QahnYfAlAk/s320/IMG_3425.JPG" alt="" id="BLOGGER_PHOTO_ID_5252562360661328546" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;经过兴海大道，蛇口港，终于来到海上世界。&lt;br /&gt;曾经在07年的时候，我曾经赴海上世界参加百度贴吧深圳吧的聚会，认识了大熊，老男人，&lt;br /&gt;大黄等人。跟着一帮人混达了很长时间，现在大家都是常聚的好友了。因此海上世界是一个&lt;br /&gt;非常有意义的地方，让我想起了一年前的那个时侯。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SOTZpHNHWRI/AAAAAAAABK4/QYoPp5J3Mj8/s1600-h/IMG_3431.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SOTZpHNHWRI/AAAAAAAABK4/QYoPp5J3Mj8/s320/IMG_3431.JPG" alt="" id="BLOGGER_PHOTO_ID_5252562365752760594" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOTZpZQc-kI/AAAAAAAABLA/visKvp-PoCc/s1600-h/IMG_3429.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOTZpZQc-kI/AAAAAAAABLA/visKvp-PoCc/s320/IMG_3429.JPG" alt="" id="BLOGGER_PHOTO_ID_5252562370598599234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;傍晚时候沿着南海大道狂奔。由于夜色降临，路途急忙，没能拍到照片，敬请见谅。今日行&lt;br /&gt;程也告一段落。&lt;br /&gt;&lt;br /&gt;最后给第二主角露一小脸。祝愿大家开心！~&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOTZprRoqXI/AAAAAAAABLI/hccYUkpdD1o/s1600-h/IMG_3417.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOTZprRoqXI/AAAAAAAABLI/hccYUkpdD1o/s320/IMG_3417.JPG" alt="" id="BLOGGER_PHOTO_ID_5252562375435397490" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;_&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-1627496774559083506?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/1627496774559083506/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_02.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1627496774559083506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1627496774559083506'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/10/blog-post_02.html' title='国庆第二天-疯狂的南山巡游'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOTbHBXOUcI/AAAAAAAABLQ/mjvojck9M2k/s72-c/google-maps-1002.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-6878744732805580712</id><published>2008-09-30T10:24:00.012+08:00</published><updated>2011-03-17T16:25:36.330+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data-structure'/><category scheme='http://www.blogger.com/atom/ns#' term='lang-c'/><title type='text'>从内存对齐到结构对齐</title><content type='html'>&lt;span style="font-style: italic;"&gt;对于直接操控内存的程序员来说，数据对齐不该是个陌生的术语。它和程序如何良好运行，&lt;br /&gt;甚至和程序是否能正常运转都有很大关系。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;在这里我将先简要说明一下内存对齐的基础知识。这些内容来自于&lt;a href="http://www-128.ibm.com/developerworks"&gt;IBM developerworks&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;内存访问粒度 memory access granularity&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;程序员可以先将内存简单的认为是一个一维数组。在C和衍生语言里，char*代表着这样一块&lt;br /&gt;内存，而在Java中甚至会用到byte[]来表示内存块。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;程序员眼中的内存&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOGPku6PAmI/AAAAAAAABF4/a_ysXk3ELoM/s1600-h/howProgrammersSeeMemory.jpg"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOGPku6PAmI/AAAAAAAABF4/a_ysXk3ELoM/s320/howProgrammersSeeMemory.jpg" alt="" id="BLOGGER_PHOTO_ID_5251636501721055842" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;我们可以看到内存从0到最大值顺序排列，每一个内存单元都被一个数字索引，这就是内存&lt;br /&gt;地址。&lt;br /&gt;&lt;br /&gt;但是现代的处理器却往往不是以一个比特为单位来访问内存的，而是以2，4，8，16，甚至&lt;br /&gt;32个字节为单位。我们把这个尺寸称之为内存访问粒度，用来表示处理器一次存取的内存大&lt;br /&gt;小。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;处理器眼中的内存&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzGLV4MI/AAAAAAAABGI/nhSRnA3aoVs/s1600-h/howProcessorsSeeMemory.jpg"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzGLV4MI/AAAAAAAABGI/nhSRnA3aoVs/s320/howProcessorsSeeMemory.jpg" alt="" id="BLOGGER_PHOTO_ID_5251636748484993218" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;内存对齐基础知识&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;我们用固定比特读取这样一个例子，来分析内存对齐。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;首先是访问粒度为1比特的处理器&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzUba52I/AAAAAAAABGY/epY4UvTFTFI/s1600-h/singleByteAccess.jpg"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzUba52I/AAAAAAAABGY/epY4UvTFTFI/s320/singleByteAccess.jpg" alt="" id="BLOGGER_PHOTO_ID_5251636752310527842" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;这和程序员脑子中的内存模型是一致的，每次读取一个比特。那么从地址0读取和地址1读&lt;br /&gt;取4个字节，情形完全相同。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;来看看访问粒度为2的情况&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzDtccJI/AAAAAAAABGA/sXjt3cBqKBk/s1600-h/doubleByteAccess.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzDtccJI/AAAAAAAABGA/sXjt3cBqKBk/s320/doubleByteAccess.jpg" alt="" id="BLOGGER_PHOTO_ID_5251636747822723218" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;从0读取的时候，粒度为2的处理器将会花费1/2的时间来读取同样大小的内存（与粒度1相&lt;br /&gt;比）。读取4个字节，将只需要2次存取。&lt;br /&gt;&lt;br /&gt;然而，地址1的读取则大不相同，因为地址1没有落在处理器的内存边界上，处理器的活儿就&lt;br /&gt;多了。这样的地址被成为“不对齐地址”。由于地址1没有对齐，那么粒度为2的处理器将会多&lt;br /&gt;花费1个存取次数，显然降低了访问速度。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;最后我们来查看粒度为4的处理器&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzIIjEeI/AAAAAAAABGQ/qF0YrR6w6ok/s1600-h/quadByteAccess.jpg"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzIIjEeI/AAAAAAAABGQ/qF0YrR6w6ok/s320/quadByteAccess.jpg" alt="" id="BLOGGER_PHOTO_ID_5251636749010145762" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;从边界地址上读取4个字节，这里只访问了一次内存。但是从“不对齐地址”处读取，依然会使&lt;br /&gt;读取次数加倍。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;懒惰的处理器&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;回想到我们上面所陈述的3种情况，我们来总结一下非对齐地址的读取。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzfQHVBI/AAAAAAAABGg/fe_xIgrkDRM/s1600-h/unalignedAccess.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SOGPzfQHVBI/AAAAAAAABGg/fe_xIgrkDRM/s320/unalignedAccess.jpg" alt="" id="BLOGGER_PHOTO_ID_5251636755215897618" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;首先处理器需要从非对齐地址读取第一个内存块，然后将不需要的内存位移出内存块，然后&lt;br /&gt;再从非对齐地址读到第二个内存块，同样移除不需要的内存地带。最后将两者合并到一起，&lt;br /&gt;放置到寄存器里。OH，这真是一个麻烦的任务～&lt;br /&gt;&lt;br /&gt;而且……有些处理器不愿意为你作这样的工作。&lt;br /&gt;&lt;br /&gt;原先的68000就是粒度为2的处理器，他却缺乏处理非对齐地址的相应电路，因此当遇到此类&lt;br /&gt;访问的时候，处理器会抛出异常。早期的Mac OS对待这种异常非常不友好，很可能会要求用&lt;br /&gt;户重启计算机。听起来实在无奈～&lt;br /&gt;&lt;br /&gt;现在所有的处理器都会使用有限数量的晶体管来完成此类任务，在这类问题上会更上一层楼。&lt;br /&gt;但无论怎样，非对齐地址的内存访问始终大大落后于对齐地址，这里处理器必须面对的一个&lt;br /&gt;现实。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;编译器中的数据对齐&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;struct P{&lt;br /&gt; char a;&lt;br /&gt; long b;&lt;br /&gt; char c;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;struct P的尺寸会是多少？很多程序员会不假思索的回答：6(1+4+1)。他们假想的元素布局&lt;br /&gt;可能会是这样：&lt;br /&gt;&lt;table border="1" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Field Type&lt;/td&gt;&lt;td&gt;Field Name&lt;/td&gt;&lt;td&gt;Field Offset&lt;/td&gt;&lt;td&gt;Field End&lt;/td&gt;&lt;td&gt;Field Size&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;char&lt;/td&gt;&lt;td align="left"&gt;a&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;br /&gt;&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;long&lt;/td&gt;&lt;td align="left"&gt;b&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;4&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;char&lt;/td&gt;&lt;td align="left"&gt;c&lt;/td&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;5&lt;br /&gt;&lt;/td&gt;&lt;td&gt;1&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td colspan="4"&gt;Total Size in Bytes:&lt;/td&gt;&lt;td&gt;6&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;然而，问问你的编译器就很知道，sizeof(struct P)是12 (GCC4)。真实的结构体布局是：&lt;br /&gt;&lt;table border="1" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Field Type&lt;/td&gt;&lt;td&gt;Field Name&lt;/td&gt;&lt;td&gt;Field Offset&lt;/td&gt;&lt;td&gt;Field End&lt;/td&gt;&lt;td&gt;Field Size&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;char&lt;/td&gt;&lt;td align="left"&gt;a&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;br /&gt;&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;long&lt;/td&gt;&lt;td align="left"&gt;b&lt;/td&gt;&lt;td&gt;4&lt;br /&gt;&lt;/td&gt;&lt;td&gt;7&lt;br /&gt;&lt;/td&gt;&lt;td&gt;4&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;char&lt;/td&gt;&lt;td align="left"&gt;c&lt;/td&gt;&lt;td&gt;8&lt;br /&gt;&lt;/td&gt;&lt;td&gt;8&lt;br /&gt;&lt;/td&gt;&lt;td&gt;1&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td colspan="4"&gt;Total Size in Bytes:&lt;/td&gt;&lt;td&gt;12&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;这和我们刚才所说的内存对齐紧密相连。为了保持较高的内存访问效率，编译器也会在数据&lt;br /&gt;结构存储上应用到数据对齐。对齐原则针对平台，编译器，可能会有较大不同，这也是这篇&lt;br /&gt;文章的重点。&lt;br /&gt;&lt;br /&gt;首先引入对齐模数概念，编译器会要求数据结构的成员地址是某个数k的倍数，这个常数k则&lt;br /&gt;被称为该数据类型的&lt;span style="font-weight: bold;"&gt;对齐模数&lt;/span&gt; (alignment modulus，余下简称modulus)。它是成员地址的&lt;br /&gt;公约数，也是成员偏移量的公倍数。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;结构体对齐原则&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;（下面的对齐原则，仅仅针对于GCC）&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;struct A {&lt;br /&gt; char a;&lt;br /&gt; char b;&lt;br /&gt;};&lt;br /&gt;//sizeof(struct A) = 2;&lt;br /&gt;&lt;br /&gt;struct B {&lt;br /&gt; short a;&lt;br /&gt; short b;&lt;br /&gt; short c;&lt;br /&gt;};&lt;br /&gt;//sizeof(struct B) = 6;&lt;br /&gt;&lt;br /&gt;struct C {&lt;br /&gt; int a;&lt;br /&gt; int b;&lt;br /&gt; int c;&lt;br /&gt;};&lt;br /&gt;//sizeof(struct C) = 12;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这样看很简单。sizeof似乎没有什么问题。char,short,int的长度分别是1,2,4，这样可以&lt;br /&gt;轻而易举的加到结果。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;struct D {&lt;br /&gt; short a;&lt;br /&gt; int b;&lt;br /&gt; unsigned c;&lt;br /&gt;};&lt;br /&gt;//sizeof(struct D) = 12;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这里先确定对齐模数，针对VC和GCC编译器，他们各有不同。&lt;br /&gt;cl.exe:&lt;br /&gt;选取成员中的最宽类型的字长为modulus(对齐模数)&lt;br /&gt;GCC:&lt;br /&gt;同样选取成员中字长最大值，但是对齐模数只在三个值间选择，他们是1，2，4。&lt;br /&gt;这意味着GCC结构体的最大modulus只能是4。&lt;br /&gt;&lt;br /&gt;struct D中最长类型为int，那么它在GCC中的对齐modulus是sizeof(int) = 4；&lt;br /&gt;&lt;br /&gt;同样，这里阐述结构体对齐的三条原则：&lt;br /&gt;1) &lt;span style="color: rgb(0, 0, 153);"&gt;结构体变量的首地址必须能够被modulus所整除&lt;/span&gt;&lt;br /&gt;2)* &lt;span style="color: rgb(0, 0, 153);"&gt;结构体每个成员相对于首地址的偏移量(Offset)必须能被modulus整除，如有需要，在&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;成员间填充空白字节（这被称为internal padding）&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;struct D的成员 a 使用到了internal padding。&lt;br /&gt;&lt;br /&gt;3) &lt;span style="color: rgb(0, 0, 153);"&gt;结构体总大小必须是modulus的整数倍，如有需要，在最末元素填充字节(trailing&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;padding)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;成员C就用到了 trailing padding。&lt;br /&gt;&lt;br /&gt;根据以上原则我们可以列出struct D内存布局图:&lt;br /&gt;&lt;table border="1" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Field Type&lt;/td&gt;&lt;td&gt;Field Name&lt;/td&gt;&lt;td&gt;Field Offset&lt;/td&gt;&lt;td&gt;Field End&lt;br /&gt;&lt;/td&gt;&lt;td&gt;Field Size&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;short&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;a&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;br /&gt;&lt;/td&gt;&lt;td&gt;2&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;/&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;(padding)&lt;br /&gt;&lt;/td&gt;&lt;td&gt;2&lt;br /&gt;&lt;/td&gt;&lt;td&gt;3&lt;br /&gt;&lt;/td&gt;&lt;td&gt;2&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;&lt;span style="font-family:Georgia,serif;"&gt;int&lt;/span&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;b&lt;br /&gt;&lt;/td&gt;&lt;td&gt;4&lt;br /&gt;&lt;/td&gt;&lt;td&gt;7&lt;br /&gt;&lt;/td&gt;&lt;td&gt;4&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;&lt;span style="font-family:Georgia,serif;"&gt;ch&lt;/span&gt;ar&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;c&lt;/td&gt;&lt;td&gt;8&lt;br /&gt;&lt;/td&gt;&lt;td&gt;8&lt;br /&gt;&lt;/td&gt;&lt;td&gt;1&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;&lt;span style="font-family:Georgia,serif;"&gt;/&lt;/span&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;(padding)&lt;br /&gt;&lt;/td&gt;&lt;td&gt;9&lt;br /&gt;&lt;/td&gt;&lt;td&gt;11&lt;br /&gt;&lt;/td&gt;&lt;td&gt;3&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td colspan="4"&gt;Total Size in Bytes:&lt;/td&gt;&lt;td&gt;12&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;struct E {         // offset/data size&lt;br /&gt; short a;   // 0/2，空位填充&lt;br /&gt; int b;     // 4/4&lt;br /&gt; char c;    // 8/1，邻接元素填充&lt;br /&gt; short d;   // 10/2&lt;br /&gt;};&lt;br /&gt;//sizeof(struct E) = 12;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;内存布局：&lt;br /&gt;&lt;table border="1" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Field Type&lt;/td&gt;&lt;td&gt;Field Name&lt;/td&gt;&lt;td&gt;Field Offset&lt;/td&gt;&lt;td&gt;Field End&lt;/td&gt;&lt;td&gt;Field Size&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;short&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;a&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;/&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;(padding)&lt;br /&gt;&lt;/td&gt;&lt;td&gt;2&lt;br /&gt;&lt;/td&gt;&lt;td&gt;3&lt;br /&gt;&lt;/td&gt;&lt;td&gt;2&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;int&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;b&lt;br /&gt;&lt;/td&gt;&lt;td&gt;4&lt;br /&gt;&lt;/td&gt;&lt;td&gt;7&lt;br /&gt;&lt;/td&gt;&lt;td&gt;4&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;char&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;c&lt;br /&gt;&lt;/td&gt;&lt;td&gt;8&lt;br /&gt;&lt;/td&gt;&lt;td&gt;8&lt;br /&gt;&lt;/td&gt;&lt;td&gt;1&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;/&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;(padding)&lt;br /&gt;&lt;/td&gt;&lt;td&gt;9&lt;br /&gt;&lt;/td&gt;&lt;td&gt;9&lt;br /&gt;&lt;/td&gt;&lt;td&gt;1&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;short&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;d&lt;br /&gt;&lt;/td&gt;&lt;td&gt;10&lt;br /&gt;&lt;/td&gt;&lt;td&gt;11&lt;br /&gt;&lt;/td&gt;&lt;td&gt;2&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td colspan="4"&gt;Total Size in Bytes:&lt;/td&gt;&lt;td&gt;12&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;这里引用到了GCC的压缩存储。压缩存储要求，结构体的成员会紧凑的将成员压缩到一个&lt;br /&gt;modulus里。GCC的强压缩方式，又可以忽略元素类型，将不同类型的成员压缩到一个&lt;br /&gt;modulus里。&lt;br /&gt;&lt;br /&gt;然后阐述的原则将会对对齐原则2重新定义：&lt;br /&gt;4) &lt;span style="color: rgb(0, 0, 153);"&gt;考虑到GCC的压缩存储方式，邻近成员会合并到一个modulus里，合并过程直到可能超出&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;modulus大小时停止&lt;/span&gt;&lt;br /&gt;5) &lt;span style="color: rgb(0, 0, 153);"&gt;合并在一个modulus里的数个成员，将会按照“子结构体”的方式来存储。比如拥有更小的&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;mini modulus，按照mini modulus排列数据成员&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;struct E 中的元素c，d就使用到了压缩存储。那么c和d将会按照“子结构体”方式存储，&lt;br /&gt;他们拥有的modulus是2 (sizeof(short))。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/* modulus只能考虑基本数据类型，因此结构体成员还需追溯其成员类型 */&lt;br /&gt;struct F {&lt;br /&gt; char a;&lt;br /&gt; struct A b;  //&lt;br /&gt;};&lt;br /&gt;//sizeof(struct F) = 3;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;对齐模数只能考虑原子数据类型，因此：&lt;br /&gt;6) &lt;span style="color: rgb(0, 0, 153);"&gt;成员结构体需要打破结构体边界，追溯成员类型。数组也是一样，modulus将和数组大小&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;无关&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;union和class对齐&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;除了struct以外，C中包含有union，而在C++中更是包含了人见人爱的class支持。他们同&lt;br /&gt;struct一样，是属于符合类型，允许定义多个不同类型的成员。&lt;br /&gt;&lt;br /&gt;我们来看看union的特性：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;union G {&lt;br /&gt; char a;&lt;br /&gt; int b;&lt;br /&gt; char c[10];&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;通过实验，我们看到结果：sizeof(union F) = 12;&lt;br /&gt;* union仍旧选用最宽数据类型作为modulus（和struct一样）&lt;br /&gt;&lt;br /&gt;union G 的modulus是4 (int)。&lt;br /&gt;&lt;br /&gt;* 而union采用完全完全压缩方式，它占有的总内存大小，将和最大成员字长一样。&lt;br /&gt;&lt;br /&gt;union G的最大成员是char c[10]，再考虑modulus=4，因此取总字长为12。&lt;br /&gt;&lt;br /&gt;然后我们写出union G的内存布局。&lt;br /&gt;&lt;table border="1" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Field Type&lt;/td&gt;&lt;td&gt;Field Name&lt;/td&gt;&lt;td&gt;Field Offset&lt;/td&gt;&lt;td&gt;Field End&lt;/td&gt;&lt;td&gt;Field Size&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;char&lt;/td&gt;&lt;td align="left"&gt;a&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;br /&gt;&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;int&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;b&lt;/td&gt;&lt;td&gt;0&lt;br /&gt;&lt;/td&gt;&lt;td&gt;3&lt;br /&gt;&lt;/td&gt;&lt;td&gt;4&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td align="left"&gt;char&lt;/td&gt;&lt;td align="left"&gt;c&lt;/td&gt;&lt;td&gt;0&lt;br /&gt;&lt;/td&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;12&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="right"&gt;&lt;td colspan="4"&gt;Total Size in Bytes:&lt;/td&gt;&lt;td&gt;12&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;class H {&lt;br /&gt;private:&lt;br /&gt; int a;&lt;br /&gt; static char b;           // static 不占空间&lt;br /&gt; short c;&lt;br /&gt; unsigned short d;&lt;br /&gt; void func0();            // public func不占空间&lt;br /&gt;public:&lt;br /&gt; int e;                   // 公私有对sizeof无影响&lt;br /&gt; virtual void func1();    // 一个类的virtual只能占据一个指针&lt;br /&gt; void func2();&lt;br /&gt; virtual void func3();    //&lt;br /&gt; virtual void func4();&lt;br /&gt; virtual void func5();    //&lt;br /&gt;};&lt;br /&gt;//sizeof(H) = 16;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;class概念是C++的根基，作为C的超集，C++在class定义中添加了非常多的特性。我们简单&lt;br /&gt;说一下class对齐和内存占用原则:&lt;br /&gt;&lt;br /&gt;1) &lt;span style="color: rgb(0, 0, 153);"&gt;modulus大小和原子类型排列的原则和struct相同&lt;/span&gt;&lt;br /&gt;class H将仍旧选取4（int）为对齐modulus。&lt;br /&gt;&lt;br /&gt;2) &lt;span style="color: rgb(0, 0, 153);"&gt;内存占用和访问控制修饰符无关（比如private，class，protected）&lt;/span&gt;&lt;br /&gt;成员a, e各自享用4个字节。&lt;br /&gt;&lt;br /&gt;3) &lt;span style="color: rgb(0, 0, 153);"&gt;static 变量和成员函数，在class结构中不占用空间&lt;/span&gt;&lt;br /&gt;static char b将不占内存空间。&lt;br /&gt;&lt;br /&gt;4) &lt;span style="color: rgb(0, 0, 153);"&gt;如果类包含虚函数，那么要算上一个指针的空间（虚指针）&lt;/span&gt;&lt;br /&gt;所有的虚函数（virtual）都共享一个虚指针，原class字长+4&lt;br /&gt;&lt;br /&gt;5) &lt;span style="color: rgb(0, 0, 153);"&gt;子类将使用基类的modulus。由于继承了成员，子类也将会包含基类的所有字节大小，在&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;此基础上定义的新成员则按照上述3个法则计算&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;引用：&lt;br /&gt;1. wikipedia wiki: &lt;a href="http://en.wikipedia.org/wiki/Sizeof"&gt;sizeof&lt;/a&gt;&lt;br /&gt;2. Rentzsch, Jonathan. "&lt;a href="http://www-128.ibm.com/developerworks/library/pa-dalign/#N100FE"&gt;Data alignment: Straighten up and fly right.&lt;/a&gt;"&lt;br /&gt;3. king. "&lt;a href="http://www.ksarea.com/articles/20071004_sizeof-struct-memory.html"&gt;sizeof(结构体)和内存对齐&lt;/a&gt;"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-6878744732805580712?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/6878744732805580712/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_30.html#comment-form' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6878744732805580712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6878744732805580712'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_30.html' title='从内存对齐到结构对齐'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Kb-lr4qFtj4/SOGPku6PAmI/AAAAAAAABF4/a_ysXk3ELoM/s72-c/howProgrammersSeeMemory.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-8026635485109748491</id><published>2008-09-26T11:48:00.003+08:00</published><updated>2011-03-06T11:24:39.820+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>[TIC++] C5. Hiding the implementation</title><content type='html'>代码阅读&amp;lt;Thinking in C++&amp;gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Chapter 5. Hiding the implementation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、友元&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//friend.cpp&lt;br /&gt;&lt;br /&gt;// public, private, protected&lt;br /&gt;// friends&lt;br /&gt;&lt;br /&gt;struct X;&lt;br /&gt;struct Y {&lt;br /&gt;   void f(X*);&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;struct X {&lt;br /&gt;private:&lt;br /&gt;   int i;&lt;br /&gt;public:&lt;br /&gt;   void initialize();&lt;br /&gt;   friend void Y::f(X*);     // struct member friend&lt;br /&gt;   friend struct Z;          // Entire struct is a friend&lt;br /&gt;   friend void g(X*, int);   // Global friend&lt;br /&gt;   friend void h();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void X::initialize()&lt;br /&gt;{&lt;br /&gt;   i = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Y::f(X *x)&lt;br /&gt;{&lt;br /&gt;   x-&amp;gt;i = 47;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;struct Z {&lt;br /&gt;private:&lt;br /&gt;   int j;&lt;br /&gt;public:&lt;br /&gt;   void initialize();&lt;br /&gt;   void g(X *x);&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void Z::initialize()&lt;br /&gt;{&lt;br /&gt;   j = 99;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Z::g(X *x)&lt;br /&gt;{&lt;br /&gt;   x-&amp;gt;i += j;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void g(X *x, int i)&lt;br /&gt;{&lt;br /&gt;   x-&amp;gt;i = i;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void h()&lt;br /&gt;{&lt;br /&gt;   X x;&lt;br /&gt;   x.i = 100;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   X x;&lt;br /&gt;   Z z;&lt;br /&gt;   z.g(&amp;amp;x);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;此代码示范了friend友元的用途，声明友元的类在告诉大家，此友元可以访问我的私有成员。&lt;br /&gt;* 从struct X的定义可以看出，在public区域定义了四种友元，他们都可以试图访问修改私&lt;br /&gt; 有成员i，当然也包括自己的成员函数。&lt;br /&gt;&lt;br /&gt; 全局友元函数 global friend&lt;br /&gt;     在函数体内，可以任意修改struct X类对象的成员i。&lt;br /&gt; 类成员作为友元 struct member friend&lt;br /&gt;     可以更改传递的X*参数。&lt;br /&gt; 整个类作为友元 entire struct&lt;br /&gt;     这样此类的所有成员函数，都拥有友元性质。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、嵌套的友元&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//nested_friend.cpp&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;cstring&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;const int sz = 20;&lt;br /&gt;&lt;br /&gt;struct Holder {&lt;br /&gt;private:&lt;br /&gt;   int a[sz];&lt;br /&gt;public:&lt;br /&gt;   void initialize();&lt;br /&gt;   struct Pointer;&lt;br /&gt;   friend struct Pointer;&lt;br /&gt;   struct Pointer {        // nested struct friend&lt;br /&gt;   private:&lt;br /&gt;       Holder *h;&lt;br /&gt;       int *p;&lt;br /&gt;   public:&lt;br /&gt;       void initialize(Holder *h);&lt;br /&gt;       void next();&lt;br /&gt;       void previous();&lt;br /&gt;       void top();&lt;br /&gt;       void end();&lt;br /&gt;       int  read();&lt;br /&gt;       void set(int i);&lt;br /&gt;   };&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// type class::nested_class::variable;&lt;br /&gt;void Holder::initialize()&lt;br /&gt;{&lt;br /&gt;   memset(a, 0, sz * sizeof(int));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Holder::Pointer::initialize(Holder *rv)&lt;br /&gt;{&lt;br /&gt;   h = rv;&lt;br /&gt;   p = rv-&amp;gt;a; // access private member of super class&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Holder::Pointer::next()&lt;br /&gt;{&lt;br /&gt;   if (p &amp;lt; &amp;amp;(h-&amp;gt;a[sz - 1]))&lt;br /&gt;       p++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Holder::Pointer::previous()&lt;br /&gt;{&lt;br /&gt;   if (p &amp;gt; &amp;amp;(h-&amp;gt;a[0]))&lt;br /&gt;       p--;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Holder::Pointer::top()&lt;br /&gt;{&lt;br /&gt;   p = &amp;amp;(h-&amp;gt;a[0]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Holder::Pointer::end()&lt;br /&gt;{&lt;br /&gt;   p = &amp;amp;(h-&amp;gt;a[sz-1]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int Holder::Pointer::read()&lt;br /&gt;{&lt;br /&gt;   return *p;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Holder::Pointer::set(int i)&lt;br /&gt;{&lt;br /&gt;   *p = i;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   Holder h;&lt;br /&gt;   Holder::Pointer hp, hp2;&lt;br /&gt;   int i;&lt;br /&gt;&lt;br /&gt;   h.initialize();&lt;br /&gt;   hp.initialize(&amp;amp;h);&lt;br /&gt;   hp2.initialize(&amp;amp;h);&lt;br /&gt;   for (i = 0; i &amp;lt; sz; i++) {&lt;br /&gt;       hp.set(i);&lt;br /&gt;       hp.next();&lt;br /&gt;   }&lt;br /&gt;   hp.top();&lt;br /&gt;   hp2.end();&lt;br /&gt;   for (i = 0; i &amp;lt; sz; i++) {&lt;br /&gt;       cout &amp;lt;&amp;lt; "hp = " &amp;lt;&amp;lt; hp.read()&lt;br /&gt;            &amp;lt;&amp;lt; ", hp2 = " &amp;lt;&amp;lt; hp2.read() &amp;lt;&amp;lt; endl;&lt;br /&gt;       hp.next();&lt;br /&gt;       hp2.previous();&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;/* result:&lt;br /&gt;hp = 0, hp2 = 19&lt;br /&gt;hp = 1, hp2 = 18&lt;br /&gt;hp = 2, hp2 = 17&lt;br /&gt;hp = 3, hp2 = 16&lt;br /&gt;hp = 4, hp2 = 15&lt;br /&gt;hp = 5, hp2 = 14&lt;br /&gt;hp = 6, hp2 = 13&lt;br /&gt;hp = 7, hp2 = 12&lt;br /&gt;hp = 8, hp2 = 11&lt;br /&gt;hp = 9, hp2 = 10&lt;br /&gt;hp = 10, hp2 = 9&lt;br /&gt;hp = 11, hp2 = 8&lt;br /&gt;hp = 12, hp2 = 7&lt;br /&gt;hp = 13, hp2 = 6&lt;br /&gt;hp = 14, hp2 = 5&lt;br /&gt;hp = 15, hp2 = 4&lt;br /&gt;hp = 16, hp2 = 3&lt;br /&gt;hp = 17, hp2 = 2&lt;br /&gt;hp = 18, hp2 = 1&lt;br /&gt;hp = 19, hp2 = 0&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这里的Holder类中又包含Pointer类定义，这是个嵌套类。例子在展示子类作为友元时的用&lt;br /&gt;途。&lt;br /&gt;在这里定义了Holder类对象h，和子类Pointer对象hp,hp2，他们包含有h的指针，和父类私&lt;br /&gt;有成员a的位置。作为友元类，hp和hp2可以访问、修改父类对象h的私有成员int a[];&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;三、初识构造函数和析构函数&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//constructor.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Tree {&lt;br /&gt;   int height;&lt;br /&gt;public:&lt;br /&gt;   Tree(int initialHeight);&lt;br /&gt;   ~Tree();&lt;br /&gt;   void grow(int years);&lt;br /&gt;   void printsize();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Tree::Tree(int initialHeight)&lt;br /&gt;{&lt;br /&gt;   height = initialHeight;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Tree::~Tree()&lt;br /&gt;{&lt;br /&gt;   cout &amp;lt;&amp;lt; "inside tree destructor " &amp;lt;&amp;lt; endl;&lt;br /&gt;   printsize();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Tree::grow(int years)&lt;br /&gt;{&lt;br /&gt;   height += years;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Tree::printsize()&lt;br /&gt;{&lt;br /&gt;   cout &amp;lt;&amp;lt; "Tree height is " &amp;lt;&amp;lt; height &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   cout &amp;lt;&amp;lt; "before opening brace " &amp;lt;&amp;lt; endl;&lt;br /&gt;   {&lt;br /&gt;       Tree t(12);  //constructor called&lt;br /&gt;       cout &amp;lt;&amp;lt; "after Tree creation" &amp;lt;&amp;lt; endl;&lt;br /&gt;       t.printsize();&lt;br /&gt;       t.grow(4);&lt;br /&gt;       cout &amp;lt;&amp;lt; "before closing brace" &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;br /&gt;       //destructor called(endline of t)&lt;br /&gt;   }&lt;br /&gt;   cout &amp;lt;&amp;lt; "after closing brace  " &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;/* result:&lt;br /&gt;before opening brace&lt;br /&gt;after Tree creation&lt;br /&gt;Tree height is 12&lt;br /&gt;before closing brace&lt;br /&gt;inside tree destructor&lt;br /&gt;Tree height is 16&lt;br /&gt;after closing brace&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;例子展示了constructor和destructor的性能。&lt;br /&gt;* constructor在建立对象的时候，由编译器插入语句，完成初始化行为，在对象生命期内&lt;br /&gt; 只执行一次。&lt;br /&gt;* destructor相反，在注销对象的时候执行。&lt;br /&gt;* 代码中使用了{}圈定对象Tree T的生命域，它在`}'之后被注销。&lt;br /&gt;下面讲述constructor一个特性。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//nojump.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class X {&lt;br /&gt;public:&lt;br /&gt;   X();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;X::X() {}&lt;br /&gt;&lt;br /&gt;void f(int i)&lt;br /&gt;{&lt;br /&gt;   if (i &amp;lt; 10) {&lt;br /&gt;       // crosses initialization of `X x1'&lt;br /&gt;//        goto jump1;&lt;br /&gt;   }&lt;br /&gt;   X x1;  &lt;br /&gt;&lt;br /&gt;jump1:&lt;br /&gt;   switch (i) {&lt;br /&gt;   case 1:&lt;br /&gt;       X x2;&lt;br /&gt;       // crosses initialization of `X x3'&lt;br /&gt;       break;&lt;br /&gt;//    case 2:&lt;br /&gt;       X x3;&lt;br /&gt;       break;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   f(9);&lt;br /&gt;   f(11);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这是一个诡异的例子，首字符注释段取消注释之后，编译器将报错: `cross&lt;br /&gt;initialization'。GCC将不允许goto，case语句等，来跳过任何对象的定义（初始化）阶段。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;四、定义stack&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//stack.h&lt;br /&gt;#ifndef _STACK_H&lt;br /&gt;#define _STACK_H&lt;br /&gt;&lt;br /&gt;class stack {&lt;br /&gt;   struct linklist {&lt;br /&gt;       void *data;&lt;br /&gt;       linklist *next;&lt;br /&gt;       linklist(void *dat, linklist* nxt);&lt;br /&gt;       ~linklist();&lt;br /&gt;   }* head;&lt;br /&gt;public:&lt;br /&gt;   stack();&lt;br /&gt;   ~stack();&lt;br /&gt;   void push(void *data);&lt;br /&gt;   void *peek();&lt;br /&gt;   void *pop();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;#endif // STACK_H&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//stack.cpp&lt;br /&gt;#include "stack.h"&lt;br /&gt;&lt;br /&gt;stack::linklist::linklist(void *dat, linklist *nxt)&lt;br /&gt;{&lt;br /&gt;   data = dat;&lt;br /&gt;   next = nxt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;stack::linklist::~linklist() {}&lt;br /&gt;&lt;br /&gt;stack::stack()&lt;br /&gt;{&lt;br /&gt;   head = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void * stack::peek()&lt;br /&gt;{&lt;br /&gt;   if (head != 0)&lt;br /&gt;       return head-&amp;gt;data;&lt;br /&gt;   else&lt;br /&gt;       return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void stack::push(void *dat)&lt;br /&gt;{&lt;br /&gt;   head = new linklist(dat, head);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void * stack::pop()&lt;br /&gt;{&lt;br /&gt;   if (head == 0)&lt;br /&gt;       return 0;&lt;br /&gt;   void *result = head-&amp;gt;data;&lt;br /&gt;   linklist *oldHead = head;&lt;br /&gt;   head = head-&amp;gt;next;&lt;br /&gt;   delete oldHead;&lt;br /&gt;   return result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;stack::~stack()&lt;br /&gt;{&lt;br /&gt;   if (head != 0)&lt;br /&gt;       return;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//stacktest.cpp&lt;br /&gt;#include "stack.h"&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;//    requireArgs(argc, 1);&lt;br /&gt;   ifstream in(argv[1]);&lt;br /&gt;   if(in == 0)&lt;br /&gt;       return -1;&lt;br /&gt;//    assure(in, argv[1]);&lt;br /&gt;&lt;br /&gt;   stack textlines;&lt;br /&gt;   string line;&lt;br /&gt;   while (getline(in, line))&lt;br /&gt;       textlines.push(new string(line));&lt;br /&gt;   string *s;&lt;br /&gt;   while ((s = (string *)textlines.pop()) != 0) {&lt;br /&gt;       cout &amp;lt;&amp;lt; *s &amp;lt;&amp;lt; endl;&lt;br /&gt;       delete s;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;/* 执行命令 ./a.out Makefile&lt;br /&gt;* 将按行逆序打印Makefile内容。&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;stack.h，stack.cpp，stacktest.cpp是链表式堆栈的实现。&lt;br /&gt;* linklist是节点数据结构的实现，他是stack数据结构的成员。&lt;br /&gt;* 无论对于父子类对象，他们都会有自己的构造函数和析构函数。&lt;br /&gt;* push函数非常漂亮！&lt;br /&gt;* 使用new 和 delete，来分配堆区空间，这会使得C++代码更加优雅。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-8026635485109748491?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/8026635485109748491/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/tic-c6-hiding-implementation.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/8026635485109748491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/8026635485109748491'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/tic-c6-hiding-implementation.html' title='[TIC++] C5. Hiding the implementation'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-1765534941855137113</id><published>2008-09-25T16:43:00.004+08:00</published><updated>2011-03-06T11:11:28.500+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux-drivers-net'/><title type='text'>Gentoo配置无限网卡ipw2100</title><content type='html'>无限网卡的配置让我倍受折腾，在一两个月内，我不知道翻阅了多少资料，问了多少人，尝&lt;br /&gt;试了多少遍，和放弃了多少遍。昨天我转换一下思维，直接从命令行里敲iwconfig命令，居&lt;br /&gt;然连接上了。因此赶快留下记录，供以后查阅。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;硬件环境&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    IBM Thinkpad R50&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    - Intel PRO/Wireless LAN 2100 无线网卡&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    - ATI Radeon Mobility 7500   &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;软件环境&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    linux-2.6.26-gentoo, i686&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    Gentoo profile: default/linux/x86/2008.0/desktop&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    gcc-4.3.1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    glibc-2.8_p20080602-r0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;配置方案&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;    内核驱动 + ipw2100固件 + iwconfig&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;下面简述安装配置过程;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、安装内核驱动&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ipw2100作为应用广泛的网卡，已经在内核里加入支持，而且你在gentoo的portage tree中&lt;br /&gt;也找不到ipw2100的驱动了。因此，你只需要在内核里编译即可（建议编译成模块），编译&lt;br /&gt;后的模块名称为ipw2100。&lt;br /&gt;&lt;br /&gt;编译选项为：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;Symbol: IPW2100 [=m]&lt;br /&gt;│ Prompt: Intel PRO/Wireless 2100 Network Connection&lt;br /&gt;│   Defined at drivers/net/wireless/Kconfig:126&lt;br /&gt;│   Depends on: NETDEVICES &amp;amp;&amp;amp; !S390 &amp;amp;&amp;amp; PCI &amp;amp;&amp;amp; WLAN_80211&lt;br /&gt;│   Location:&lt;br /&gt;│     -&gt; Device Drivers&lt;br /&gt;│       -&gt; Network device support (NETDEVICES [=y])&lt;br /&gt;│         -&gt; Wireless LAN&lt;br /&gt;│           -&gt; Wireless LAN (IEEE 802.11) (WLAN_80211 [=y])&lt;br /&gt;│   Selects: WIRELESS_EXT &amp;amp;&amp;amp; FW_LOADER &amp;amp;&amp;amp; IEEE80211&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、安装firmware&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;firmware是不公开的驱动程序需要的数据。ipw2100的固件在gentoo里可以直接安装，安装&lt;br /&gt;后的固件在 /lib/firmware 中。&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;wickyl@ ~: eix ipw2100&lt;br /&gt;[I] net-wireless/ipw2100-firmware&lt;br /&gt;   Available versions:  (1.3)  1.3&lt;br /&gt;   Installed versions:  1.3(1.3)(04:50:13 PM 08/31/2008)&lt;br /&gt;   Homepage:            http://ipw2100.sourceforge.net/&lt;br /&gt;   Description:         Firmware for the Intel PRO/Wireless 2100 3B miniPCI adapter&lt;br /&gt;wickyl@ ~: sudo emerge ipw2100&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;至此ipw2100的驱动已经安装完毕了，加载模块ipw2100正确之后，可以用ifconfig查找到新&lt;br /&gt;增的网卡借口（我的是eth1），也可以在dmesg中发现模块打印的信息。&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;wickyl@ ~: sudo ifconfig&lt;br /&gt;eth1      Link encap:Ethernet  HWaddr 00:0c:f1:0c:87:17&lt;br /&gt;        inet addr:172.1.2.191  Bcast:172.1.255.255  Mask:255.255.0.0&lt;br /&gt;        UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1&lt;br /&gt;        RX packets:13955 errors:28 dropped:0 overruns:0 frame:0&lt;br /&gt;        TX packets:2493 errors:0 dropped:0 overruns:0 carrier:0&lt;br /&gt;        collisions:0 txqueuelen:1000&lt;br /&gt;        RX bytes:2311035 (2.2 MiB)  TX bytes:507580 (495.6 KiB)&lt;br /&gt;        Interrupt:11 Base address:0x2000 Memory:c0204000-c0204fff&lt;br /&gt;&lt;br /&gt;lo        Link encap:Local Loopback&lt;br /&gt;        inet addr:127.0.0.1  Mask:255.0.0.0&lt;br /&gt;        UP LOOPBACK RUNNING  MTU:16436  Metric:1&lt;br /&gt;        RX packets:265 errors:0 dropped:0 overruns:0 frame:0&lt;br /&gt;        TX packets:265 errors:0 dropped:0 overruns:0 carrier:0&lt;br /&gt;        collisions:0 txqueuelen:0&lt;br /&gt;        RX bytes:20472 (19.9 KiB)  TX bytes:20472 (19.9 KiB)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;wickyl@ ~: dmesg | grep ipw2100&lt;br /&gt;ipw2100: Intel(R) PRO/Wireless 2100 Network Driver, git-1.2.2&lt;br /&gt;ipw2100: Copyright(c) 2003-2006 Intel Corporation&lt;br /&gt;ipw2100: Detected Intel PRO/Wireless 2100 Network Connection&lt;br /&gt;firmware: requesting ipw2100-1.3.fw&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;三、安装必备软件支持&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;必备的软件包括wireless-tools, dhcpcd，gentoo的&lt;a href="http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=4&amp;amp;chap=4"&gt;官方文档&lt;/a&gt;中提醒你，无线的配置工具可&lt;br /&gt;以使用 wpa_supplicant 和 iwconfig(wireless-tools)，但是我始终无法使用&lt;br /&gt;wpa_supplicant 成功配置无线网卡，如果你成功了，请告诉我，让我也惊讶一下。&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;wickyl@ ~: sudo emerge wireless-tools dhcpcd&lt;br /&gt;&lt;br /&gt;These are the packages that would be merged, in order:&lt;br /&gt;&lt;br /&gt;Calculating dependencies... done!&lt;br /&gt;[ebuild   R   ] net-wireless/wireless-tools-29  USE="nls -multicall" 0 kB&lt;br /&gt;[ebuild   R   ] net-misc/dhcpcd-4.0.1  USE="compat zeroconf" 0 kB&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;四、配置网络接口 (eth1)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;网络接口的配置，在 gentoo 里显得规范而且有特色，它的主配置文件在 /etc/conf.d/net&lt;br /&gt;里，在&lt;a href="http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=4&amp;amp;chap=4"&gt;官方文档&lt;/a&gt;中详细的介绍了无线网络服务的配置。&lt;br /&gt;&lt;br /&gt;配置步骤分两步，首先建立 /etc/init.d/net.eth1 链接。&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;wickyl@ ~: ln -s /etc/init.d/net.lo /etc/init.d/net.eth1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;然后是配置 /etc/conf.d/net，以下是我的配置（eth1）：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#### wireless networking configuration&lt;br /&gt;#### ipw2100 + wpa_supplicant&lt;br /&gt;config_eth1=("dhcp");&lt;br /&gt;modules=("iwconfig");&lt;br /&gt;key_&amp;lt;essid1&amp;gt;="[1] &amp;lt;passwd&amp;gt; key [1] enc open"&lt;br /&gt;key_&amp;lt;essid2&amp;gt;="off"&lt;br /&gt;&lt;br /&gt;preferred_aps=("&amp;lt;essid1&amp;gt;" "&amp;lt;essid2&amp;gt;")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;简单说明一下，我的eth1是使用dhcp来配置网络和路由器地址的，这需要你安装dhcpcd。我&lt;br /&gt;从没有使用静态地址配置无线网络，那样显得很不实际。&lt;br /&gt;&lt;br /&gt;modules=("iwconfig");&lt;br /&gt;指定无线配置接口，可选项是：iwconfig/wpa_supplicant。&lt;br /&gt;&lt;br /&gt;key_&amp;lt;essid1&amp;gt;="[1] &amp;lt;passwd&amp;gt; key [1] enc open"&lt;br /&gt;key_&amp;lt;essid2&amp;gt;="off"&lt;br /&gt;指定AP接入点和加密方式。这里的&amp;lt;essid1&amp;gt;使用了开放方式，需要用&amp;lt;passwd&amp;gt;指定密码。&lt;br /&gt;而&amp;lt;essid2&amp;gt;则没有设立密码，一般的公网就是不设定密码的。&lt;br /&gt;&lt;br /&gt;preferred_aps=("&amp;lt;essid1&amp;gt;" "&amp;lt;essid2&amp;gt;")&lt;br /&gt;preferred_aps指定AP的优先顺序。你也可以添加接入点APs的更多选项，包括屏蔽接入点等&lt;br /&gt;等。这在手册中都有介绍。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;五、启动 net.eth1 服务来完成配置&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;wickyl@ ~: sudo rc-config start net.eth1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;配置完成之后，可以用iwconfig来查询信息。这是&lt;a href="http://www.nslib.cn/"&gt;南山图书馆&lt;/a&gt;一个AP的配置信息。&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;wickyl@ ~: sudo iwconfig eth1&lt;br /&gt;Password:&lt;br /&gt;eth1      IEEE 802.11b  ESSID:"nslib"  Nickname:"ipw2100"&lt;br /&gt;        Mode:Managed  Frequency:2.412 GHz  Access Point: 00:02:6F:05:CF:7A&lt;br /&gt;        Bit Rate=11 Mb/s   Tx-Power:16 dBm&lt;br /&gt;        Retry short limit:7   RTS thr:off   Fragment thr:off&lt;br /&gt;        Encryption key:off&lt;br /&gt;        Power Management:off&lt;br /&gt;        Link Quality=98/100  Signal level=-49 dBm&lt;br /&gt;        Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0&lt;br /&gt;        Tx excessive retries:0  Invalid misc:4   Missed beacon:4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;为什么我消耗老长的时间？&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;长久以来，我都没有爱好选择习惯，如果一个事物有更多的好处，那我偏向于倾注经历在此&lt;br /&gt;事物上。&lt;br /&gt;在gentoo的&lt;a href="http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=4&amp;amp;chap=4#doc_chap2"&gt;手册&lt;/a&gt;上，明确写着：“wpa_supplicant is the best choice”。我听之任之，一&lt;br /&gt;直都在使用 wpa_supplicant 来坚持配置无限网卡。&lt;br /&gt;&lt;br /&gt;在&lt;a href="http://www.szlug.org/"&gt;szlug&lt;/a&gt;上，我&lt;a href="http://groups.google.com/group/szlug/browse_thread/thread/bf1d3b3039ff1776"&gt;张贴&lt;/a&gt;询问了配置问题，上面列举了我怎么在这个问题上消磨生命的。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;ieee80211_crypt: registered algorithm 'NULL'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这东西我不知道所言何物，按照rae老兄的指示，我用Ubuntu LiveCD测试了一下，乖乖！&lt;br /&gt;Gnome下的NetworkManager工具直接提示我输入无限网接入密码。实在是太自卑了！&lt;br /&gt;我查看了一下dmesg info。&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;ieee80211_crypt: registered algorithm 'WEP'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这显然是ieee80211加密算法的问题。我重新编译内核，加入了ieee80211_crypt_wep模块。&lt;br /&gt;&lt;br /&gt;然后又是启动服务的时候报错，我使用的是wpa_supplicant。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;ipw2100: Fatal interrupt. Scheduling firmware restart.&lt;br /&gt;ipw2100: exit - failed to send CARD_DISABLE command&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;我始终没有尝试过转换角度，如果早些时候可以退一步，来使用iwconfig配置，如果我像昨&lt;br /&gt;天一样轻轻的敲入一个iwconfig命令，我就可以发现世界是多么的美好。&lt;br /&gt;&lt;br /&gt;事情很奇妙，不是么？有选择，就有出路。这就是Linux。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-1765534941855137113?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/1765534941855137113/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/gentooipw2100.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1765534941855137113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1765534941855137113'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/gentooipw2100.html' title='Gentoo配置无限网卡ipw2100'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-5897775020632519588</id><published>2008-09-23T12:45:00.010+08:00</published><updated>2011-03-17T16:20:56.402+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>9月21日移步老虎涧</title><content type='html'>17爬爬吧在最近有了突飞的进步：它的QQ群成为高级群，开始过多容纳更多的驴友；爬爬吧&lt;br /&gt;也有了自己的队旗；他也有了自己的贴吧。&lt;br /&gt;&lt;br /&gt;活动组织：&lt;a href="http://tieba.baidu.com/f?kz=478862495"&gt;http://tieba.baidu.com/f?kz=478862495&lt;/a&gt;&lt;br /&gt;GoogleMaps:&lt;br /&gt;&lt;a href="http://maps.google.com/maps/ms?ie=UTF&amp;amp;msa=0&amp;amp;msid=102563878911537749872.000456f0206e6b722a6c2"&gt;http://maps.google.com/maps/ms?ie=UTF&amp;amp;msa=0&amp;amp;msid=102563878911537749872.000456f0206e6b722a6c2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;这次的活动，选取了梧桐山的老虎涧。这是非常适合溯溪登山，前往梧桐山的一条捷径。但&lt;br /&gt;是这次的活动人数过多（35人），因此没有选择达到大梧桐峰作为目的地。行程将要选择经&lt;br /&gt;历三个瀑布，然后环山路到恩上村，午饭后搭乘饭馆老板的车，沿着新开的盐田高速下山。&lt;br /&gt;&lt;br /&gt;这就是“17爬爬吧”的队旗，上面清楚的写上Q群的号码，和群的性质：深圳户外。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNh2UUfxVxI/AAAAAAAAA14/oKBa5T2CDXk/s1600-h/IMG_3171.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNh2UUfxVxI/AAAAAAAAA14/oKBa5T2CDXk/s320/IMG_3171.JPG" alt="" id="BLOGGER_PHOTO_ID_5249075457171740434" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;这次的人非常之多，也有了明细的分工。包括领队黄瓜，中间Wick（我），结尾老狼，还有&lt;br /&gt;队医米卡飞飞。装备完善，可谓作足了准备阿！&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNh2UmEtFHI/AAAAAAAAA2A/44sL6JLCLAQ/s1600-h/IMG_3172.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNh2UmEtFHI/AAAAAAAAA2A/44sL6JLCLAQ/s320/IMG_3172.JPG" alt="" id="BLOGGER_PHOTO_ID_5249075461890053234" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNh2U__D4jI/AAAAAAAAA2I/34VWl0vjAsk/s1600-h/IMG_3173.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNh2U__D4jI/AAAAAAAAA2I/34VWl0vjAsk/s320/IMG_3173.JPG" alt="" id="BLOGGER_PHOTO_ID_5249075468845703730" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;马上临近十一了，黄金周的气氛洋溢在每个人的脸上。&lt;br /&gt;除了我们以外，仍旧有别的户外组织和我们一起同行。达到第一个瀑布，已经有小伙子们按&lt;br /&gt;捺不住，跳入清泉。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SNh2VdkbnUI/AAAAAAAAA2Q/YecML0zqfpI/s1600-h/IMG_3178.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SNh2VdkbnUI/AAAAAAAAA2Q/YecML0zqfpI/s320/IMG_3178.JPG" alt="" id="BLOGGER_PHOTO_ID_5249075476787076418" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;第二个瀑布最热闹，大堆的小伙子前赴后继跳入瀑布中，有如下饺子一样。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNh2WMOxSxI/AAAAAAAAA2Y/vr7VBeegKWA/s1600-h/IMG_3183.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNh2WMOxSxI/AAAAAAAAA2Y/vr7VBeegKWA/s320/IMG_3183.JPG" alt="" id="BLOGGER_PHOTO_ID_5249075489312688914" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;老虎涧坡度要比马峦山陡峭，水流更多，岩石更滑，因此难度也更大。如果要选择溯溪，一&lt;br /&gt;定要有防滑鞋。还有不爱穿袜子的女孩子，一定要注意了，这对爬山都相当不利。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi0-sLd91I/AAAAAAAAA3o/mf7dGa8TOHs/s1600-h/IMG_3216.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi0-sLd91I/AAAAAAAAA3o/mf7dGa8TOHs/s320/IMG_3216.JPG" alt="" id="BLOGGER_PHOTO_ID_5249144354804463442" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SNi0-0fB-UI/AAAAAAAAA3w/aiYyf-zk3_o/s1600-h/IMG_3223.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SNi0-0fB-UI/AAAAAAAAA3w/aiYyf-zk3_o/s320/IMG_3223.JPG" alt="" id="BLOGGER_PHOTO_ID_5249144357033998658" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;梧桐山也是一个出色的绿色生态系统，有着繁多的动植物品种。但是沿途只发现蚂蚁和蜘蛛&lt;br /&gt;……&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi0_RCIP5I/AAAAAAAAA34/It7t-f3vjjw/s1600-h/IMG_3233.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi0_RCIP5I/AAAAAAAAA34/It7t-f3vjjw/s320/IMG_3233.JPG" alt="" id="BLOGGER_PHOTO_ID_5249144364697403282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;第三个瀑布，很是漂亮。从这里分道，一队直奔大梧桐峰，而大部队则环山绕道恩上村。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SNi0_7dJ9xI/AAAAAAAAA4A/ysjVSMjin7U/s1600-h/IMG_3236-1.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SNi0_7dJ9xI/AAAAAAAAA4A/ysjVSMjin7U/s320/IMG_3236-1.JPG" alt="" id="BLOGGER_PHOTO_ID_5249144376085051154" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;恩上村一路平坦，会经过梧桐山的爬坡。小队推进速度很快。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNi1AYCxrYI/AAAAAAAAA4I/ziWW_DMXHIM/s1600-h/IMG_3241.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNi1AYCxrYI/AAAAAAAAA4I/ziWW_DMXHIM/s320/IMG_3241.JPG" alt="" id="BLOGGER_PHOTO_ID_5249144383759035778" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;面朝沙头角的一面，可以看到盐田港，对面就是香港。很多联通的朋友可以收到香港的信号。&lt;br /&gt;还可以看到Minsk航母。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi2I9tQU8I/AAAAAAAAA4Q/XFw5HlDxtUQ/s1600-h/IMG_3244.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi2I9tQU8I/AAAAAAAAA4Q/XFw5HlDxtUQ/s320/IMG_3244.JPG" alt="" id="BLOGGER_PHOTO_ID_5249145630819898306" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi2JKbpyYI/AAAAAAAAA4Y/LCUuj6GC86g/s1600-h/IMG_3243.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi2JKbpyYI/AAAAAAAAA4Y/LCUuj6GC86g/s320/IMG_3243.JPG" alt="" id="BLOGGER_PHOTO_ID_5249145634235730306" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;登山路途艰辛，到达恩上村时开始一路平坦。沿途汗水和足迹，印证老虎涧的历程。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi2JtfNCnI/AAAAAAAAA4g/GdqF1BCu7GE/s1600-h/IMG_3246.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi2JtfNCnI/AAAAAAAAA4g/GdqF1BCu7GE/s320/IMG_3246.JPG" alt="" id="BLOGGER_PHOTO_ID_5249145643645864562" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNi2J15TwmI/AAAAAAAAA4o/axC2GAsLnOk/s1600-h/IMG_3245.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNi2J15TwmI/AAAAAAAAA4o/axC2GAsLnOk/s320/IMG_3245.JPG" alt="" id="BLOGGER_PHOTO_ID_5249145645902840418" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;恩上大坝，风景优美。这里奉上集体照。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNi4Q1mbn2I/AAAAAAAAA44/48ynVofLGLE/s1600-h/IMG_0538.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNi4Q1mbn2I/AAAAAAAAA44/48ynVofLGLE/s320/IMG_0538.JPG" alt="" id="BLOGGER_PHOTO_ID_5249147965106003810" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi2J8CgLNI/AAAAAAAAA4w/_8UQz3iV8TI/s1600-h/IMG_3247.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi2J8CgLNI/AAAAAAAAA4w/_8UQz3iV8TI/s320/IMG_3247.JPG" alt="" id="BLOGGER_PHOTO_ID_5249145647552015570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;到达恩上村时候已经下午两点，我们开始坐下。村庄里的景色非常优美，和马峦山不相上下。&lt;br /&gt;这里还保持着田园耕作的方式，很多作物可以自给自足，无公害的绿色蔬菜也是美味。&lt;br /&gt;在等菜的当儿，大家伙儿按捺不住，开始搓起麻将。广东麻将有如内地的扑克一样普及啊～&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi4Rc9q3vI/AAAAAAAAA5A/5_Va2JLYaNU/s1600-h/IMG_3254.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SNi4Rc9q3vI/AAAAAAAAA5A/5_Va2JLYaNU/s320/IMG_3254.JPG" alt="" id="BLOGGER_PHOTO_ID_5249147975672454898" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi4RrzLyII/AAAAAAAAA5I/Bc3zUo6C-LQ/s1600-h/IMG_3257.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi4RrzLyII/AAAAAAAAA5I/Bc3zUo6C-LQ/s320/IMG_3257.JPG" alt="" id="BLOGGER_PHOTO_ID_5249147979655006338" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;饭馆老板送我们下山，下山路将经过新修的盐田高速公路，环山绕道而下，有种GT赛车的感&lt;br /&gt;觉。（这是沿途汽车抗议我们的偷拍）&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi4R_NWBRI/AAAAAAAAA5Q/D0c4ZZ_MhC4/s1600-h/IMG_3263.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi4R_NWBRI/AAAAAAAAA5Q/D0c4ZZ_MhC4/s320/IMG_3263.JPG" alt="" id="BLOGGER_PHOTO_ID_5249147984865002770" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi4SIDpkVI/AAAAAAAAA5Y/oo-Do3YB31Q/s1600-h/IMG_3271.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi4SIDpkVI/AAAAAAAAA5Y/oo-Do3YB31Q/s320/IMG_3271.JPG" alt="" id="BLOGGER_PHOTO_ID_5249147987240259922" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;这是山脚下的盐田区法院，旁边是盐田区文化馆。从外表来看，宏伟的难以想象啊……&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNi6iVLhurI/AAAAAAAAA5g/RfZ1GFk1rTg/s1600-h/IMG_3272.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNi6iVLhurI/AAAAAAAAA5g/RfZ1GFk1rTg/s320/IMG_3272.JPG" alt="" id="BLOGGER_PHOTO_ID_5249150464664124082" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi6iRJEAGI/AAAAAAAAA5o/D8ufxu6RTeM/s1600-h/IMG_3273.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNi6iRJEAGI/AAAAAAAAA5o/D8ufxu6RTeM/s320/IMG_3273.JPG" alt="" id="BLOGGER_PHOTO_ID_5249150463580045410" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;谢谢观赏～&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-5897775020632519588?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/5897775020632519588/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/921.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/5897775020632519588'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/5897775020632519588'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/921.html' title='9月21日移步老虎涧'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Kb-lr4qFtj4/SNh2UUfxVxI/AAAAAAAAA14/oKBa5T2CDXk/s72-c/IMG_3171.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-4781080301266855818</id><published>2008-09-20T16:32:00.013+08:00</published><updated>2011-03-06T11:24:39.825+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>[TIC++] C3. C in C++</title><content type='html'>&lt;span style="font-weight: bold;font-size:180%;" &gt;代码阅读&amp;lt;Thinking in C++&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Chapter 3. C in C++&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、指针运算&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//ptr_math.c&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;#define P(EX) cout &amp;lt;&amp;lt; #EX &amp;lt;&amp;lt; ": " &amp;lt;&amp;lt; EX &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;    int a[10];&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &amp;lt; 10; i++)&lt;br /&gt;        a[i] = i;&lt;br /&gt;&lt;br /&gt;    int *ip = a;&lt;br /&gt;    P(*ip);&lt;br /&gt;    P(*++ip);&lt;br /&gt;    P(*(ip + 5));&lt;br /&gt;&lt;br /&gt;    int *ip2 = ip + 5;&lt;br /&gt;    P(*ip2);&lt;br /&gt;    P(*(ip2 - 4));&lt;br /&gt;    P(*--ip2);&lt;br /&gt;    P(ip2 - ip);&lt;br /&gt;}&lt;br /&gt;/* result:&lt;br /&gt;*ip: 0&lt;br /&gt;*++ip: 1&lt;br /&gt;*(ip + 5): 6&lt;br /&gt;*ip2: 6&lt;br /&gt;*(ip2 - 4): 2&lt;br /&gt;*--ip2: 5&lt;br /&gt;ip2 - ip: 4&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;C中强大的指针在C++里得到很好的保留，指针的灵活也给初学者带来困惑&lt;br /&gt;1. `#EX'宏定义，此宏定义，将直接迭代打印变量名称（而不是变量值）&lt;br /&gt;2. 指针是带有其类型信息的，根据信息，编译器理解指针运算的单位。&lt;br /&gt;   int  *pi;&lt;br /&gt;   char *pc = (char*)pi;&lt;br /&gt;   pi++; //int型指针跳转4个字节&lt;br /&gt;   pc++; //char指针增加1个字节&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、介绍引用&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//pass_reference.cpp&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;void f(int&amp;amp; r)  //reference&lt;br /&gt;{&lt;br /&gt;    cout &amp;lt;&amp;lt; "r  = " &amp;lt;&amp;lt; r &amp;lt;&amp;lt; endl;&lt;br /&gt;    cout &amp;lt;&amp;lt; "&amp;amp;r = " &amp;lt;&amp;lt; &amp;amp;r &amp;lt;&amp;lt; endl;&lt;br /&gt;    r = 5;&lt;br /&gt;    cout &amp;lt;&amp;lt; "r  = " &amp;lt;&amp;lt; r &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;    int x = 47;&lt;br /&gt;&lt;br /&gt;    cout &amp;lt;&amp;lt; "x  = " &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;    cout &amp;lt;&amp;lt; "&amp;amp;x = " &amp;lt;&amp;lt; &amp;amp;x &amp;lt;&amp;lt; endl;&lt;br /&gt;    f(x);&lt;br /&gt;    cout &amp;lt;&amp;lt; "x  = " &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;/* result:&lt;br /&gt;x  = 47&lt;br /&gt;&amp;amp;x = 0xbfbb29ac&lt;br /&gt;r  = 47&lt;br /&gt;&amp;amp;r = 0xbfbb29ac&lt;br /&gt;r  = 5&lt;br /&gt;x  = 5&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;引用是C++中的新概念，相当于给变量起了一个新名字。通常用于参数传递。&lt;br /&gt;* C中允许传值，和传址两中方式，在C++又包含了传递引用。&lt;br /&gt;* 传递引用和传址不一样的是，调用方只是传递变量，而非该变量的指针，被调用函数则心&lt;br /&gt;  领神会，隐性得到参数地址(&amp;amp;r = &amp;amp;x)。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;三、C++中的类型转换&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//dynamic_cast.cpp&lt;br /&gt;class Base&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;    int m_iNum;&lt;br /&gt;    virtual void foo() {};  //缺少虚函数会报错&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Derived: public Base&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;    char *m_szName[100];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;    Base *pb;&lt;br /&gt;    Derived *pd1 = static_cast&amp;lt;Derived *&amp;gt;(pb);&lt;br /&gt;    Derived *pd2 = dynamic_cast&amp;lt;Derived *&amp;gt;(pb);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(非TIC++代码)&lt;br /&gt;dynamic_cast 是C++引入的类型转换方法，其他另外还有三个标准方法，这里将举例介绍&lt;br /&gt;dynamic_cast和const_cast。&lt;br /&gt;static_cast是静态类型转换，他仅要求：不可以在无关类型间转换。在基类和子类的指针&lt;br /&gt;和引用转换过程中，其下行转换是危险的（即便可能通过），因为static_cast不会进行类&lt;br /&gt;型转换。&lt;br /&gt;dynamic_cast则弥补了这个缺陷，上下行转换都会进行类型检查，不符合的时候会返回NULL&lt;br /&gt;指针，表明转换失败（而不是报错）。值得注意的是，下行转换的时候dynamic_cast要求基&lt;br /&gt;类保留纯虚函数，否则会报错（因为纯虚函数拥有包含运行时类型信息的虚函数表，无虚函&lt;br /&gt;数是没有虚函数表的）。&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//const_cast.cpp&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;    const int i = 0;&lt;br /&gt;&lt;br /&gt;    int *j = (int*)&amp;i;                // deprecated form&lt;br /&gt;    j = const_cast&amp;lt;int*&amp;gt;(&amp;amp;i);         // preferred, only int* to int*&lt;br /&gt;//    long *l = const_cast&amp;lt;long*&amp;gt;(&amp;amp;i);  // int* to long*? invalid!&lt;br /&gt;    volatile int k = 0;&lt;br /&gt;    int *u = const_cast&amp;lt;int*&amp;gt;(&amp;amp;k);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;const_cast&amp;lt;TYPE&amp;gt;(expression)仍然是C++的标准类型转换方法。他用来转换const和&lt;br /&gt;volatile（比如常量指针转换为非常量指针）。有一个要求，那就是要求TYPE和express类&lt;br /&gt;型必须一致。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-4781080301266855818?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/4781080301266855818/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/tic-c3-c-in-c.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/4781080301266855818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/4781080301266855818'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/tic-c3-c-in-c.html' title='[TIC++] C3. C in C++'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-9167030723121991654</id><published>2008-09-20T16:23:00.007+08:00</published><updated>2011-03-06T11:24:39.830+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>[TIC++] C2. Making objects</title><content type='html'>代码阅读 &amp;lt;Thinking in C++&amp;gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Chapter 2. Making Objects&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;一、第一个C++程序&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//hello.cpp---------------------&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;// cout is an object&lt;br /&gt;// `&amp;lt;&amp;lt;' is an overloaded operator&lt;br /&gt;// `namespace' is used to prevent name collisionx&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt; cout &amp;lt;&amp;lt; "Hello world! "&lt;br /&gt;      &amp;lt;&amp;lt; "I am "  &amp;lt;&amp;lt; 8&lt;br /&gt;      &amp;lt;&amp;lt; " today!"&amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;这是C++的第一个代码程序。和大多其他语言的教材一样，Bruce Eckel也选择了`Hello&lt;br /&gt;world!'这样一个程序来开启C++之门。这个程序的框架和C极其相似，有头文件包含，main&lt;br /&gt;函数等等。&lt;br /&gt;&lt;br /&gt;1. &amp;lt;iostream&amp;gt;是C++的标准头文件，这些头文件包含了标准数据结构定义和函数的索引。他&lt;br /&gt;  们位于: /usr/lib/gcc/i686-pc-linux-gnu/4.3.1/include&lt;br /&gt;  (在`gcc -v'中可以查询configure项：includedir)&lt;br /&gt;2. namespace是C++引入的概念，为了避免命名污染，C++用namespace来指定一些变量的可&lt;br /&gt;  视范围(scope)，`using namespace std'是使用std标准命名空间。&lt;br /&gt;3. cout是iostream中定义的一系列标准对象，`&amp;lt;&amp;lt;'则实现了cout对象的运算符重载，作用&lt;br /&gt;  是将字符等对象输出到标准输出对象cout。&lt;br /&gt;&lt;br /&gt;iostream定义标准对象有：&lt;br /&gt;   * cout&lt;br /&gt;     一个ostream类的对象，用来打印数据到标准输出设备(STDOUT)&lt;br /&gt;   * cerr&lt;br /&gt;     也是ostream类的对象，将非缓冲输出数据写入到标准错误设备(STDERR)&lt;br /&gt;   * clog&lt;br /&gt;     和cerr相似，但是使用缓冲方式输出&lt;br /&gt;   * cin&lt;br /&gt;     istream，用来从标准输入设备中读取数据(STDIN)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;二、numconv.cpp&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//numconv.cpp---------------------&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt; int number;&lt;br /&gt;&lt;br /&gt; cout &amp;lt;&amp;lt; "please input the number : ";&lt;br /&gt; cin  &amp;gt;&amp;gt; number;&lt;br /&gt; cout &amp;lt;&amp;lt; "value in octal =  0" &amp;lt;&amp;lt; oct &amp;lt;&amp;lt; number &amp;lt;&amp;lt; endl;&lt;br /&gt; cout &amp;lt;&amp;lt; "value in hex   = 0x" &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; number &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;程序从终端读取一个整数，以八进制和十六进制将其打印，展现的是重载运算符的灵活用法。&lt;br /&gt;输出说明：&lt;br /&gt; 1. 如果输入起始字符不是整数，则打印无规则数据。（？）&lt;br /&gt; 2. 如果输入起始字符是整数，则一直读取到不是字符或者换行符，然后打印。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;三、文件流介绍&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//scopy.cpp---------------------&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt; ifstream in("Makefile");&lt;br /&gt; ofstream out("output");&lt;br /&gt; string s;&lt;br /&gt;&lt;br /&gt; // don't worry about how much storage to allocate for a string&lt;br /&gt; // just add things to it!&lt;br /&gt; while (getline(in, s))&lt;br /&gt;  out &amp;lt;&amp;lt; s &amp;lt;&amp;lt; "\n";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;读取文件Makefile，按行打印到文件output（一次输出一行）。&lt;br /&gt;* ifstream和ostream是来自&amp;lt;fstream&amp;gt;的类，负责建立文件流对象（读和写）。&lt;br /&gt;* string是C++的内建类，这里不必再去担心如何为string对象分配空间。&lt;br /&gt;* getline来源于&amp;lt;string&amp;gt;。&lt;br /&gt; istream&amp;amp; getline( istream&amp;amp; is, string&amp;amp; s, char delimiter = '\n' );&lt;br /&gt;* out如同标准对象cout一样，可以使用重载运算符`&amp;lt;&amp;lt;'。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;四、介绍vector&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//getwords.cpp---------------------&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;vector&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt; vector&amp;lt;string&amp;gt; v;&lt;br /&gt; ifstream in("Makefile");&lt;br /&gt;&lt;br /&gt;// string line;&lt;br /&gt;// while (getline(in, line)) // (1)&lt;br /&gt;//  v.push_back(line);&lt;br /&gt; string word;&lt;br /&gt; while (in &amp;gt;&amp;gt; word)        // (2)&lt;br /&gt;  v.push_back(word);&lt;br /&gt;&lt;br /&gt; for (int i = 0; i &amp;lt; v.size(); i++)&lt;br /&gt;  cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; ": " &amp;lt;&amp;lt; v[i] &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;使用C++标准模板类vector。&lt;br /&gt;1. vector是C++的标准模板类，作为C++代码可重用性的体现，STL一直是C++中变动频繁的&lt;br /&gt;  地方。&lt;br /&gt;2. vector&amp;lt;string&amp;gt;将临近元素像数组一样存储。&lt;br /&gt;  vector成员赋值和添加元素都可以在O(k)中完成，查找和插入则在O(k*n)中完成。&lt;br /&gt;  vector支持一系列操作（cppreference.com）：&lt;br /&gt;&lt;pre class="prettyprint"&gt;  &lt;br /&gt; /* vector&amp;lt;TYPE&amp;gt;:&lt;br /&gt;  * void assign( size_type num, const TYPE&amp;amp; val );&lt;br /&gt;  * void assign( input_iterator start, input_iterator end );&lt;br /&gt;  * void   insert( iterator loc, size_type num, const TYPE&amp;amp; val );&lt;br /&gt;  * void push_back( const TYPE&amp;amp; val );&lt;br /&gt;  */&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-9167030723121991654?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/9167030723121991654/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/c2-making-objects.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/9167030723121991654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/9167030723121991654'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/c2-making-objects.html' title='[TIC++] C2. Making objects'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-5315560607322339013</id><published>2008-09-20T16:04:00.005+08:00</published><updated>2011-03-06T11:24:39.836+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lang-cpp'/><title type='text'>代码阅读TIC++：序章</title><content type='html'>一、硬件环境&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;IBM Thinkpad R50&lt;br /&gt;Intel Pentium M 1400MHz&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;二、软件环境&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;Gentoo Linux 2008.0&lt;br /&gt;linux-2.6.26-gentoo&lt;br /&gt;GCC 4.3.1&lt;br /&gt;GNU binutils 2.1.8&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;GCC编译器，其具体信息可以通过`gcc -v'来查询：&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  Using built-in specs.&lt;br /&gt;  Target: i686-pc-linux-gnu&lt;br /&gt;  Configured with:&lt;br /&gt;  /var/tmp/portage/sys-devel/gcc-4.3.1/work/gcc-4.3.1/configure&lt;br /&gt;  --prefix=/usr&lt;br /&gt;  --bindir=/usr/i686-pc-linux-gnu/gcc-bin/4.3.1&lt;br /&gt;  --includedir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.1/include&lt;br /&gt;  --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.1&lt;br /&gt;  --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.1/man&lt;br /&gt;  --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.1/info&lt;br /&gt;  --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.1/include/g++-v4&lt;br /&gt;  --host=i686-pc-linux-gnu&lt;br /&gt;  --build=i686-pc-linux-gnu&lt;br /&gt;  --disable-altivec&lt;br /&gt;  --enable-nls&lt;br /&gt;  --without-included-gettext&lt;br /&gt;  --with-system-zlib&lt;br /&gt;  --disable-checking&lt;br /&gt;  --disable-werror&lt;br /&gt;  --enable-secureplt&lt;br /&gt;  --disable-multilib&lt;br /&gt;  --enable-libmudflap&lt;br /&gt;  --disable-libssp&lt;br /&gt;  --enable-cld&lt;br /&gt;  --disable-libgcj&lt;br /&gt;  --with-arch=i686&lt;br /&gt;  --enable-languages=c,c++,treelang,fortran&lt;br /&gt;  --enable-shared&lt;br /&gt;  --enable-threads=posix&lt;br /&gt;  --enable-__cxa_atexit&lt;br /&gt;  --enable-clocale=gnu&lt;br /&gt;  --with-bugurl=http://bugs.gentoo.org/&lt;br /&gt;  --with-pkgversion='Gentoo 4.3.1 p1.0'&lt;br /&gt;Thread model: posix&lt;br /&gt;gcc version 4.3.1 (Gentoo 4.3.1 p1.0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;三、关于《Thinking in C++》&lt;br /&gt;《Thinking in C++》是C++非常出色的教材类书籍，作者是Bruce Eckel&lt;br /&gt;（同时也是《Thinking in Java》的作者）。&lt;br /&gt;你可以在&lt;a href="http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html"&gt;这里&lt;/a&gt;查看到他的全面信息，同样在&lt;a href="http://www.mindview.net/Books/DownloadSites"&gt;这里&lt;/a&gt;可以下载电子版图书。&lt;br /&gt;&lt;br /&gt;四、代码编译&lt;br /&gt;在下载的文件里，一般都包含有书籍里的代码。&lt;br /&gt;编译他们是很简单的，通常情况下，执行一下命令，就可以得到可执行文件 a.out.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;g++ filename.cpp&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;线程的例子需要在加上另外的POSIX thread支持的gcc选项`-pthread'。&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;g++ filename.cpp -pthread&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;多文件项目可以自己简单的写出Makefile，在此不再赘述。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-5315560607322339013?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/5315560607322339013/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_20.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/5315560607322339013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/5315560607322339013'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_20.html' title='代码阅读TIC++：序章'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-6379211843746999365</id><published>2008-09-14T23:30:00.009+08:00</published><updated>2011-03-17T16:20:56.404+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>中秋佳节，马峦山溯溪</title><content type='html'>深圳的秋老虎气候接近尾声了，对于一个属于盛夏的城市，我们目送深圳夏天离去，一个最&lt;br /&gt;好的方式，就是爬山、流汗。9月14日又是中秋节，因此对马峦山的聚会倍加期待。&lt;br /&gt;&lt;br /&gt;那先说一下啥是溯溪，溯溪并非爬山，而是沿着溪流顺山而上。这说明活动围绕水而展开，&lt;br /&gt;而不是徒步登山。&lt;br /&gt;&lt;br /&gt;这次登山的目的地，选择了深圳的马峦山，在深圳小梅沙的北部。海拔300～590米，在盛夏&lt;br /&gt;山上气温比深圳市区要低3摄氏度。马峦山没有工业污染，空气清新，没有城市噪音，环境&lt;br /&gt;质量相当之高。&lt;br /&gt;&lt;br /&gt;活动：马峦山溯溪&lt;br /&gt;人数：26人&lt;br /&gt;官方Q群：4565678&lt;br /&gt;贴吧：http://tieba.baidu.com/f?kz=477382839&lt;br /&gt;&lt;br /&gt;公交线路：103（上下沙），360（银湖），364（深航大厦），387（火车站），833（龙岗）&lt;br /&gt;GoogleEarth地址：&lt;br /&gt;http://maps.google.com/maps/ms?ie=UTF&amp;amp;msa=0&amp;amp;msid=102563878911537749872.000456ae6390c1a543d9d&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;活动开始……&lt;br /&gt;&lt;br /&gt;这是深圳海洋世界正门，这是小梅沙旁边极其出名的水上游乐园，大家在里面可以看到的东&lt;br /&gt;东，从南极企鹅，北极熊，到海豚表演等等。门票100元/人，咱们只是沿途看看，咱们都不&lt;br /&gt;说话。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM00RDU2jDI/AAAAAAAAAec/qYi0EVj33-E/s1600-h/IMG_3097.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM00RDU2jDI/AAAAAAAAAec/qYi0EVj33-E/s320/IMG_3097.JPG" alt="" id="BLOGGER_PHOTO_ID_5245906608511683634" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;领队：黄瓜，看这装备可谓具备专业驴友素质，头巾，登山包，还有刚买的Canon EOS&lt;br /&gt;1000D，那是相当的骚包。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM00RcqSGcI/AAAAAAAAAek/dbX5zxtWXnI/s1600-h/IMG_3098.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM00RcqSGcI/AAAAAAAAAek/dbX5zxtWXnI/s320/IMG_3098.JPG" alt="" id="BLOGGER_PHOTO_ID_5245906615312456130" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;大部队跟上，我来垫后。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM07X6IYoTI/AAAAAAAAAfE/GkN014Toneo/s1600-h/IMG_3101.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM07X6IYoTI/AAAAAAAAAfE/GkN014Toneo/s320/IMG_3101.JPG" alt="" id="BLOGGER_PHOTO_ID_5245914422883950898" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;途径叠翠湖，风景不算精致，倒是没有污染，感觉很好。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SM00R_hSThI/AAAAAAAAAes/d7T_e38NMeA/s1600-h/IMG_3103.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SM00R_hSThI/AAAAAAAAAes/d7T_e38NMeA/s320/IMG_3103.JPG" alt="" id="BLOGGER_PHOTO_ID_5245906624669961746" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM00SMh2UpI/AAAAAAAAAe0/YbUzx1_DcRs/s1600-h/IMG_3104.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM00SMh2UpI/AAAAAAAAAe0/YbUzx1_DcRs/s320/IMG_3104.JPG" alt="" id="BLOGGER_PHOTO_ID_5245906628161983122" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;溯溪自然是顺溪流直上，因此攀岩必不可少，也具备一定的危险性。如果选择溯溪，定要具&lt;br /&gt;备足够的水源和登山鞋。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM00SeFvaDI/AAAAAAAAAe8/L7iwOedpkzQ/s1600-h/IMG_3106.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM00SeFvaDI/AAAAAAAAAe8/L7iwOedpkzQ/s320/IMG_3106.JPG" alt="" id="BLOGGER_PHOTO_ID_5245906632875927602" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM07YRU1_uI/AAAAAAAAAfM/PhNbtgt0nOI/s1600-h/IMG_3121.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM07YRU1_uI/AAAAAAAAAfM/PhNbtgt0nOI/s320/IMG_3121.JPG" alt="" id="BLOGGER_PHOTO_ID_5245914429110222562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;沿途的细沙，给了一特写。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM07Y0Jd7OI/AAAAAAAAAfU/jZHPdK3znOM/s1600-h/IMG_3108.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM07Y0Jd7OI/AAAAAAAAAfU/jZHPdK3znOM/s320/IMG_3108.JPG" alt="" id="BLOGGER_PHOTO_ID_5245914438457748706" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;除了体验大自然的意趣，团队协作也是有意思的部分。需要大家向朋友伸出双手，感受彼此&lt;br /&gt;的关怀。当然关怀之外有啥大事儿发生，当然需要当事人负责的。。。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM07ZBlG49I/AAAAAAAAAfc/od6_FOStTvA/s1600-h/IMG_3116.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM07ZBlG49I/AAAAAAAAAfc/od6_FOStTvA/s320/IMG_3116.JPG" alt="" id="BLOGGER_PHOTO_ID_5245914442063340498" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM07ZfElkpI/AAAAAAAAAfk/fFEKz2-Eq9o/s1600-h/IMG_3115.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM07ZfElkpI/AAAAAAAAAfk/fFEKz2-Eq9o/s320/IMG_3115.JPG" alt="" id="BLOGGER_PHOTO_ID_5245914449980002962" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;非常喜欢的瀑布！我们还跳入水里游泳，打闹。让几天来的郁闷一扫而光。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM09PmIVYUI/AAAAAAAAAfs/obirkQsFxxQ/s1600-h/IMG_3123.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM09PmIVYUI/AAAAAAAAAfs/obirkQsFxxQ/s320/IMG_3123.JPG" alt="" id="BLOGGER_PHOTO_ID_5245916479099330882" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;披荆斩棘之后迎来山顶前的冲刺部分，黄瓜告诉咱们，到山顶就可以吃饭了。有美味的土家&lt;br /&gt;烧鸡等着我们。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM09PzPoWYI/AAAAAAAAAf0/07Z0NThFg08/s1600-h/IMG_3125.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM09PzPoWYI/AAAAAAAAAf0/07Z0NThFg08/s320/IMG_3125.JPG" alt="" id="BLOGGER_PHOTO_ID_5245916482619595138" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM09QFRygiI/AAAAAAAAAf8/VUPiLK1fE3w/s1600-h/IMG_3130.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM09QFRygiI/AAAAAAAAAf8/VUPiLK1fE3w/s320/IMG_3130.JPG" alt="" id="BLOGGER_PHOTO_ID_5245916487460487714" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;到达山顶的农家，店家开始现杀现做，准备咱们的午饭。这里风光无限。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM09QlHKVWI/AAAAAAAAAgE/cHO71bsPqUc/s1600-h/IMG_3134.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM09QlHKVWI/AAAAAAAAAgE/cHO71bsPqUc/s320/IMG_3134.JPG" alt="" id="BLOGGER_PHOTO_ID_5245916496005846370" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM09Q1odV2I/AAAAAAAAAgM/Tv2YwPaR2oY/s1600-h/IMG_3135.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM09Q1odV2I/AAAAAAAAAgM/Tv2YwPaR2oY/s320/IMG_3135.JPG" alt="" id="BLOGGER_PHOTO_ID_5245916500440471394" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;今天是中秋节活动，避不了的是中秋月饼，还有主角土家烧鸡。当然这里可以看到是二十六&lt;br /&gt;个人，分五个月饼，囧rz&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM0-1ewCRnI/AAAAAAAAAgU/htKzRvZUnQw/s1600-h/IMG_3132.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM0-1ewCRnI/AAAAAAAAAgU/htKzRvZUnQw/s320/IMG_3132.JPG" alt="" id="BLOGGER_PHOTO_ID_5245918229465024114" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM0-1qr17FI/AAAAAAAAAgc/jqlAxZ067jI/s1600-h/IMG_3141.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Kb-lr4qFtj4/SM0-1qr17FI/AAAAAAAAAgc/jqlAxZ067jI/s320/IMG_3141.JPG" alt="" id="BLOGGER_PHOTO_ID_5245918232668662866" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;待到四点钟下山，沿途疾步如飞。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM0-19tlLCI/AAAAAAAAAgk/icwGMSIVe7w/s1600-h/IMG_3142.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM0-19tlLCI/AAAAAAAAAgk/icwGMSIVe7w/s320/IMG_3142.JPG" alt="" id="BLOGGER_PHOTO_ID_5245918237776227362" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SM0-2AjRhZI/AAAAAAAAAgs/QIVNHNEnztc/s1600-h/IMG_3143.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SM0-2AjRhZI/AAAAAAAAAgs/QIVNHNEnztc/s320/IMG_3143.JPG" alt="" id="BLOGGER_PHOTO_ID_5245918238538302866" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;我们在夕阳下结束一天旅程。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM0-2Yq3K5I/AAAAAAAAAg0/0bTs1QHOH9E/s1600-h/IMG_3147.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM0-2Yq3K5I/AAAAAAAAAg0/0bTs1QHOH9E/s320/IMG_3147.JPG" alt="" id="BLOGGER_PHOTO_ID_5245918245012581266" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM0_Lrs6Z2I/AAAAAAAAAg8/hMViII4idlw/s1600-h/IMG_3146.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SM0_Lrs6Z2I/AAAAAAAAAg8/hMViII4idlw/s320/IMG_3146.JPG" alt="" id="BLOGGER_PHOTO_ID_5245918610898708322" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;谢谢观赏，而后会更新几张更加别致的照片……&lt;br /&gt;&lt;br /&gt;照片更新一张吧。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SM6MckKWBQI/AAAAAAAAAkc/k4o3Xx_7OCs/s1600-h/IMG_0326.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Kb-lr4qFtj4/SM6MckKWBQI/AAAAAAAAAkc/k4o3Xx_7OCs/s320/IMG_0326.JPG" alt="" id="BLOGGER_PHOTO_ID_5246285038304494850" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-6379211843746999365?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/6379211843746999365/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_14.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6379211843746999365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/6379211843746999365'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_14.html' title='中秋佳节，马峦山溯溪'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Kb-lr4qFtj4/SM00RDU2jDI/AAAAAAAAAec/qYi0EVj33-E/s72-c/IMG_3097.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-1821974840473441667</id><published>2008-09-12T20:01:00.004+08:00</published><updated>2011-03-17T16:23:06.176+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>小鑫光临深圳</title><content type='html'>前天小鑫发短信问我：深圳西站到深圳主站有多远？二十块钱打的行不？&lt;br /&gt;我回答：恩，二十块钱，我可以带你过去。&lt;br /&gt;小鑫：你现在买车了？&lt;br /&gt;我：架车，楼下房东的。&lt;br /&gt;&lt;br /&gt;我不明白为什么远在南京的小鑫会问我这样的问题，怎么突然对深圳感兴趣起来了？直到昨&lt;br /&gt;天下午吓了我一跳。小鑫打电话说：我下午五点会到深圳西站。我才明白这家伙是有预谋的。&lt;br /&gt;&lt;br /&gt;南头距离深圳西站非常的近，因此我选择徒步过去。四点半出门后我发现头上乌云，走到半&lt;br /&gt;路的时候，深圳吓起瓢泼大雨。眼前就是深圳西站，这让我很是郁闷。小鑫回话说：深圳的&lt;br /&gt;第一印象是雷声响、雨点大、来势猛、铺天盖地的大暴雨。哎，囧阿！&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SMpas2GEWjI/AAAAAAAAAT8/PIvuOmnVcio/s1600-h/IMG_3053.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Kb-lr4qFtj4/SMpas2GEWjI/AAAAAAAAAT8/PIvuOmnVcio/s320/IMG_3053.JPG" alt="" id="BLOGGER_PHOTO_ID_5245104442508073522" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;（这位老哥正准备进站，可是突降大雨又遇堵车）&lt;br /&gt;&lt;br /&gt;咱们在一家湘菜馆里坐下，小鑫感觉非常痛苦，一盘拆骨肉辣的是浑身冒汗。这才向我道来&lt;br /&gt;原由：由于小鑫在南京通过了华为的面试，这就到坂田的华为基地来面试呢。这华为效率还&lt;br /&gt;是冈冈地呢～&lt;br /&gt;&lt;br /&gt;吃饭的时候聊了很多，说说两年来干的活，一直都是又苦又累。且说上个工作以来，几乎是&lt;br /&gt;夜夜都要在十二点之后下班。这也不是公司的规定，氛围如此，倘若有人十点早退，也不会&lt;br /&gt;有人拦你。但当老班十一点开车夜巡的时候，发现你仍旧挑灯夜战，他也会夸你两句。对于&lt;br /&gt;深圳人来说，这样苦的差事也不是未听过，但是总不至于像南京那样普遍。如若在南京的你&lt;br /&gt;不喜，那你也可以走人，门槛外求职的人比比皆是。南京的工作压力能到这种地步？让我不&lt;br /&gt;解了……&lt;br /&gt;&lt;br /&gt;只道是终须一别，在送走小鑫之后，也唯有祝愿他工作蒸蒸日上，注意身体。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SMpatFj1JZI/AAAAAAAAAUE/t6Jl6SfIXj8/s1600-h/IMG_3056.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Kb-lr4qFtj4/SMpatFj1JZI/AAAAAAAAAUE/t6Jl6SfIXj8/s320/IMG_3056.JPG" alt="" id="BLOGGER_PHOTO_ID_5245104446659437970" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;（小鑫以奉献精神向大家问好，祝愿大家中秋快乐。此照片翻录必究）&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-1821974840473441667?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/1821974840473441667/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_12.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1821974840473441667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/1821974840473441667'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_12.html' title='小鑫光临深圳'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SMpas2GEWjI/AAAAAAAAAT8/PIvuOmnVcio/s72-c/IMG_3053.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-2649454099453796419</id><published>2008-09-02T11:29:00.005+08:00</published><updated>2011-03-17T16:23:49.314+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>记录腾讯面试</title><content type='html'>今天去了腾讯公司的老巢，坐落在飞亚达大楼的7层。&lt;br /&gt;&lt;br /&gt;第一次去的时候还是有点发蒙，因为飞亚达那里长时间施工，一时间晕头转向的绕道沙河立&lt;br /&gt;交后面。这样一折腾之后，浑身汗透了，和出道深圳的时候极其类似。&lt;br /&gt;&lt;br /&gt;在上电梯的时候，我就琢磨着，腾讯的势力有多大。因为4，5，6层电梯开门总是能看到正&lt;br /&gt;对面的腾讯前台，到了7层一问：小伙子，3楼到10楼都是腾讯地盘。一切简洁代过。&lt;br /&gt;&lt;br /&gt;技术型的面试就是简单，递给两张试题，圆珠笔，草稿纸，支个地方就可以了。我在作题目&lt;br /&gt;的时候还能看到后面的人在用source insight写代码，偶尔也会回头和我打招呼，对眼色。&lt;br /&gt;&lt;br /&gt;面试题目是核心，大家一定想知道很多。我应聘的是Linux后台开发（看到QQ大批的业务，&lt;br /&gt;他的后台却是Linux，你们大家如何想呢？），题目自然是关注Linux编程环境。面试的师傅&lt;br /&gt;问我作C还是C++，我答曰C。于是他给我抽出试卷B。&lt;br /&gt;&lt;br /&gt;题目总共两张，总共9道题，大致划分：&lt;br /&gt;&lt;br /&gt;编程环境，2道，execl调用，TCP select问题&lt;br /&gt;数据结构，3道，sizeof，数据存储，查找算法&lt;br /&gt;编程语言，1道，C++类存储&lt;br /&gt;算法，2道，算法分析和设计&lt;br /&gt;编程工具，1道，Makefile&lt;br /&gt;&lt;br /&gt;我基本都有答，不过有两个是彻底瞎蒙的。&lt;br /&gt;1. 问题输出结果&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#include "unistd.h"&lt;br /&gt;#include "stdio.h"&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt; printf("call execl");&lt;br /&gt; sleep(1);&lt;br /&gt; execl("/bin/sh", "", NULL);&lt;br /&gt; printf("error!\n");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;正解--&gt;&lt;br /&gt;这个东西只会输出ls结果，两个printf都是不输出的。&lt;br /&gt;首先，Linux IO是行缓冲形式，未遇到换行和强制输出是不数出的，待到execl执行后，创&lt;br /&gt;建新的进程映像，后面的printf也不会去执行。&lt;br /&gt;&lt;br /&gt;2. TCP通讯中，select到读事件，但是读到的数据量是0，为什么，如何解决。&lt;br /&gt;同步传输控制？我根本没使用过:(&lt;br /&gt;&lt;br /&gt;其他的基本通过，有一个问题很有意思。&lt;br /&gt;&lt;br /&gt;3. 假设电信每分钟登录次数是60w次，现在要提醒5分钟内重复登录的用户，如何设计程序&lt;br /&gt;缓存和查找算法？&lt;br /&gt;我说，数据库查询得到5分钟内拨号号码，然后根据号码建立位图数组。他反问我：你知道&lt;br /&gt;数组要有多大么？我答曰，假设足够大……&lt;br /&gt;我又说，为建立的号码列表排序，方便以后二分检索，他又反问：那如果我说这个程序是动&lt;br /&gt;态的呢？要知道随时都会有其他用户登录。我没法回答了。&lt;br /&gt;你咋不早说妮！！……&lt;br /&gt;&lt;br /&gt;----------&lt;br /&gt;&lt;br /&gt;这么多天来，我一直都在琢磨一个事情，为何自己的能力在一个阶段上，迟迟不能进步。老&lt;br /&gt;是想着作大项目，得到项目经验，却在一些大工程上不知道如何下手。我才发现一个严重的&lt;br /&gt;问题，我往往忽略了很多关键性和基础性的能力培养。数据结构和算法设计是两个核心的概&lt;br /&gt;念，除此之外，那些应付性的代码和蹩脚的设计根本无法谈上经验，似乎这两年都在无止境&lt;br /&gt;的乏味折腾。&lt;br /&gt;&lt;br /&gt;所以还是，千里之行，始于足下。如果极限概念模糊，也不要吝惜自己“宝贵”的时间，咬牙&lt;br /&gt;抱起高等数学吧。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-2649454099453796419?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/2649454099453796419/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_02.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2649454099453796419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/2649454099453796419'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/blog-post_02.html' title='记录腾讯面试'/><author><name>Wick</name><uri>http://www.blogger.com/profile/11312073580759197007</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Kb-lr4qFtj4/SNutrLXexDI/AAAAAAAAA-s/HMPLpdBuCNE/S220/brook.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4063622103172507649.post-3955349923710429328</id><published>2008-09-02T11:28:00.000+08:00</published><updated>2011-03-17T16:20:56.407+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='miscs'/><title type='text'>8月24日登顶梧桐峰</title><content type='html'>喜欢折腾的城市人一直有青睐。我同样觊觎梧桐山太长时间，来深&lt;br /&gt;圳的两年期间里多次想抚摸梧桐的脊梁，这次终于有机会了！借助黄瓜同志的大力组织，“17爬&lt;br /&gt;爬吧”成员大举向梧桐山进发。&lt;br /&gt;&lt;br /&gt;天气情况来看，台风“鹦鹉”昨日才离开，因此海洋里的水汽一定非常多，恰好今天天气一片&lt;br /&gt;大好，晴空万里，可谓天时地利。&lt;br /&gt;&lt;br /&gt;然后报一下路线，从地图上看，基本是看不出来啥的，我也不知道当初采用了哪条小路。大&lt;br /&gt;概的说，9:30从左上方的梧桐山村出发，长途跋涉到梧桐山顶峰(13:20)，然后下登山道到好&lt;br /&gt;汉坡停车场，经历环山道回到梧桐山村(18:30)。（梧桐山村 -- 大梧桐顶 -- 好汉坡停车场&lt;br /&gt;-- 梧桐山村）&lt;br /&gt;（Google地图上显示的梧桐山）&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLvSMKrKfI/AAAAAAAAApw/Mzp55DhQ3hE/s1600-h/mt_wutong.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLvSMKrKfI/AAAAAAAAApw/Mzp55DhQ3hE/s400/mt_wutong.jpg" alt="" id="BLOGGER_PHOTO_ID_5238512412367989234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;梧桐山主峰高度：943.7米&lt;br /&gt;耗时：9小时&lt;br /&gt;评价：那是~相当的折腾，相当的享受&lt;br /&gt;&lt;br /&gt;历练，开始~&lt;br /&gt;&lt;br /&gt;这是梧桐山正门，可以看出游人很多。另外奉上黄瓜小队的集体合影。前排蓝色围脖的就是&lt;br /&gt;队长——凉拌黄瓜，一个资深的驴友。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLlgWOw6BI/AAAAAAAAAmo/pjqfwqGs0K0/s1600-h/IMG_2897.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLlgWOw6BI/AAAAAAAAAmo/pjqfwqGs0K0/s320/IMG_2897.JPG" alt="" id="BLOGGER_PHOTO_ID_5238501660471388178" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLlPdSUcmI/AAAAAAAAAmg/yWUq3h7S1PY/s1600-h/IMG_2900.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLlPdSUcmI/AAAAAAAAAmg/yWUq3h7S1PY/s320/IMG_2900.JPG" alt="" id="BLOGGER_PHOTO_ID_5238501370307572322" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;登山开始出不久，很快到达梧桐水库。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Q9lAKC5w-YI/SLLmJA8Q2tI/AAAAAAAAAmw/Z9ADkCzRcF4/s1600-h/IMG_2904.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Q9lAKC5w-YI/SLLmJA8Q2tI/AAAAAAAAAmw/Z9ADkCzRcF4/s320/IMG_2904.JPG" alt="" id="BLOGGER_PHOTO_ID_5238502359131282130" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;我们的过道一路环水，山水缠绕。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLoVmGXWbI/AAAAAAAAAnY/mQe4MfBW-JM/s1600-h/IMG_2906.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLoVmGXWbI/AAAAAAAAAnY/mQe4MfBW-JM/s320/IMG_2906.JPG" alt="" id="BLOGGER_PHOTO_ID_5238504774287448498" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Q9lAKC5w-YI/SLLoWAuOncI/AAAAAAAAAng/oo8ZsI_dwkk/s1600-h/IMG_2909.JPG"&gt;&lt;img style="cursor: pointer; width: 240px; height: 240px;" src="http://3.bp.blogspot.com/_Q9lAKC5w-YI/SLLoWAuOncI/AAAAAAAAAng/oo8ZsI_dwkk/s320/IMG_2909.JPG" alt="" id="BLOGGER_PHOTO_ID_5238504781433970114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;沿途也一路遥望山顶，烟雾缭绕。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLorAxvHUI/AAAAAAAAAno/1gSU_tcHlYg/s1600-h/IMG_2913.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLorAxvHUI/AAAAAAAAAno/1gSU_tcHlYg/s320/IMG_2913.JPG" alt="" id="BLOGGER_PHOTO_ID_5238505142225935682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;我们在成千上万的阶梯中行进，到达山腰之处，可见度已经较低。再往山脚望去，完全不可&lt;br /&gt;见底。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLpYcoGeOI/AAAAAAAAAnw/CVWL2zjqmjU/s1600-h/IMG_2947.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLpYcoGeOI/AAAAAAAAAnw/CVWL2zjqmjU/s320/IMG_2947.JPG" alt="" id="BLOGGER_PHOTO_ID_5238505922795829474" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Q9lAKC5w-YI/SLLpYiM8jRI/AAAAAAAAAn4/9JD3hT_sFUU/s1600-h/IMG_2952.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Q9lAKC5w-YI/SLLpYiM8jRI/AAAAAAAAAn4/9JD3hT_sFUU/s320/IMG_2952.JPG" alt="" id="BLOGGER_PHOTO_ID_5238505924292545810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;累死累活终于到达顶峰，看这一队人整成这样~&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLqJTzw08I/AAAAAAAAAoA/33fKsesrPKM/s1600-h/IMG_2960.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLqJTzw08I/AAAAAAAAAoA/33fKsesrPKM/s320/IMG_2960.JPG" alt="" id="BLOGGER_PHOTO_ID_5238506762242413506" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLsN5qYRAI/AAAAAAAAAoQ/CwOfacCk1-4/s1600-h/IMG_2964.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLsN5qYRAI/AAAAAAAAAoQ/CwOfacCk1-4/s320/IMG_2964.JPG" alt="" id="BLOGGER_PHOTO_ID_5238509040146334722" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;遥望山脚，莲塘，梧桐山村，沙头角！！！就这样被你征服~~~&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLt5KcFyqI/AAAAAAAAApY/Wf4w5nBKJak/s1600-h/IMG_2957.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_Q9lAKC5w-YI/SLLt5KcFyqI/AAAAAAAAApY/Wf4w5nBKJak/s320/IMG_2957.JPG" alt="" id="BLOGGER_PHOTO_ID_5238510882895809186" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLt5mW1ckI/AAAAAAAAApg/5oZUQhHHvTQ/s1600-h/IMG_2959.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLt5mW1ckI/AAAAAAAAApg/5oZUQhHHvTQ/s320/IMG_2959.JPG" alt="" id="BLOGGER_PHOTO_ID_5238510890389959234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;然后开始下山，坡路很陡，感觉像在华山论剑。大明来了肯定罩不住。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Q9lAKC5w-YI/SLLsOImKE2I/AAAAAAAAAoY/3jnhYpbVSm4/s1600-h/IMG_2970.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Q9lAKC5w-YI/SLLsOImKE2I/AAAAAAAAAoY/3jnhYpbVSm4/s320/IMG_2970.JPG" alt="" id="BLOGGER_PHOTO_ID_5238509044155159394" border="0" /&gt;&lt;/a&gt; &lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLsOeLKzyI/AAAAAAAAAog/0sX6k9JAwyw/s1600-h/IMG_2972.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLsOeLKzyI/AAAAAAAAAog/0sX6k9JAwyw/s320/IMG_2972.JPG" alt="" id="BLOGGER_PHOTO_ID_5238509049947541282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;沿途的狗狗，在山腰平台处迷路，快急疯了都。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLsOoNl2DI/AAAAAAAAAoo/89Gb4f3n9zY/s1600-h/IMG_2975.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLsOoNl2DI/AAAAAAAAAoo/89Gb4f3n9zY/s320/IMG_2975.JPG" alt="" id="BLOGGER_PHOTO_ID_5238509052642056242" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;临近好汉坡，这里是俯视和仰视角度。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLsO9sgw7I/AAAAAAAAAow/OR2s1cCor_A/s1600-h/IMG_2976.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLsO9sgw7I/AAAAAAAAAow/OR2s1cCor_A/s320/IMG_2976.JPG" alt="" id="BLOGGER_PHOTO_ID_5238509058408891314" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Q9lAKC5w-YI/SLLtcXRbpRI/AAAAAAAAAo4/VSfiHk3qIbM/s1600-h/IMG_2977.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Q9lAKC5w-YI/SLLtcXRbpRI/AAAAAAAAAo4/VSfiHk3qIbM/s320/IMG_2977.JPG" alt="" id="BLOGGER_PHOTO_ID_5238510388124558610" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;归途。这里的山路十八弯。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLtcs5JWyI/AAAAAAAAApA/VSqV3IThkiY/s1600-h/IMG_2982.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLtcs5JWyI/AAAAAAAAApA/VSqV3IThkiY/s320/IMG_2982.JPG" alt="" id="BLOGGER_PHOTO_ID_5238510393928276770" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLtdMBb4-I/AAAAAAAAApI/4k_wFYdNkrM/s1600-h/IMG_2983.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLtdMBb4-I/AAAAAAAAApI/4k_wFYdNkrM/s320/IMG_2983.JPG" alt="" id="BLOGGER_PHOTO_ID_5238510402284544994" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;夕阳下的正门，让俺们心痛——大家实在累坏了，中途两人抽筋，莹莹基本瘫倒。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLtdZ0WSRI/AAAAAAAAApQ/o2ezZOrCupU/s1600-h/IMG_2985.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Q9lAKC5w-YI/SLLtdZ0WSRI/AAAAAAAAApQ/o2ezZOrCupU/s320/IMG_2985.JPG" alt="" id="BLOGGER_PHOTO_ID_5238510405987748114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;谢谢大家捧场！此次梧桐山不虚此行，希望大家有机会尝试！&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Q9lAKC5w-YI/SLLqJkfcx3I/AAAAAAAAAoI/hHBR3QG4aXg/s1600-h/IMG_2967.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_Q9lAKC5w-YI/SLLqJkfcx3I/AAAAAAAAAoI/hHBR3QG4aXg/s320/IMG_2967.JPG" alt="" id="BLOGGER_PHOTO_ID_5238506766720616306" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;谢谢观赏。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4063622103172507649-3955349923710429328?l=izhangxc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://izhangxc.blogspot.com/feeds/3955349923710429328/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://izhangxc.blogspot.com/2008/09/824.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/3955349923710429328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4063622103172507649/posts/default/3955349923710429328'/><link rel='alternate' type='text/html' href='http://izhangxc.blogspot.com/2008/09/824.html' title='8月24日登顶梧桐峰'/><author><name>Wick</na
