不推荐这本书
2013-06-08
很久之前,在网上看到有人推荐C++书籍的时候,有一位说,推荐C++ Primer,注意不是C++ Primer Plus,完全是两本不同的书。后来也零零星星地听到过一些关于这本C++ Primer Plus的评价,大致都是说这本书不行,请去看C++ Primer或者Accelerate C++之类的。
前些日子偶然看到,这本书在豆瓣上评分很高,在Amazon.com上面评分也很高,书评也几乎都是一边倒的,只是偶有一两个负面的评价。总体而言我还是比较看重豆瓣读书的评分的,于是就在闲暇时间看了这本书的前四章。
由于豆瓣将所有版本的书评一同显示,可能需要强调一下,我看的是第六版英文版。
结论是这本书完全不行,无论读者是什么基础什么背景,从这本书里能获得的东西都很少。我知道大家都是不愿意放弃自己的阅读体验的,或许有人真的能通过这本书入门C++,那就请不必太过于在意下面对于这本书的负面评论。这篇书评是为了那些和我一样喜欢看豆瓣书评的人提个醒,从我个人的角度来看,读这本书的收益抵不上你将在1200页的正文上花费的时间。
首先,来看看这本书的定位。前言中说,这本书可以当做一本textbook,也可以用来自学。没有假设读者有C的经验,但是有编程经验是desiable的。书名里也说了,这是primer,初级读本。
书的编排上,如果之前有C的经验,那么前些章节可以略读过去。这一点有些疑问,作者自己也说了,C++不是简单地在C的语法上增加些东西而已。不过这这个问题让我们先放一放,先看下去。
先是历史课,然后作者讨论了可移植性,简而言之作者说C++是可移植的,但是事实上没那么简单,不过在初级读本里面,也没必要深入讨论。第一次让我有疑问的是20页,作者说你甚至可以用一个word processor来写源代码,只要你将文件保存为标准的ASCII文本就行。
这种说法对新人非常不好。首先用word processor来写源代码是不好的,启动慢,而且没有语法高亮和方便的缩进控制,或许还有些其他奇奇怪怪的问题。一种比较好的方法是用专门给程序员设计的文本编辑器,作者完全没有提到。如果只是要表达什么样的都可以,那么至少要多说两句,例如在win或者OS X的富文本编辑器下应该怎么做。
然后作者讨论了各种C++实现所用的源代码文件的扩展名,在一般的书籍上只是简单地说一句,扩展名一般是可以哪些,具体的请查阅手册,作者不厌其烦地列了一个表格,1200页地篇幅很多就是在浪费在这种东西上的?
而且这个表格让我开始怀疑这本书的严谨性了。Unix是一种C++实现?退一步说,Unix有标准化的C++实现?再退一步说,Unix只规定接口,怎么可能是实现?
接下来作者又不厌其烦地介绍了各种平台上的C++环境,其中还参杂着历史课……读者这时候真的关心将近20年前的事情吗?作者在下文还特地说,可以用mv将a.out重命名,就是不愿意介绍-o参数可以在编译的时候指定文件名……而且,这里说的unix还不包括linux和OS X,一个用BSD Minix之类的读者真的需要介绍这些吗?
之后是g++,作者还特地提到了某个古董版本的g++不会自动链接C++的库。到了win上面的IDE,却只是简简单单说了两句,明明IDE是最复杂的东西,作者宁愿在前面讲很多历史,也不愿意多花点笔墨介绍一点IDE。
我之前读过的一些英文书籍,都会选择具体的一两种环境来介绍。对于C++,最流行的肯定是MS的IDE和GNU的g++。Windows上面介绍VS express 2010 C++,其他平台上介绍g++,不是能减少很多麻烦,省去很多无谓的笔墨吗?
这是本书的严重问题之一,很多地方沉溺于介绍一些对读者没什么帮助的东西,或者是历史课,或者是和C做没什么用的对比,或者是初学者根本用不上的东西,一些非标准的C++编译器的问题,中间还有些许错误。作者不明白该如何选择材料,而是将他能想到的东西一股脑地塞给读者,其中还带着些令人不快的霉味。
或许有人会觉得历史课,或者和C做对比,有助于增进理解。这或许是因人而异的事情,但是这本书中这些内容实在是太多了,C++本身的特性已经非常复杂,读者真的有精力去关注过去的C++编译器是什么样子的,或者C的写法是什么样子的吗?请问C中一个identifier的长度限制,对于学习C++有什么帮助呢?在这本书出版的2011年,你不幸地随便下载到了一个十来年前的C++编译器(居然还能运行,不容易!),然后发现有些标准化的特性它不支持,那么重新去下载一个就行了,g++和MSVC++ express都不要钱的!
第四章的大部分篇幅,是在教读者写C代码。有些地方作者自己也说了,如果我们用C++的数据类型,事情就会变得很简单。但是后文的例子中继续用C字符串,不明白这是为什么。在实际情况中,用C字符串的情况很少。C字符串的字符串处理相当麻烦,之前看到过一个项目从C迁移到C++的理由之一就是,C的字符串处理实在是太枯燥了。写代码是一个积累经验的过程,如果写习惯了C风格的代码,迁移到C++的风格又要有一个适应的过程。用C风格的代码,作者也只是在写一写非常不自然的例子,比如List 4.22。
C的基础对于学习C++有帮助,特别是在一些语义分析上面,但这不代表学习C++还要用C风格的字符串,在存储空间大小都无法确定的时候,还要优先考虑array而不是vector。
虽然后面的章节我没看,但是如果坚持用C风格的代码来学习,读者最终也写不出真正的C++来。
最后,这本书的技术性错误很多。注意是技术性错误,而不是typo之类的小问题,如果你没有相关经验,根本就看不出作者说错了。而且这些错误,很多是作者写的不必要的部分中出现的。
对于这些错误,以及个人觉得表达上欠妥的地方,在豆瓣做了读书笔记,觉得“技术性错误多”缺乏论据的,可以去翻阅一下。
(还要补充说明一下,有些人或许觉得,有错误没关系,反正编译试验一下就行了。但很可惜,一些未定义行为的代码可以通过编译,甚至可能给你一个看上去比较正常的结果。还有些人或许觉得,在网上一搜不就有答案了,但是,一个C++的问题,在网上能搜到很多错误的回答,如果真的要搜,去stackoverflow.com比较好。)
所以说,这本书的材料组织混乱而且过时的内容多(一个指针变量通常是2字节或4字节?2011年还有那么多的16位环境?),很多内容是C风格而且错误较多,如果你需要一个参考意见,我建议你不要用这本书来学习C++。
这种回答缺乏建设性,初学C++看什么书比较好呢?C++ Primer是个常见的回答,但是对于这种巨细无遗讲语法的风格,一部分人会非常不适用。虽然我觉得第五版还是很不错的……Accelerated C++也是个常见的回答,但是一般认为这本书学习曲线很陡峭,而且个人觉得这本书的例子非常无趣。Bjarne新写的programming或许是个不错的选择,但我没有看过,不知道是不是应该推荐。
用前四章来评价一本书或者不够准确,或许今后有空的时候继续看吧。