精華區beta Tech_Job 關於我們 聯絡資訊
※ 引述《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