<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Es Gilt Viele Mauern Abzubauen</title>
	<atom:link href="http://boundary.cc/feed/" rel="self" type="application/rss+xml" />
	<link>http://boundary.cc/wordpress</link>
	<description>Joker Lee&#039;s Blog</description>
	<lastBuildDate>Thu, 03 May 2012 08:04:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>入手MacBook Air</title>
		<link>http://boundary.cc/wordpress/2012/02/macbook-air-and-client-techs/</link>
		<comments>http://boundary.cc/wordpress/2012/02/macbook-air-and-client-techs/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 14:29:26 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://boundary.cc/?p=112</guid>
		<description><![CDATA[　　割肉买了台macbook air，准备搞ios开发。 　　本来准备用虚拟机将就一下，找公司IT大哥帮忙用vmware装了一个黑苹果，虽然卡的很，但也凑合用。装完以后一看系统有更新，想都没想点了下载安装，第二天早上一来兴高采烈的点了重启，悲剧发生了，重启后没法启动了，网上搜了一把原来vmware不能升级10.7.2，如果升级了得用PE引导，用xxx工具替换xxx文件，blablabla&#8230; 各种蛋疼，遂决定如一台mac设备。 　　由于在公司和家里都要用到，所以死贵iMac就不用考虑了。Mac Mini看起来很酷，价格便宜，可以来回背着，接显示器屏幕大；pro cpu主频比较高，显示性能好；air轻便，续航能力强。网上有人云Pro适合开发，硬盘大主频高显卡好什么的，但是想起机械硬盘的龟速、噪声和发热，果断选择SSD的Air，由于主要用于开发，11寸对于开发来说有点太小，最后选了13寸的版本。直接去公司旁边的水货实体店拿的现货，比淘宝上最便宜的贵了200，但是帮装了很多软件，省了自己慢慢拖的痛苦，尤其是xcode、office这种上G的软件。 　　拿到手后先熟悉快捷键和多点触摸的各种手势，吐槽一下dashboard，这实在是个除了费电占cpu外没啥用途的东西。然后装上Evernote、Dropbox、Chrome等常用工具，配vim和zsh，shell才是posix系统的杀手锏。一切搞定后开始看iphone开发，objc和c++差不多，没有garbage collection，语法比较奇特，和传统的c有比较大的区别，还得多看看书，熟悉一下。 　　下狠心买mac主要是觉得ios开发是比较有商机的客户端发展方向，PC桌面端和android的市场环境都不是很好，推广不是很好做。而apple的App Store环境会好很多，开发者只需要把精力集中在做出好的APP，无需考虑太多部署、适配和发行的事情。相比之下Android的开发者还需要将app提交到各种市场，被绑上各种app广告，应用付费基本不可能。 　　不知不觉关注点已经完全集中于Web前端和客户端技术上，其他领域完全酱油。现在浏览器和native客户端打得火热，由于终端设备的多样化，标准的浏览器交互很难完全适合不同终端的操作特性，所以端化的趋势从未减弱。从技术上来说，虽然html5各种nb的新特性不断冒出，但是浏览器市场的多元化导致和html5本身的复杂化到时html5一统江湖基本上不可能出现，html5很难取代客户端技术。 　　明天接着看书，这几周的周末是不会闲着了。]]></description>
			<content:encoded><![CDATA[<p>
　　割肉买了台macbook air，准备搞ios开发。
</p>
<p>
　　本来准备用虚拟机将就一下，找公司IT大哥帮忙用vmware装了一个黑苹果，虽然卡的很，但也凑合用。装完以后一看系统有更新，想都没想点了下载安装，第二天早上一来兴高采烈的点了重启，悲剧发生了，重启后没法启动了，网上搜了一把原来vmware不能升级10.7.2，如果升级了得用PE引导，用xxx工具替换xxx文件，blablabla&#8230; 各种蛋疼，遂决定如一台mac设备。
</p>
<p>
　　由于在公司和家里都要用到，所以死贵iMac就不用考虑了。Mac Mini看起来很酷，价格便宜，可以来回背着，接显示器屏幕大；pro cpu主频比较高，显示性能好；air轻便，续航能力强。网上有人云Pro适合开发，硬盘大主频高显卡好什么的，但是想起机械硬盘的龟速、噪声和发热，果断选择SSD的Air，由于主要用于开发，11寸对于开发来说有点太小，最后选了13寸的版本。直接去公司旁边的水货实体店拿的现货，比淘宝上最便宜的贵了200，但是帮装了很多软件，省了自己慢慢拖的痛苦，尤其是xcode、office这种上G的软件。
</p>
<p>
　　拿到手后先熟悉快捷键和多点触摸的各种手势，吐槽一下dashboard，这实在是个除了费电占cpu外没啥用途的东西。然后装上Evernote、Dropbox、Chrome等常用工具，配vim和zsh，shell才是posix系统的杀手锏。一切搞定后开始看iphone开发，objc和c++差不多，没有garbage collection，语法比较奇特，和传统的c有比较大的区别，还得多看看书，熟悉一下。
</p>
<p>
　　下狠心买mac主要是觉得ios开发是比较有商机的客户端发展方向，PC桌面端和android的市场环境都不是很好，推广不是很好做。而apple的App Store环境会好很多，开发者只需要把精力集中在做出好的APP，无需考虑太多部署、适配和发行的事情。相比之下Android的开发者还需要将app提交到各种市场，被绑上各种app广告，应用付费基本不可能。
</p>
<p>
　　不知不觉关注点已经完全集中于Web前端和客户端技术上，其他领域完全酱油。现在浏览器和native客户端打得火热，由于终端设备的多样化，标准的浏览器交互很难完全适合不同终端的操作特性，所以端化的趋势从未减弱。从技术上来说，虽然html5各种nb的新特性不断冒出，但是浏览器市场的多元化导致和html5本身的复杂化到时html5一统江湖基本上不可能出现，html5很难取代客户端技术。
</p>
<p>
　　明天接着看书，这几周的周末是不会闲着了。</p>
]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2012/02/macbook-air-and-client-techs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Make No Law</title>
		<link>http://boundary.cc/wordpress/2012/01/make-no-law/</link>
		<comments>http://boundary.cc/wordpress/2012/01/make-no-law/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 16:04:40 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[读书笔记]]></category>
		<category><![CDATA[make no law]]></category>

		<guid isPermaLink="false">http://boundary.cc/?p=103</guid>
		<description><![CDATA[这两天把《批评官员的尺度》读完了。
我对这本书的理解是，这本书以美国宪法第一修正案为线索，站在新闻工作者的视角，以沙利文案为主要案例，论述了近200年来最高法院用宪法第一修正案对言论自由的边界的划定。
这本书的英文标题是 Make No Law : the Sullivan Case and the First Amendment，直译过来就是“不得立法：沙利文案和宪法第一修正案”，译作的标题则是选取了言论自由议题中的一个吸引国人眼球的一个侧面。]]></description>
			<content:encoded><![CDATA[<p>这两天把《批评官员的尺度》读完了。</p>
<p>我对这本书的理解是，这本书以美国宪法第一修正案为线索，站在新闻工作者的视角，以沙利文案为主要案例，论述了近200年来最高法院用宪法第一修正案对言论自由的边界的划定。</p>
<p>这本书的英文标题是 Make No Law : the Sullivan Case and the First Amendment，直译过来就是“不得立法：沙利文案和宪法第一修正案”。另外，译作封面，标题上方有一行小字“若批评不自由，则赞美无意义”，这行字反映出作（译）者的立场，虽然原书封面上并没有这行字。原书作者刘易斯通过列举各种历史案例和旁征博引，力图以客观的态度叙述沙利文案及其他相关案例，但刘易斯本人也是新闻从业者，虽然书的最后几章也有对沙利文案的判决带来的各种影响有分析，所以更多的是站在新闻出版业的角度，字里行间流露出对绝对新闻自由的推崇，对“这是值得当街起舞的时刻”的引用便可看出。</p>
<p><span id="more-103"></span><br />
实事上，沙利文案的判决绝不是正义战胜邪恶、真理战胜谬误这么简单，言论自由的边界也远没有清晰的界定。书中对沙利文案判决的形成也有较为详细的描述，可以看出沙利文案的判决最后以5：4形成多数意见是很不容易的， 并且后续涉及言论自由的案件中，5：4这种得票接近的判决屡见不鲜，争议之大，可见一斑。书中诸多的引用绝大多数是为了证明言论自由的重要意义，而对于绝对言论自由所引发的社会问题没有花太多笔墨。本书只是揭开了这个复杂问题的冰山一角。</p>
<p>对于国内的读者来说，这本书的另一个意义是了解美国的司法体系，从侧面观察大法官的工作方式和价值。沙利文案的最重要的意义之一是将宪法第一修正案应用到诽谤官司中。法官们通过“时代的需求、主流道德和政治理论的感知，和对公共政策的直觉”解释和修正法律，以适应社会的变化和发展。沙利文案是自“马伯里诉麦迪逊案”确立联邦最高法院的司法审查权以来又一次重要的实践。</p>
<p>总的来说对于我这样的法盲是部非常不错的启蒙书籍。</p>
<p>“若批评不自由，则赞美无意义”</p>
<p>“若自由无约束，则自由无意义”</p>
<p><a href="http://boundary.cc/wordpress/wp-content/uploads/2012/01/20087251657351.jpg"><img src="http://boundary.cc/wordpress/wp-content/uploads/2012/01/20087251657351.jpg" alt="九人" title="九人" width="487" height="337" class="aligncenter size-full wp-image-105" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2012/01/make-no-law/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>快餐式的Google Reader</title>
		<link>http://boundary.cc/wordpress/2010/12/fast-food-type-google-reader/</link>
		<comments>http://boundary.cc/wordpress/2010/12/fast-food-type-google-reader/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 18:09:35 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[日记]]></category>
		<category><![CDATA[Google Reader]]></category>
		<category><![CDATA[学习]]></category>

		<guid isPermaLink="false">http://jackaldire.com/?p=100</guid>
		<description><![CDATA[God，上一篇日志已经记不得是什么时候写得了。。。 最近把工作的事定了，有闲心开始思考一些以前一直没有思考的问题。今天有个同学问我一个C++相关的问题，我隐约记得不久前在Google Reader上看到过类似问题的讨论，但是搜了半天也没有找到。这个引子再次勾起了我对自己当前Google Reader的学习模式的思考——我每天在Reader上花1个小时甚至更多，到底是为了什么，实际又获得了什么？ 两年前开始用阅读器订阅RSS，最初只有几个源，月光博客是其中之一，每天不到10篇文章更新，基本上花个10分钟就看完了。后来通过论坛的“Google Reader共享计划”获得了一个share list，使得我的Google Reader中的followings从0跃升到20+，这是一个重要的转折点。在此之前，我主要看自己订阅的几个RSS的文章，文章数量不多，但都是我比较感兴趣的。Follow了share list中的朋友以后，我阅读的优先级逐步从自己订阅的RSS向朋友share的文章过渡，与此同时，我从朋友share的文章的来源里不断挖掘出新的RSS源，这个过程到现在也没有停止。现在我订阅了总共92个源（我数完以后自己也被震惊了- -）。其实很早以前我就意识到了这些变化，最明显的一点就是订阅的RSS每天的更新看不完了。为了不让括号中（xxx+）代表未读文章数的数字过于刺眼，就得越来越多的“Mark All as Read”，慢慢地觉得每天Mark十几次实在是太烦，于是未读数就稳定在1000+了。 随着following与follower的增多，感觉Google Reader越来越社会化。因为每个人的关注点不同，大家Share的文章有各种各样的内容，从新闻、技术、社会到娱乐等等，其中不乏一些很有学习价值的文章，这些文章的存在让我觉得Reader不仅仅是一个信息获取的渠道，也是一个很好的学习环境。于是我每天投入在Reader上的时间越来越长，从最初的10分钟到1个小时甚至更多（我曾尝试一整天呆在Reader上）。呆久了就发现了一些现象： Reader并不会对他人share的文章分类，所有文章都在一个列表里，相邻的两篇文章经常毫风马牛不相及甚至有很大落差。比如刚看完一片引人入胜的技术文章还没来得及回味一下，右手习惯性的按了下‘J’（这个键真的是闭着眼也能摸得到，不得不说vi的键位设置的很科学。。），一个糗事百科的分享赫然显示在眼前。于是乎偷笑了半分钟后，上一篇技术文章讲得是什么已经烟消云散了 Reader上的信息可以说是近乎爆炸了，如果每天看100+以上的文章，看完以后绝大多数文章连标题都记不得了。对于有学习价值的文章，仅仅是在看的时候做了简单的思考，既没有适当的笔记也没有必要的反思。大脑就像一个固定长度的队列一样，老的信息迅速被新的挤出队列，什么没留下。 几天不上Reader就会觉得自己变成Outman，并且有一种强烈的落后感。打开Reader狼吞虎咽一通以后（吃起来味道不错，快餐貌似都是这样），自信就又回来了，从Outman回到了IT潮人，又可以去和别人侃了，顿时心情舒畅了许多。很多时候上reader只是为了满足自己的心理需要而已。 我从上面的现象中总结出下面几个问题： 别人分享的东西并不总是自己需要的 被一些无关紧要的东西吸引注意力，往往不用动脑子的东西更有吸引力 对于需要思考的问题没有花时间去思考 心浮气躁的状态下很难有所收获 面对现在这个越来越像人人网的Reader，必须得想办法改变一下了。从今天开始我准备做一些尝试： 首先是清理掉了近一半基本不看的的RSS，以及一些总是share没有营养的文章的followings。然后我把花在Reader上的时间分成了两部分：一部分是浏览新闻、咨询以及娱乐内容，在此期间如果发现有学习价值的文章则用星标或者ReadItLater记录下来；另一部分就是仔细阅读前面留下来的文章，每天只看一两篇，并且做笔记（Evernote很不错，我现在写blog也在用），及时把自己的想法记录下来。此外我还计划控制在每天在Reader上闲逛的时间。 先实验一阵子吧，看看效果如何。]]></description>
			<content:encoded><![CDATA[<p>God，上一篇日志已经记不得是什么时候写得了。。。</p>
<p>最近把工作的事定了，有闲心开始思考一些以前一直没有思考的问题。今天有个同学问我一个C++相关的问题，我隐约记得不久前在Google Reader上看到过类似问题的讨论，但是搜了半天也没有找到。这个引子再次勾起了我对自己当前Google Reader的学习模式的思考——我每天在Reader上花1个小时甚至更多，到底是为了什么，实际又获得了什么？</p>
<p><span id="more-100"></span></p>
<p>两年前开始用阅读器订阅RSS，最初只有几个源，月光博客是其中之一，每天不到10篇文章更新，基本上花个10分钟就看完了。后来通过论坛的“Google Reader共享计划”获得了一个share list，使得我的Google Reader中的followings从0跃升到20+，这是一个重要的转折点。在此之前，我主要看自己订阅的几个RSS的文章，文章数量不多，但都是我比较感兴趣的。Follow了share list中的朋友以后，我阅读的优先级逐步从自己订阅的RSS向朋友share的文章过渡，与此同时，我从朋友share的文章的来源里不断挖掘出新的RSS源，这个过程到现在也没有停止。现在我订阅了总共92个源（我数完以后自己也被震惊了- -）。其实很早以前我就意识到了这些变化，最明显的一点就是订阅的RSS每天的更新看不完了。为了不让括号中（xxx+）代表未读文章数的数字过于刺眼，就得越来越多的“Mark All as Read”，慢慢地觉得每天Mark十几次实在是太烦，于是未读数就稳定在1000+了。</p>
<p>随着following与follower的增多，感觉Google Reader越来越社会化。因为每个人的关注点不同，大家Share的文章有各种各样的内容，从新闻、技术、社会到娱乐等等，其中不乏一些很有学习价值的文章，这些文章的存在让我觉得Reader不仅仅是一个信息获取的渠道，也是一个很好的学习环境。于是我每天投入在Reader上的时间越来越长，从最初的10分钟到1个小时甚至更多（我曾尝试一整天呆在Reader上）。呆久了就发现了一些现象：</p>
<ul>
<li>Reader并不会对他人share的文章分类，所有文章都在一个列表里，相邻的两篇文章经常毫风马牛不相及甚至有很大落差。比如刚看完一片引人入胜的技术文章还没来得及回味一下，右手习惯性的按了下‘J’（这个键真的是闭着眼也能摸得到，不得不说vi的键位设置的很科学。。），一个糗事百科的分享赫然显示在眼前。于是乎偷笑了半分钟后，上一篇技术文章讲得是什么已经烟消云散了</li>
<li>Reader上的信息可以说是近乎爆炸了，如果每天看100+以上的文章，看完以后绝大多数文章连标题都记不得了。对于有学习价值的文章，仅仅是在看的时候做了简单的思考，既没有适当的笔记也没有必要的反思。大脑就像一个固定长度的队列一样，老的信息迅速被新的挤出队列，什么没留下。</li>
<li>几天不上Reader就会觉得自己变成Outman，并且有一种强烈的落后感。打开Reader狼吞虎咽一通以后（吃起来味道不错，快餐貌似都是这样），自信就又回来了，从Outman回到了IT潮人，又可以去和别人侃了，顿时心情舒畅了许多。很多时候上reader只是为了满足自己的心理需要而已。</li>
</ul>
<p>我从上面的现象中总结出下面几个问题：</p>
<ul>
<li>别人分享的东西并不总是自己需要的</li>
<li>被一些无关紧要的东西吸引注意力，往往不用动脑子的东西更有吸引力</li>
<li>对于需要思考的问题没有花时间去思考</li>
<li>心浮气躁的状态下很难有所收获</li>
</ul>
<p>面对现在这个越来越像人人网的Reader，必须得想办法改变一下了。从今天开始我准备做一些尝试：</p>
<p>首先是清理掉了近一半基本不看的的RSS，以及一些总是share没有营养的文章的followings。然后我把花在Reader上的时间分成了两部分：一部分是浏览新闻、咨询以及娱乐内容，在此期间如果发现有学习价值的文章则用星标或者ReadItLater记录下来；另一部分就是仔细阅读前面留下来的文章，每天只看一两篇，并且做笔记（Evernote很不错，我现在写blog也在用），及时把自己的想法记录下来。此外我还计划控制在每天在Reader上闲逛的时间。</p>
<p>先实验一阵子吧，看看效果如何。</p>
]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2010/12/fast-food-type-google-reader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows下实现EXE的自删除与自修改</title>
		<link>http://boundary.cc/wordpress/2010/04/exe-self-delete-and-self-modify/</link>
		<comments>http://boundary.cc/wordpress/2010/04/exe-self-delete-and-self-modify/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 04:21:17 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[编程]]></category>

		<guid isPermaLink="false">http://jackaldire.com/?p=97</guid>
		<description><![CDATA[自从开始实习就没有更新过blog了，加上软工、数据库、图形学乱七八糟的实验，有点忙不过来了。 本来一直在想以后做Linux相关的开发，周围认识的很多学长都走上了这条路，开始实习后却事与愿违搞起了Linux开发。其实说实话一直也不知道自己的兴趣点在哪里，工作了一个月后感觉可能还是桌面和互联网更适合自己，对于系统开发、运维这样的工作，干长时间可能会受不了&#8230;&#8230;纠结啊 前两天和朋友聊到windows下一个程序如何删除自己，正好以前和同学讨论过这个问题，写出来凑个数。 其实真正的删除自己肯定是做不到的，至少用户态不行。windows下只要一个文件被某个进程打开就不能被删掉（Linux下可以删除任何打开的文件，只要有权限，而且一般不会影响程序的执行，因为文件系统会等到所有的打开的fd都释放后会才回收inode和data）,所以一个windows进程在运行的时候是肯定不可以删除自己的可执行文件的，只能想一些旁门左道了。 Solution 方法其实很简单，就是在程序结束前开另一个进程去删自己，但是要求是自己删自己，所以只能借助系统utils。这时候就需要bat脚本来帮忙了。在CMD下删除一个文件很容易，一条del命令就搞定了，但是需要保证执行脚本的时候原进程已经结束运行了，一般来说用一条延时命令walk around“ping 127.0.0.1 -n 2”，2为秒数，然后用“&#038;”连接del命令删除文件 ping 127.0.0.1 -n 2 &#62;nul &#38;&#38; del path/to/your/file.exe 更为保险的做法是在bat里用tasklist命令查看进程，循环直到找不到当前进程位置 原来的和同学讨论的是一个程序如何自己修改自己，做到单文件自动更新，实际上和自己删除自己是一个问题。无非就是先生成一个自身的副本，修改副本，再程序结束后用bat脚本覆盖自己就ok了，源代码如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 [...]]]></description>
			<content:encoded><![CDATA[<p>自从开始实习就没有更新过blog了，加上软工、数据库、图形学乱七八糟的实验，有点忙不过来了。</p>
<p>本来一直在想以后做Linux相关的开发，周围认识的很多学长都走上了这条路，开始实习后却事与愿违搞起了Linux开发。其实说实话一直也不知道自己的兴趣点在哪里，工作了一个月后感觉可能还是桌面和互联网更适合自己，对于系统开发、运维这样的工作，干长时间可能会受不了&#8230;&#8230;纠结啊</p>
<p>前两天和朋友聊到windows下一个程序如何删除自己，正好以前和同学讨论过这个问题，写出来凑个数。<br />
<span id="more-97"></span><br />
其实真正的删除自己肯定是做不到的，至少用户态不行。windows下只要一个文件被某个进程打开就不能被删掉（Linux下可以删除任何打开的文件，只要有权限，而且一般不会影响程序的执行，因为文件系统会等到所有的打开的fd都释放后会才回收inode和data）,所以一个windows进程在运行的时候是肯定不可以删除自己的可执行文件的，只能想一些旁门左道了。</p>
<h2>Solution</h2>
<p>方法其实很简单，就是在程序结束前开另一个进程去删自己，但是要求是自己删自己，所以只能借助系统utils。这时候就需要bat脚本来帮忙了。在CMD下删除一个文件很容易，一条del命令就搞定了，但是需要保证执行脚本的时候原进程已经结束运行了，一般来说用一条延时命令walk around“ping 127.0.0.1 -n 2”，2为秒数，然后用“&#038;”连接del命令删除文件</p>

<div class="wp_syntax"><div class="code"><pre class="bat" style="font-family:monospace;">ping 127.0.0.1 -n 2 &gt;nul &amp;&amp; del path/to/your/file.exe</pre></div></div>

<p>更为保险的做法是在bat里用tasklist命令查看进程，循环直到找不到当前进程位置</p>
<p>原来的和同学讨论的是一个程序如何自己修改自己，做到单文件自动更新，实际上和自己删除自己是一个问题。无非就是先生成一个自身的副本，修改副本，再程序结束后用bat脚本覆盖自己就ok了，源代码如下</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;windows.h&gt;</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> argv<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">char</span> self<span style="color: #009900;">&#91;</span>_MAX_PATH<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>  
    <span style="color: #993333;">char</span> swap<span style="color: #009900;">&#91;</span>_MAX_PATH<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// get the full path of myself</span>
    GetModuleFileName<span style="color: #009900;">&#40;</span>NULL<span style="color: #339933;">,</span> self<span style="color: #339933;">,</span> _MAX_PATH<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// copy myself to a temp file for modify </span>
    strcpy<span style="color: #009900;">&#40;</span>swap<span style="color: #339933;">,</span> self<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    strcat<span style="color: #009900;">&#40;</span>swap<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;.tmp&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// add .tmp postfix. better to use tempnam()</span>
    CopyFile<span style="color: #009900;">&#40;</span>self<span style="color: #339933;">,</span> swap<span style="color: #339933;">,</span> FALSE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
    FILE <span style="color: #339933;">*</span> fp <span style="color: #339933;">=</span> fopen<span style="color: #009900;">&#40;</span>swap<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;ab&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// pending whatever you want to the exe</span>
    fwrite<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Hack is not good, but i love it.&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">32</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> fp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    fclose<span style="color: #009900;">&#40;</span>fp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// &quot;ping&quot; is used for delay to wait the main process terminated.</span>
    <span style="color: #666666; font-style: italic;">// &quot;move /Y src dst&quot; : overide whtout warnning</span>
    <span style="color: #666666; font-style: italic;">// quotation marks are needed for paths which contain blank.</span>
    <span style="color: #993333;">char</span> bat<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #339933;">*</span>_MAX_PATH <span style="color: #339933;">+</span> <span style="color: #0000dd;">30</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;cmd /c ping 127.0.0.1 -n 2 &gt;nul &amp;&amp; move /Y <span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #339933;">;</span>
    strcat<span style="color: #009900;">&#40;</span>bat<span style="color: #339933;">,</span> swap<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    strcat<span style="color: #009900;">&#40;</span>bat<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    strcat<span style="color: #009900;">&#40;</span>bat<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot; <span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    strcat<span style="color: #009900;">&#40;</span>bat<span style="color: #339933;">,</span> self<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    strcat<span style="color: #009900;">&#40;</span>bat<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">// bat += &quot;path\to\swap&quot; &quot;path\to\self&quot; </span>
&nbsp;
    WinExec<span style="color: #009900;">&#40;</span>bat<span style="color: #339933;">,</span> SW_HIDE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Exec the bat script with window hiden</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>C库函数和win32 API混用，看着挺别扭，本来写的时候还想尝试一下匈牙利，被恶心到以后还是放弃了，还好用到的API都参数比较简单，自从大一的时候看到一个win32 API调用占了半屏后，对win32 API就深为恐惧，再加上满屏幕的大写，读起来简直就是噩梦&#8230;</p>
<h2>Improvement</h2>
<p>用ping命令延时只是一个walk around，在系统负载很重的情况下，2秒程序也未必退出了，所以应该寻找一个方法确定一个exe是否在运行。小研究了一下bat，发现通过tasklist命令和find命令可以搞定：</p>

<div class="wp_syntax"><div class="code"><pre class="bat" style="font-family:monospace;">:loop
tasklist /NH | find /i &quot;xxx.exe&quot;
if %ERRORLEVEL% equ 1 (
goto loop
) else (
del path\to\your\file\xxx.exe
)
exit</pre></div></div>

<p>ERRORLEVEL变量是上一条命令的返回值，不停的在进程列表里寻找xxx.exe直到找不到为止。</p>
<p>顺便bless一下灾区的同胞们还有但愿今天可以拿到工资&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2010/04/exe-self-delete-and-self-modify/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>自己动手写Linux Shell（三） —— 支持IO重定向</title>
		<link>http://boundary.cc/wordpress/2010/01/write-your-own-shell-3-io-redirection/</link>
		<comments>http://boundary.cc/wordpress/2010/01/write-your-own-shell-3-io-redirection/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 14:57:56 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[Linux与开源]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://jackaldire.com/?p=86</guid>
		<description><![CDATA[1.IO重定向功能分析 IO重定向也是Shell的基本功能之一，这篇文章比较全面地介绍了Linux Shell的IO重定向功能。总结一下，IO重定向的大致格式是这样： cmd &#91;src &#124; &#38;&#93; &#40;&#62; &#124; &#60; &#124; &#62;&#62; &#41; &#40;&#38; num&#124;-&#41; &#124; dst 貌似写得有点复杂（我不是故意的）。解释一下，整个重定向语句由三部分组成： 第一部分（[src&#124;&#038;]）：src代表被重定向的文件描述符，一般是0（stdin）、1（stdout）和2（stderr），此外还可以是‘＆’，代表2和3，也就是把stdout和stderr同时重定向。这一部分通常是省略的，‘>’和‘>>’隐含了0，‘ &#124; < &#124; >>）：三种操作符。‘’将src的输出重定向到目标文件（若文件不存在则创建，否则现有文件被截断(truncation)）；‘>>’将src的输出附加到（pending）目标文件尾部（若文件不存在则创建）。 第三部分（ (&#038; num&#124;-) &#124; dst ）：第三部分有两种形式，最常见的就是一个文件名，代表重定向的目标。此外还可以是&#8217;&#038;'加一个数字，代表将src重定向到数字代表的文件描述符上。另外‘&#038;’后还可以接‘-’，代表关闭src。比如： $ cmd 2&#62;&#38;1 将标准错误重定向到标准输出 $ cmd 1&#62;&#38;- 关闭标准输出 $ cmd 0&#60;&#38;- 关闭标准输入 2.IO重定向功能实现 Linux的IO重定向实际上是通过dup函数和close函数配合实现。close关闭一个文件描述符，而dup复制一个文件描述符，并且新产生的文件描述符是当前可用文件描述符的最小值。 通过先将要重定向的fd关闭，在将重定向的目标文件的描述符dup就实现了重定向（因为012三个描述符默认都是打开的，关闭任何一个后其都将成为当前可用的最小文件描述符）。 为了支持重定向命令的分析，实现里新添加了一个结构，记录了每个重定向的必须信息，然后在子进程fork以后根据记录信息进行重定向操作。 测试的时候发现了一个有趣的问题。比如： $ ls &#62;f1 &#62;f2 $ cat &#62;f1 &#62;f2 这两条命令在bash里的结果是后面的重定向覆盖了前面的重定向，这和我的实现是一样的，也是最简单的。而在zsh里，第一条命令的结果是f1 [...]]]></description>
			<content:encoded><![CDATA[<h2>1.IO重定向功能分析</h2>
<p>IO重定向也是Shell的基本功能之一，<a href="http://www.ibm.com/developerworks/cn/linux/l-iotips/">这篇文章</a>比较全面地介绍了Linux Shell的IO重定向功能。总结一下，IO重定向的大致格式是这样：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">cmd  <span style="color: #7a0874; font-weight: bold;">&#91;</span>src <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">&amp;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>     <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span>      <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&amp;</span> num<span style="color: #000000; font-weight: bold;">|</span>-<span style="color: #7a0874; font-weight: bold;">&#41;</span>  <span style="color: #000000; font-weight: bold;">|</span> dst</pre></div></div>

<p>貌似写得有点复杂（我不是故意的）。解释一下，整个重定向语句由三部分组成：</p>
<p><span id="more-86"></span></p>
<p>第一部分（[src|&#038;]）：src代表被重定向的文件描述符，一般是0（stdin）、1（stdout）和2（stderr），此外还可以是‘＆’，代表2和3，也就是把stdout和stderr同时重定向。这一部分通常是省略的，‘>’和‘>>’隐含了0，‘<’隐含了1，也就是说</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ cmd <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #c20cb9; font-weight: bold;">file</span> 等价于
$ cmd <span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #c20cb9; font-weight: bold;">file</span>
$ cmd <span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #c20cb9; font-weight: bold;">file</span> 等价于
$ cmd <span style="color: #000000;">1</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #c20cb9; font-weight: bold;">file</span></pre></div></div>

<p>第二部分（> | < | >>）：三种操作符。‘<’将src的输入重定向到目标文件；‘>’将src的输出重定向到目标文件（若文件不存在则创建，否则现有文件被截断(truncation)）；‘>>’将src的输出附加到（pending）目标文件尾部（若文件不存在则创建）。</p>
<p>第三部分（ (&#038; num|-)  | dst ）：第三部分有两种形式，最常见的就是一个文件名，代表重定向的目标。此外还可以是&#8217;&#038;'加一个数字，代表将src重定向到数字代表的文件描述符上。另外‘&#038;’后还可以接‘-’，代表关闭src。比如：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ cmd <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">1</span>     将标准错误重定向到标准输出
$ cmd <span style="color: #000000;">1</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span>-      关闭标准输出
$ cmd <span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">&lt;&amp;</span>-      关闭标准输入</pre></div></div>

</p>
<h2>2.IO重定向功能实现</h2>
<p>Linux的IO重定向实际上是通过dup函数和close函数配合实现。close关闭一个文件描述符，而dup复制一个文件描述符，并且新产生的文件描述符是当前可用文件描述符的最小值。</p>
<p>通过先将要重定向的fd关闭，在将重定向的目标文件的描述符dup就实现了重定向（因为012三个描述符默认都是打开的，关闭任何一个后其都将成为当前可用的最小文件描述符）。</p>
<p>为了支持重定向命令的分析，实现里新添加了一个结构，记录了每个重定向的必须信息，然后在子进程fork以后根据记录信息进行重定向操作。</p>
<p>测试的时候发现了一个有趣的问题。比如：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">&gt;</span>f1 <span style="color: #000000; font-weight: bold;">&gt;</span>f2
$ <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&gt;</span>f1 <span style="color: #000000; font-weight: bold;">&gt;</span>f2</pre></div></div>

<p>这两条命令在bash里的结果是后面的重定向覆盖了前面的重定向，这和我的实现是一样的，也是最简单的。而在zsh里，第一条命令的结果是f1 f2文件有相同的内容，也就是标准输出同时被重定向到f1和f2两个文件里了；第二条命令的效果等同于先把f1、f2两个文件现连接起来再重定向到cat的输入。这是相当神奇的，到现在也没找到实现方法，看来得找时间研究一下zsh的代码了。</p>
<p>其实实现重定向最麻烦的地方是命令分析，也就是字符串处理。parse_command函数俨然已经100行了，两个switch-case加无数个if-else组成的大自动机，不加注释恐怕就是write-only了（感觉加了注释还是write-only）&#8230;</p>
<p>打开重定向文件那里有一点问题，一大堆flags或来或去，最傻的是忘了给创建的文件设置mode，结果只能用root权限查看&#8230;</p>
<p><strong>源代码 : <a href='http://jackaldire.com/wordpress/wp-content/uploads/2010/01/jdsh_v3.h'>jdsh_v3.h</a> <a href='http://jackaldire.com/wordpress/wp-content/uploads/2010/01/jdsh_v3.c'>jdsh_v3.c</a>（为了让乱七八糟的代码稍微可读一点，单独分了个头文件出来）</strong></p>
<p>剩下的任务就是管道了，有必要把代码好好整理一下了。</p>
]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2010/01/write-your-own-shell-3-io-redirection/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>自己动手写Linux Shell（二） —— 支持后台执行</title>
		<link>http://boundary.cc/wordpress/2010/01/write-your-own-shell-2-background-task/</link>
		<comments>http://boundary.cc/wordpress/2010/01/write-your-own-shell-2-background-task/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 18:09:53 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[Linux与开源]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://jackaldire.com/?p=82</guid>
		<description><![CDATA[在写完一个最简单的命令解释器以后，我给自己的shell起了个名字——jdsh（JackalDire Shell）。 本来以为加入后台执行不是什么难事，但是认真想了一下要处理好一个字符‘＆’不是一般的麻烦，各种问题接踵而至，于是决定先找点轻松的活干。 1.加入shell内建命令 每个shell都有自己的内建命令，最常见的有“cd”、“pwd”、“exit”等等。没有“cd“的shell是没法干活的。 其实很简单，标准的做法建个hash表把所有内建命令加进去，parse command以后先查一下表就行了，然后可以通过像Linux Syscall的实现方法一样，用一个字符串连接宏（##）找到对应的处理函数。但是由于只准备写寥寥几个命令，偷懒直接 if else if了（= =!）。 2.打印命令提示符Prompt 每个命令行shell都有命令提示符，告诉用户现在可以敲命令。大多数的linux shell的prompt是可以定制的。我采用了bash的默认格式“[username@hostname cwd]$ ”。实现prompt里的cwd（current working directory）时候发现了一个问题：基本上所有linux shell里都用了&#8217;~'代替$HOME。于是做个个字符串替换，使得home文件夹在显示的时候都显示为&#8217;~'（命令里的路径还不支持&#8217;~'） 3.处理SIGINT、SIGQUIT和SIGTSTP信号 SIGINT信号对应按下ctrl+c，shell对该信号的处理方式是（观察zsh/bash得到，没有查文档）：若shell当前没有前台任务，则输入一个空行，放弃当前正在输入的命令；若当前有前台任务，则SIGINT信号由前台程序捕捉。 SIGQUIT信号对应按下ctrl+\，shell对该信号的处理方式是（观察zsh/bash得到，没有查文档）：若shell当前没有前台任务，则忽略该信号，放弃当前正在输入的命令；若当前有前台任务，则SIGQUIT信号由前台程序捕捉。 SIGQUIT信号对应按下ctrl+z，shell对该信号的处理方式是（观察zsh/bash得到，没有查文档）：若shell当前没有前台任务，则忽略该信号，放弃当前正在输入的命令；若当前有前台任务，则SIGQUIT信号由前台程序捕捉。 PS:对这APUE里的信号表看了一遍，好像没有其他要特殊处理的信号了。 其实很好处理，用signal函数或者sigaction都可以（偷懒就用signal了）。在shell的主进程里改变SIGINT的信号处理函数、忽略SIGQUIT和SIGTSPT信号就可以。 有一个问题需要注意：必须在fork的子进程里恢复对这几个信号的默认处理方式。因为fork产生子进程和父进程有相同的信号处理函数signal handler。解决方法就是fork以后在子进程里手动恢复修改过的信号。另一种方法是不用fork，改用clone系统调用，通过clone flags里的CLONE_SIGHAND参数使得复制出来的进程不保留父进程的信号处理函数。 回到主题上&#8230;.. 4.后台运行程序 其实单纯的实现后台运行很简单，把前面程序里的wait去掉使shell主进程不等待子进程结束就OK了。问题在于，shell是通过一个&#8217;&#038;'字符决定后台执行，如何才能从命令里提取出这个代表后台执行的&#8217;&#038;'字符？ 看起来似乎一个字符串查找就能解决，其实并非如此：如果这&#8217;&#038;'是在一个路径名里呢(Linux中只有一个字符不能做文件名：&#8217;/')。看一下别的shell很快就会找到解决方法：转义字符。如果想把有特殊含义的字符当作一个普通字符处理，那么就要在前面加上转移字符&#8217;\'（比如空格、&#8217;\'、&#8217;&#038;'、&#8217;~'、&#8217;-'等等）。 要支持转移字符，我原来用strsep实现的优美的parse command函数就得全部扔掉重写。没办法，换成了fgetc和丑陋的switch case。 有了转义字符，就可以处理含有特殊字符的文件名了^ ^ 另外，我观察到bash和zsh在后台程序运行结束后都会显示一条提示信息显示pid和命令，于是我也想把这个功能加进去。思路很简单，就是改变SIGCHLD信号的handler，捕捉到SIGCHLD后输出进程信息就可以了。默认SIGCHLD信号是通过wait和waitpid函数捕捉。signal能改变SIGCHLD信号的处理函数，但是无法获得足够的信息（pid、退出代码等），而sigaction支持复杂的信号处理函数，通过向信号处理函数传递siginfo结构，提供更充足的信息（还是sigaction强大）。 差不多就这样了&#8230;代码量翻了一倍，直接贴出来有点恐怖，所以扔到附件了～（BUG很多，就不一一列举了，sign～） 源代码：jdsh_v2.c]]></description>
			<content:encoded><![CDATA[<p>在写完一个最简单的命令解释器以后，我给自己的shell起了个名字——jdsh（JackalDire Shell）。</p>
<p>本来以为加入后台执行不是什么难事，但是认真想了一下要处理好一个字符‘＆’不是一般的麻烦，各种问题接踵而至，于是决定先找点轻松的活干。</p>
<h2>1.加入shell内建命令</h2>
<p><span id="more-82"></span></p>
<p>每个shell都有自己的内建命令，最常见的有“cd”、“pwd”、“exit”等等。没有“cd“的shell是没法干活的。</p>
<p>其实很简单，标准的做法建个hash表把所有内建命令加进去，parse command以后先查一下表就行了，然后可以通过像Linux Syscall的实现方法一样，用一个字符串连接宏（##）找到对应的处理函数。但是由于只准备写寥寥几个命令，偷懒直接 if else if了（= =!）。</p>
<h2>2.打印命令提示符Prompt</h2>
<p>每个命令行shell都有命令提示符，告诉用户现在可以敲命令。大多数的linux shell的prompt是可以定制的。我采用了bash的默认格式“[username@hostname cwd]$ ”。实现prompt里的cwd（current working directory）时候发现了一个问题：基本上所有linux shell里都用了&#8217;~'代替$HOME。于是做个个字符串替换，使得home文件夹在显示的时候都显示为&#8217;~'（命令里的路径还不支持&#8217;~'）</p>
<h2>3.处理SIGINT、SIGQUIT和SIGTSTP信号</h2>
<p>SIGINT信号对应按下ctrl+c，shell对该信号的处理方式是（观察zsh/bash得到，没有查文档）：若shell当前没有前台任务，则输入一个空行，放弃当前正在输入的命令；若当前有前台任务，则SIGINT信号由前台程序捕捉。</p>
<p>SIGQUIT信号对应按下ctrl+\，shell对该信号的处理方式是（观察zsh/bash得到，没有查文档）：若shell当前没有前台任务，则忽略该信号，放弃当前正在输入的命令；若当前有前台任务，则SIGQUIT信号由前台程序捕捉。</p>
<p>SIGQUIT信号对应按下ctrl+z，shell对该信号的处理方式是（观察zsh/bash得到，没有查文档）：若shell当前没有前台任务，则忽略该信号，放弃当前正在输入的命令；若当前有前台任务，则SIGQUIT信号由前台程序捕捉。<br />
PS:对这APUE里的信号表看了一遍，好像没有其他要特殊处理的信号了。</p>
<p>其实很好处理，用signal函数或者sigaction都可以（偷懒就用signal了）。在shell的主进程里改变SIGINT的信号处理函数、忽略SIGQUIT和SIGTSPT信号就可以。</p>
<p>有一个问题需要注意：必须在fork的子进程里恢复对这几个信号的默认处理方式。因为fork产生子进程和父进程有相同的信号处理函数signal handler。解决方法就是fork以后在子进程里手动恢复修改过的信号。另一种方法是不用fork，改用clone系统调用，通过clone flags里的CLONE_SIGHAND参数使得复制出来的进程不保留父进程的信号处理函数。</p>
</p>
<p>回到主题上&#8230;..</p>
<h2>4.后台运行程序</h2>
<p>其实单纯的实现后台运行很简单，把前面程序里的wait去掉使shell主进程不等待子进程结束就OK了。问题在于，shell是通过一个&#8217;&#038;'字符决定后台执行，如何才能从命令里提取出这个代表后台执行的&#8217;&#038;'字符？</p>
<p>看起来似乎一个字符串查找就能解决，其实并非如此：如果这&#8217;&#038;'是在一个路径名里呢(Linux中只有一个字符不能做文件名：&#8217;/')。看一下别的shell很快就会找到解决方法：<strong>转义字符</strong>。如果想把有特殊含义的字符当作一个普通字符处理，那么就要在前面加上转移字符&#8217;\'（比如空格、&#8217;\'、&#8217;&#038;'、&#8217;~'、&#8217;-'等等）。</p>
<p>要支持转移字符，我原来用strsep实现的优美的parse command函数就得全部扔掉重写。没办法，换成了fgetc和丑陋的switch case。</p>
<p>有了转义字符，就可以处理含有特殊字符的文件名了^ ^</p>
<p>另外，我观察到bash和zsh在后台程序运行结束后都会显示一条提示信息显示pid和命令，于是我也想把这个功能加进去。思路很简单，就是改变SIGCHLD信号的handler，捕捉到SIGCHLD后输出进程信息就可以了。默认SIGCHLD信号是通过wait和waitpid函数捕捉。signal能改变SIGCHLD信号的处理函数，但是无法获得足够的信息（pid、退出代码等），而sigaction支持复杂的信号处理函数，通过向信号处理函数传递siginfo结构，提供更充足的信息（还是sigaction强大）。</p>
<p>差不多就这样了&#8230;代码量翻了一倍，直接贴出来有点恐怖，所以扔到附件了～（BUG很多，就不一一列举了，sign～）</p>
<p>源代码：<a href='http://jackaldire.com/wordpress/wp-content/uploads/2010/01/jdsh_v21.c'>jdsh_v2.c</a></p>
]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2010/01/write-your-own-shell-2-background-task/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>自己动手写Linux Shell（一） —— 简单的命令解释器</title>
		<link>http://boundary.cc/wordpress/2010/01/write-your-own-shell-1-a-simple-command-interpreter/</link>
		<comments>http://boundary.cc/wordpress/2010/01/write-your-own-shell-1-a-simple-command-interpreter/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 10:32:37 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[Linux与开源]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://jackaldire.com/?p=80</guid>
		<description><![CDATA[寒假在做Linux Kernel Project这本书上的习题，第二章的练习是写一个简单的shell，看了一下要求觉得这个练习很有价值，涉及到很多Linux C Programming的知识，所以准备认真地做一下。 最终的目标如下: 命令解释执行 支持后台执行(&#038;) 支持输入输出重定向(, >>) 支持管道IPC 内建命令cd, pwd, exit等 可见写一个shell并不是一件简单的事，从简单的一步一步做起吧，手头有APUE，一边做一边查。 一个简单的命令解释器 命令解释执行是shell最基本的功能，实现的方法很简单：从标准输入流中读入命令，然后exec一下就行了。但是还有很多琐碎的地方需要处理： 1.命令行参数传递 首先需要将输入的命令字符串按空格打断（strsep实在是太方便了），然后将打断的字符串构建成一个char*数组，通过execv的第二个参数传递给程序。 注：man exec可以得到关于exec函数族的详细说明。需要说明的是execlp和execvp会在PATH环境变量中的目录搜索可执行程序，而其他的exec函数族函数不会，如果不使用这两个函数，则需要自己编写代码搜索PATH环境变量。 2.使用fork建立子进程 直接在当前进程里exec的话，exec执行的程序结束后，整个程序也就结束了，因为exec直接将原来的进程上下文替换。所以需要fork一个新进程来执行命令，而父进程阻塞直到子进程结束后继续执行，这个可以通过wait函数实现。 3.处理命令的返回值 大多数的shell在命令程序返回非零值（异常退出）会打印出其返回值。而子进程的返回值可以在父进程里通过wait函数的第一个参数得到。然后通过一组宏可以方便地确定子进程的返回状态。这部分内容在APUE里有详细说明（8.6节），下面代码里的pr_exit函数基本上就是从APUE上抄过来的。 4.检查各个函数的返回值 Linux C Programming的一个原则就是在所有可能fail的地方加入检查代码。绝大多数C库函数和Linux系统函数都以负数返回值表示出错，并且通过C库的全局变量errno可以获得错误号，从而得到错误原因，并输出到标准错误流。由于整个过程动作固定，就用一个CHKERR宏来完成了。 下面是源代码 CODE BELOW ARE UNDER GPLV3 LISENCE 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [...]]]></description>
			<content:encoded><![CDATA[<p>寒假在做Linux Kernel Project这本书上的习题，第二章的练习是写一个简单的shell，看了一下要求觉得这个练习很有价值，涉及到很多Linux C Programming的知识，所以准备认真地做一下。</p>
<ol><strong>最终的目标如下:</strong></p>
<li>命令解释执行</li>
<li>支持后台执行(&#038;)</li>
<li>支持输入输出重定向(<, >, >>)</li>
<li>支持管道IPC</li>
<li>内建命令cd, pwd, exit等</li>
</ol>
<p>可见写一个shell并不是一件简单的事，从简单的一步一步做起吧，手头有APUE，一边做一边查。</p>
<p><span id="more-80"></span></p>
<h2>一个简单的命令解释器</h2>
<p>命令解释执行是shell最基本的功能，实现的方法很简单：从标准输入流中读入命令，然后exec一下就行了。但是还有很多琐碎的地方需要处理：</p>
<h3>1.命令行参数传递</h3>
<p>首先需要将输入的命令字符串按空格打断（strsep实在是太方便了），然后将打断的字符串构建成一个char*数组，通过execv的第二个参数传递给程序。</p>
<p>注：man exec可以得到关于exec函数族的详细说明。需要说明的是execlp和execvp会在PATH环境变量中的目录搜索可执行程序，而其他的exec函数族函数不会，如果不使用这两个函数，则需要自己编写代码搜索PATH环境变量。</p>
<h3>2.使用fork建立子进程</h3>
<p>直接在当前进程里exec的话，exec执行的程序结束后，整个程序也就结束了，因为exec直接将原来的进程上下文替换。所以需要fork一个新进程来执行命令，而父进程阻塞直到子进程结束后继续执行，这个可以通过wait函数实现。</p>
<h3>3.处理命令的返回值</h3>
<p>大多数的shell在命令程序返回非零值（异常退出）会打印出其返回值。而子进程的返回值可以在父进程里通过wait函数的第一个参数得到。然后通过一组宏可以方便地确定子进程的返回状态。这部分内容在APUE里有详细说明（8.6节），下面代码里的pr_exit函数基本上就是从APUE上抄过来的。</p>
<h3>4.检查各个函数的返回值</h3>
<p>Linux C Programming的一个原则就是在所有可能fail的地方加入检查代码。绝大多数C库函数和Linux系统函数都以负数返回值表示出错，并且通过C库的全局变量errno可以获得错误号，从而得到错误原因，并输出到标准错误流。由于整个过程动作固定，就用一个CHKERR宏来完成了。
<p>下面是源代码</p>
<p><strong>CODE BELOW ARE UNDER <a href="http://www.gnu.org/licenses/gpl-3.0-standalone.html">GPLV3 LISENCE</a></strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* By JackalDire, Jan 29 2010 
 * Tested on Linux Kernel 2.6.32, gcc 4.4.3 */</span>
<span style="color: #339933;">#include &lt;unistd.h&gt;</span>
<span style="color: #339933;">#include &lt;sys/wait.h&gt;</span>
&nbsp;
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;stdlib.h&gt;</span>
<span style="color: #339933;">#include &lt;string.h&gt;</span>
<span style="color: #339933;">#include &lt;errno.h&gt;</span>
&nbsp;
<span style="color: #339933;">#define LINE_MAX 8192</span>
<span style="color: #339933;">#define ARG_MAX 1024</span>
<span style="color: #339933;">#define ARG_NR_MAX 32</span>
&nbsp;
<span style="color: #339933;">#define CHKERR(ret, msg) if (ret &lt; 0) {\
        fprintf(stderr, &quot;ERROR : \&quot;%s\&quot;, %s\n&quot;, \
                msg, strerror(errno)); \
        exit(-1);   \
    } </span>
&nbsp;
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> args<span style="color: #009900;">&#91;</span>ARG_NR_MAX <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">extern</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span> environ<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">char</span> line<span style="color: #009900;">&#91;</span>LINE_MAX <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">void</span> parse_command<span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span> cmd<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> res<span style="color: #339933;">;</span>
    size_t cnt <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
    <span style="color: #808080; font-style: italic;">/* tokenize the command string by space */</span>
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>res <span style="color: #339933;">=</span> strsep<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>cmd<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot; &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        args<span style="color: #009900;">&#91;</span>cnt<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> strdup<span style="color: #009900;">&#40;</span>res<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    args<span style="color: #009900;">&#91;</span>cnt<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> pr_exit<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> name<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> status<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>WIFEXITED<span style="color: #009900;">&#40;</span>status<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">// exit normally</span>
        <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>WIFSIGNALED<span style="color: #009900;">&#40;</span>status<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;%s exit abnormally, signal %d caught%s.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>
                name<span style="color: #339933;">,</span> WTERMSIG<span style="color: #009900;">&#40;</span>status<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #339933;">#ifdef WCOREDUMP</span>
            WCOREDUMP<span style="color: #009900;">&#40;</span>status<span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #ff0000;">&quot; (core file generated)&quot;</span> <span style="color: #339933;">:</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">#else</span>
            <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">#endif</span>
    <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>WIFSTOPPED<span style="color: #009900;">&#40;</span>status<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;child stopped, signal %d caught.&quot;</span><span style="color: #339933;">,</span>
                WSTOPSIG<span style="color: #009900;">&#40;</span>status<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> argv<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">char</span> c<span style="color: #339933;">;</span>
    size_t idx<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> r<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> status<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        idx <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
        bzero<span style="color: #009900;">&#40;</span>line<span style="color: #339933;">,</span> LINE_MAX <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        c <span style="color: #339933;">=</span> fgetc<span style="color: #009900;">&#40;</span>stdin<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">&amp;&amp;</span> c <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            line<span style="color: #009900;">&#91;</span>idx<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> c<span style="color: #339933;">;</span>
            c <span style="color: #339933;">=</span> fgetc<span style="color: #009900;">&#40;</span>stdin<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        parse_command<span style="color: #009900;">&#40;</span>line<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        r <span style="color: #339933;">=</span> fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        CHKERR<span style="color: #009900;">&#40;</span>r<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;fork&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>r <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            r <span style="color: #339933;">=</span> execvp<span style="color: #009900;">&#40;</span>args<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">//printf(&quot;ret : %d\n&quot;, r);</span>
            CHKERR<span style="color: #009900;">&#40;</span>r<span style="color: #339933;">,</span> args<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            wait<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>status<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            pr_exit<span style="color: #009900;">&#40;</span>args<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> status<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>一个简单的命令解释器就这样完成了，下面的工作就是添加后台执行功能，休息一会^ ^</p>
]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2010/01/write-your-own-shell-1-a-simple-command-interpreter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[消遣]Love Functions</title>
		<link>http://boundary.cc/wordpress/2010/01/love-function/</link>
		<comments>http://boundary.cc/wordpress/2010/01/love-function/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 13:51:46 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[fun]]></category>

		<guid isPermaLink="false">http://jackaldire.com/?p=79</guid>
		<description><![CDATA[Version 1 (ZZ) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 result love&#40;boy, girl&#41; &#123; if &#40; boy.有房&#40;&#41; [...]]]></description>
			<content:encoded><![CDATA[<h2>Version 1 (ZZ)</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;">result love<span style="color: #008000;">&#40;</span>boy, girl<span style="color: #008000;">&#41;</span> 
<span style="color: #008000;">&#123;</span> 
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span> boy.有房<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> and boy.有车<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
        boy.<span style="color: #007788;">set</span><span style="color: #008000;">&#40;</span>nothing<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
        <span style="color: #0000ff;">return</span> girl.嫁给<span style="color: #008000;">&#40;</span>boy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>girl.愿意等<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
        <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span> <span style="color: #000040;">!</span> <span style="color: #008000;">&#40;</span>boy.赚钱 ＞ <span style="color:#800080;">1e6</span> and girl.感情 ＞ <span style="color: #0000dd;">8</span> <span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
            <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>day<span style="color: #000080;">=</span><span style="color: #0000dd;">1</span><span style="color: #008080;">;</span> day ＜<span style="color: #000080;">=</span><span style="color: #0000dd;">365</span><span style="color: #008080;">;</span> day<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
                <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span> day <span style="color: #000080;">==</span> 情人节 <span style="color: #008000;">&#41;</span> 
                    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span> boy.<span style="color: #007788;">givegirl</span><span style="color: #008000;">&#40;</span>玫瑰<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span> girl.感情<span style="color: #000040;">++</span><span style="color: #008080;">;</span> 
                    <span style="color: #0000ff;">else</span> girl.感情<span style="color: #000040;">--</span><span style="color: #008080;">;</span> 
                <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span> day <span style="color: #000080;">==</span> girl.生日<span style="color: #008000;">&#41;</span> 
                    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span> boy.<span style="color: #007788;">givegirl</span><span style="color: #008000;">&#40;</span>玫瑰<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span> 
                        girl.感情<span style="color: #000040;">++</span><span style="color: #008080;">;</span> 
                <span style="color: #0000ff;">else</span> girl.感情<span style="color: #000040;">--</span><span style="color: #008080;">;</span> 
                boy.拼命赚钱<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
                <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span> girl.耐心 <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span> <span style="color: #000040;">&amp;&amp;</span> girl.有其它追求者<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
                    girl.<span style="color: #0000ff;">goto</span><span style="color: #008000;">&#40;</span>nother_boy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
                    boy.郁闷中<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
                    boy.天天到BYR灌水<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
                    <span style="color: #0000ff;">return</span> 没有结果<span style="color: #008080;">;</span> 
                <span style="color: #008000;">&#125;</span> 
            <span style="color: #008000;">&#125;</span> 
        <span style="color: #008000;">&#125;</span>
        <span style="color: #0000ff;">try</span> 
        <span style="color: #008000;">&#123;</span> 
            girl.要男友买房<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
            girl.要男友买车<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
            girl.每天逛专卖店<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span> boy.有房<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;&amp;</span> boy.有车<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
                girl.去澳洲旅游<span style="color: #008000;">&#40;</span>boy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
                girl.到英国威斯敏斯结婚<span style="color: #008000;">&#40;</span>boy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
                girl.嫁给<span style="color: #008000;">&#40;</span>boy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
                boy.没日没夜挣钱<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
            <span style="color: #008000;">&#125;</span> 
        <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">catch</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
            girl.<span style="color: #007788;">byebye</span><span style="color: #008000;">&#40;</span>boy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
            boy.郁闷中<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
            boy.天天到天涯灌水<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
            <span style="color: #0000ff;">return</span> girl.<span style="color: #007788;">broadcast</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;这个男人真小气&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
        <span style="color: #008000;">&#125;</span> 
        <span style="color: #0000ff;">return</span> girl.每天逛专卖店<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
    <span style="color: #008000;">&#125;</span> 
    <span style="color: #0000ff;">return</span> girl.<span style="color: #0000ff;">goto</span><span style="color: #008000;">&#40;</span>another_boy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p><span id="more-79"></span></p>
<h2>Version 2 (By wks)</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> love<span style="color: #008000;">&#40;</span>Man <span style="color: #000040;">&amp;</span>m, Woman <span style="color: #000040;">&amp;</span>w<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
     <span style="color: #0000ff;">try</span> <span style="color: #008000;">&#123;</span> 
         <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>w.<span style="color: #007788;">isFuckable</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
         doSomething<span style="color: #008000;">&#40;</span>things<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">rand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">%</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>things<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">/</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>things<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
         wait<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
        <span style="color: #008000;">&#125;</span> 
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">catch</span> <span style="color: #008000;">&#40;</span>CanWaitNoLongerException e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
    <span style="color: #008000;">&#125;</span> 
    m.<span style="color: #007788;">fuck</span><span style="color: #008000;">&#40;</span>w<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<h2>Version 3 (By me)</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> Man<span style="color: #008080;">::</span><span style="color: #007788;">love</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
    <span style="color: #0000ff;">try</span> <span style="color: #008000;">&#123;</span> 
        <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>m.<span style="color: #007788;">alive</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>m.<span style="color: #007788;">hasHouse</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">||</span> <span style="color: #000040;">!</span>m.<span style="color: #007788;">hasCar</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
            m.<span style="color: #007788;">makeMoney</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>  <span style="color: #666666;">// good luck if this is not a infinite loop... </span>
        <span style="color: #008000;">&#125;</span> 
        Woman w <span style="color: #000040;">*</span><span style="color: #008080;">;</span> 
        <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>w <span style="color: #000080;">=</span> findMM<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>  <span style="color: #666666;">// good luck if this do not block forever... </span>
        <span style="color: #008000;">&#123;</span> 
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>w<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>isLove<span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #0000dd;">this</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;&amp;</span> w<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getParents<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">isLike</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #0000dd;">this</span><span style="color: #008000;">&#41;</span> 
                <span style="color: #000040;">&amp;&amp;</span> w<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getParents<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">getParents</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">isLike</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #0000dd;">this</span><span style="color: #008000;">&#41;</span> 
                <span style="color: #000040;">&amp;&amp;</span> ...<span style="color: #008000;">&#41;</span>    
                marry<span style="color: #008000;">&#40;</span>w<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
            <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">continue</span><span style="color: #008080;">;</span> 
        <span style="color: #008000;">&#125;</span> 
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">catch</span> <span style="color: #008000;">&#40;</span>房子又涨价了Exception  <span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
        letItBe<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">catch</span> <span style="color: #008000;">&#40;</span>遇到宋思明了Exception  <span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>  
        letItBe<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">catch</span> <span style="color: #008000;">&#40;</span>被炒鱿鱼了Exception <span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
        letItBe<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">catch</span> <span style="color: #008000;">&#40;</span>家命难违Exception <span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> 
        letItBe<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
    ...... 
    <span style="color: #008000;">&#125;</span> finally <span style="color: #008000;">&#123;</span> 
        mayGodSaveMe<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
    <span style="color: #008000;">&#125;</span> 
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2010/01/love-function/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[C++]一个由C-Style类型转换引发的血案</title>
		<link>http://boundary.cc/wordpress/2010/01/c-style-cast-issues/</link>
		<comments>http://boundary.cc/wordpress/2010/01/c-style-cast-issues/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 13:13:21 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://jackaldire.com/?p=78</guid>
		<description><![CDATA[没事搜了一下自己域名，无意间发现老早提交的open directory申请居然通过了&#8230;想到一个多月没写东西，大惭&#8230; 为了尽快阻止这个连续N天没有日志的记录，先找一篇凑数&#8230; 先上开胃小菜 Appetizer 有人在byr论坛C++版上问了这样一道C++面试题： class A &#123; public: void fun&#40;&#41; &#123; &#125; &#125;; &#160; class B: public A &#123; public: virtual void fun&#40;&#41; &#123; &#125; &#125;; &#160; class C: public B &#123; public: void fun&#40;&#41;&#123;&#125; &#125;; &#160; class D: virtual public A &#123; public: void fun&#40;&#41;&#123;&#125; &#125;; &#160; int main&#40;void&#41; &#123; void *p; [...]]]></description>
			<content:encoded><![CDATA[<p>没事搜了一下自己域名，无意间发现老早提交的<a href="http://www.dmoz.org/World/Chinese_Simplified/%E8%AE%A1%E7%AE%97%E6%9C%BA/%E4%BA%92%E8%81%94%E7%BD%91%E7%BB%9C/%E7%BD%91%E7%BB%9C%E8%B5%84%E6%BA%90/%E5%8D%9A%E5%AE%A2/%E6%8A%80%E6%9C%AF/">open directory</a>申请居然通过了&#8230;想到一个多月没写东西，大惭&#8230;</p>
<p>为了尽快阻止这个连续N天没有日志的记录，先找一篇凑数&#8230;</p>
<h2>先上开胃小菜 Appetizer</h2>
<p>有人在<a href="http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&#038;ID=34447&#038;pos=49&#038;page=1">byr论坛C++版</a>上问了这样一道C++面试题：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> A <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span> <span style="color: #0000ff;">void</span> fun<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>    <span style="color: #008000;">&#123;</span>    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">class</span> B<span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> A <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> fun<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">class</span> C<span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> B <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span> <span style="color: #0000ff;">void</span> fun<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">class</span> D<span style="color: #008080;">:</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">public</span> A <span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">void</span> fun<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span>  <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>p<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>A<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>fun<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>C<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>fun<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// why fault here?</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>D<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>fun<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>为什么在((C*)NULL)->fun()这句挂了呢？</p>
<p><span id="more-78"></span><br />
原因很简单：B的fun是虚函数, 而C继承B, 所以通过C对象指针调用fun的时候触发基类virtual方法的多态特性, 需要查通过vptr查询虚表, 但是对NULL强制类型转换并不会设置vptr（vptr的设置是在构造函数中完成的），编译器就把地址0（NULL）中的内容当vptr，一解引用就segment fault了。</p>
<p>其实一开始看((A*)NULL)->fun();这句也觉得别扭，没有构造对象就直接调用非static的成员方法，居然还没有运行错误。想了一想，实际上在编译期，编译器都会通过一个<a href="http://en.wikipedia.org/wiki/Name_mangling">name mangling机制</a>将类的成员函数转换成一个具有唯一名字的非成员函数。程序开始运行时，成员函数和非成员函数一样都被载入到内存。所以只要在调用的成员函数不用到需要由类构造函数构造的成分（比如成员变量和vptr），这种通过指针调用成员函数就不会出错。</p>
<p>其实这个问题并不复杂，但是jmpesp老兄在回帖中写了一道更恶心的题目。</p>
<h2>主菜来了 Main Dishes</h2>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> A <span style="color: #008000;">&#123;</span>  
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>  
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> fun<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">float</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;A&quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>  
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>  
&nbsp;
<span style="color: #0000ff;">class</span> B <span style="color: #008000;">&#123;</span>  
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>  
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> fun<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;B&quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>  
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>  
&nbsp;
<span style="color: #0000ff;">class</span> C<span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> B, <span style="color: #0000ff;">public</span> A <span style="color: #008000;">&#123;</span>  
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>  
    <span style="color: #0000ff;">void</span> fun<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">float</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;C float&quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">void</span> fun<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span>   <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;C int&quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span> 
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>       
    C<span style="color: #000040;">*</span> p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> C<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>B<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>A<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>p<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>fun<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>问该段代码的输出是什么？</p>
<p>自己编译运行了一下输出是：C float&#8230;</p>
<p>首先输出C是确定的，因为无论怎么转型， p都是指向一个C对象，而A、B中的fun都是虚函数，所以调用的肯定是C类方法。输出float看起来比较诡异，原因肯定在这个(B*)(A*)c-style转型上。</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">     <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #008000;">&#40;</span>A<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>p <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
     <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #008000;">&#40;</span>B<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>p <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
     <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #008000;">&#40;</span>B<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>A<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>p <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span></pre></div></div>

<p>上面的代码得到以下输出：<br />
00382E30<br />
00382E34<br />
00382E30</p>
<p>可见(B*)(A*)p和(A*)p是相同的。</p>
<p>分析如下：</p>
<p>C继承了A和B，所以一个C对象里包含了一个A对象和B对象。由上面的输出知道(A*)p使得p偏移到了C对象中的A对象，是个static_cast。 接下来(B*)再对指向A对象的p进行转型，这时候问题就出现了，B对象并不包含A对象，编译器也不知道p指向的A对象实际上是包含在一个C对象里，所以 (B*)这次转换，只是改变了p的静态类型，并没有改变p指向的位置，是个reinterpret_cast也就是说p还是指向一个A对象。所以通过p调用fun(1)的时候，查的是A的虚表，先查到virtual void A::fun(float)，再到void C::fun(float)</p>
<p>这个问题的关键就在(B*)(A*)p这两个C-Style的函数式转型(functional cast)上:<br />
(A*)p是从派生类C到基类A的转换，有可能是个向从派生类到基类的static_cast，也有可能是个简单的reinterpret_cast, 从运行结果上看(A*)是个static_cast，而由(A*)到(B*)的转换不可能是static_cast（static_cast (static_cast(p)))是编译不过的），所以只能是reinterpret_cast</p>
<p>这里又出现了一个问题，为什么(A*)p是个static_cast而不是reinterpret_cast？至少这与我的直觉不服，在ISO C++标准5.4节找到如下定义(见图):</p>
<p>也就是说一个C-style的强制类型转换如果可以解释成多个列表里的C++ style转型，取在列表里位置最前面的一个。static_cast在reinterpret_cast前，所以得到了下面的结果：</p>
<p style="text-align: center;"><strong>(B*)(A*)p 等价于 reinterpret_cast(static_cast(p))</strong></p>
<h2><strong>由这道题目说明（Conclusion）：</strong></h2>
<ol>
<li><strong>千万不要用C-style对对象指针进行转型，请用C++-style的static_cast、reinterpret_cast和dynamic_cast，以免造成意料之外的错误。</strong></li>
<li><strong>C++标准是个好东西，它胜过任何技术手册，一旦对语言特性有困惑，查标准是最好的解决方法。</strong></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2010/01/c-style-cast-issues/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[一道面试题]含有*的字符串匹配问题</title>
		<link>http://boundary.cc/wordpress/2009/11/string-matching-with-wildcard/</link>
		<comments>http://boundary.cc/wordpress/2009/11/string-matching-with-wildcard/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 01:13:43 +0000</pubDate>
		<dc:creator>Joker</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[算法]]></category>
		<category><![CDATA[面试题]]></category>

		<guid isPermaLink="false">http://jackaldire.com/?p=76</guid>
		<description><![CDATA[Question 字符串1：只含有英文字母 字符串2：含有英文字母和*，其中符号*表示匹配任意字符0或者多次，即正则表达式里面的含义。 现在给定这样的两个串，要求判断是否匹配？ bool isMatch ( const char *str1, const char *str2) 例如：str1 = “hello”, str2 = “he*o”，则二者匹配，返回true,str1 = “hello”, str2 = “he*l”，则不匹配，返回false。 Solution 关键是如何处理*，首先想到的就是回溯，在纸上画了一下得到如下算法 设输入是两个字符串 s, t, 其中t可能包含* 1.当*t不是*的时候, 就像普通的串匹配一样, 移动s和t 2.当*t是*的时候, 假设*t后面第一个不是*的字符是x, 若x是null, 直接匹配成功, 否则在s中找到当前位置后所有字符x的位置, 这时候问题转化成了t中x后的串和s中当前位置以后所有以x为开始的串的匹配问题, 递归调用即可, 其中任意一个匹配成功, 则原串匹配成功, 若都没有匹配成功则匹配失败. 3.当*s和*t其中一个是null时 跳出循环, 若此时 *t == &#8216;*&#8217;, 则++t 知道 t != &#8216;*&#8217;, 这时若 [...]]]></description>
			<content:encoded><![CDATA[<h2>Question</h2>
<p>字符串1：只含有英文字母<br />
字符串2：含有英文字母和*，其中符号*表示匹配任意字符0或者多次，即正则表达式里面的含义。</p>
<p>现在给定这样的两个串，要求判断是否匹配？<br />
bool isMatch ( const char *str1, const char *str2)</p>
<p>例如：str1 = “hello”, str2 = “he*o”，则二者匹配，返回true,str1 = “hello”, str2 = “he*l”，则不匹配，返回false。</p>
<p><span id="more-76"></span></p>
<h2>Solution</h2>
<p>关键是如何处理*，首先想到的就是回溯，在纸上画了一下得到如下算法</p>
<p>设输入是两个字符串 s, t, 其中t可能包含* <.p><br />
1.当*t不是*的时候, 就像普通的串匹配一样, 移动s和t <br />
2.当*t是*的时候,  假设*t后面第一个不是*的字符是x,  若x是null, 直接匹配成功,  否则在s中找到当前位置后所有字符x的位置, 这时候问题转化成了t中x后的串和s中当前位置以后所有以x为开始的串的匹配问题, 递归调用即可, 其中任意一个匹配成功, 则原串匹配成功, 若都没有匹配成功则匹配失败.</p>
<p>3.当*s和*t其中一个是null时 跳出循环, 若此时 *t  == &#8216;*&#8217;, 则++t 知道 t != &#8216;*&#8217;,  这时若 *t == 0 则代表匹配成功, 否则匹配失败。</p>
<p>代码如下:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;cstring&gt;</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> is_match<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> s, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> t<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>s <span style="color: #000040;">&amp;&amp;</span> <span style="color: #000040;">*</span>t<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #FF0000;">'*'</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #000040;">*</span>s <span style="color: #000080;">==</span> <span style="color: #000040;">*</span>t<span style="color: #008000;">&#41;</span>
            <span style="color: #000040;">++</span>s, <span style="color: #000040;">++</span>t<span style="color: #008080;">;</span>
        <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #FF0000;">'*'</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #000040;">*</span>s <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #000040;">*</span>t<span style="color: #008000;">&#41;</span>
            <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0000ff;">do</span> <span style="color: #000040;">++</span>t<span style="color: #008080;">;</span> <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
            <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span> <span style="color: #008080;">;</span> <span style="color: #000040;">*</span>s<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>s<span style="color: #008000;">&#41;</span>
                <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>s <span style="color: #000080;">==</span> <span style="color: #000040;">*</span>t <span style="color: #000040;">&amp;&amp;</span> is_match<span style="color: #008000;">&#40;</span>s<span style="color: #000040;">+</span><span style="color: #0000dd;">1</span>, t<span style="color: #000040;">+</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
            <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">++</span>t<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>s <span style="color: #000080;">==</span> <span style="color: #000040;">*</span>t<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>is_match<span style="color: #008000;">&#40;</span>argv<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span>, argv<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;match&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;not match&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<h2>改进</h2>
<p>上面的暴力算法如果遇到“aaaaaaaaaaaaaaaa”，“a*a*a*a*a*a*a*a*a*a*a*a”这样的输入，会达到2^n的复杂度，是无法接受的。注意到，递归搜索是有很多重复的状态，自然就想到了记忆化搜索，时间空间复杂度均为O(n^2)，代码如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;cstring&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> MAX_LEN <span style="color: #000080;">=</span> <span style="color: #0000dd;">1024</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> dp<span style="color: #008000;">&#91;</span>MAX_LEN<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>MAX_LEN<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> is_match<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> p, <span style="color: #0000ff;">int</span> q, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> s, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> t<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>dp<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span> <span style="color: #000080;">&gt;=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">return</span> dp<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> <span style="color: #000040;">&amp;</span>ans <span style="color: #000080;">=</span> dp<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>s<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #000040;">!</span>t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        ans <span style="color: #000080;">=</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>s<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span> <span style="color: #000040;">||</span> <span style="color: #000040;">!</span>t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span> <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            ans <span style="color: #000080;">=</span> is_match<span style="color: #008000;">&#40;</span>p, q <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, s, t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span> <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            ans <span style="color: #000080;">=</span> is_match<span style="color: #008000;">&#40;</span>p <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, q, s, t<span style="color: #008000;">&#41;</span>
                <span style="color: #000040;">||</span> is_match<span style="color: #008000;">&#40;</span>p, q <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, s, t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>s<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span> <span style="color: #000080;">==</span> t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            ans <span style="color: #000080;">=</span> is_match<span style="color: #008000;">&#40;</span>p <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, q <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, s, t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">return</span> ans<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> is_match<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> s, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> t<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">memset</span><span style="color: #008000;">&#40;</span>dp, <span style="color: #000040;">-</span><span style="color: #0000dd;">1</span>, <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>dp<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> is_match<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span>, <span style="color: #0000dd;">0</span>, s, t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>  
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>is_match<span style="color: #008000;">&#40;</span>argv<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span>, argv<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;match&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;not match&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://boundary.cc/wordpress/2009/11/string-matching-with-wildcard/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

