怎样写C代码——《狂人C》习题解答1——余响
相关随笔:怎样写C代码——《狂人C》习题解答1http://www.cnblogs.com/KBTiller/archive/2011/03/14/1983964.html#
"怎样写C代码——《狂人C》习题解答1"发表前,心里一直有些忐忑。因为里面没有高深莫测的道理,没有眼花缭乱的技巧,也不解决复杂艰苦的难题,只是一些平平淡淡的如白开水一样的常识。虽然离开白开水人是根本活不下去的,但我还是担心这些在博客园这种地方别人都已经很清楚了,没有必要说。
然而出乎我的预料的是,从该文评论中可以发现,我这篇随笔绝对不是无的放矢,而是很有必要。zzd网友的评论实在太给力了,我真该说声谢谢。
我在文中的观点之一是,要认真审题,真正弄清楚问题是什么,明确程序的功能。
zdd网友回应:
#5楼2011-03-14 21:27 | zdd
抛开这段代码存在的许多其他问题不谈,问题中的“能组成多少个互不相同且无重复数字的三位数”显然被编程者所忽视了。这样的代码没有什么价值。 敢问这话是什么意思?抛开这段代码的性能不谈,我看不出任何不符合题意的地方,在指导别人认真审题的时候,最好自己也认真一点。
他说他“看不出任何不符合题意的地方”,明显地忽略了“能组成多少个”这个要求,更没有看到代码根本就没有解答这个问题。不能答非所问是小学老师就早就教导过我们的。
zzd网友告诉我“在指导别人认真审题的时候,最好自己也认真一点”我非常感谢。但我不知道他自己认真审题没有,为什么对“能组成多少个”这个要求视而不见。所以很愿意与他共勉。
#8楼2011-03-14 21:57 | zdd
用这道题来讲程序的结构,实在有点乏力,因为这题太简单,谈不上什么结构,直接写就行了,你那样一步一步填反而有些麻烦了。再者,在主函数中直接写代码也不是个好习惯,应该分离出来单独做成函数更好一些,还有你的程序写得也不太好,没有任何扩展性。本人不才,写一个献丑,打印任意层数的三角形
01 #include <stdio.h>
02
03 void PrintTriangle(int level)
04 {
05 for (int i = 1; i <= level; ++i)
06 {
07 for (int j = 0; j < level - i; ++j)
08 printf("%c", ' ') ;
09
10 printf("%c", '/');
11
12 for (int k = 1; k <= i * 2 - 2; ++k)
13 printf ("%c", '_') ;
14
15 printf("%c\n", '\\') ;
16 }
17 }
18
19 int main(void)
20 {
21 PrintTriangle(10) ;
22
23 getchar() ;
24 return 0 ;
25 }
zdd网友认为“用这道题来讲程序的结构,实在有点乏力”。
其实我哪里是在讲程序的结构呢?我根本没涉及这个问题。我除了说要认真审题,养成写注释、先把握总体再关注细节以及随时测试这些良好的编程习惯之外,另一个主要观点是“程序员不但应当完成正确的代码,而且更应当用正确地方式完成代码”。我实在搞不懂zzd网友为什么扯到了“程序的结构”上。这是哪儿跟哪儿啊,完全是风马牛不相及的事情么?
更为严重的是,zzd的这段代码根本不符合题目要求。题目要求的是输出
/\
/ \
/ \
/ \
/________\
但zzd的代码的输出竟然是
/\
/__\
/____\
/______\
/________\
/__________\
/____________\
/______________\
/________________\
/__________________\
大概他认为他有权力任意曲解用户的需求,或者代表用户自说自话地确定用户的需求。或者就是像我所警示初学者的那样——根本没注意审题,完全不知道程序应该具有什么样的功能。
“打印任意层数的三角形”,基本上就属于外行话了,在计算机解决的问题中,是没有“任意”这个概念的。计算机所能解决的问题都是在“有限”限定的范围,否则也就不会有资源枯竭这回事情了。所谓“任意”是一种没有完全摆脱数学思维的想当然。
说到程序结构,我倒是认为那种把函数定义写在前面以省略函数声明的贪小便宜的风格其实非常丑陋。理由我在《狂人C》这本书里也提过。
“直接写就行了,你那样一步一步填反而有些麻烦了”,我只能说他完全没能理解我的观点:“程序员不但应当完成正确的代码,而且更应当用正确地方式完成代码”。但他同样也没有提出恰当的反对理由。只能说他并不懂得良好的“工序”的意义,编程习惯的重要性。更不懂得如何设计“工序”以及如何培养习惯。
此外他的代码中的“printf ("%c", '/') ;”其实有更简单的写法:"putchar('/');"。我不清楚他为什么舍近求远地用了那么一种实现(再怎么不济也应该写成“printf ("/") ;”啊,至于“printf("%c\n", '\\') ; ” 简直就没法看)。无论从代码的简洁还是程序的效率方面考虑都不应该像他那么写。
他的代码中出现了两句几乎一模一样的for语句。代码中出现重复的语句,稍微有点编程修养的程序员是根本写不出手的。“应该分离出来单独做成函数更好一些”这句话的真谛,不知道他自己真正理解没有。
此外他认为“system()函数最终是系统调用?系统调用的开销远大于库函数调用。这里应该用getchar()才是上策!”。我不清楚他是否注意到了使用 getchar()带来的那个毫无意义的、丑陋的字符回显。完成程序要求以外的功能是一种罪过,这是软件测试的基本常识。另外,system("PAUSE"); 并非我写的,那是DEV C++为方便编程者观察运行结果自动生成的。
“在主函数中直接写代码也不是个好习惯”,当然不是。但我所解答的题目是《狂人C》第一章的题目,《狂人C》预设读者毫无编程知识,难道要求他们一开始就使用函数?zzd网友自己当初的第一个C程序是通过自己定义函数完成的吗?