我看一些ACM訓練人員的代碼風格的一些總結,這對以後的職業發展好嗎?
最近看一些演算法題目,看了一些ACMer的代碼,就大部分來說,很多人的風格有如下特點:
1. 喜歡使用棧的全局變數,比如題目說輸入數據的個數不會超過1000,代碼直接寫一個全局的int a[1010]類似的。2. 很多喜歡把數據輸入和數據處理放在一個函數,甚至就只有一個main函數。3. 如果使用了堆內存,不喜歡釋放,C語言的不喜歡free,C++的不喜歡delete,因為浪費時間,影響程序排名。4. 變數名起的都很短,喜歡用一些無意義的符號,因為這樣代碼長度可以比較短。5. 喜歡數組下標從1開始計數,比如有11個數據,因為使用了int a[1010]類似的棧數組,經常從a[1]開始計數, a[11]代表最後一個數據。
6. 對cin無愛,就算是C++,因為scanf效率高一些,喜歡在流式操作的C++裡面大量使用scanf。7. 一般不會對輸入做異常檢查,也不會對某些參數做斷言判斷。這些習慣對實際項目中有益嗎?通常我自己做項目的時候發現代碼風格是很重要的問題,主要表現在以下幾點:1. 變數命名很重要,通常我寫的代碼有可能會讓同實驗室課題組的童鞋review的,一旦使用迷惑的變數名會讓代碼變得難以理解,況且注釋寫的不太多,一旦出現bug,寫代碼的人恰好不在或者有其他事情,別人修復bug會變得極為困難。2. 把處理封裝起來,可以使得代碼在處理相似功能的時候進行復用,減少沒有必要的冗餘的代碼編寫,所以把處理過程封裝成函數,或者封裝成一個class會經常遇到。3. 內存泄露是無法忍受的,一般項目測試不僅要對能想到的測試用例進行測試,而且還要做壓力測試,使用很大的數據輸入,或者連續讓程序跑幾十個小時看會不會出問題。4. 一般都是使用下標從0開始的數組。5. 有些項目老闆的需要老是變,一會要這個功能,一會要添加那個鳥功能,所以代碼的可維護性和可擴充新也很重要。
這樣的話,項目一坐下來,發現大部分的問題和瓶頸都在初期的一些設計上,最開始我的變成的風格是很亂的,經過項目的一些小鍛煉,養成了一些習慣,所以看有些ACMer的代碼會感覺很難受。在Online Judge系統上面做一些題目之後,發現就算使用O(n)演算法,我寫的代碼的運行時間還是比題目AC列表裡面的一些童鞋的代碼運行時間稍微長一些。
其實我覺得上面說的問題都不是問題。因為現在是在寫ACM代碼,寫代碼的目的是為了能儘可能快速的過題,因為要快速的過題,所以要儘可能的方便,能少敲一點就有可能快一點,就有可能罰時比別人少。比如這種非常噁心的代碼方式:
#define rep(i, n) for (int i = 0; i &< (n); i++)
#define repu(i, a, b) for (int i = (a); i &< (b); i++)
#define repf(i, a, b) for (int i = (a); i &<= (b); i++)
#define repd(i, a, b) for (int i = (a); i &>= (b); i--)
但這些其實對於將來不會有多大的影響。真正在工程開發中,公司自然會規定每個員工必須遵循的代碼風格,以便於全局統一,便於閱讀。
ACM偏演算法,事實上更偏向於數學了,和軟體開發絕對是兩回事。
ACM比賽的核心是演算法,程序只是載體,一般程序不算太長,所以可維護性要給性能、編寫速度讓步。
而在實際的編程項目里,關鍵是要讓代碼具有可讀性和可維護性,初期的架構設計顯得非常重要,而後期的編碼就沒什麼難度了。就樓主列的幾項ACM風格,確實全部不適合在軟體開發中使用。
你沒領悟最關鍵的一點。
在做不同的事情的時候,應該選擇不同的方案。acm對項目的幫助是邏輯思考和調試程序的能力。變數怎麼命名,用不用全局變數真心和習慣關係不大,而是看你在做什麼事。你要自己做作業的時候,寫個程序分解個質因數也要考慮可擴展可維護?順便在acm中,使用一些手段使你專註於計算過程,而不是別的事是有好處的,畢竟把核心寫對是要很多精力的,別的事情都是干擾
另外說一點下標從1開始也有不少好處:比如 a[1] ~ a[n] 是你的數,那麼你要求s[1] ~ s[n]是前n項的和就可以寫s[n] = s[n-1] + a[n],利用s[0] = 0這樣的特性,這在動態規劃中經常要用的。這都不是大問題,甚至幾乎不是任何問題。做項目之前肯定是要統一編碼規範的,你說的那些有acmer為了拿first blood一般不會太顧及編碼規範,可以說acm講究速度至上。可以說任何一個acmer轉做工程之後編碼規範什麼的幾乎看看手冊就改過來了,不需要任何難度。至於你說動態分配不釋放的問題只要多注意就好,畢竟c++內存管理是很頭疼的事情,這個需要多實踐。
拿競賽和工程比,沒啥可比性。側重點不同。
「過早的優化是萬惡之源」,更何況是優化程序可讀性,回收內存這種對AC沒用的東西。
用的時候再考慮就好了,你說的那些需要考慮的工程細節甚至不如水題難度,不足為慮。商業代碼是給人看的,ACM代碼是給機器看的。面向的對象不同,自然也沒有可比性。
學術派和工程派永遠沒法統一。寫商業程序請看林銳的《高質量編程》,acm那些東西寫出來同事絕壁罵死你但是acm也會給你帶來一些思維、演算法等方面的提升也就是說acm會增強你的內功,但到了商業場合,收起acm招架,因為你要和一群人配合,不能隊友在擺銅人陣,自己在跳廣場舞吧
推薦閱讀:
※為什麼 C 語言的輸入輸出函數比 C++ 的輸入輸出流要快?
※有沒有比較好的自學IT的網站?適用於不管是初學者還是其他段位的程序猿的網站?
※如何評價2016年藍橋杯決賽?
※C++ 是否適合做 GUI?