相關隨筆:怎樣寫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程式是通過自己定義函數完成的嗎?