2014年7月13日 星期日

Programming雜談

記得第一次接觸到程式,是高中的時候,那時候學的語言是BASIC,但並沒有教很多,所以印象不深。到了大一修計算機概論,才開始正式接觸C語言。之後,就一直在CC++這兩個程式語言之間打轉。除了寫自己的程式外,也看了不少別人寫的程式。經過這幾年的codingdebug經驗,我覺得要寫好程式,只看書是不夠的,還需要掌握一些要領。而且,大部分的書籍都像是說明書一樣,把程式語言的語法、功能介紹完,就結束了。說實在的,這樣的書不值得推薦,因為程式的語法直接上網查即可,又何必買書多花錢呢?
我覺得掌握要領,以及養成正確的習慣,才是寫好程式的不二法門。因此我希望藉著這篇文章,介紹一下我認為寫程式真正應該注意的項目。當然,我的經驗肯定比不上資工背景的人,也比不上真正的老手。但我還是希望這篇文章能幫助到未來有需要依賴程式來處理問題的人。如果有人認為我的論點錯誤,也請不吝賜教。
以下我以條列的方式,介紹撰寫程式所應掌握的事項,在文章中將以C/C++為主。
1.      變數命名方式:變數的命名,有助於讓自己記住該變數的用途。例如宣告表示長與寬的兩個變數時,你可以有以下兩種做法。
(1)   int a=3; //長度
int b=4; //寬度
(2)   int length=3;
int width=4;
雖然(1)的做法有額外註解,但是當你的程式寫到幾百行之後,每次一忘記a,b是什麼變數,你就得用滑鼠滾輪捲回去之前宣告的地方確認,相當麻煩。倒不如用(2)的寫法,除非你英文很爛,不然你不可能會忘記的。
還有一件事,每當變數一宣告完成時,我建議直接給予一個初始值,特別是宣告指標尤其需要這樣做(int *ptr=0),如此可以避免一些錯誤發生。
另外,曾經有人推薦過"匈牙利命名法",有興趣的人可以自己Google研究一下(我自己很少用,因為用不慣)
2.      排版:我想應該不少人是使用DEV-C++來寫程式,不過該軟體的排版功能做得很差,每次縮排的位置都不同,因此我也看過很多排版非常亂的程式,多半是用DEV-C++寫的。排版其實不難,難在很多人無法養成習慣(趕作業的時候通常沒有心情處理排版),但是良好的排版可以增加程式的可讀性,也可以讓看程式的人不會看到眼花都看不懂你在寫什麼。
其實除了DEV C++以外,很多編譯器都有支援排版的功能,例如Visual studio系列、或是Code::Blocks,或是用NotePad++撰寫,再以GCC編譯器於命令列編譯。
至於怎麼排版才是好的排版,我認為不同的人有不同的原則,不需要硬性規定,只要你自己能夠看得順眼,我相信其他人也可以看得懂。總之,該對齊的敘述要對齊,遇到迴圈或判斷式要縮排,這些應該就算是基本原則了。
3.      變數宣告的格式:要把程式寫好,我覺得程式的邏輯,整體的架構很重要。不過更重要的部分,是在於要怎麼根據你的問題來宣告變數,就像蓋房子一開始要先選對建材一樣。以下我舉個例:
宣告變數來表示空間中的三個坐標點,有三種方式。
(1)   double x1,y1,z1,x2,y2,z2,x3,y3,z3;
(2)   double point1[3],point2[3],point3[3];
(3)   struct point
{
double x,y,z;
};
point p1,p2,p3;
以上三種做法,誰好誰壞,我認為沒有一定的標準,但是撰寫大型程式時,我會推薦你用(2),(3)的做法,因為宣告變數的數目較少,也較有條理。
4.      將問題分類,逐步完成:很多人會害怕寫程式,常常是因為自己要處理的問題太複雜,所以嚇得連第一步都跨不出去。其實不管問題再困難,一定都可以將其分類,例如把問題拆成排序、產生亂數、計算目標式等,然後,將這些小問題分別處理,各個擊破,原本複雜的問題就會迎刃而解。
此外,我建議把每個分解後的小問題,分別寫成不同的function或是class,這樣可以更方便處理,當你其中某個環節出問題了,你就只需要針對有問題的function進行debug。不要只是把程式一股腦的寫在main function中,增加自己debug的負擔。
5.      每寫好一小段就進行compile並驗證:也許是害怕太早面對現實,有些人總是喜歡把程式碼全部寫完後,再一起進行compile,結果就是要在上百行的程式中找出自己的問題錯在哪裡。我相信每完成一小段程式,就compile一次,確認結果正確再繼續往後撰寫,絕對有效率得多,而且也會讓你更篤定地處理之後的程式碼。
6.      註解:一個架構完整、變數名稱明確、可讀性高的程式,即使未加註解也能讓人了解到大部分的作業程序。若要加上註解,則應寫在真正重要的地方,例如某些重要的敘述、函式、迴圈,或是在變數後面加註說明,但是不要寫廢話,例如:
int length=10; //長度
這叫翻譯,不叫做註解,如果真的要註解,就應該更清楚的說明是什麼東西的長度,這樣才有意義。
我覺得更好的做法,是在撰寫程式的同時,另外寫一份說明檔,描述你的程式作用為何,這樣也可以讓別的使用者能夠更快理解你在做什麼。
7.      不要遵守太過死板的原則:有些書本會建議大家不要使用goto語法,或是不要使用全域變數。書本上會這樣提醒當然是有道理的,畢竟像goto這樣的語法用多了確實會導致程式碼的混亂。但是總會有些情況,使用goto會讓你更容易解決問題,如果死守著不使用的原則,那只會把問題變複雜而已。我的建議是,語法要用在該用的地方,針對問題的本質,對症下藥,就好像遇到要用迴圈處理的問題時,你也不可能永遠都只用for迴圈來處理。

其實寫程式還是有很多有用的小技巧,例如指標的使用方式,還有記憶體的管理,但是我不想在這裡提及,因為那是更進階的內容。而且,如果連基本的要領都掌握不好,會再多的技巧,也是枉然。

沒有留言:

張貼留言