购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

新世纪的C语言“万宝全书”

C语言,从诞生至今,已经有接近50年的历史。从最早期的NB(即New B;中文读者看到这个名字更能开怀一笑吧),到写出UNIX的C,再到ISO/IEC 9899标准,C语言在不知不觉中经历了很多变化。唯一变化不大的地方,似乎就是它的流行程度了。在我当年学习BASIC和Pascal时,少科站的王建德老师就对C非常推崇,说真正要用计算机干活还得用C。所以,在我后来有机会从Apple II转向IBM PC时,就顺理成章地用上了Turbo C。从那时起,就从来没有出现过一种语言,可以真正取代C。在TIOBE编程社区指数上,C长期位居前二;最近,在Java地位有所下降的情况下,C又重新回归榜首的宝座。因此,学习C语言一直有着很强的必要性。

C的教科书可谓汗牛充栋,并有C语言发明人写的经典珠玉在前,一直为人所称颂。那么,本书又有什么特点呢?

回答这个问题之前,我先来问你一下:当前的C标准是什么?

——如果你知道C89,那说明你知道C是有标准的。嗯,这比不知道要好。

——如果你回答C99,那说明你知道C还在演化。不过,那都是上个世纪的事了,对不?

——如果你答出了C11,你厉害,我相信大部分C开发者并不知道不仅C++ 有11标准,C也有一个11年的标准——虽然这个标准的存在感有点弱,特别是跟C++11相比的话。

——最后,你居然知道C18(也叫C17)?太牛了,事实上,在读这本书之前,我都不确定我之前有没有听说过C18……

而本书讨论了C的所有特性,从C89一直到C18。内容足够新,也足够全面,这就是它的最大特点。

克尼汉(Brian W. Kernighan)和里奇(Dennis M. Ritchie)的经典著作《C程序设计语言(第2版)》(以下简称为 K&R )出版于1988年,基本覆盖了C89。显然,它不可能讨论任何属于C99或是更新C标准的内容。目前,我们日常接触的C代码也许用到的C11/C18特性还不多,但C99特性实际上已经挺多了:如果你的项目里用到了 uint8_t 或是 bool ,那你就已经用到了C99。C标准后续还有很多改进(并且大部分得到GCC等主流编译器的支持),读完这本书你也就会基本了解这些内容了。

除了内容够新之外,书中还全面讨论了各种实际的环境和使用场景,包括Windows、UNIX和类UNIX操作系统(如Linux)等,而不像 K&R 一样仅限于UNIX。在 K&R 成书之际,微软还处于DOS的年代(Windows尚在研发中),为UNIX从业者所不齿;Mac刚刚诞生,还非常小众;Linux则还需要一些年头才会问世。显然, K&R 不可能对它们进行讨论。而本书则讨论了所有这些环境,甚至还包括了今天看来已经过时的MS DOS。比如,在第17章的“问与答”中提到了“Null pointer assignment”,那可真是我在DOS年代编程的梦魇了。虽然今天几乎应该没人会遇到这个错误了,但我还是很高兴有本书终于清楚地描述了我当年写C程序时遇到过的这个错误的原因。

作为一本教科书(而不是主要作为参考书),本书非常注意循序渐进,对复杂概念的讲述采用了逐步推进的方法。拿作者自己的话来说:

针对有一定难度的主题,我采用了螺旋式的介绍方法。也就是说,对于较难的主题先进行简要介绍,然后在后续章节中再进行一次或多次介绍,每次逐渐增加一些细节内容。本书的进度是经过深思熟虑的。每章都按照循序渐进的方式进行组织,前后内容由浅入深,相互呼应。对于大多数学生来说,这种循序渐进的方法是最合适的:既能避免产生厌倦,又能防止“信息过载”。

举一个例子,第3章就出现了指针,但作者把对指针的完整讲解放到了第11章和后续的一些其他章节中。尤其重要的是,作者把指针相关的复杂声明语法放到了第18章里,而没有早早拿出来对初学者进行“劝退”。并且,在讲述复杂声明时(书中给出的例子是“ int *(*x[10])(void); ”),作者给出了两条简单的规则帮助读者来解读,又给出图示展示解读的顺序,最后还指出可以用typedef来简化声明。回想起我初学C时教科书中的复杂声明例子,以及知乎上仍偶尔可见的让初学者更加糊涂的讲解指针的“例子”,我觉得作者的讲述方式真的对初学者非常友好——尤其考虑到C的复杂声明需要从里往外读,实在有点“反人性”(可以对比一下一个从外往里读的C++ 的相似声明:“ array<function<int*()>, 10> x; ”)。

这种循序渐进不仅体现在跨章节的情况,在一章之内也有类似的处理,最典型的就是把很多初学者不需要立即了解的知识放到了章尾的“问与答”里。比如,当我读到下面的句子时,“当我们把一个包含小数点的常量赋值给 float 型变量时,最好在该常量后面加一个字母 f ”,我有点奇怪作者为什么没有进一步解释。但作者在此处加上了“Q&A”的标记,对照着读一下就清楚了。在“问与答”里,作者先给出了简短的解释,然后指出,更详细的解释要看后面的第7章。这种逐步递进、而不是试图一下子就向初学者塞一大堆他们很可能暂时还不需要的知识的做法,确实对初学者比较友好。

对于我这种已经熟悉C语言的人来说,“问与答”反倒是个有意思的冷知识来源。比如,我之前也不知道,根据C89的规范,标识符只有前6个字符保证有效,而且不一定会区分大小写!(幸好大部分实现提供了更好的保证。)

作为一部教科书,代码示例和习题自然是不可缺少的。书中示例和习题都非常充足,足以满足教学和自学的需要。除了讲述清晰之外,内容的正确性也非常重要。有一部亚马逊上有很多五星好评的C教科书,却被专家评为“彻头彻尾的胡说八道(Complete Nonsense)”,就是因为作者用明白晓畅的散文写出了错误的内容,文字传达了错误的信息,代码也不能给出期望的结果。对这本书,我可以很高兴地告诉大家,迄今为止我还没发现任何错误,中文翻译也非常流畅易懂。考虑到英文版的惊人售价(超过一百美元!),中文版读者真的很幸运。

循序渐进这个优点,在一小部分(能力强的)人眼里也可能成为缺点:他们会认为本书节奏过慢(亚马逊读者评论的原话是“takes a painfully slow approach to covering even the most basic programming”),而欣赏 K&R 的简约风格(英文版正文部分不足200页,不到本书的四分之一)。我虽然对C语言已经相当熟悉,阅读本书时倒也没有这种感觉;我同样相信绝大部分读者会喜欢这种循序渐进的风格。而即使对于喜欢简约风格的人来说,我也需要指出, K&R 距今已经超过30年,不管是背景知识(没有也不可能介绍Linux和GCC),还是代码风格(如函数前面省略 int 返回值声明),都有过时之嫌。而后人根据对C的多年实践经验总结出的陷阱和教训,克尼汉和里奇也不可能先知先觉地进行描述。尤其对于初学者,我们确实需要更好的教材。

语言在进化,新的时代需要新的经典。不管是初学者,还是需要了解C的新标准特性的老程序员,都能从这样一本好书中获益。

吴咏炜
Boolan首席咨询师 sf04gCQxFAVtNgVE7AL1/9INqqgeLEZNmqdG3ZBreRowxWKletsTKmHPuysKdFV5

点击中间区域
呼出菜单
上一章
目录
下一章
×