之前已经学习过谭师傅的第五章。现在来学习每六章,《循环控制》。
这一章一开头就把我雷到了:谭师 傅讲的第一种循环,居然是用goto语句构成的循环。虽然谭师傅还是在两三处地方讲到,“滥用goto语句将使程序…可读性差”,“一般不采用 goto语句”,等等。不过,在谭师傅看来,为了“大大提高效率”,用goto语句也不妨。不过对于初学者,我有一句忠告:在任何时候都不要用goto, 因为任何用goto能实现的程序,不用goto也都能实现,而且程序更可读,更容易维护。
谭师傅说,goto语句“一般有两种用途”,一 种是和 if 一起构成循环,一种是从多重循环体中跳到循环体外。对此我要说:请拿红笔在上面打一个大大的叉,并把它做为最坏的编程习惯,时刻提醒自己不要把程序写成那样。第一个所谓用途,完全和 while 循环等价,又不如 while 简洁易读。第二种用途就是维护代码的程序员的恶梦。你花一分钟写了一个goto,做维护的人可能要花几个钟头才能明白这段代码是要做什么。要知道,这个做维护的人很有可能是你自己!
接下来谭师傅开始讲 while 循环。谭师傅说,当 while 后的表达式“为非0值时”,“执行 while 语句中的内嵌语句”。谭师傅又开始发明术语了。什么叫做“内嵌语句”?另外,在前面(13)里已经讲过了,严格来说,当把指针型数据作为逻辑表达式时,非 NULL时为真,但NULL的数值不一定为0。只不过这点一般程序员可以不用操心,因为编译器会自动做转换,如果 p 是指针的话,把 p == 0 语句变成 p == NULL。
谭师傅的例6.2中把主函数声明成了void(即“void main() {…}”)。这在C89里面还可以,在C99里不算错,但不提倡。使用gcc –std=c99来编译的话会给出警告。最好还是能写成 int main() {…} 的形式。
谭师傅在讲 do-while 循环时,在例6.3中又出现了奇怪的缩进。
谭 师傅又说,“对同一个问题可以用while语句处理,也可以用do…while语句处理”,但同时又说,在某些情况下,“两种循环的结果是不同的”。 我如果是初学者,一定会被谭师傅绕进去。其实说起来就是简单的一句话:do-while里的循环体至少会被执行一次,而while则不一定。谭师傅硬是花 了一个小节外加三个程序例来说明这个问题。
后面谭师傅又讲了 for 循环。我这里看不到全的,不过我相信对于这么一个最常用的循环语句谭师傅还是有能力讲清楚的。不过我对于谭师傅的“ for 语句功能最强”这个观点还是怀有疑虑。由于几种循环语句可以互相转化(包括用goto写的循环)在“功能”上似乎应该没有什么区别。区别只在于可读性。什 么样的语句写出来最好懂就应该用什么样的语句。
再往后,谭师傅又讲了break和continue。第6.8.1节中的例子里有一个 float pi = 3.14159,然后用 pi 来算圆的面积。要知道 float 只保证有6位有效数字,这个 pi 太过于精确了些,用个 3.14 就够了。如果需要更高的精度,最好用 double。例6.5中又出现了奇怪的缩进。
然后谭师傅又讲了几个例子。例6.6是计 算圆周率的近似值,里面有这样一句:while(fabs(t)>1e-6),其中变量 t 的类型是 float。ANSI C规定 float 能够表达的最小数为 1e-5,所以这个 while 可能在 t 值降到 1e-5 以下时就停下来。同样,最后输出时只有前六位是可靠的,因为ANSI C的 float 只保证6位有效数字。
例6.7是计算 Fibonacci数列的前40个数。这个例子很奇怪,因为算法实际上和开始给的公式有区别。开始的递归公式是由前两个数推出第三个数,实际的算法则是一 次由两个数推到下两个数。虽然结果是一样的,例子本身却因此变得不容易理解,而且不适用于计算奇数个数的Fibonacci数列。
例6.10里又出现了类型不匹配。getchar返回的是一个int,字符常量也是int,而谭师傅总是用char,有点望文生义的意思。
第6章就学习到这里,下次再继续学。
2009年4月24日 at 4:43 pm
接下去,别停,谢谢!
2009年6月1日 at 4:13 pm
1,goto没那么废。如果用goto能让代码更清晰,则应该毫不犹豫的用。goto跳出多重循环也的确是一个例子。不用goto,则必须在每层循环加上一个标志位的判断然后break,这样不如goto清晰和直接,尤其是如果这个goto是跳转到函数即将结束处(函数随后释放资源并退出)。
2,for的确比while更强。即便是最简单的例子while(true)和for(;;)。后者也显得更清晰。而且前者还有一个含糊的缺点。它用了一个不变的条件判断。许多代码分析工具会报一个警告。并把它认同与if(a=1)这样的语句。
3,谭老师的书是很废,但大学中教计算机语言的老师就没有不废的。想想也正常,中国大学有丰富项目经验的人很少,即便有,这样的人也不会去教学生最基本的语言。所以我觉得你对谭老师过于刻薄了。