《狂人C》读評(一) 理解程序设计篇

KBTiller兄在书籍扉页写指正,不敢指正,共同讨论。其实第一篇在年前已看完,由于过节心态浮躁一直没能总结记录。仔细想想自己真是拖拉的要命,再不写点东西对不起KBTiller兄的热情心意。本文大部分内容属于跟作者观点不一致的描述,我不是初学者,所以与其是读书笔记,不如说挑刺,尽管这样,书中还是有不少让我受益良多的地方。为了整理方便,主体内容分四个不同的部分,有的问题分界比较模糊,主观因素比重很大。至于为什么会这么长,那是因为我吹毛求疵了 :)。

一、精彩绝伦:我认为的很出彩的地方

1、最精彩的地方就是作者对细节对技术本质的探索,这点让我肃然起敬,这才是一个工程师应该具备的最高的品质。
2、P22 这个NEO画的真神了(KBTiller兄你想累死初学者么 ^^)。
3、P27 正文第3段第1行 “从这两条规则中发现在代码中只能写成正的十进制整数常数”,以前一直没有发现这点,读到这里真是如醍醐灌顶!P39的练习也是这个道理。
4、强调数据类型为基本是本书在技术上最特色的闪光点,数据类型的确是C语言的复杂所在,也是最难正确理解和使用地方,在我读的任何一本C语言书籍中还没有能系统的提及此,作者几乎对每个类型都做了深入分析,赞!
5、P71-P73 专门讲解了优先级结合性和运算次序的关系,这也是C语言中非常让人迷惑的地方,很多学了三五年的熟手还经常会犯错误,归根结底就是当初基础没打好,这里非常专业的分析了它们之间的关系,帮助初学者避免很多问题,这是很多C语言书籍尤其是国内教科书最欠缺的地方。
6、把=读成赋值,这个主意的确非常棒。
7、P111利用判断三角形种类这个问题来锻炼读者的逻辑判断能力是非常恰到好处的。初学者对代码的理解和控制不够熟练,往往会出现逻辑混乱的状况,这时候正需要加强练习。
8、P142用了小4页来讲解++ — 运算符,帮”教授“和”专家“们的学生排除遗毒,作者大人辛苦了!

二、知识错误:知识点出错或者遗漏的地方

1、P7正文第4段第1行 “1987年87 ANSI C公布”,根据我在维基百科和C参考手册上的资料得知,ANSI C委员会是在1982年筹建,1983年正式成立的,而在1989年推出了ANSI C标准,俗称C89,这里是应该是错误了。
2、P13正文第8段第8行 “其中的字符都原样输出,除非出现“/”引导的字符序列或“%”引导的字符序列” 除了/和%引导的字符序列外,??引导的三字符序列也会被转换,尽管这个家伙几乎被遗忘了。
3、P13代码第3块第一行 “/” 、/n 、/a 、/b 、/t 、// 、/” 、/’”,这里怎么多了一个/”,而且少了/v /f /r /? ,这属于字符转义符,还有别的转义符,描述不够精确。P49也有这个问题。
4、P14脚注1 “目前好像还没有实现可以使用汉字的C语言编译器” P16脚注1也是。VS2008中文版支持中文字符作为标识符,当时发现了这个的缘故是自己define出来一套汉编。看到这个,再版书籍的时候会不会考虑使用VC++ Express作为首选IDE呢,呵呵。
5、P24正文第4段第2行 “称呼这种编号的专业术语有很多种,有的叫ASCII码,有的叫内码,有的叫Unicode编码” ASCII码和Unicode编码都是内码的一种(如果英文也有内码这种说法的话),在这里把他们并列起来描述不适合,应该把内码删掉,换成其他的,如GBK/GB2312。
6、P48正文第4段第3行 “所以 signed是可以省写的这一说法,如果不说是错误的,那么至少是不严谨的。” 其实就是错误的,不能省略,在函数的声明和定义中如果一个使用 signed char 一个使用 char ,gcc下会编译出错,这点在CU论坛上也讨论过了,不多做解释,详细见链接:http://bbs.chinaunix.net/thread-1834841-2-11.html 从17楼开始,中有素质低下者请自动无视。
7、P82正文第10段第1行 “在{}之内,C99以前的规定是先把对编译器的事儿说完,再说让CPU做的事。也就是说要先写声明,再写语句”。C89也没有这个规矩阿,大概是K&R的C才会有这个要求(K&R要不要求我还真不清楚,但TurboC会要求)。

三、表述不当:在书中出现的位置不对或者容易引发歧义或者笔误疏漏的地方

1、P3正文第2段第1行 “通常我们所看到的计算机,一般都会有键盘、鼠标、显示器、机箱等几个部分”。这里讲机箱并不太合适,毕竟机箱只是一个空壳子,里面的内容才是最重要的,所以把“机箱”改成“主机”更适合。
2、P6正文第21段第1行 “汇编语言用助记符(add ,move)”,前面给出的例子是用的mov,但这里写出来是move,还是统一更好。
3、P7正文第4段第2行 “这个标准在1990年被国际标准化组织(International Standards Organization,ISO)”,ISO的英文标准名字是International Organization for Standardization 虽然看起来很古怪(貌似缩写成IOS更合适 –!)而且在后面P47也是用的International Organization for Standardization,所以这里要统一下。
4、P9正文第3段第1行 “由于使用了一段事先写好的程序段(这是编译器提供的)”。在这里说的是printf库函数,库函数不是编译器的一部分,但初学者又不知道啥叫函数库,所以建议改成“这是随编译器一起提供的”。
5、P16正文第8段第3行 “如表1-1所示,是C99新增的关键字。” 但是表1-1给出的是C99全部关键字,只有被加了标注的才是新增关键字,而且语法也有点问题。所以这里个人建议更改为“表1-1是C99全部的关键字。”
6、P20练习2.6 “使用printf()函数应在代码开头的位置通过编译是编译器处理命令对函数的名称做相应的说明“。 “编译是”应该是笔误。
7、P25正文第3段第2行 “在123后面写;是因为123无法被单独写在代码中。” 这句话理解起来不太得劲,建议改成“无法单独作为一句代码”更好。
8、P32正文第2段第1行 “内存(Memery Unit)这个词,本来就是记忆器件的意思。” Memery Unit最好翻译成内存单元,毕竟后面跟了个Unit。
9、P36正文15段第1行 “求一个负数的补码,还可以用2^机器数的总位数 减去这个数直接得到。” 减负等于加正,所以应该是“加上这个数直接得到”。
10、P49代码第5块 “/八进制数 /x十六进制数” ,C语言对转义字符的长度还是有要求的,八进制不能超过3个,十六进制不超过2个,这应该在后面写上。
11、P60正文第6段第2行 “然而12/10用%2d输出的是1,也就是说不会输出1前面的0,如果希望输出为02,则在%与2d之间应再在写个0——%02d” ,这里应该是要输出01,笔误写成02了。
12、P65习题12.“输入一身份证号码,输出这个人的生日。” 之前没有讲任何输入函数,所以这道题不适合在这里出现。
13、P67正文第3段 运算符介绍,有后缀运算符,但是没有说前缀运算符。
14、P69正文第3段第1句,“在这个表达式中,赋值号右面的表达式中的…” 前面一直把=称为赋值运算符,在这里忽然冒出个赋值号,不和谐阿。
15、P73脚注2 “利用续行的标志,从某种意义上说,单调也可以割裂”,“单词”

This entry was posted in 程序设计 and tagged . Bookmark the permalink.

51 Responses to 《狂人C》读評(一) 理解程序设计篇

  1. snail says:

    D大~这个是书手稿吗?出版了吗?

  2. Gao19870101 says:

    作者太狠了,我到目前没有这么认真的看过一本书!!!

  3. hyclq says:

    厉害!为之汗颜[e08]

  4. KBTiller says:

    davelv兄不辞辛苦,如此认真地阅读拙著,并客观公正地给予评价和勘正。本人实在是不胜荣幸。在此向davelv兄鞠躬致谢!
    由于诸事缠身,一直没有时间认真作复,尚请davelv兄海涵。
    下面一一回复。

  5. KBTiller says:

    一、
    1.davelv兄过誉。谢谢!davelv兄对待技术的认真态度,一直是我所亦步亦趋的。
    2.这个例子最初是在配光盘的前提下设计的。如果光盘里有相应的原始材料,完成这个题目应该不是很困难,也就是一些简单的编辑工作(复制、粘贴、查找、替换)。

  6. KBTiller says:

    这个题目的目的有两个:一是让学习者一开始就领略到编程的乐趣和神奇;再一个是希望学习者能体会到编程应该按照合理的“工序”过程进行(比如先替换/为//,再替换"这样的字符为/"……)。
    可惜后期制作时决定不配光盘。这也说明了“需求变更”会代来何等巨大的麻烦啊。哈哈

  7. KBTiller says:

    这个题目设计失策的地方在于,也许应该给个美女的NEO(?)。
    有空我会在我的博客里把这个题目的材料和详细做法写一下。

    • davelv says:

      回复 KBTiller:当初设计习题的时候也应该有对应参考答案之类的吧,不过书中没有提到在什么地方可以获取,本作大卖时,KBTiller兄要搞个解析的网站/博客来满足读者需求 ^^

  8. KBTiller says:

    3.那条是我有感于某些书籍里刚刚说完“十进制整数常量由0~9十个数字组成”,紧接着却给出-123这样自相矛盾的例子而特意强调的。程序员应该严谨,应该能清楚地区分什么叫常量,什么叫常量表达式。

  9. KBTiller says:

    4.知己!我强烈地反对片面地强调“算法”,我认为那会误导初学者。
    5.知音!不枉我当时写得用心良苦。
    6.谢谢!听到有人把“==”读成“等于等于”我感到很别扭,我觉得那是对思维的扭曲,不利于编程。

  10. KBTiller says:

    7.谢谢!这个例子我还有普及一点粗浅的"软件测试"常识的意思。
    8.“教授”和“专家”们的遗毒太深,我不得不多费点口舌。

  11. KBTiller says:

    二、
    1、
    你说的对。谢谢指正!
    题外话:
    其实这个BUG是我早期引用资料不当造成的,后期我也发现了。我记得我已经改正了,但很奇怪最后还是印出来了。但是不管怎样,我还是要对此负责(谁让封面上有我的名字呢)。

    • davelv says:

      回复 KBTiller:这点的确让人很郁闷,不过有KBTiller兄这么认真的态度,修订版本后一定是精益求精了。

  12. KBTiller says:

    2、
    你对!说实话,当时我确实没想起来“三字符序列”。谢谢提醒。
    不过“三字符序列”在国内并不怎么用得到,所以一直是这本书所努力淡化和回避的。况且需要设置编译选项这样复杂的手续。
    但为知识的全面完整考虑,可能在这里加个脚注为好。

  13. KBTiller says:

    3、
    确实多了一个“/"”,此外缺少“/v”、“/f”、“/r”、“/?”。
    缺少的几个是因为,当时考虑这几个有不同的实现(尤其是“/f”),可能根本看不出效果,“/?”如果不用“三字符序列”没有必要,怕一开始就把读者带入不必要的细节之中。

  14. KBTiller says:

    4、
    是我孤陋寡闻了。因为要介绍C99,我一直没认真注意过VS2008,只关心哪些编译器能较好地实现C99了。
    “使用VC++ Express作为首选IDE”是个很有诱惑力的好主意,我会认真考虑。
    5、
    这个地方我只考虑如何通俗易懂了,根本没考虑严谨的问题。写的有点随意了。应该改正。

  15. KBTiller says:

    6、
    你对!同时感谢CU的各位网友指正,尤其是OwnWaterloo网友。
    7、
    这个让我很震惊。我需要几天时间考证一下。后面的容下次再回。

  16. Anryfree says:

    表示楼主很漂亮[e04]

  17. manymore13 says:

    你这书看几遍了?LZ看书够仔细的。。[e01]

  18. KBTiller says:

    关于 二 、7、
    K&R中提过这个事情,VC++6.0也是这样。

  19. KBTiller says:

    这个问题我查了半天C89也不得要领,但OwnWaterloo网友给出了一个非常漂亮的解答:
    http://bbs.chinaunix.net/viewthread.php?tid=2289611&extra=&page=2 (19楼)

    • davelv says:

      回复 KBTiller:恩,看来我也是犯了没有深入的错误,Water兄也给这样的解释 gcc无论 -std=什么都没有这样的限制, 除非 gcc -std=c89 -pedantic

  20. KBTiller says:

    三、
    1.接受你的意见。谢谢
    2.接受你的意见。谢谢
    3.我觉得应该统一改成International Organization for Standardization
    4.接受你的意见。谢谢
    5.接受你的意见。谢谢

  21. baozhifei says:

    我是来看头像的。[e03]

  22. liaay says:

    为C++执着而奋斗,和此标题不符,呵呵

  23. yonghui_hao says:

    厉害、····[e03]

  24. fdh120 says:

    [e03]来看头像。。。。

  25. KBTiller says:

    三、6
    的确是笔误。已经写到勘误表中。谢谢

  26. KBTiller says:

    三、7
    这句话确实很难说清楚。谢谢你的建议,我再仔细琢磨一下。

  27. KBTiller says:

    三、8
    也许应该翻成存储器?翻译成内存单元我担心BYTE这样的东西又说不清了,但翻成存储器又怕和外存搞混。我再查一下标准吧

  28. KBTiller says:

    三、9
    是的。我写的容易让人误解,应该是减去这个数的绝对值

  29. KBTiller says:

    三、10
    你说的对!谢谢

  30. KBTiller says:

    三、11
    你看得真仔细。万分感谢!

  31. KBTiller says:

    三、12
    调整内容时疏忽了这道习题,很不应该。谢谢

回复 davelv 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注