<?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>iCoder.ME</title>
	<atom:link href="http://icoder.cloudcontrolled.com/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://icoder.cloudcontrolled.com</link>
	<description>C, C++, Emacs Lisp, and more</description>
	<lastBuildDate>Sat, 24 Sep 2011 16:19:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Mac里输入特殊符号</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/09/25/type-symbols-in-mac/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/09/25/type-symbols-in-mac/#comments</comments>
		<pubDate>Sat, 24 Sep 2011 16:19:17 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://icoder.cloudcontrolled.com/?p=906</guid>
		<description><![CDATA[Mac里输入特殊符号特别简单，按住option键(or with shift as well)再按键盘即可。下面是wiki里的两幅映射表： 这个链接对特殊符号分类分得很好：http://www.andyjv.com/mac.html]]></description>
			<content:encoded><![CDATA[<p>Mac里输入特殊符号特别简单，按住option键(or with shift as well)再按键盘即可。下面是wiki里的两幅映射表：</p>
<p><a href="http://icoder.cloudcontrolled.com/index.php/2011/09/25/type-symbols-in-mac/special-characters-mac/" rel="attachment wp-att-907"><img src="http://icoder.cloudcontrolled.com/wp-content/uploads/2011/09/Special-Characters-Mac.png" alt="" title="Special-Characters-Mac" width="410" height="139" class="alignnone size-full wp-image-907" /></a></p>
<p><a href="http://icoder.cloudcontrolled.com/index.php/2011/09/25/type-symbols-in-mac/special-characters-mac-alt-key-shift/" rel="attachment wp-att-908"><img src="http://icoder.cloudcontrolled.com/wp-content/uploads/2011/09/Special-Characters-Mac-Alt-Key-Shift.png" alt="" title="Special-Characters-Mac-Alt-Key-Shift" width="410" height="139" class="alignnone size-full wp-image-908" /></a></p>
<p>这个链接对特殊符号分类分得很好：<a href="http://www.andyjv.com/mac.html">http://www.andyjv.com/mac.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/09/25/type-symbols-in-mac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GNU screen给session设置名字——screen -S NAME</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/09/16/gnuscreen-session-name/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/09/16/gnuscreen-session-name/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 08:48:17 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icoder.cloudcontrolled.com/?p=903</guid>
		<description><![CDATA[创建时设置: $ screen -S NAME 在session中设置: C-a : sessionname NAME 恢复: $ screen -r NAME]]></description>
			<content:encoded><![CDATA[<pre class="mycode">
创建时设置:
$ screen -S NAME

在session中设置:
C-a :
sessionname NAME

恢复:
$ screen -r NAME
</pre>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/09/16/gnuscreen-session-name/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>awk中创建子进程</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/07/22/subprocess-in-awk/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/07/22/subprocess-in-awk/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 06:25:27 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Awk]]></category>

		<guid isPermaLink="false">http://icoder.cloudcontrolled.com/?p=898</guid>
		<description><![CDATA[在使用awk过程中越发觉得awk强大！ 有这样一个任务，输入文件(in.txt)是一个无序的多行文本，格式如下： baidu www.baidu.com/ 7 net114 www.net114.com NULL soufun zzbbs.soufun.com 202.108.253.30 baidu www.baidu.com/ 8 miibeian www.miibeian.gov.cn 110.85.5.15 baidu www.baidu.com/ 1 baidu www.baidu.com/ 2 net114 www.net114.com 122.11.51.71 miibeian www.miibeian.gov.cn 8.5.1.74 baidu www.baidu.com/ 3 ... ... 每行3列，列之间用 \t 分隔。 需求是：将in.txt按照第一列切分成多个文件，并要求输出文件有序。 对于这个需求，第一想到的做法是用awk将文件拆分，然后再对输出的几个文件排序。 这样做OK，但有点小问题：awk将in.txt拆分后，再进行排序，就会占用2倍的磁盘空间，因为原始文件占一份磁盘空间，排序后的文件也要占一份磁盘空间。 &#8230;<p class="read-more"><a href="http://icoder.cloudcontrolled.com/index.php/2011/07/22/subprocess-in-awk/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>在使用awk过程中越发觉得awk强大！</p>
<p>有这样一个任务，输入文件(in.txt)是一个无序的多行文本，格式如下：</p>
<pre>
baidu       www.baidu.com/     7
net114      www.net114.com     NULL
soufun      zzbbs.soufun.com           202.108.253.30
baidu       www.baidu.com/     8
miibeian    www.miibeian.gov.cn        110.85.5.15
baidu       www.baidu.com/     1
baidu       www.baidu.com/     2
net114      www.net114.com     122.11.51.71
miibeian    www.miibeian.gov.cn        8.5.1.74
baidu       www.baidu.com/     3
... ...
</pre>
<p>每行3列，列之间用 \t 分隔。</p>
<p>需求是：将in.txt按照第一列切分成多个文件，并要求输出文件有序。<br />
<span id="more-898"></span></p>
<p>对于这个需求，第一想到的做法是用awk将文件拆分，然后再对输出的几个文件排序。</p>
<p>这样做OK，但有点小问题：awk将in.txt拆分后，再进行排序，就会占用2倍的磁盘空间，因为原始文件占一份磁盘空间，排序后的文件也要占一份磁盘空间。</p>
<p>然后考虑的是直接在awk里通过pipe直接输出给sort进行排序，这样就只占用一份空间了，代码大致如下：</p>
<pre class="mycode">
cat in.txt | awk -F'\t' '{ print $2"\t"$3 | "sort > out."$1".sorted"; }'
</pre>
<p>我这样将代码写完后想到了一个问题：对于上面这段代码，awk内部会开几个子进程呢？</p>
<p>因为对于我的输入(in.txt)， 通过awk切分后 print 那条管道命令会变成多条，如：</p>
<pre>
第1行输入： print "www.baidu.com  \t  7" | " sort > out.baidu.sorted"
第2行输入： print "www.net114.com  \t  122.11.51.71" | " sort > out.net114.sorted"
... ...
第4行输入： print "www.baidu.com/  \t  8" | " sort > out.baidu.sorted"
... ...
</pre>
<p>看上面几行：<br />
   * 对于第1行，awk启动了一个子进程，执行的命令是： &#8220;sort > out.baidu.sorted&#8221;;<br />
   * 第2行，awk应该启动另一个子进程，执行的命令是： &#8220;sort > out.net114.sorted&#8221;;<br />
   * 第4行，<b>现在问题来了:</b>执行的命令还是： &#8220;sort > out.baidu.sorted&#8221;, 那对于awk来说，<i>是会新启一个子进程还是用第1行启的子进程呢？</i></p>
<p>我们把awk脚本简单修改下，通过pstree来看看就知道了.</p>
<pre class="mycode">
修改后的awk命令：
cat in.txt | awk -F'\t' '{ print $2"\t"$3 | "sort > out."$1".sorted"; system("sleep 3"); }' &#038;
让脚本后来处理，并且每输出一行sleep 3sec.

然后看看awk到底创建了几个子进程：
$ pstree -a | grep -C10 "cat"
  |   |           |-awk -F\t {\040print\040$2"\t"$3\040|\040"sort\040>\040out."$1".sorted";\040system("sleep\0403");\040}
  |   |           |   |-sh -c sort\040>\040out.baidu.sorted
  |   |           |   |   `-sort
  |   |           |   |-sh -c sort\040>\040out.net114.sorted
  |   |           |   |   `-sort
  |   |           |   |-sh -c sort\040>\040out.soufun.sorted
  |   |           |   |   `-sort
  |   |           |   |-sh -c sort\040>\040out.miibeian.sorted
  |   |           |   |   `-sort
  |   |           |   `-sleep 3
</pre>
<p>从pstree显示的结果看来，<b class="red">awk对于相同的命令只启动了一个子进程。</b></p>
<p>再查了下awk手册，里面的说法也确定了我的观察结果：</p>
<div>
NOTE: If using a pipe or co-process to getline, or from print or printf within a loop, you  must  use  close()  to create new instances of the command.  AWK does not automatically close pipes or co-processes when they return EOF.
</div>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/07/22/subprocess-in-awk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>shell中如何wait某个后台程序并取得其返回值</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/07/12/wait-for-bg-process-in-bash/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/07/12/wait-for-bg-process-in-bash/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 22:37:09 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://icoder.cloudcontrolled.com/?p=893</guid>
		<description><![CDATA[要等待某个特定PID的后台程序执行结束并取得其返回值(exit code)，在BASH中可以这样做： cmd &#038; p1=$! wait $p1 &#124;&#124; ret=$? 简单解释下： cmd &#038; p1=$! 其实是2条语句： cmd &#038; 后台执行程序cmd. p1=$! 将上个进程的PID存入p1中 而 wait $p1 &#124;&#124; ret=$? 也是两条语句： wait $p1 等待PID是$p1的进程结束，p1进程的返回值将作为wait的返回值. ret=$? 取得上条命令的返回值，存入ret中 因此，全部展开后变成： cmd &#038; p1=$! wait $p1 ret=$?]]></description>
			<content:encoded><![CDATA[<p>要等待某个特定PID的后台程序执行结束并取得其返回值(exit code)，在BASH中可以这样做：</p>
<pre class="mycode">
cmd &#038; p1=$!
wait $p1 || ret=$?
</pre>
<p><span id="more-893"></span></p>
<p>简单解释下：<br />
cmd &#038; p1=$!<br />
其实是2条语句： </p>
<ul>
<li>cmd &#038; 后台执行程序cmd.</li>
<li>p1=$!  将上个进程的PID存入p1中</li>
</ul>
<p>而 wait $p1 || ret=$?<br />
也是两条语句：</p>
<ul>
<li>wait $p1 等待PID是$p1的进程结束，p1进程的返回值将作为wait的返回值.</li>
<li>ret=$?  取得上条命令的返回值，存入ret中</li>
</ul>
<p>因此，全部展开后变成：</p>
<pre class="mycode">
cmd &#038;
p1=$!
wait $p1
ret=$?
</pre>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/07/12/wait-for-bg-process-in-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[zz] C++ 学习 专家推荐书单</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/06/30/cxx-recommended-books/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/06/30/cxx-recommended-books/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 11:08:16 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Cpp]]></category>

		<guid isPermaLink="false">http://icoder.cloudcontrolled.com/?p=887</guid>
		<description><![CDATA[Table Of Content: 综合/巨著: 《C++程序设计语言（特别版）》 《C++Primer中文版》（第四版） 《C++编程思想》（第二版） 入门: 《Accelerated C++中文版》 《C++ PRIMERPLUS》(第5版)中文版 中级: 《C++必知必会》 《Effective C++中文版》 《More Effective C++中文版》 《Effective STL》 《C++高级编程》 《C++沉思录》(Ruminations on C++) 《设计模式》(Design Patterns) 《C++经典问答》(C++ FAQs) 专题/高级: 《C++标准程序库：自修教程与参考手册》(The C++ Standard Library: A Tutorial and Reference) 《Imperfect C++中文版》 &#8230;<p class="read-more"><a href="http://icoder.cloudcontrolled.com/index.php/2011/06/30/cxx-recommended-books/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<h2>Table Of Content:</h2>
<p><b class="blue">综合/巨著:</b><br />
   《C++程序设计语言（特别版）》<br />
   《C++Primer中文版》（第四版）<br />
   《C++编程思想》（第二版）<br />
<b class="blue">入门:</b><br />
   《Accelerated C++中文版》<br />
   《C++ PRIMERPLUS》(第5版)中文版<br />
<b class="blue">中级:</b><br />
   《C++必知必会》<br />
   《Effective C++中文版》<br />
   《More Effective C++中文版》<br />
   《Effective STL》<br />
   《C++高级编程》<br />
   《C++沉思录》(Ruminations on C++)<br />
   《设计模式》(Design Patterns)<br />
   《C++经典问答》(C++ FAQs)<br />
<b class="blue">专题/高级:</b><br />
   《C++标准程序库：自修教程与参考手册》(The C++ Standard Library: A Tutorial and Reference)<br />
   《Imperfect C++中文版》<br />
   《大规模C++程序设计》<br />
   《C++设计新思维：泛型编程与设计模式之应用》(Modern C++ Design)<br />
   《C++网络编程，卷1，卷2》<br />
<span id="more-887"></span></p>
<p>======================================</p>
<h2>综合/巨著</h2>
<h3>《C++程序设计语言（特别版）》</h3>
<p>Bjarne Stroustrup<br />
中文版：裘宗燕　译<br />
机械工业出版社<br />
影印版：高等教育出版社</p>
<p>程序设计语言的书，有一个很有趣的现象，就是语言发明者几乎都要写书，而语言开发年代越新的，书的质量似乎越差。C和C++以及Perl的夫子自道均成为不可动摇的经典，相比之下C的口碑最好，20年后仍然首屈一指；Java（人民邮电出版社即将出版）处于中点，虽然也堪称经典，但是因为竞争激烈，不如前面几部著作那样不可替代；PHP（O’Reilly出版）又次之；C#更次之，几乎等同于文档；到了Ruby作者的那本Nutshell（O’Reilly出版），甚至骂声都不少了。</p>
<p>　　本书不适合初学者，内容较深，而且许多地方在你有了一定经验之后再去体会，才会发现其高妙之处。但是对于中高级读者，本书完全当得字字珠玑的评价。从某种意义上说，许多其他中级C++图书中的条款、经验之谈，读起来似乎新鲜，但是仔细翻看本书，其实Bjarne早已经谈到。无怪乎有传说Bjarne对Scott Meyer并不感冒，曾表示后者无非是收集了一些自己四处流露的思想成书，却铸就大名（小道消息，切勿外传）。稍微遗憾的是，裘教授的翻译虽然已属难得，但是不够平易，有些地方增加了阅读的门槛，书中的索引错误较多，而且按中文排序，反而不方便查找。</p>
<p>　　Stroustrup的另一本著作《C++语言的设计和演化》，也值得推荐，要想成为真正的C++高手，就需要了解各种特性的来龙去脉，此书绝对不应错过。当然，对于语言本身学习并非必需。</p>
<h3>《C++Primer中文版》（第四版）</h3>
<p>Stanley B.Lippman, Josee Lajoie, Barbara E.Moo<br />
中文版：蒋爱军等译<br />
人民邮电出版社<br />
第三版影印版：人民邮电出版社</p>
<p>本书经常被人与Stroustrup的著作相提并论，甚至有“倚天屠龙”之称。当然，Stroustrup书中那种深不可测的感觉，不是本书作者追求的目标，C++最佳教本是本书最好的定义。不过，本书又不仅仅是教本而已，其中也处处体现着大师级作者的丰富经验和真知灼见。</p>
<p>　　与一般修订不同，第四版中作者几乎完全重写，我们甚至找不到什么完全相同的话，其决心之大，可见一斑。在标准并无更新的情况下，这样大的改动，原因何在呢？在我看来，这体现了C++界在面对Java、C#等更加“简单的”语言的挑战下达成的一种共识。其核心，就是摆脱历史负担，将C++当作一门新语言教学，通过标准库、最佳实践的强调，降低C++学习和使用的难度。</p>
<p>　　从我自己的阅读体验来说，本书第三版抱负太大，过于求全，按照面向过程、基于对象、面向对象和泛型四种编程风格组织内容，对于初学者来说是存在负作用的。第四版一开始就使用标准库，而且素材的组织更加流畅，可读性大大提高，学习曲线大大缩短。而现代编程风格的融入，又使本书仍然显得卓然不群。如果说第三版推荐给初学者阅读我还心存疑虑的话，第四版就没有任何障碍了。值得一提的是，本书的翻译非常优秀，不输于任何已知的名家。</p>
<h3>《C++编程思想》（第二版）</h3>
<p>卷1：标准C++导引，卷2：实用编程技术<br />
Bruce Eckel<br />
中文版、影印版：机械工业出版社</p>
<p>本书的名气之大，几乎不在以上两种巨著之下，尤其是卷2出版之后。其优点在于融入了最新的业界实践，比如防御性编程、测试驱动开发、设计模式等等。当然，对面向对象思想的阐释也是Bruce Eckel的成名招牌。之所以只能获得一个列席的资格，原因出在翻译上。</p>
<h2>入门</h2>
<h3>《Accelerated C++中文版》</h3>
<p>Andrew Koenig, Barbara E.Moo<br />
中文版：中国电力出版社<br />
影印版：机械工业出版社</p>
<p>　　C++入门图书极多，《C++ Primer》其实也可以算作入门书，尤其是第四版。但是，更多地被人（包括Bjarne Stroustrup）推荐的入门书却非本书莫属。当然，与竞争对手相比，本书定价和篇幅上的优势非常明显。作者夫妇都是最早在贝尔实验室与Stroustrup并肩作战的先驱，Moo女士甚至担任过cfront编译器的项目经理，是Stroustrup等人的领导。他们在斯坦福大学采用标准库优先的方法，使学生一上来就能编写有用的“大”程序，取得了很好的效果。如今这种方法已经成为一种共识。需要注意的是，中文版的翻译问题较多。</p>
<p>　　与此类似的是Lippman根据Primer缩编的《Essential C++》，因为结构是第三版的，对初学者来说难度比较大，所以不再推荐。</p>
<h3>《C++ PRIMERPLUS》(第5版)中文版</h3>
<p>Prata 孙建春　韦强译<br />
人民邮电出版社<br />
《C++入门经典》（第3版）（新书！）<br />
Ivor Horton　李予敏译<br />
清华大学出版社</p>
<p>　　这两本书以及Deitel父子的C++属于同一档次的图书，作者经验均非常丰富，图书涵盖较全，选材中规中矩，历经多版修订，各方面都比较成熟，作为入门都是不错的。相比之下，Prata的篇幅更加合适，而且我感觉他的叙事风格更符合大部分初学者的学习习惯。说明一点，以上的评价是根据原版做出，中译本我们并未见到，欢迎购买了这三本书的读者评价比较翻译质量。</p>
<h2>中级</h2>
<p>　　中级图书基本上是经验之谈，讲述如何实际编程、哪些地方容易出错以及各种场合下的do和don’t的问题。有篇Amazon书评用一个妙喻很好地说明了中级和教程图书的区别，教程是驾驶员手册，而中级图书是陪练。在真正开始驾驶时，谁都希望有一位专家在副驾驶座位上随时提醒纠正。</p>
<p>　　C++专家的实力在中级图书层次得到了充分体现。Java和C#等等在此层次就逊色得多。Java只有Effective Java、PracticalJava以及人民邮电出版社新近出版的《Java解惑》三种，C#更只有Effective C#和Framework Design Guidelines（均将由人民邮电出版社出版）两本，也许是语言本身使然？</p>
<h3>《C++必知必会》</h3>
<p>Stephen Dewhurst　荣耀译<br />
人民邮电出版社</p>
<p>　　本书的原名是C++ Common Knowledge，也就是常识之义。出版社的宣传语是“最好的第二本C++图书”。的确，掌握语言并有一定实践经验后，这本书可以作为一个知识点的复查单，看看自己的C++知识和技能与一名合格的专业程序员还有哪些差距。Dewhurst的文字非常平易，很容易读进去。这本书对于C++高手也是有用的：可以在周围的同事询问一些常识问题时，代为解答。本书得到荣耀这样优秀的译者，更加增色不少。</p>
<h3>Scott Meyers系列:</h3>
<h3>《Effective C++中文版》</h3>
<p>第二版：侯捷译<br />
华中科技大学出版社<br />
第三版影印：电子工业出版社</p>
<h3>《More Effective C++中文版》</h3>
<p>侯捷译　中国电力出版社</p>
<h3>《Effective STL》</h3>
<p>潘爱民译　清华大学出版社</p>
<p>　　长期以来，因为这个系列Scott Meyers在C++界的地位几乎是一人之下，其影响之大，可想而知。Meyers的确是难得的优秀技术作家，不仅在于他开创的Effective的写作方式，更在于他精湛技术和透彻叙述的完美结合。这一方面Stroustrup其实是需要向他学习的。三本书各有偏重：EC是语言基础和技术，MEC是高级特性和设计，STL专讲标准库。值得注意的是，Effective C++一书已经有了新版本，加入了模板、资源管理、多线程等内容，而且素材非常新，涵盖了Boost和TR1。对各种语言的比较相信很多读者也会兴趣盎然。Herb Sutter系列《Exceptional C++中文版》卓小涛译中国电力出版社《More Exceptional C++中文版》於春景译华中科技大学出版社《Exceptional C++ Style》（新书！）刘未鹏译人民邮电出版社《C++编程规范》（新书！）刘基诚译人民邮电出版社</p>
<p>　　近年来，Meyers在业界的二号地位已经渐渐被Herb Sutter所取代。Sutter身兼C++标准委员会主席和微软C++/CLI架构师两个角色，而且长期在CUJ上撰稿，包括生动有趣的“对话”专栏，还坚持主持新闻组中Guru of the Week，对社区的贡献确实很大。当然，Exceptional三部曲，加上与Andrei Alexandrescu合著的Bible级的《C++编程规范》一书，无疑也是他得以确立今日地位的重要砝码。</p>
<p>　　Exceptional系列也是由条款组成，但是采用提问、解答的形式。准确地说，这个系列完全可以划归高级，因为连Scott Meyers都说自己经常掉入其中题目的陷阱中。书中涉及的语言细节之深，其他地方很难看到。当然，最直接的作用，是进行自测或者测试别人。</p>
<p>　　我们认为，《C++编程规范》一书是近年来最重要的一本C++新书。之所以这样说，并非因为书中有什么别处没有的新内容，而是因为它的全面性（这本书其实是Sutter和Alexandrescu对博大精深的C++知识以及浩如烟海的C++文献的一次总结和梳理，因此比其他中级图书都要全面）和必要性——本书可以作为游历C++世界的地图，无论你处于什么层次，都可以通过它找到自己的位置，确定前进的方向。书中的文字极为凝练，许多文字都需要阅读各条之后的文献才能透彻了解。这是与其他类似图书另一个不同之处。正因为此，我在翻译过程中，曾经发愿要像清儒注经那样做一个注释极丰富的译本，而且已经为此收集了大部分相关的文献。但是时间显然成了无法逾越的障碍。盼望着还有实现的机会，也希望读者能够助我一臂之力。</p>
<h3>《C++高级编程》</h3>
<p>Nicholas A.Solter,Scott J.Kleper<br />
刘鑫　杨健康　等译<br />
机械工业出版社</p>
<p>　　与前面介绍的Effective式图书不同，本书是一本非常优秀的中级教程，有些部分很像《C++编程思想》，比如对软件工程的强调。但是本书不侧重语言特性的介绍，而是涵盖更加全面，而且更加贴近实战。书的组织形式比较特别，主体是实例和知识点的总结梳理，但是总的架构又与一般教程相同。如果说其他中级图书都是通过上课来传授驾驶知识的教练的话，本书就是一位陪你上路的真正的陪练。</p>
<h3>《C++沉思录》(Ruminations on C++) </h3>
<p>Andrew Koenig,Barbara E.Moo 著<br />
黄晓春 译<br />
人民邮电出版社</p>
<p>　　本书是两位大师级作者从各种杂志上发表的文章中去芜存菁，重新整理更新，汇集而成的一部经典著作。虽然原版出版于1996年，但是作者根据当时的标准草案进行了修改，基本上是符合C++98标准的，没有过时的问题。与前面我们推荐的其他中级图书都不同，本书并不旨在讨论语言本身的具体细节，而是把重点放在如何用C++解决问题上。由于出自杂志文章，Koenig和Moo夫妇娓娓道来的平易风格显露无遗，可读性很强。在有了一些基础知识之后，阅读本书，可以在轻松的氛围中对许多C++特性和功能有更加深刻的领悟。</p>
<p>　　本书得到了BjarneStroustrup本人的推荐，而且几乎所有C++推荐列表中都不可或缺，可见其重要性。中文译本质量不错，有些令人奇怪的是，此书现在已经很难买到了。</p>
<h3>《设计模式》(Design Patterns)</h3>
<p>Erich Gamma 等著<br />
李英军 等译<br />
机械工业出版社</p>
<p>　　显然，任何一份C++推荐书目都不能缺少这部毋庸置疑的经典，虽然除了例子采用C++编写之外，本书的意义并不局限于C++领域。10多年之后，要想真正精通面向对象技术，本书仍然是必由之路。稍微遗憾的是，随着作者之一Vlis鄄sides的去世，本书曾经有过的新版计划已经遥遥无期，很可能会不了了之。即使未来会有新版出现，很可能也不会采用C++代码作为示例了。</p>
<p>　　初学者阅读本书可能会感觉困难，因为其中精髓很多是出自Gamma的博士论文或者其他作者的学术论文。某种程度上而言，本书很有《论语》之类经典微言大义的味道，不少看起来不大起眼的语句，实际上饱含深意，需要反复琢磨和研习。正因为此，后辈专家们又撰写了许多阐发性的著作，去年底影印出版的《深入浅出设计模式》（东南大学出版社）采用图文结合的方式，可读性极佳。如果觉得这种读图方式有些“轻浮”，《设计模式精解》（第二版即将由人民邮电出版社出版）则是最佳选择，书中透彻讲述了设计模式背后的各个原则，有人称之为《设计模式》的最佳阐释版本。我们认为该书比较有利于初学读者的，是作者用自己学习设计模式的经验来教学，很容易接受。此外，还应该向大家推荐的是James Coplien所著的《Advanced C++中文版》，出版于1991年。准确地说，这本书才是真正的C++模式图书，因为其中讲到的都是语言惯用法（idiom）级的模式。书中提出的CVA（共性与变性分析）为《设计模式精解》发扬光大，作为一种关键的面向对象分析方法，成为后者的亮点之一。阅读此书需要比较扎实的C++基础，因为不少具体的建议已经过时。读者可以参考Amazon网站对此书的一个评论，论者很好地指出了比较重要的过时内容。</p>
<h3>《C++经典问答》(C++ FAQs)</h3>
<p>周远成 译<br />
中国电力出版社</p>
<p>　　本书的问答形式对于某些读者而言，可能是最佳的一种学习或者复习方式。本书的素材来自comp.lang.c++新闻组的常见问答，整理成书时，几位管理员花了很大力气扩展充实，最后的篇幅是网上版本的5倍，内容非常全面细致，不仅比较深入地讨论了C++语法和语意中比较容易误解的引用、const正确性、虚函数、构造函数与析构函数、初始化列表、操作符重载等等，还覆盖了异常、模板、RTTI等高级主题，尤为可喜的是，书中还超越C++本身，讨论了面向对象设计问题。</p>
<p>　　很遗憾，本书的中文版翻译比较糟糕，而且似乎已经绝版。读者可以访问网上版本，虽然没有书全面深入，但是基本的问题都已经包括，令人欣慰的是，网上版本还在不断更新，比如在编程规范一节中就加入了《C++编程规范》的内容和链接。网上版本有两种中文译本，都比较可靠。申旻的简体翻译版本虽然不是最新，但已经比较完备，叶秉哲的繁体翻译版本稍旧，但叶本人是Stroustrup C++著作繁体版的译者，功力不凡，颇具参考价值。</p>
<h2>专题/高级</h2>
<h3>《C++标准程序库：自修教程与参考手册》(The C++ Standard Library: A Tutorial and Reference)</h3>
<p>侯捷等译<br />
Nicolai M.Josuttis<br />
华中科技大学出版社</p>
<p>　　正如Stroustrup和Lippman等大师教导的，学习和掌握C++的核心之一，就是用好标准库。目前许多C++使用者的问题，也正是由于背负C的历史枷锁，对标准库的认识和掌握不好所致。本书是学习STL的首选读物。此外，Pete Becker所著还未出版的《The C++ Standard Library Extensions:A Tutorial and Reference》是本书的C++0x延续。细心的读者可以看到两本书的副标题完全一样。据说机械工业出版社将出版后一本书。</p>
<h3>《Imperfect C++中文版》</h3>
<p>Matthew Wilson 著<br />
荣耀 刘未鹏 译<br />
人民邮电出版社</p>
<p>　　在上次专栏中，我们举贤不避亲地将本文作者之一所翻译的《C++编程规范》列为近年来最重要的C++新作。有位资历颇深的朋友对此大不以为然。本书就是他心仪的对象。从某种意义上来说，朋友的理由非常充分，本书的深度和广度确实远非编程规范所能比。作者Matthew Wilson是近年来涌现的C++社区新星，除了因为开发STLSoft库而知名之外，他还是《C/C++ User&#8217;s Journal》停刊之前最活跃的专栏作家，几乎每月都有一篇以上的文章，视野开阔，而且颇多创见，看得出技术上的积累不俗。</p>
<p>　　Wilson撰写本书应该说是抱有雄心的（公然宣称Imperfect C++当然需要胸有成竹），而成书的质量也的确不负众望，得到了Stroustrup在内的众口称赞。虽然总体而言，本书的目标读者是中高级的C++程序员，但是从一些新手那里得到的反馈来看，许多内容对初学者也有很大帮助（当然，很多内容对于初学者过难）。与Meyers、Sutter和Dewhurst等人讲求凝练不同，Wilson为了历数C++的各种不完美之处，却写出了一本非常完备的书，书中许多概念解释得比大部分教程都好，而且结合了C++最新的发展。比如，我做Mentor时的一个入门级学员曾提到，书中对POD等基本概念的完整讲述，其他书中就很难找到。</p>
<p>　　当然，书中的深入部分是罕见的深入。但是这种深入又不同于Loki的Alexandrescu和Boost的DavidAbrahams那么追求极限以至于有些阳春白雪，更多地是面向实际应用的，比如二进制兼容、多线程、优化等等主题就是目前C++应用中非常重要但是又很少有书论及的。</p>
<p>　　如果你自认为是一名专业C++程序员，本书千万不能错过。</p>
<h3>《大规模C++程序设计》</h3>
<p>John Lakos 著<br />
李师贤 明仲 等译<br />
中国电力出版社</p>
<p>　　是的，本书原版出版于1996年，C++98标准制定之前。所以读者在阅读时必须根据自己的C++语言知识，鉴别其中在新标准环境下不适用的建议。但是我们认为，它的价值时至今日仍然没有其他书可以代替。此前，只有Stroustrup在《C++程序设计语言》中用了一个部分来讲述类似的主题，虽然非常经典，但并不解渴。</p>
<p>　　据朋友告知，国内许多大型软件企业都将此书作为指定读物，这与国外C++为主要开发语言的公司情况完全相同。10年前，本文作者之一初次参与工业级的C++项目时，从一位前辈手中借阅了这本书，它对我的职业生涯产生了不可估量的影响。现在回想起来，自己实在是非常幸运，能够在那么早就获得组件、接口、物理设计等等知识。书中反映了作者在著名的电子设计工具公司Mentor Graphics任职期间积累的大型软件开发经验，材料曾经用于作者在哥伦比亚大学的课堂（美国的大学生们也的确是很幸运的）。应该说，书中讲述的方面是真正一线开发非常需要的，也不知道为何没有更多著作跟进。有消息说Lakos本人正在写一本《ScalableC++》，讨论C++组件，真是非常值得期待。</p>
<h3>《C++设计新思维：泛型编程与设计模式之应用》(Modern C++ Design)</h3>
<p>Andrei Alexandrescu 著<br />
侯捷 等译</p>
<p>　　本书出版时曾经引起不小的轰动，作者也因此奠定了炫技派先锋的地位。可以说，书中以及作者开发的Loki库将泛型编程和模板技术发挥到了极致，对于读者了解这种C++机制的强大很有好处。但是，正如Stroustrup所批评的，过于精巧的设计并不能很好地用于实际。所以我们建议读者将本书作为开眼界之用，无需死钻牛角尖。有类似性质的书还有Boost代表David Abrahams所著的《C++ Template Metaprogramming: Concepts, Tools,and Techniques from Boost and Beyond》，但个人以为，Boost代表的方向更为正确，值得关注。模板元编程与目前很多人视为编程语言发展方向的DSL（领域专用语言）关系非常密切，很可能成为C++迎接新浪潮的关键技术。事实上学院派的C++大作《产生式编程》的作者Krzysztof Czarnecki目前就是在研究如何用C++实现DSL。</p>
<h3>《C++网络编程，卷1，卷2》</h3>
<p>Douglas C.Schmidt 等著<br />
本书两卷分别由华中科技大学出版社和电子工业出版社出版。</p>
<p>　　网络编程显然是C++非常重要的应用领域，由于此前缺乏库的支持，相关图书一直非常缺乏，本书的出版一定程度上弥补了这一空白。但是本书一部分内容更接近于ACE文档，而其他部分总体上又比较学院化。所以第二作者又编写了《ACE程序员指南》（中国电力出版社）作为补充。此外，与ACE展开竞争的ICE也是一个非常不错的网络程序库，没有相关图书出版。</p>
<p>　　能够归入高级的，还有一本好书：Stan Lippman的《深度探索C++对象模型》（华中科技大学出版社）。要想对C++的内部机制了解通透，此书是不可缺少的。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/06/30/cxx-recommended-books/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[zz] C++强大的背后</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/06/13/about-cpp/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/06/13/about-cpp/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 02:10:48 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Cpp]]></category>

		<guid isPermaLink="false">http://icoder.cloudcontrolled.com/?p=884</guid>
		<description><![CDATA[在31年前(1979年)，一名刚获得博士学位的研究员，为了开发一个软件项目发明了一门新编程语言，该研究员名为Bjarne Stroustrup，该门语言则命名为——C with classes，四年后改称为C++。C++是一门通用编程语言，支持多种编程范式，包括过程式、面向对象(object-oriented programming, OP)、泛型(generic programming, GP)，后来为泛型而设计的模版，被发现及证明是图灵完备的，因此使C++亦可支持模版元编程范式(template metaprogramming, TMP)。C++继承了C的特色，既为高级语言，又含低级语言功能，可同时作为系统和应用编程语言。 C++广泛应用在不同领域，使用者以数百万计。根据近十年的调查，C++的流行程度约稳定排行第3位(于C/Java之后)。 C++经历长期的实践和演化，才成为今日的样貌。1998年，C++标准委员会排除万难，使C++成为ISO标准(俗称C++98)，当中含非常强大的标准模版库(standard template library, STL)。之后委员会在2005年提交了有关标准库的第一个技术报告(简称TR1)，并为下一个标准C++0x而努力。可惜C++0x并不能在200x年完成，各界希望新标准能于2011年内出台。 流行的C++编译器中，微软Visual C++ 2010已实现部分C++0x语法并加入TR1扩充库，而gcc对C++0x语法和库的支持比VC2010更多。 应否选择C++哪些程序适宜使用C++?C++并非万能丹，我按经验举出一些C++的适用时机。 C++适合构造程序中需求较稳定的部分，需求变化较大的部分可使用脚本语言； 程序须尽量发挥硬件的最高性能，且性能瓶颈在于CPU和内存； 程序须频繁地与操作系统或硬件沟通； 程序必须使用C++框架/库，如大部分游戏引擎(如Unreal/Source)及中间件(如Havok/FMOD)，虽然有些C++库提供其他语言的绑定，但通常原生的API性能最好、最新； 项目中某个目标平台只提供C++编译器的支持。按应用领域来说，C++适用于开发服务器软件、桌面应用、游戏、实时系统、高性能计算、嵌入式系统等。 使用C++还是C?C++和C的设计哲学并不一样，两者取舍不同，所以不同的程序员和软件项目会有不同选择，难以一概而论。与C++相比，C具备编译速度快、容易学习、显式描述程序细节、较少更新标准(后两者也可同时视为缺点)等优点。在语言层面上，C++包含绝大部分C语言的功能(例外之一，C++没有C99的变长数组VLA)，且提供OOP和GP的特性。但其实用C也可实现OOP思想，亦可利用宏去实现某程度的GP，只不过C++的语法能较简洁、自动地实现OOP/GP。C++的RAII(resource acquisition is initialization，资源获取就是初始化)特性比较独特，C/C#/Java没有相应功能。回顾历史，Stroustrup开发的早期C++编译器Cpre/Cfront是把C++源代码翻译为C，再用C编译器编译的。由此可知，C++编写的程序，都能用等效的C程序代替，但C++在语言层面上提供了OOP/GP语法、更严格的类型检查系统、大量额外的语言特性(如异常、RTTI等)，并且C++标准库也较丰富。有时候C++的语法可使程序更简洁，如运算符重载、隐式转换。但另一方面，C语言的API通常比C++简洁，能较容易供其他语言程序调用。因此，一些C++库会提供C的API封装，同时也可供C程序调用。相反，有时候也会把C的API封装成C++形式，以支持RAII和其他C++库整合等。 为何C++性能可优于其他语言?相对运行于虚拟机语言(如C#/Java)，C/C++直接以静态形式把源程序编译为目标平台的机器码。一般而言，C/C++程序在编译及链接时可进行的优化最丰富，启动时的速度最快，运行时的额外内存开销最少。而C/C++相对动态语言(如Python/Lua)也减少了运行时的动态类型检测。此外，C/C++的运行行为是确定的，且不会有额外行为(例如C#/Java必然会初始化变量)，也不会有如垃圾收集(GC)而造成的不确定性延迟，而且C/C++的数据结构在内存中的布局也是确定的。有时C++的一些功能会使程序性能优于C，当中以内联和模版最为突出，这两项功能使C++标准库的sort()通常比C标准库的qsort()快多倍(C可用宏或人手编码去解决此问题)。另一方面，C/C++能直接映射机器码，之间没有另一层中间语言，因此可以做底层优化，例如使用内部(intrinsic)函数和嵌入汇编语言。然而，许多C++的性能优点并非免费午餐，代价包括较长的编译链接时间和较易出错，因而增加开发时间和成本，这点稍后补充。 我进行了一个简单全局渲染性能测试(512&#215;512像素，每像素10000个采样)，C++ 1小时36分、Java 3小时18分、Python约18天、Ruby约351天。评测方式和其他语言的结果详见博文。 C++常见问题C++源代码跨平台吗?C++有不错的跨平台能力，但由于直接映射硬件，因性能优化的关系，跨平台能力不及Java及多数脚本语言。然而，实践跨平台的C++软件还是可行的，但须注意以下问题： C++标准没有规定原始数据类型(如int)的大小，需要特定大小的类型时，可自订类型(如int32_t)，同时对任何类型使用sizeof()而不假设其大小； 字节序(byte order)按CPU有所不同，特别要注意二进制输入输出、reinterpret_cast法； 原始数据和结构类型的地址对齐有差异； 编译器提供的一些编译器或平台专用扩充指令； 避免作应用二进制接口(application binary &#8230;<p class="read-more"><a href="http://icoder.cloudcontrolled.com/index.php/2011/06/13/about-cpp/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>在31年前(1979年)，一名刚获得博士学位的研究员，为了开发一个软件项目发明了一门新编程语言，该研究员名为Bjarne Stroustrup，该门语言则命名为——C with classes，四年后改称为C++。C++是一门通用编程语言，支持多种编程范式，包括过程式、面向对象(object-oriented programming, OP)、泛型(generic programming, GP)，后来为泛型而设计的模版，被发现及证明是图灵完备的，因此使C++亦可支持模版元编程范式(template metaprogramming, TMP)。C++继承了C的特色，既为高级语言，又含低级语言功能，可同时作为系统和应用编程语言。<br />
C++广泛应用在不同领域，使用者以数百万计。根据近十年的调查，C++的流行程度约稳定排行第3位(于C/Java之后)。 C++经历长期的实践和演化，才成为今日的样貌。1998年，C++标准委员会排除万难，使C++成为ISO标准(俗称C++98)，当中含非常强大的标准模版库(standard template library, STL)。之后委员会在2005年提交了有关标准库的第一个技术报告(简称TR1)，并为下一个标准C++0x而努力。可惜C++0x并不能在200x年完成，各界希望新标准能于2011年内出台。<br />
流行的C++编译器中，微软Visual C++ 2010已实现部分C++0x语法并加入TR1扩充库，而gcc对C++0x语法和库的支持比VC2010更多。<br />
应否选择C++哪些程序适宜使用C++?C++并非万能丹，我按经验举出一些C++的适用时机。<br />
<span id="more-884"></span></p>
<p>C++适合构造程序中需求较稳定的部分，需求变化较大的部分可使用脚本语言；<br />
程序须尽量发挥硬件的最高性能，且性能瓶颈在于CPU和内存；<br />
程序须频繁地与操作系统或硬件沟通；<br />
程序必须使用C++框架/库，如大部分游戏引擎(如Unreal/Source)及中间件(如Havok/FMOD)，虽然有些C++库提供其他语言的绑定，但通常原生的API性能最好、最新；<br />
项目中某个目标平台只提供C++编译器的支持。按应用领域来说，C++适用于开发服务器软件、桌面应用、游戏、实时系统、高性能计算、嵌入式系统等。<br />
使用C++还是C?C++和C的设计哲学并不一样，两者取舍不同，所以不同的程序员和软件项目会有不同选择，难以一概而论。与C++相比，C具备编译速度快、容易学习、显式描述程序细节、较少更新标准(后两者也可同时视为缺点)等优点。在语言层面上，C++包含绝大部分C语言的功能(例外之一，C++没有C99的变长数组VLA)，且提供OOP和GP的特性。但其实用C也可实现OOP思想，亦可利用宏去实现某程度的GP，只不过C++的语法能较简洁、自动地实现OOP/GP。C++的RAII(resource acquisition is initialization，资源获取就是初始化)特性比较独特，C/C#/Java没有相应功能。回顾历史，Stroustrup开发的早期C++编译器Cpre/Cfront是把C++源代码翻译为C，再用C编译器编译的。由此可知，C++编写的程序，都能用等效的C程序代替，但C++在语言层面上提供了OOP/GP语法、更严格的类型检查系统、大量额外的语言特性(如异常、RTTI等)，并且C++标准库也较丰富。有时候C++的语法可使程序更简洁，如运算符重载、隐式转换。但另一方面，C语言的API通常比C++简洁，能较容易供其他语言程序调用。因此，一些C++库会提供C的API封装，同时也可供C程序调用。相反，有时候也会把C的API封装成C++形式，以支持RAII和其他C++库整合等。<br />
为何C++性能可优于其他语言?相对运行于虚拟机语言(如C#/Java)，C/C++直接以静态形式把源程序编译为目标平台的机器码。一般而言，C/C++程序在编译及链接时可进行的优化最丰富，启动时的速度最快，运行时的额外内存开销最少。而C/C++相对动态语言(如Python/Lua)也减少了运行时的动态类型检测。此外，C/C++的运行行为是确定的，且不会有额外行为(例如C#/Java必然会初始化变量)，也不会有如垃圾收集(GC)而造成的不确定性延迟，而且C/C++的数据结构在内存中的布局也是确定的。有时C++的一些功能会使程序性能优于C，当中以内联和模版最为突出，这两项功能使C++标准库的sort()通常比C标准库的qsort()快多倍(C可用宏或人手编码去解决此问题)。另一方面，C/C++能直接映射机器码，之间没有另一层中间语言，因此可以做底层优化，例如使用内部(intrinsic)函数和嵌入汇编语言。然而，许多C++的性能优点并非免费午餐，代价包括较长的编译链接时间和较易出错，因而增加开发时间和成本，这点稍后补充。<br />
我进行了一个简单全局渲染性能测试(512&#215;512像素，每像素10000个采样)，C++ 1小时36分、Java 3小时18分、Python约18天、Ruby约351天。评测方式和其他语言的结果详见博文。<br />
C++常见问题C++源代码跨平台吗?C++有不错的跨平台能力，但由于直接映射硬件，因性能优化的关系，跨平台能力不及Java及多数脚本语言。然而，实践跨平台的C++软件还是可行的，但须注意以下问题： </p>
<p>C++标准没有规定原始数据类型(如int)的大小，需要特定大小的类型时，可自订类型(如int32_t)，同时对任何类型使用sizeof()而不假设其大小；<br />
字节序(byte order)按CPU有所不同，特别要注意二进制输入输出、reinterpret_cast法；<br />
原始数据和结构类型的地址对齐有差异；<br />
编译器提供的一些编译器或平台专用扩充指令；<br />
避免作应用二进制接口(application binary interface, ABI)的假设，例如调用函数时参数的取值顺序在C/C++中没定义，在C++中也不可随便假设RTTI/虚表等实现方式。总括而言，跨平台C++软件可在头文件中用宏检测编译器和平台，再用宏、typedef、自定平台相关实现等方法去实践跨平台，C++标准不会提供这类帮助。<br />
C++程序容易崩溃?和许多语言相比，C/C++提供不安全的功能以最优化性能，有可能造成崩溃。但要注意，很多运行时错误，如向空指针/引用解引用、数组越界、堆栈溢出等，其他语言也会报错或抛出异常，这些都是程序问题，而不是语言本身的问题。有些意见认为，出现这类运行时错误，应该尽量写入日志并立即崩溃，不该让程序继续运行，以免造成更大的影响(例如程序继续把内存中错误的数据覆写文件)。若要容错，可按业务把程序分割为多进程，像Chrome或使用fork()的形式。然而，C++有许多机制可以减少错误，例如以string代替C字符串；以vector或array(TR1)代替原始数组(有些实现可在调试模式检测越界)；使用智能指针也能减少一些原始指针的问题。另外，我最常遇到的Bug，就是没有初始化成员变量，有时会导致崩溃，而且调试版和发行版的行为可能不同。<br />
C++要手动做内存管理?C++同时提供在堆栈上的自动局部变量，以及从自由存储(free store)分配的对象。对于后者，程序员需手动释放，或使用不同的容器和智能指针。 C++程序员经常进一步优化内存，自定义内存分配策略以提升效能，例如使用对象池、自定义的单向/双向堆栈区等。虽然C++0x还没加入GC功能，但也可以自行编写或使用现成库。此外，C/C++也可以直接使用操作系统提供的内存相关功能，例如内存映射文件、共享内存等。<br />
使用C++常要重造轮子?我曾参与的C++项目，都会重造不少标准库已提供的功能，此情况在其他语言中较少出现。我试图分析个中原因。首先，C++标准库相对很多语言来说是贫乏的，各开发者便会重复地制造自订库。从另一个角度看，C++标准库是用C++编写的(很多其他语言不用自身而是用C/C++去编写库)，在能力和性能上，自订库和标准库并无本质差别；另外，标准库为通用而设，对不同平台及多种使用需求作取舍，性能上有所影响，例如EA公司就曾发表自制的EASTL规格，描述游戏开发方面对STL的性能及功能需求的特点；此外，多个C++库一起使用，经常会因规范不同而引起冲突，又或功能重叠，所以项目可能须自行开发，或引入其他库的概念或实现(如Boost/TR1/Loki)，改写以符合项目规范。<br />
C++编译速度很慢?错，是非常慢。我认为C++可能是实用程序语言中编译速度最慢的。此问题涉及C++沿用C的编译链接方式，又加入了复杂的类/泛型声明和内联机制，使编译时间倍增。在C++对编译方法改革之前(如module提案)，可使用以下技巧改善：第一，使用pimpl手法，因性能损耗应用于调用次数不多的类；第二，仅包含必要头文件，并尽量使用及提供前置声明版本的头文件(如iosfwd)；第三采用基于接口的设计，但须注意虚函数调用成本；第四，采用unity build，即把多个cpp文件结合在一个编译单元进行编译；第五，采用分布式生成系统如IncrediBuild。<br />
C++缺乏什么功能?虽然C++已经非常复杂，但仍缺少很多常见功能。 C++0x作出了不少改善，例如语言方面加入Lambda函数、闭包、类型推导声明等，而库方面则加入正则表达式、采用哈希表的unordered_set/unordered_map、引用计数智能指针shared_ptr/weak_ptr等。但最值得留意的是C++0x引入多线程的语法和库功能，这是C++演进的一大步。然而，模组、GC、反射机制等功能虽有提案，却未加进C++0x。<br />
C++使用建议为应用挑选特性集我同意Stroustrup关于使用C++各种技术的回应：“你可以做，不意味着你必须这么做。(Just because you can do it, doesn&#8217;t mean that you have to.)” C++充满丰富的特性，但同时带来不同问题，例如过分复杂、编译及运行性能的损耗。一般可考虑是否使用多重继承、异常、RTTI，并调节使用模版及模版元编程的程度。使用过分复杂的设计和功能，可能会令部分团队成员更难理解和维护。<br />
为团队建立编程规范C++的编码自由度很高，容易编写风格迥异的代码，C++本身也没有定义一些标准规范。而且，C++的源文件物理构成，较许多语言复杂。因此，除了决定特性集，每个团队应建立一套编程规范，包括源文件格式(可使用文件模版)、花括号风格。<br />
尽量使用C++风格而非C风格由于C++有对C兼容的包袱，一些功能可以使用C风格实现，但最好使用C++提供的新功能。最基本的是尽量以具名常量、内联函数和泛型取代宏，只把宏用在条件式编译及特殊情况。旧式的C要求局部变量声明在作用域开端，C++则无此限制，应把变量声明尽量置于邻近其使用的地方，for()的循环变量声明可置于for的括号内。 C++中能加强类型安全的功能应尽量使用，例如避免“万能”指针void *，而使用个别或泛型类型；用bool而非int表示布尔值；选用4种C++ cast关键字代替简单的强制转换。<br />
结合其他语言如前文所述，C++并非适合所有应用情境，有时可以混合其他语言使用，包括用C++扩展其他语言，或在C++程序中嵌入脚本语言引擎。对于后者，除了使用各种脚本语言的专门API，还可使用Boost或SWIG作整合。<br />
C++学习建议C++缺点之一，是相对许多语言复杂，而且难学难精。许多人说学习C语言只需一本K&#038;R《C程序设计语言》即可，但C++书籍却是多不胜数。我是从C进入C++，皆是靠阅读自学。在此分享一点学习心得。个人认为，学习C++可分为4个层次： </p>
<p>第一层次，C++基础：挑选一本入门书籍，如《C++ Primer》、《C++大学教程》、或Stroustrup撰写的经典《C++程序设计语言》或他一年半前的新作《C++程序设计原理与实践》，而一般C++课程也止于此，另外《C++ 标准程序库》及《The C++ Standard Library Extensions》可供参考；<br />
第二层次，正确高效地使用C++：此层次开始必须自修，阅读过《(More)Effective C++》、《(More)Exceptional C++》、《Effective STL》及《C++编程规范》等，才适宜踏入专业C++开发之路；<br />
第三层次，深入了解C++：关于全局问题可读《深入探索C++对象模型》、《Imperfect C++》、《C++沉思录》、《STL源码剖析》，要挑战智商，可看关于模版及模版元编程的书籍如《C++ Templates》、《C++设计新思维》、《C++模版元编程》；<br />
第四层次，研究C++：阅读《C++语言的设计和演化》、《编程的本质》(含STL设计背后的数学根基)、C++标准文件《ISO/IEC 14882:2003》、C++标准委员会的提案书和报告书[/url]、关于C++的学术文献。由于我主要是应用C++，大约只停留于第二、三个层次。然而，C++只是软件开发的一环而已，单凭语言并不能应付业务和工程上的问题。建议读者不要强求几年内“彻底学会C++的知识”，到达第二层左右便从工作实战中汲取经验，有兴趣才慢慢继续学习更高层次的知识。虽然学习C++有难度，但也是相当有趣且有满足感的。<br />
数十年来，C++虽有起伏，但她依靠其使用者而不断得到顽强的生命力，相信在我退休之前都不会与她分离，也希望更进一步了解她，与她走进未来。 </p>
<p>本文原于《程序员》2010年8月刊揭载。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/06/13/about-cpp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gcc的&#8221;变参宏&#8221;(Variadic Macros)</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/05/31/variadic-macros/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/05/31/variadic-macros/#comments</comments>
		<pubDate>Tue, 31 May 2011 15:17:12 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[Gcc]]></category>

		<guid isPermaLink="false">http://icoder.cloudcontrolled.com/?p=877</guid>
		<description><![CDATA[就像变参函数那样，gcc里的宏(Macros)也可以定义不定个数的参数，主要就是配合变参函数使用。例如： #define eprintf(...) fprintf (stderr, __VA_ARGS__) 注意：这里是两个下划线__. 使用时： eprintf ("%s:%d: ", input_file, lineno) ==> fprintf (stderr, "%s:%d: ", input_file, lineno) 除了使用gcc提供的__VA_ARGS__代替变参外，我们还可以给参数起名字，方法是在&#8221;&#8230;&#8221;之前写上名字，如： #define eprintf(args...) fprintf (stderr, args) 这里有一个问题，例如下面： #define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__) eprintf ("success!\n") ==> fprintf(stderr, "success!\n", ); &#8230;<p class="read-more"><a href="http://icoder.cloudcontrolled.com/index.php/2011/05/31/variadic-macros/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>就像变参函数那样，gcc里的宏(Macros)也可以定义不定个数的参数，主要就是配合变参函数使用。例如：</p>
<pre>
#define eprintf(...) fprintf (stderr, __VA_ARGS__)
</pre>
<p>注意：这里是两个下划线__.</p>
<p>使用时：</p>
<pre>
eprintf ("%s:%d: ", input_file, lineno)
          ==>  fprintf (stderr, "%s:%d: ", input_file, lineno)
</pre>
<p>除了使用gcc提供的__VA_ARGS__代替变参外，我们还可以给参数起名字，方法是在&#8221;&#8230;&#8221;之前写上名字，如：</p>
<pre>
#define eprintf(args...) fprintf (stderr, args)
</pre>
<p>这里有一个问题，例如下面：</p>
<pre>
#define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)

eprintf ("success!\n")
          ==> fprintf(stderr, "success!\n", ); // 问题：这里多了个逗号！
</pre>
<p>这样肯定是不行的，因此，gcc还为此提供了&#8221;##&#8221;符号。##符号在 <i>逗号</i> 和 <i>参数名</i> 之间时不做连字符作用，而作为变参宏的特别用处，如下：</p>
<pre>
#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

eprintf ("success!\n")
          ==> fprintf(stderr, "success!\n"); // aha! 这样就OK了！
</pre>
<p>这个已经是C99标准了，并且gcc能很好的支持，只有一点要注意的：</p>
<blockquote><p>
Variadic macros are a new feature in C99. GNU CPP has supported them for a long time, but only with a named variable argument (`args&#8230;&#8217;, not `&#8230;&#8217; and __VA_ARGS__). If you are concerned with portability to previous versions of GCC, you should use only named variable arguments. On the other hand, if you are concerned with portability to other conforming implementations of C99, you should use only __VA_ARGS__.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/05/31/variadic-macros/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>c++的const_cast</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/05/19/const-cast-in-cpp/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/05/19/const-cast-in-cpp/#comments</comments>
		<pubDate>Wed, 18 May 2011 16:35:28 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Cpp]]></category>

		<guid isPermaLink="false">http://icoder.cloudcontrolled.com/?p=870</guid>
		<description><![CDATA[c++的const_cast操作符是给一个变量删除或增加 const 或 volatile 修饰，例如： const int a = 10; int &#038;b = const_cast&#60;int&#38;&#62;(a); // 注意：这里任何b=xxx的操作都会导致为定义行为的发生！ // 因为a原始定义的时候就是const类型. 或： void func(const int &#038;c) { int &#038;d = const_cast&#60;int&#38;&#62;(c); d = 20; // 这里修改是ok的，因为c原始定义并不是const类型 // 只是在函数传参时才变成"const"的 } int main(void) { int &#8230;<p class="read-more"><a href="http://icoder.cloudcontrolled.com/index.php/2011/05/19/const-cast-in-cpp/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>c++的<b class="red">const_cast</b>操作符是给一个变量<b>删除</b>或<b>增加</b> <i>const</i> 或 <i>volatile</i> 修饰，例如：</p>
<pre class="mycode">
const int a = 10;
int &#038;b = const_cast&lt;int&amp;&gt;(a);
// 注意：这里任何b=xxx的操作都会导致为定义行为的发生！
//     因为a原始定义的时候就是const类型.

或：

void func(const int &#038;c) {
    int &#038;d = const_cast&lt;int&amp;&gt;(c);
    d = 20; // 这里修改是ok的，因为c原始定义并不是const类型
            // 只是在函数传参时才变成"const"的
}

int main(void) {
    int c = 10;
    func(c);
}
</pre>
<p><b>对const_cast&lt;&gt;的变量进行修改操作只有在原始变量不是真正的const情况下是安全的, 如果原始变量是const类型，那么任何修改都会导致为定义行为。</b></p>
<blockquote><p>const_cast is safe only if you&#8217;re casting a variable that was originally non-const.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/05/19/const-cast-in-cpp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>变长数组与alloca</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/05/18/array-of-variable-length-and-alloca/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/05/18/array-of-variable-length-and-alloca/#comments</comments>
		<pubDate>Wed, 18 May 2011 13:53:52 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[Gcc]]></category>

		<guid isPermaLink="false">http://icoder.cloudcontrolled.com/?p=864</guid>
		<description><![CDATA[C99标准里规定了允许在栈上定义变长数组或者叫变长自动数组(Variable-length Automatic Array). 例如： /* s1 and s2 are two strings(char*) */ char str[strlen (s1) + strlen (s2) + 1]; /* str 就是栈上的变长数组 */ strcpy (str, s1); strcat (str, s2); 栈上的变长数组比堆上的变长数组有什么好处呢？ 1. 不需要担心内存回收，数组变量在超出作用域后会自动回收； 2. 对于多维数组使用尤为方便，例如： int arr[m][n][k]; int ***p = &#8230;<p class="read-more"><a href="http://icoder.cloudcontrolled.com/index.php/2011/05/18/array-of-variable-length-and-alloca/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>C99标准里规定了允许在栈上定义<b>变长数组</b>或者叫<b class="red">变长自动数组</b>(<b>Variable-length Automatic Array</b>). 例如：</p>
<pre class="mycode">
/* s1 and s2 are two strings(char*) */
char str[strlen (s1) + strlen (s2) + 1]; /* str 就是栈上的变长数组 */
strcpy (str, s1);
strcat (str, s2);
</pre>
<p>栈上的变长数组比堆上的变长数组有什么好处呢？</p>
<p>1. 不需要担心内存回收，数组变量在超出作用域后会自动回收；<br />
2. 对于多维数组使用尤为方便，例如：</p>
<pre class="mycode">
int arr[m][n][k];
int ***p = (int***)malloc(sizeof(int) * m * n * k); /* 这样使用不如 arr 直观方便 */
</pre>
<p>gcc在这方面早就有了很好的支持，我实际试的是在3.x版就已经支持了，而且，对于C90和C++都支持。<br />
另外，gcc还增加了一个函数：<b class="red">alloca()</b><br />
类似malloc()，只是alloca()分配的内存是在栈上。</p>
<p>alloca() 和栈上的变长数组的区别在于，alloca() 的分配的内存有效范围是在整个函数内部，而变长数组的有效范围是 { } 之间，例如：</p>
<pre class="mycode">
void func(void)
{
    int *p = NULL;
    if (xxx) {
        p = alloca(sizeof(int)); /* alloca分配的内存在if语句外也可以使用. */
        int arr[n]; /* arr的有效范围在if语句内. */
        ...
    }
    ...
}
</pre>
<p>不过需要注意的是，如果alloca和变长数组在同一个函数里混用时，当一个变长数组被销毁时，在他之后调用的alloca分配的内存也将被销毁。这是gcc manual中的原文：</p>
<blockquote><p>If you use both variable-length arrays and alloca in the same function, deallocation of a variable-length array will also deallocate anything more recently allocated with alloca.</p></blockquote>
<p>这点很好理解，变长数组和alloca都是在栈上分配内存，编译器在对栈上的变量销毁时只是简单的弹栈，如下：</p>
<pre>
if (xxx) {
   int arr[n];
   p = alloca(xxx);
}

上面这段代码执行时栈的变化：

      |   |       top-->|   |             |   |
top-->|   |             | p |             | p |已经无效了！
      |arr|             |arr|             |arr|弹栈，销毁arr
      |...|             |...|       top-->|...|
      +---+             +---+             +---+
(1)分配arr空间      (2)分配p的空间       (3)销毁arr时p同时被销毁
</pre>
<p>因此，虽然alloca和变长数组可以给我们带来方便，但使用时一定要小心！</p>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/05/18/array-of-variable-length-and-alloca/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[zz]STL迭代器何时失效，很重要，一不小心后果严重</title>
		<link>http://icoder.cloudcontrolled.com/index.php/2011/04/27/stl-iterator-invalidation/</link>
		<comments>http://icoder.cloudcontrolled.com/index.php/2011/04/27/stl-iterator-invalidation/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 13:49:55 +0000</pubDate>
		<dc:creator>wuxicn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Cpp]]></category>

		<guid isPermaLink="false">http://icoder.me/?p=854</guid>
		<description><![CDATA[1. vector&#60;T&#62;::iterator [23.2.4.3] vector modifiers iterator insert(iterator position, const T&#38; x); void insert(iterator position, size_type n, const T&#38; x); template &#60;class InputIterator&#62; void insert(iterator position, InputIterator first, InputIterator last); Notes: Causes reallocation if the new size is greater than the &#8230;<p class="read-more"><a href="http://icoder.cloudcontrolled.com/index.php/2011/04/27/stl-iterator-invalidation/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<h2>1. vector&lt;T&gt;::iterator</h2>
<p>[23.2.4.3] vector modifiers<br />
iterator insert(iterator position, const T&amp; x);<br />
void insert(iterator position, size_type n, const T&amp; x);<br />
template &lt;class InputIterator&gt;<br />
   void insert(iterator position, InputIterator first, InputIterator last);</p>
<p>Notes: Causes reallocation if the new size is greater than the old capacity. <b class="green">If no reallocation happens, all the iterators and references before the insertion point remain valid</b>&#8230;&#8230;.</p>
<p>iterator erase(iterator position);<br />
iterator erase(iterator first, iterator last);</p>
<p>Effects: <b class="red">Invalidates all the iterators and references after the point of the erase.</b></p>
<h2>2. list&lt;T&gt;::iterator</h2>
<p>[23.2.2.3] list modifiers<br />
iterator insert(iterator position, const T&amp; x);<br />
void insert(iterator position, size_type n, const T&amp; x);<br />
template &lt;class InputIterator&gt;<br />
   void insert(iterator position, InputIterator first, InputIterator last);</p>
<p>void push_front(const T&amp; x);<br />
void push_back(const T&amp; x);</p>
<p>Notes: <b class="green">Does not affect the validity of iterators and references. &#8230;&#8230;</b></p>
<p>iterator erase(iterator position);<br />
iterator erase(iterator first, iterator last);</p>
<p>void pop_front();<br />
void pop_back();<br />
void clear();</p>
<p>Effect: <b class="red">Invalidates only the iterators and references to the erased elements</b>.</p>
<h2>deque&lt;T&gt;::iterator</h2>
<p>[23.2.1.3] deque modifiers</p>
<p>iterator insert(iterator position, const T&amp; x);<br />
void insert(iterator position, size_type n, const T&amp; x);<br />
template &lt;class InputIterator&gt;<br />
   void insert(iterator position, InputIterator first, InputIterator last);</p>
<p>Effects: An <b class="red">insert in the middle of the deque invalidates all the iterators and references to elements</b> of the deque.<br />
<b class="red">An insert at either end of the deque invalidates all the iterators</b> to the deque, but has <b class="green">no effect on the validity of references to elements</b> fo the deque.</p>
<p>iterator erase(iterator position);<br />
iterator erase(iterator first, iterator last);</p>
<p>Effects: <b class="red">An erase in the middle of the deque invalidates all the iterators and references to elements</b> of the deque. <b class="green">An erase at either end of the deque invalidates only the iterators and the references to the erased elements</b>.</p>
<h2>Assosiative container::iterator</h2>
<p>&lt;set&gt; &lt;map&gt; &lt;multiset&gt; &lt;multimap&gt;<br />
[23.1.2] line 8:<br />
The insert members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.</p>
]]></content:encoded>
			<wfw:commentRss>http://icoder.cloudcontrolled.com/index.php/2011/04/27/stl-iterator-invalidation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

