※ 引述《acmonkey (UCL Champion)》之銘言:
: 我們唸通訊的人 C/C++真的摸的不多(做研究大部分都在用Matlab)
: 資料結構啦 作業系統啦 Algo啦 軟體工程啦
: 這些對寫程式來說很重要的知識 我們也都不太熟 or 根本沒摸過
: 小弟也曾把自己寫的C/C++給在軟體業作資安的朋友看過
: 他給我的評語:
: "看的出來不是初學 但是程式整體的架構不太好 要維護不是很容易
: 可讀性不夠好 但架構是真的很重要 你寫的東西離真正出去做事還有一點距離"
老實說,雖然很想不負責任地說:「寫出好程式是靠天份的」
不過剛好前陣子有個令人吐血的極佳範例,不吐不快,就提供出來給大家參考。
【程式簡介】
該程式主要在做多個二維資料之間的運算(以下簡稱window),
例如:window1需要和window2做AND運算
window1 window2 Result
1 1 0 0 1 1 AND後 0 1 0
1 1 0 0 1 1 => 0 1 0
1 1 0 0 1 1 0 1 0
註:此範例已大量簡化,單純舉例用,非實際較複雜的資料
【思考點1】
既然是window-based(二維)的資料,理應先創造出儲存每個window的資料格式
那應該每個window用一個陣列來存,然後彼此用linked list來串接?
還是直接用一個三維陣列來存?
想寫出好程式之前,應該有能力去判斷使用哪種資料結構,最能符合需求
上述二種我都可以接受,但是原作者只用一個二維來存所有window,
這樣的缺點是每次要取特定window的值,都需要先計算其相對位置,才能取得資料
其實這樣都還是可以接受,只要特別寫一個取window用的函數即可。
不過吐血點在於,他每次要取值,都要重新根據window的寬度,
去計算出這次window運算的資料位置,也就是說類似的for迴圈充滿著整個程式
每個for迴圈裡面的終止條件寫的都是A*B*C ...
【思考點2】
既然是window-based的資料,若有相關運算,如filter、AND、OR之類的,
應該也要有相關的函數來處理,只需傳入二個window的資料,
即可產出運算後的window資料。
不過原作者卻是用for迴圈來做出每一個運算,當然for裡面的起始、終止條件,
也同樣是A*B*C...
這樣的缺點,就是你很難看出這一"團"for迴圈究竟在幹嘛,
無論是找bug或是事後維護,甚至以後接你程式的人,都會是一種煎熬
【思考點3】
由於程式要處理的資料,有很多種類型,雖然同樣是window-based,
但可能每次要處理的運算不同,Type1可能要用filter的方式處理,Type2可能只是AND
在整個執行的流程上,就勢必要做切割,將整個步驟切成一節一節的,
方便抽換不同需求要做的動作。
原作者的作法,當然就是每種Type走自己的路,所以類似的運算,一團又一團的for迴圈
就是一而再,再而三地複製貼上
【結論】
好的設式是需要設計的,用怎樣的資料結構來儲存,最方便使用、最彈性,或最有效率。
好的程式是有模組化概念的,同樣的函數可一再利用,雖然複製貼上很簡單,
但是這種程式不易讀,不易讀就代表容易出錯、事後難維護。
最初設計程式的格局,決定你程式該怎麼寫。
如果你寫的程式,只要跑2個window就結束了,那我何必搞一堆函數來做?
最簡單的for迴圈就已足夠,大格局做小規模的事,是殺雞焉用牛刀。
可是若程式需要跑許多的迴圈,用在許多不同類型的資料上,此時還用for迴圈做,
就是用小格局去做大規模的事,這樣是不可能做得好的。
個人認為寫程式,是一種藝術,嘗試去欣賞別人程式,然後學起來,自然就會進步。
我也不是資工背景,雖然缺少很多課程的幫助,但那應該不是寫好程式的必要條件。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.32.198.108