◇◇新语丝(www.xys.org)(xys3.dxiong.com)(www.xysforum.org)(xys2.dropin.org)◇◇ 也说谭浩强大师的低级错误 作者:Yush 张云楼同学说: 《C程序设计》例3.3说在TurboC上32767+1没有得到32768,得到的是-32768。然 后作者说“将变量b改成long型就可以得到预期结果32768了”,敢问谭教授上机 试过没有,我试过了,不行。 “注意版本”同学驳斥说: 例1作者试过了TC几个版本,编译模式估计是缺省的,改过吗?感觉现在用TC很 少了吧,近20年前流行的。我相信教材作者至少在某个版本上试验过,很可能后 来版本更新了引起问题。版本兼容性问题在计算机界普遍存在。 谭大师在《C程序设计》(2005年第三版第44页)说: 在Turbo C和Turbo C++中,一个int型的变量的最大允许值为32767,如果再加1, 会出现什么情况? 例3.3 整型数据的溢出 #include main() { int a,b; a=32767; b=a+1; printf(”%d, %d\n”, a, b); } 运行结果为: 32767, -32768 ……将变量b改成long型就可得到预期结果32768。 经Turbo C 2.01实验(其他16位编译系统应有同样结果),证明谭大师所说的 “将变量b改成long型就可得到预期结果32768”错误。 将变量b改成long型,输出仍为-32768。原因是printf函数按%d两字节int型整数 格式,取传递过来的b的4字节中的低两字节(二进制1000000000000000,对应 -32768)输出。 再将printf中与b对应的格式符%d改为%ld,输出仍为-32768。原因是b=a+1一句 中,a+1运算按编译器默认的两字节整数进行,结果为二进制1000000000000000 (对应-32768);赋值给b时,b的高两字节将进行符号位扩展(而非填0),b的 值为二进制 11111111111111111000000000000000(对应4字节long型整数 -32768)。因此,还必须将a+1中的a或1强制转换或设置为long型,才能得到预 期结果32768。 以下是修改后的程序(三处修改缺一不可): #include main() { int a; long b; a=32767; b=(long)a+1; /* or b=a+1L */ printf(”%d, %ld\n”, a, b); } 谭大师所谓“将变量b改成long型就可得到预期结果32768”不可能在任何一个16 位C编译系统上成功(而在32位系统上,根本不会出现例3.3的溢出问题),因此, 谭大师显然如张云楼同学所猜测没有上机试过;也不存在“注意版本”同学所谓 的“版本更新了引起问题”。 注:可在http://books.google.com中搜索“整型数据的溢出”,即可一瞻谭大 师大作风采(封面上赫然印着“发行700万册记录”)。   补记:   在网上找了个谭浩强著《C程序设计》第二版扫描版(未知出版年份版次), 错误与google books上的第三版(2005年清华大学出版社)相同。又据无敌法王 提供的第二版(2004年9月第53次印刷),相应表述已改正为:“将变量a和b改 成long型,并按%ld格式输出,就可得到预期的结果32768”。据此推测,此书第 三版是在错误的第二版老版本上“升级”的,在这方面,确如“注意版本”同学 所说,“版本更新了引起问题”。 (XYS20090313) ◇◇新语丝(www.xys.org)(xys3.dxiong.com)(www.xysforum.org)(xys2.dropin.org)◇◇