Revision 2.0
by K ][ N G of A R K ™
前 言
Long long time ago, on a topic far far away……是的,很久很久以前,kingofark无心之中写了一篇关于学习C++和编程的发牢骚的文章。未曾料到的是,这篇文章被N个好心的网络同胞流传至今,以至于作者得意忘形的将文章简称为Ks50PV,在浅薄和浮躁中麻醉自己。
某个醉生梦死的深夜,kingofark关上电脑,屋内一片墨黑,忽然发觉窗外的透彻和宁静。凑到窗前向天空看去,惊讶的发现白光——不,Agent Mulder,不是UFO——来自圆月。笔者联想到了牛郎织女——先辈们早已灰飞烟灭,只有故事被流传下来,因为被流传而流传。
一篇文章不能因为被流传而流传,被流传的不应该是流传本身。带着这样的冲动,kingofark又打开电脑……
眼前给大家展现的,是经过kingofark重新审视,结合作者最新感受的修订版。其中有些条款彻底的更换或者修改了。这一方面反映了国内图书市场近年来发生的变化,另一方面也反映出:其实有些时候,无知的人说得最多。欢迎大家批评讨论甚至予以唾弃。
在这个修订版中,作者没有删掉旧的条款,仅在新旧条款前加了“新”、“旧”二字以示区别。新旧条款下面伴有作者的评论。
1. 把C++当成一门新的语言学习(和C没啥关系!真的。);
是的,我们仍然应该抱着这样一种心态来学习C++。前一段时间,C/C++ User’s Journal 上面有一连串关于C与C++关系的文章,Bjarne Stroustrup、Herb Sutter等几位C++领域的大师从不同方面讨论了C/C++今后发展的问题,颇为深刻。
看问题有深有浅,有高有低。我们不是大师,不要把C和C++说得好像自己的两个儿子。
水果刀是一种刀。瑞士军刀也是一种刀,但它何尝不是剪刀、起子、锯子、锉刀、牙签、指南针、尺子、放大镜……?谁在使用瑞士军刀之前还要先培训如何使用水果刀?另外,在水果刀上面粘一个剪刀、起子、锯子、锉刀、牙签、指南针、尺子、放大镜……我估计也不会太好用(不叫“瑞士军刀”,叫“超级武器霸王3000”)。
旧:2. 看《Thinking In C++》,不要看《C++变成死相》;
新:2. 看《Accelerated C++》,看《C++ Gochas》;
如今《Thinking In C++ 2nd》也出了中文版,翻译质量好坏kingofark不想再谈——毕竟有人(至少在www.china-pub.com上)觉得翻译还不错。经常忍不住要去跟人争辩翻译质量的kingofark忽然明白了萝卜白菜定理的另一个推论:看书好像看A片,有人爱看欧美,有人爱看日台,各得其乐。自己去衡量罢,不过最好不要参与图书信息页上面的无聊口舌战。请记住一句话,一句就好:管它黑猫白猫,能抓老鼠就是好猫。
Andrew Koenig的《Accelerated C++》是一本真正具有实践性的入门书。该书传承了《Ruminations On C++》的阐述方法,通过一个又一个具体的设计实例充分体现使用C++进行开发的真正优势之所在。事实上,笔者觉得Andy的书都是程序员必读(还好不算多)。对于《Accelerated C++》的评论,国外网站上皆有,笔者不再累述。
Stephen C. Dewhurst的《C++ Gochas》是一本“奇特”的书。说“奇特”不是因为Gotcha这个单词对于中国人难于理解(何况中译书干脆把这个标题扔掉不要了),而是在于:Dewhurst用酸中带刺、笑里藏刀的口吻提醒程序员一些编写C++程序(本来就)应该注意到的问题。这些问题中,有编码细节问题,有编码习惯问题,甚至有个人修养问题。CUJ上有一篇对该书的评论,笔者认为还比较中肯。笔者看了该书的样章以后的感受是:忠言向来都逆耳;这本书中的观点你可以不认同,但其确实引出了一些应该注意(而通常没被注意)的问题,这对于一个程序员来说是非常值的关注的。
旧:3. 看《The C++ Programming Language》和《Inside The C++ Object Model》,不要因为他们很难而我们自己是初学者所以就不看;
新:3. 看《The C++ Programming Language》和《Inside The C++ Object Model》,不要因为它们很难而我们自己并不想搞“学术研究”所以就不看;
这两本书的确都不适合初学者看,旧条款说得有些过激,想必当初kingofark是希望刺激一下那些“浮躁的人(包括kingofark)”(见条款10-15)。
总听人说“语言其实都是相通的”。问:什么时候才能融会贯通?答:通透其理的时候。
好好学吧您呐!
4. 不要被VC、BCB、BC、MC、TC等词汇所迷惑——他们都是集成开发环境,而我们要学的是一门语言;
5. 不要放过任何一个看上去很简单的编程小问题——它们往往并不那么简单,或者可以引伸出很多知识点;
侯捷先生译的《C++ Primer Answer Book》和裘宗燕老师译的《C++ Solutions – Companion to TCPPL》都已经出版了。作为在校学生或者C++自学者,通过这样两本书来操练自己的编码实践,实在是最合适不过了。
6. 会用Visual C++,并不说明你会C++;
会唱歌又会弹吉他,并不说明你会搞音乐创作——只不过有点“苗头”而已(且不能拔)。
7. 学class并不难,template、STL、generic programming也不过如此——难的是长期坚持实践和不遗余力的博览群书;
博览群书不一定必要,但是,To learn or not to learn…that is the question! 学习C++,这些内容不可或缺。
旧:8. 如果不是天才的话,想学编程就不要想玩游戏——你以为你做到了,其实你的C++水平并没有和你通关的能力一起变高——其实可以时刻记住:学C++是为了编游戏的;
新:8. 学编程与玩游戏,两者“相互作用,相互影响,辩证统一”,可以分割;不过的确有很多人因为爱玩游戏而学编程,也有不少人因为不爱学编程而玩游戏;其实这里面的道理再简单不过:如果你不是厨师——而自己会做一手好菜,自己当然有余地饱尝美味;如果你是厨师——拜托你不要光顾着吃,好好学厨艺行不行?回头吃肥了跌进猪圈人家认不出你。
旧条款是一句理由不充分的气话,源于当时笔者对沉溺游戏的“科班学生”的焦虑。
关于游戏编程,其实也有不少好书,比如Andre Lamothe的《Tricks of The Windows Game Programming Gurus 2nd》《Tricks of 3D Game Programming Gurus》,通俗易懂、门槛儿低,深入浅出,大师的经验体会娓娓道来,精辟深刻,直入核心。对该作者的书,国外网站有评价,不用笔者费口舌了(好词儿都用光了)。
笔者本人对游戏编程也蛮有兴趣,非常喜欢Andre Lamothe的书。书有多好呢?这么说吧:《Tricks of The Windows Game Programming Gurus》中文版虽然译得参差暧昧、差强人意(比如把数据结构linked list译为“连接的清单”),仍然还是瑕不掩瑜,可以让人坐在电脑跟前打开VC,一口气读到深夜,体验使用VC/DirectX SDK编写游戏的乐趣。
旧:9. 看Visual C++的书,是学不了C++语言的;
新:9. 在工作环境中,请小声与同事说话。
方便快捷(且易导致发胖)的快餐业McDonald、KFC到了中国,成了孩子们的牙祭和每周的节日,情侣们约会的廉价地点。一到周末,McDonald、KFC店内“一片欢腾的景象”。所有人都大声说话。
咖啡厅本来是过去从美片上面看到的那种“零零星星有着装高雅的俊男美女在催情的柔光下窃窃私语”的梦幻般的地方。中国的咖啡厅,烟雾缭绕,音箱发出不柔和的八十年代怀旧欧美歌曲(且一般都不是原人原唱)——地方话,骂人话,话话别扭;手机声,牌将声,声声入耳。所有人都大声说话。
软件公司里面,开发人员探讨技术问题,间歇中的打趣,是再正常不过的事情。A和女秘书B正在咯咯的打情骂俏;C为了告诉D文档已经做好了,伸长了脖子盖过AB的声音;一旁的E正在面红脖子粗的与高手F激烈的讨论一个技术难题,这时候绝对不准有谁的声音比他还高;G向作管理的H抱怨公司的软件工程没有做好,伴着唾液的“啧啧”浊音故意要让自己的上司听到。所有人都大声说话。
请你记住一点:你大声说话,同事只听得见你的声音;你小声说话,同事还听得见你的心情。交流需要的是心境。
10. 浮躁的人容易说:XX语言不行了,应该学YY;——是你自己不行了吧!?
11. 浮躁的人容易问:我到底该学什么;——别问,学就对了;
12. 浮躁的人容易问:XX有钱途吗;——建议你去抢银行;
旧:13. 浮躁的人容易说:我要中文版!我英文不行!——不行?学呀!
新:13. 浮躁的人容易说:我要中文版!我英文不行!——希望这不是你不好好学的原因。
14. 浮躁的人容易问:XX和YY哪个好;——告诉你吧,都好——只要你学就行;
15. 浮躁的人分两种:a)只观望而不学的人;b)只学而不坚持的人;
16. 把时髦的技术挂在嘴边,还不如把过时的技术记在心里;
17. C++不仅仅是支持面向对象的程序设计语言;
C++是以multi-paradigm为目标的通用型语言,学习起来应该全面了解。标准库为你做了很多,不用都是浪费。而如果你是做嵌入式,不妨参考一下Embedded C++的规范。
技术跟进,工具更新,并不一定就是盲目浮躁——镰刀锄头怎比得过洋枪洋炮?笔者愿意相信,学生、年轻程序员、初学者都比较容易了解这些,同时也正需要被引导着去了解这些。但是在国内,大学教授、项目经理、相信“人月不是神话”的领导者们——他们了解吗?我疑心重重。
强奸,蹂躏无辜良民;奸淫幼女,摧残纯洁的心灵;出版淫秽音像图书制品,毒害青少年儿童。偏偏这些事情在IT领域里面不算违法犯规。
18. 学习编程最好的方法之一就是阅读源代码;
JDK,CLI正是上佳的参考资料。至于C++方面,除了STL,还有Boost,Loki,ACE等等优秀的代码值得研究、参考,甚至抄袭(如果你有足够技术能力的话)。
旧:19. 在任何时刻都不要认为自己手中的书已经足够了;
新:19. 书不在多,好书则灵;
如今国内的图书市场较之过去几年,最大的改变的就是大量国外图书的引进。书少的时候,没有选择的余地;书多的时候,选择太多,无所适从。这里就有一个如何择书的问题。接受推荐是一个不错的选择——不,我不是说某些图书网站上的口舌对骂。
面对这种情况,读者需要的其实是正确的引导。
旧:20. 请阅读《The Standard C++ Bible》(中文版:标准C++宝典),掌握C++标准;
新:20. 请参考《 TCPPL 3rd》《C++ Primer 3rd》《The Standard C++ Library》,掌握C++标准;
基本上,以目前的图书状况来看,要掌握>C++标准,看哪本书也看不到《The Standard C++ Bible》>(中文版:标准C++宝典)这一本上来。笔者在另外的文章里已经发表过对这本书的看法。
说起权威的C++参考书,一定少不了《TCPPL 3rd》《C++ Primer 3rd》《The Standard C++ Library》。
Bible? 唔……看《TCPPL 3rd》《C++ Primer 3rd》《The Standard C++ Library》的读者,大可不必信教。
21. 看得懂的书,请仔细看;看不懂的书,请硬着头皮看;
要知道,很多时候其实不是看不懂,而是没有自信,以为看不懂。
本条款对于学习外语同样适用。
22. 别指望看第一遍书就能记住和掌握什么——请看第二遍、第三遍;
总有人(甚至是kingofark自己)抱怨说没有足够的时间看书。从某个角度来看,确实如此——但这不是你不看书的理由,对吧?
旧:23. 请看《Effective C++》《More Effective C++》《Exceptional C++》;
新:23. 请看《Effective C++》《More Effective C++》《Effective STL》《Exceptional C++》《More Exceptional C++》《Exceptional C++ Styles》《C++ Templates》《Ruminations On C++》《C Traps and Pitfalls》《Expert C Programming》;
写这么多不是要谁都看都买。这些都是顶级好书,根据自己的情况择来读之,易收宏效。
Andrew Koenig的《C Traps and Pitfalls》是程序员必读。令笔者不寒而栗的是,该书提到的许多错误笔者都犯过(而且一直在犯!)。《Expert C Programming》也是一本相当好的书,其中译本也不错,可惜就笔者而言,书中对某些典故的翻译欠妥(比如StarTrek,其作为西方的一种文化现象,已经渗透到西方文明的方方面面,对其中一些典故的引用对于中国人来说,不经解释可能是不太容易理解的)。
24. 不要停留在集成开发环境的摇篮上,要学会控制集成开发环境,还要学会用命令行方式处理程序;
特别令人惊讶的是,笔者发现有些人(居然!)不知道VC还有一个叫做cl.exe 的命令行编译器!运行一个超级阳春的Hello World (居然!)需要到IDE里面去建一个project!没听说过 bcc32、dumpbin、grep、nmake、makefile、javadoc……唔……呃……打个不恰当的比方:冬天非得穿着大棉袄厚棉裤才能享受做爱的乐趣吗?
25. 和别人一起讨论有意义的C++知识点,而不是争吵XX行不行或者YY与ZZ哪个好;
注:XX、YY、ZZ可以指代:某计算机语言;某专家;某种哲学体系;某种软件开发理论;某种新技术新思维;某个“务虚(务实)的”观点;某班的男生。
26. 请看《程序设计实践》,并严格的按照其要求去做;
题外话:从Herb Sutter的网站www.gotw.ca上看到,Sutter与Alexandrescu欲合著一本C++ Coding Standard,应该也是令人期待的一本书。
旧:27. 不要因为C和C++中有一些语法和关键字看上去相同,就认为它们的意义和作用完全一样;
新:27. 注意C与C++之间的区别。
在国内,有那么一群猪……噢不,我是说大学教师……噢不不,我是说项目经理……不不不……对不起,其实我是想说“人”,对C/C++/Java/C#/……存有太多太多的误解(一般很愚蠢,以至于别人都不知道该怎么解释才好)。
旧:28. C++绝不是所谓的C的“扩充”——如果C++一开始就起名叫Z语言,你一定不会把C和Z语言联系得那么紧密;
新:28. 了解各个语言之间的关系和区别,切忌盲目褒贬、妄加评论;
关于C与C++的关系及C++的发展与演化,C++创造者Bjarne Stroustrup在《The Design And Evolution of C++》(中译本,裘宗燕老师译)里面已经说得很清楚了。
学C++的朋友应该看看本书,就当是扫盲。
旧:29. 请不要认为学过XX语言再改学C++会有什么问题——你只不过又在学一门全新的语言而已;
新:29. 请不要认为学过XX语言再改学YY会有什么问题——你只不过又在学一门全新的语言而已;
30. 读完了《Inside The C++ Object Model》以后再来认定自己是不是已经学会了C++;
事实上,这样的高阶书你不一定就非要去啃,关键是浮躁与不浮躁、自信与自满的问题。
31. 学习编程的秘诀是:编程,编程,再编程;
这一点在Andrew koenig的书《Ruminations On C++》《Accelerated C++》里面有很好的体现。随着Andy 的书一起作思维上的编程,自己再动动手,将是非常美妙的学习经历。
旧:32. 请留意下列书籍:《C++面向对象高效编程(C++ Effective Object-Oriented Software Construction)》《面向对象软件构造>(Object-Oriented Software Construction)》《设计模式(Design Patterns)》《The Art of Computer Programming》;
新:32. 请留意下列书籍:《Design by Contract,by Example》《Refactoring》《Design Patterns Explained》;
《Design by Contract,by Example》《Refactoring》《Design Patterns Explained》毫无疑问是好书,且中译本令人期待。
旧:33. 记住:面向对象技术不只是C++专有的;
新:33. 记住:哇!面向对象技术又不只是C++专有的;
嗯?我怎么会说“又”这个字?
旧:34. 请把书上的程序例子亲手输入到电脑上实践,即使配套光盘中有源代码;
新:34. 善加利用配套光盘;
35. 把在书中看到的有意义的例子扩充;
36. 请重视C++中的异常处理技术,并将其切实的运用到自己的程序中;
36. 请重视DbC(Design by Contract)以及异常处理技术,并将其切实的贯彻和运用到自己的程序中;
Exception Handling引发着无数的讨论。关于exception handing的各种议题,看Herb Sutter的文章的确让人有些“震惊”。Embedded C++倒是蛮干脆——STL,Exception Handling全部删光光——可见什么事物总有个适用范围。
DbC绝不仅仅是assertion。DbC要求各个组件各尽其责,将交流和协作建立在非常明晰严格的条款之基础上。DbC是不容忽视的,其所涉及的层面和深度,或许比我们想象的要广,要深。
37. 经常回顾自己以前写过的程序,并尝试重写,把自己学到的新知识运用进去;
38. 不要漏掉书中任何一个练习题——请全部做完并记录下解题思路;
39. C++语言和C++的集成开发环境要同时学习和掌握;
40. 既然决定了学C++,就请坚持学下去,因为学习程序设计语言的目的是掌握程序设计技术,而程序设计技术是跨语言的;
41. 就让C++语言的各种平台和开发环境去激烈的竞争吧,我们要以学习 >C++语言本身为主;
旧:42. 当你写C++程序写到一半却发现自己用的方法很拙劣时,请不要马上停手;请尽快将余下的部分粗略的完成以保证这个设计的完整性,然后分析自己的错误并重新设计和编写(参见43);
新:42. 只有通过编码实践才能领会设计思维;
43. 别心急,设计C++的class确实不容易;自己程序中的class和自己的class设计水平是在不断的编程实践中完善和发展的;
44. 决不要因为程序“很小”就不遵循某些你不熟练的规则——好习惯是培养出来的,而不是一次记住的;
45. 每学到一个C++难点的时候,尝试着对别人讲解这个知识点并让他理解——你能讲清楚才说明你真的理解了;
46. 记录下在和别人交流时发现的自己忽视或不理解的知识点;
47. 请不断的对自己写的程序提出更高的要求,哪怕你的程序版本号会变成Version 100.XX;
郑重提醒:请学会使用版本控制工具!Visual Source Safe,CVS——使用它们作版本控制绝对比你新建一个名为“MyApp_New2”的目录要好得多!在实际开发中,不使用版本控制工具的结果可以用一句话概括:能变得多糟,就定会变得多糟。
48. 保存好你写过的所有的程序——那是你最好的积累之一;
49. 请不要做浮躁的人;
50. 请热爱C++!
其实Eiffel、Java、C#也不错:-)