谭浩强《C语言程序设计(第二版)》的前50页中的错误分析[转帖]
看见论坛上有人说推荐谭的书,本人不以为然,特此转了这个强人写帖子,给大家看看,谭浩强《C语言程序设计(第二版)》的前50页中的错误分析
:谭书也算是一本奇书了,据说已经发行了300多万册。这本书真的那么好吗?师长早有教诲,因此本人从来没有好好读过谭书。近日遇周围人盛赞谭书,非辩论不可。虽本人不愿应战,但也不得已将谭书找来翻翻。随便翻了一段,就发现错误百出,在此将其中最前面的一些整理出来,提出与国内广大行家和新入道者讨论,望行家们提出批评,供新入道者参考。
书中程序的不规范性、不良的格式和低劣的编程都不在这里深究了。实在是太多,要深究、分析和改正起来,必须写一本数倍于谭书的大作,本人实在没这个时间和精力。水平高的人有的是,欢迎写几个续篇。
注:下面将作者尊称为“谭先生”。负的行号表示一页里倒数的行数。
P1行1:…,它适于作为系统描述语言,…
这开宗明义的第一句话就说明谭先生对于计算机科学的术语不甚了了。什么叫“系统描述”,什么叫“系统程序设计”?人们都都说C是一种“系统程序设计语言”,而“系统描述语言”则完全是另一种东西。想必谭先生对它们之间的差异和关系都不清楚。在这种情况下就来下断言,一上马就露了怯。
P2表格:if (e) S;
这个错误说明谭先生对C语句基本结构也不清楚。在C语言里,分号是普通语句的结束符号,是语句的一部分。如果谭先生的S表示语句,那么后随的分号是必需的吗?如果谭先生的S表示语句中分号前面的一部分,那么又如何理解可以放在这里的 { ... } 顺序结构呢?它算语句吗?可以放在这里吗?要加分号吗?无论怎么看,谭先生都难以自圆其说!
P3行4:C语言是理想的结构化语言,…
不知谭先生的这个论断由何而来。C的创造者肯定不会说这句话,即使是C语言最狂热的崇拜者恐怕也不敢这样说。幸亏谭先生生在中国,其书只在中国出版,否则恐怕他就不会好过了,不知有多少人要找谭先生理论个究竟。
P3行7-8:例如整型量与字符型数据以及逻辑型数据可以通用。
此句子表现出的语文水平就不深究了。要问谭先生的简单问题是,“量”与“数据”是什么关系?再一个问题是,C语言什么时候增加了“逻辑型数据”?
P3行14:C语言允许直接访问物理地址。
不知这个论断从何而来。至少无法从C语言参考手册中找到根据,看来是谭先生为C语言增加的特殊功能。
P4程序:This is a c program.
通观世界上所有有关C语言的重要著作,C语言的名字“C”都是用大写表示。这里好象谭先生表示了对C的不肖,与前面大相径庭,不知何故。
P5行9:注释可以出现在程序中的任何位置。
这里又修改了C语言的规则。这里给谭先生提个小问题:“请找出在C程序里不能出现注释的位置(或说,加了注释就会改变程序意义的位置)。”请10秒钟内回答。
P5行12:“%d”表示“十进制整数类型”。
写程序有问题呀!怎么一遇到具体问题,写出的解释到处都是毛病。“%d”根本就不表示任何类型,它只是对函数printf提出一个转换要求。如果一个初学者产生这种理解偏差还有情可言,像谭先生这样的“大师”级人物也犯此等低级错误,实在是不可原谅。
P5行-8:scanf和printf都是C语言提供的标准输入输出函数…
按本人理解,C语言本身不提供任何有关输入输出的功能,也不提供任何标准函数。只是ANSI C建议了一个标准函数库。至少C参考手册上是这么说的,在谭书中其他部分也这么说。概念不太清楚就容易漏马脚。
P6行13:可以说C是函数式的语言。
太荒唐了,完全是望文生义。谭先生的计算机科学技术知识水平可见一斑。函数式语言是计算机科学领域中有明确意义的术语。再者说,即使不理解,也应该尽量回避一下大家都知道的东西,这下不就漏了底。说C是函数式语言,就像说谭先生是“错话大师”一样(毕竟他也说了许多对的话嘛!)。看来谭先生需要补一补计算机科学的基础知识,听说谭先生是清华大学毕业,那里的计算机系也还不错嘛。
P6行14-15:…ANSI C提供100多个库函数,Torbo C和MSC 4.0提供300多个库函数。
什么叫“提供”,这里的两个“提供”无论如何也不是同一个意思,因为将ANSI C和Torbo C、MSC 4.0并列讨论根本就没道理。谭先生知道它们各表示什么吗?知道语言标准和语言实现之间的关系和差异吗?
P7行12-14:当然,不同的计算机系统需要对函数库中的函数做不同的处理。不同的计算机系统除了提供函数库中的标准函数外,还按照硬件的情况提供一些专门的函数。
谭先生在这里说的是什么“计算机系统”,哪个层次的计算机系统?首先应该将这里的计算机系统都改为“C语言系统”。但是即使修改之后,最后一句话也没有讲到点子上,应该怎样修改就算留给谭先生的能力测验题了。
P9行-12和-2:选择“Compiler”菜单… (4)执行程序。按“F10”键,…
看来谭先生也没怎么用过Turbo C。编辑之后如何去选择“Compiler”菜单,当然要先按F10键。但谭先生在这里就不讲,而到后面又讲。估计还是自己没怎么用过,没什么印象,不知怎样讲有助于学生使用。
P10行8:脱离Turbo C,…
这又是谭先生发明的不规范词汇。正规的术语是“退出”,“结束”,“终止”。
P11行5:…,但将后缀自动改成“.o”(表示它是 .obj文件),…
改什么后缀?实在弄不明白,至少不是规范的说法。再说了,它怎么又成了 .obj文件,在UNIX系统里那有“.obj文件”的容身之地?对UNIX术语不熟悉也不要自己随便发明说法嘛。
P11行13-14:此时,a.out中不存放目标文件。
首先,谭先生对目标文件和可执行文件的差异认识不清,在这里就露了马脚。另外,后半句的说法也实在不规范,a.out不过是个文件名,文件名中存放文件是什么意思呢?当然,初学者这么说也就罢了,“大师”这么说,实在令人遗憾!
P14行18:计算机算法可分为两大类别:数值运算算法和非数值运算算法。
听说过“数值算法”,但没有听说过“数值运算算法”。对于“非数值”也一样。谭先生在发明术语方面建树颇丰,但在基础教科书中大量发明术语又有什么理由呢?或者就是要给初学者找麻烦,或者就是对计算机科学技术的基本术语不甚了了,还能找到其他解释吗?
P19行-2:…,已为世界各国程序工作者普遍采用。
谭先生对世界了解得也不多呀!现在哪国程序工作者还广泛采用流程图呢?请列举一二!
P21行6-7:…,可以看出流程图是表示算法的较好工具。
和什么比较得出这个结论?今天计算机科技界还有多少人这样认识?谭先生独领风骚了。
P22行-6:1966年,Bohra和Jacopini提出了以下三种基本结构,…
请谭先生问问这两位先生是不是他们的发明,他们肯定诚惶诚恐。看来谭先生对计算机科学技术发展的历史也知之有限(知之有限并没有什么,但不要信口开河嘛)。这里给谭先生上一课:在ALGOL 60里这三种结构已经很清楚了。如果不信,请谭先生查阅ALGOL 60的手册(编程语言的最有名的文献了,谭先生没有看过吗?枉为大师了!)。60这个数我们都认识,它好象也比66小一点嘛。
P24行4:…有两类循环结构。
谭先生又下结论了,而且又是错的。究竟有多少类“典型的”循环结构?本人也不敢下结论。这方面的经典(全世界计算机专业工作者认为的,可能谭先生不这样认为)文献是Knuth的一篇文章,请谭先生自己找找看看。当然,还是先要弄清楚是那一篇,这就算是给谭先生出的一个查文献题吧。
P25行-5:因此,人们都普遍认为最基本的是本节介绍的三种基本结构。
谭先生这样认为,难道人们就得这样认为吗?实际上,人们认为是三类基本结构(不是三种),其中的分支结构和循环结构又有许多典型情况。谭先生的“本节”和这本书一样不可作为凭据。
P25行-1:1973年美国学者…和…提出了一种新的流程图形式。……
可惜新世纪版之新早已是旧世纪之旧了。综观世界,还有什么比较新的程序设计基础教材还在用N-S图讨论程序设计吗?这已经成为“中国特色”“谭先生特色”的东西了。中国的计算机基础教育早就应该抛弃这些已经被世界抛弃的落后描述技术了。
P28行14-21:归纳起来可知,一个结构化的算法是由一些基本结构顺序组成的;…。如果一个算法不能分解为若干个基本结构,则它必然不是一个结构化的算法。
看来谭先生对于计算机科学领域中的术语“嵌套”并不了解,也不会用。仔细看看谭先生书上的几个算法,就可以发现它们大都不是基本结构的顺序组合,而是嵌套组合。又学了一招。
P32行-14:…,保证了程序的质量。
保证了?没有吧!结构化方法的创始人们也不敢这样说。采用结构化方法一点也不耽误我们大家(包括谭先生)写出低质量的程序,如谭书中到处都可以看到的那样。
P38行3.1
什么是数据结构,计算机界自有公论。将“结构体”说成是一种数据结构实在会让人笑掉大牙的。是不是应该建议谭先生先读一两本数据结构教科书,而后在考虑写什么东西。
P39行-6:其值可以改变的量称为变量。
真糟糕!程序里的变量居然被谭先生当作一种“量”。任何通晓计算机科学技术的人都不会同意这种说法。“变量”到底是什么?将谭先生的上述说法与随后的描述做个对比,就不难发现他自己都无法自圆其说。
P39行-4到-2:变量名实际上是一个符号地址,在对程序编译连接时由系统给每一个变量名分配一个内存地址。
这么简单的一句话里包含的错误太多了,谭先生请慎言,言多必失。首先,变量名根本不是什么符号地址(懂得什么叫符号地址吗?),它不过是在程序中代表变量的一种记号。一个变量也未必有地址(如寄存器变量),未必有唯一的地址(什么变量?谭先生知道吗?C语言里大量变量都是这样),这些都说明,将变量名看成符号地址是不行的,说不通的。其次,系统(什么系统?请说清楚。这里不想给出修改错误的提示了,算是给谭先生的一道语言作业题)是给变量分配地址,而不是给“变量名”分配地址。再者,每个变量的地址都是“编译连接”时分配的吗?或是对C语言了解肤浅,或者就是信口开河。要把这个论述改正确,请谭先生查阅有关材料,看C语言中有几种变量,地址是什么时候确定的(分配的)。
P40行-12:在C语言中,要求对所有用到的变量作强制定义,…
什么叫“强制定义”,好象没有这种说法嘛!我们都知道“强制”在C语言里有一个意思,就是不知道什么是“强制定义”。谭先生就简单说“先定义,后使用”还好一点,错误少一点,但这个说法也是有条件的(请谭先生想想,有什么条件?)。
P41图3.2(b)。
谭先生在这里将整数确定为两个字节,这本身就需要说明(免了吧,反正本书一贯不追求严谨)。更可笑的是这里还自作聪明地将它画成两个分离的字节。请问,知道什么叫byte order(字节序)吗,如果你画出各个字节,就必须解释这个问题。奉劝谭先生,不知道的东西还是别碰它,老老实实画出连续的16位,免得让别人知道你不懂。
P42整页。
到底C语言有几个整数类型?谭先生知道什么是“一个类型”吗?这里先说“整型变量的基本类型符”(什么叫基本类型符,不懂),又说“因此有以下三类整型变量”,又说“归纳起来,可以用以下6种整型变量”。谭先生的“种”和“类”是什么关系?和术语“类型”又是什么关系?这里的一片混乱反映出概念上的一锅糨糊。关于各种整数类型的表示范围的一般性说法和最后一段所说的C标准规定也是不和谐的,前面说得有鼻子有眼,后边又说C标准没规定,这算怎么回事呢!
P43行4-6:在微机上用long可以得到更大范围的整数,但同时会降低运算速度,因此除非万不得已,不要随便使用long类型。
用long什么整数也得不到,更不说得到什么范围的整数了。long的一个用途是用于定义变量,而被定义的变量(可能,注意,只是可能)能够存储更大的数。此外,这里的论断也早已过时了,谭先生还是生活在旧世纪,在旧世纪写新世纪教材,而且主观地为新世纪下结论,太武断了!当然,错误也就不可抵赖了(300万本,焚书也难尽)。
P44-45第4小节。
关于整数类型的值范围,C标准都只定义了原则,谭先生总自作主张地将它具体化,现在又想来定义计算溢出的意义了。首先,整型的表示范围未必如谭先生所说,如果这个不对乎,下面的讨论也就都是瞎掰了。其次,即使运算出现在整型值的边界上,其效果也未必如谭先生所述。语言标准说这时求出的值是undefined,谭先生却说是defined。看来ANSI C标准化组还需要谭先生垂帘听政,给他们纠正失误。不知新的C标准化组请谭先生做什么。
P47行-6:许多C编译系统将实型常量作为双精度来处理。
前面还有类似说法,这里一并讨论。首先,C语言根本就没有实型常量,只说浮点常量。另外就是想请谭先生告诉我们,那个C系统“不”把浮点常量看作双精度类型的。其实ANSI C标准已经规定了,浮点常量就是双精度类型的。这里谭先生怎么该肯定的又不肯定了呢?你查查标准呀!!
P49行-6:字符型变量用来存放字符常量。
荒唐!真是莫名其妙。到底是变量还是常量?如果一个变量里存放了一个常量,存放之后还能修改吗?要是能修改,那怎么叫常量呢?要是不能修改,那怎么叫变量呢?自己套住了吧。这里根本就没“常量”什么事!字符型变量里存的东西,大家都称它为“字符值”。
P50行5:…,实际上并不是把该字符本身放到内存单元中,而是将该字符的ASCII代码放到存储单元中。
可笑!可笑!难道还有某种语言、某种机器,能把字符“本身”放到存储单元里吗?那大概是谭先生自己用的“谭先生计算机”,反正大家是用不到了(还没有用到,或许将来这种计算机要取代冯-诺依曼计算机。谁敢说一定不会呢!)。还有,C标准也没说一定用美国人搞的ASCII代码呀,美国人都没有说,谭先生怎么就帮助他们说了呢?谭先生知道还有别的编码字符集吗?欧洲人要是听到这种说法,非和谭先生急了不可。
好不容易到了50页,感谢读者(可能也包括谭先生及其崇拜者)耐心地读了这么长时间。谢谢了。可惜的是,本人无法将1-50页的所有问题一一列出(否则篇幅还要大几倍,大家更觉得厌烦了),更无法将整本书中的问题一一列出分析(否则就是一本比原书厚得多得大书了),当然,本人也无义务为谭先生找出所有的问题。作为一个测验,还是请谭先生自己找吧,本文只算是抛砖引玉了。
谭先生的书能改好吗?本人实在深表怀疑。这样一本错误百出(不,错误千出)的书,由谭先生这样丰富学识和程序设计经验的人来修改,没有两三年时间,或许更长,是不要希望能改到令人满意程度的。再者说,这里列举的都是小问题,谭书本身的整体结构和教学目标都值得提出深深的疑问。如果能够改好,那早就是另一本书了。但是,能写出来吗?
或许,最值得深思的是,这样一本不合格(按照计算机科学技术及其教育的评价标准)的东西居然统治了中国计算机基础教育这么多年,这个问题真是中国计算机教育界和计算机实业界的悲哀啊!300万本,搞坏了多少投身于计算机领域学习的人,难道我们还希望这个数字再无穷无尽地增加下去吗?!如果问,为什么中国的计算机软件行业一直无法起飞,这些难道不也是一方面的问题吗?