◇◇新语丝(www.xys.org)(xys3.dxiong.com)(www.xysforum.org)(xys2.dropin.org)◇◇ 对“注意版本”驳张云楼《谭浩强大师的世界纪录》的一点看法 作者:g3like 看了作者“注意版本”驳张云楼《谭浩强大师的世界纪录》的文章,感觉有 一点,该作者似乎并没有完全理解张云楼要表达的真实意见,他把所有的问题都 归结为版本问题,却没有举出任何一例不会出问题的版本,似乎也缺少了一点实 证精神。 至少对于张云楼的例1,注意版本理解肯定是有误的,因为我在一开始没有 看到谭书原例题时,我也有着与他几乎相同的错误理解,即:张云楼肯定错了, 但实际上并非如此,这个例子根本不可能涉及到版本问题。 为此我查找了谭浩强《C程序设计》(第三版)的原题。 《C程序设计》例3.3,原题是这样的: #include void main() { int a,b; a=32767; b=a+1; printf("%d,%d\n",a,b); } 运行结果为:32767,-32768 这个例题的运行结果是完全没有问题的,问题出在后面一段讲解上,讲解的 主要内容是解释为什么第二个输出结果是-32768,其实这也没什么问题,关键是 段落的最后加上了一句:“从这里可以看到:C语言的用法比较灵活,往往出现 副作用,而系统又不给出‘出错信息’,要靠程序员的细心和经验来保证结果的 正确。将变量b改成long型就可得到预期结果32768.” 单单把这句话拎出来其实也看不出什么错误来,但是和上面的例题放在一起 是肯定要出问题的,这种错误一般情况下教计算机的老师很难发现,张云楼也指 出,这种错误是学生提出来的,为什么呢?因为实际上机运行一下就会马上发现, 仅仅把变量b的类型改为long型,输出结果仍然不可能达到预期的效果,因为这 个程序中还用到了printf()这样一个输出函数,想把变量b作为long型输出, 必须把输出格式也改成long型才可以,也就是最后一条语句要改成 printf("%d,%ld\n",a,b);作为教C语言的老师,出于本能反应,也会在输出格式 上加以修改的,但作为学生,单纯的照着例题敲程序,一般情况下一个字符都不 敢动,到了这里自然会出现问题。 更为严重的是,讲解printf()函数的章节还在这个例题之后,学生学到此 时基本上对printf()函数的用法一无所知。如果没有老师的指点,学生自学到 此处,对教材作者表示不满几乎是一定的。 所以,张云楼说这里是谭浩强的错误,一点没说错。 对于例2,注意版本说,那个表达式,在有些版本的编译器确实是支持的, 这点本来就是毫无疑问的,可是张云楼也并没有说那个表达式有错啊?他只是认 为“赋值表达式能够作为左值”的说法太可笑了,关键是这种提法欠妥,不像是 搞编程的人说出来的话。 不过,对于“(a=3*5)=4*3”这种表达式的看法,绝对无条件支持注意版本, 这本身就是一种吃饱了撑的用法,我们可以看懂这种用法,但是编程时绝对不要 这样用。 对于例3,张云楼说,ANSI C 标准上提到的:“The controlling expression of a switch statement shall have integer type.”,本身并无 问题,至少我个人不清楚还有没有其他版本的ANSI C 标准上有其他说法,这个 说法本身也没有什么问题。 注意版本说“非整数的类型很可能那个版本的标准是为了照顾某些旧软 件。”,个人觉得不太可能。如果switch语句后面的表达式在某些版本可以使用 双精度型甚至是字符串型、指针类型、结构体类型,那后面的case该怎么写啊? 就算某些版本有其特殊性,除非举出例子,否则我仍然很难相信会有一种版本的 switch语句支持所有的数据类型。 而谭浩强的原文则是:“ANSI 标准允许switch后面的“表达式”为任何类 型”。这种说法肯定是错误的,虽然在swtich()的括号里确实可以放字符型的 表达式,但是字符型的表达式从本质上说也是属于整型的。要是仅仅以表达式类 型为整型和字符型可以成立,就推出switch后面的“表达式”可以为任何类型的 结论,无疑是不负责任的。 个人认为,除了例1例3的错误是板上钉钉的事实之外,例2如果一定要说谭 浩强错误,也稍有点牵强,但是这个例子不利于教学则是毫无疑问的事情。 (XYS20090314) ◇◇新语丝(www.xys.org)(xys3.dxiong.com)(www.xysforum.org)(xys2.dropin.org)◇◇