就入門級別而言,什麼樣的代碼才能叫做「優秀的代碼」?
如題。
題主是cs大一新生,現階段正在學C及C++。常在群里聽到比較熟絡的學長或者前輩調侃我們現在寫的代碼或者他們自己曾經寫的代碼「不堪入目」。 由此就很好奇。現階段的我們所面對的程序設計題,一般題解的結構和思路非常簡單,但該如何區分出這一類題目的題解代碼是優秀還是糟糕(在確保實現題目要求的前提下)?除卻縮進以及變數名這類代碼風格的問題,還有什麼地方可以體現一段代碼的高下?以及大家常說的「工程級別的代碼」應當是什麼樣的?如果可以的話希望可以舉例說明,謝謝!
isocpp/CppCoreGuidelines
1、能work
2、自己能看懂
3、別人能看懂
找個知名的開源項目看看不就知道了。比如 stl 的源碼。
工程上要求可讀性、可維護性、模塊化、文檔和注釋、代碼規範、經過靜態檢測
建議看看阿里開源的java 編程規範,還有《代碼大全》《編程匠藝》《clean code》啥的
入門工程師寫優秀的代碼這句話有衝突,就像一個剛畢業的人就可以拿到千萬融資。
我是說你聰明呢還是說你有天賦?不,或許應該稱一聲:大佬~
過一段時間自己能讀懂自己寫的啥
寫完半年後捏著鼻子去讀,還能很快搞清楚當時在幹嘛,就相當優秀了
縮進空格什麼的,你用vs寫就OK了。至於代碼風格,多寫寫吧。
最重要的,變數和函數名要用英文,不要用字母,不然鬼知道abc代表什麼。
函數在main函數之後定義,在main函數之前聲明,這樣不用糾結幾個函數之間到底誰先定義誰後定義,還保證一打開程序可以第一眼看到main函數
本人大一時也有和題主相似的疑惑
如今上了大二,經過各方面折騰,似乎有了點兒體會剛開始寫程序時,只想著怎麼實現功能,功能實現了,萬事大吉,或者另一方面,學語言的時候總是想盡量用一些高級語法,似乎這樣更能體現水平,等把一大堆亂七八糟的特性揉到一起,各種debug後還能運行,頓時感覺自己寫的代碼比別人高級多了,比如大家都在用數組的時候,你非要用malloc ,或者嫌malloc不夠吊,搞個vector,加個迭代器,這在學語言的時候是不錯的做法,但的確算不上好代碼後來,去搞機器人,團隊的要求很高,經過殘酷的訓練後,再寫代碼,(由於嵌入式的特殊性,資源有限)不會動不動就寫個int,空間能省則省,每寫一步都會大致估算程序的運行(嵌入式程序對時序很有要求,很多bug是由於時序的問題,所以必須保時間序的時間能大致計算,其實會有類似時間控制函數這種東西,實際開發還不能用循環,只能用選擇),這是針對單片機程序的要求當然還有更通用的,我終於知道為什麼C不會用來開發大型軟體了,就比如說僅僅寫個幾千行的單片機程序,如果你隨便設變數名,完全不寫注釋,各種extern全時間局變數滿天飛,你的程序絕對很難跑起來,就算跑起來穩定性也不高,就算有了穩定性,當要新加功能的時候,那你就懵逼了,這就是代碼可讀性的問題,變數名要直觀,不要簡單的abcd,且盡量在使用的時候定義變數,更清晰(主要對C)
所以代碼的好壞,1,可能看你所要實現的功能,如果不寫單片機,在PC上,誰還考慮內存對齊啊(當然內存分配還是要考慮的),就比如我現在刷ACM,嵌入式的邏輯對我一點用都沒有,2,還有很重要的就是你的代碼可讀性,不能自己寫完後都懶得看吧,3,還有一點,就是你的演算法,可能你現在寫的你認為很簡單的程序,但是運行的很慢,就比如說最簡單的多項式求值,剛開始可能是用兩層循環O(n^2)的演算法,但其實只要O(n)就可以了(秦九韶)
,由於演算法課是高年級開的,所以等你學了演算法以後你就明白了至於工程代碼,我也是剛開始做項目,但由於期末八門考試,項目還沒正式開始,我感覺學軟體的同學會比較清除這個確實不好衡量,每個人對有優秀代碼的定義不一樣。
至於工「程級別的代碼「,比如說商用的,有的人認為首先要不出錯,在不出錯的基礎上可讀性、可維護性好。有的人認為首先要有可讀性,因為你的代碼很可能會由別人閱讀、別人來維護。
至於在大學階段,「優秀的代碼「首先要邏輯清楚,還有就是你說的變數名和方法名的問題。
可讀性,題主可以這麼試試:代碼實現某個功能,然後交給你同學去讀,如果他看完你的代碼,知道你想要幹什麼,或者說知道你的代碼能實現什麼,可讀性就挺好的了。不寫注釋或者只寫關鍵注釋
可維護性:代碼實現某個功能,然後交給你同學去讀,看完你的代碼之後你說要增加某個功能,或者要改一下原來的功能,看看你同學能不能實現。不寫注釋或者只寫關鍵注釋
當然了,你找的這個同學水平不能太差,要不然沒意義。如果他的水平超出你很多的話,他倒是能給你提意見。
## 1.代碼風格
一個好的代碼風格會讓人更容易接受你的代碼,並且更容易理解.
## 2.小優化
代碼的核心部分有沒有多餘的操作?是不是可以剪掉?特判一些特殊情況?有些地方是不是可以換種寫法效率更高?一些能用位運算的底層優化?有些不需要調STL是不是可以考慮自己手寫?
## 3.命名
自定義的結構體,函數名,變數名,類,名字空間是不是起的正常的名字?(這個判斷方法就是你打開你之前2個月的代碼,看看能不能看懂.)
## 4.注釋
核心和關鍵的地方是否有頗為詳細的注釋?或者說起讓人能夠理解的注釋.一些奇奇怪怪的傳參的地方?一些莫名其妙return的地方?
## 5.優化你的版本
從你的1.0版出來以後,就應該嘗試去優化他,保證代碼風格不變的情況下,換成性能比原來更加優秀的數據結構,或者是換種思路去處理?然後再把這些版本**保留下來**
## 6.多讀多寫多看
去看別人的代碼,看看STL裡面的源碼,比如別人的紅黑樹是怎麼實現的?自己試著寫一寫?按照別人的代碼你是否能夠理解其核心和奧秘?
## 7.什麼是好的工業代碼
我不好下這個判斷,上次嘗試寫個入門項目的時候,有位julao跟我說我的風格太OI了……似乎……比較注重速度,而沒有競賽所謂的空間限制,並沒有見過太多的工業代碼……
總之能實現要求,時間複雜度低的代碼,就算比較難以讀懂,只要你寫的比較有結構和框架,沒有很多的冗雜的累贅計算,對於大一新生而言應該是很優秀的(^_^)
---
頹廢OIer嘗試寫項目時候被diss的感受……
以上以及瀉藥.---
我記得知乎是支持markdown的……以及想問一下題主對於入門級的定義……只是一個高中蒟蒻OIer……不知道大一新生應該是什麼水平……
糟糕的代碼:可讀,可維護性差。沒有層次關係,全局變數互相依賴。語法沒有正確掌握隨便亂用。不會令人產生想讀的慾望。
優秀的代碼:邏輯乾淨整潔,就像有一個思路清晰的人在和你交流,1.2.3.4.5,一點一點條理清晰。
cpp遵守google編程規範。標準庫使用方法查詢cppreference。google作為唯一的搜索引擎。編程時常打開幾份開源代碼,每當要寫一個邏輯時,先去看看其他人怎麼寫的,參照,模仿。不斷地提煉,總結。
工程級別的代碼和糟糕的代碼的差別不是三言兩語,或者舉個example就能解釋的清楚的。等你參加工作,維護幾個爛項目就能理解深刻了。建議去國內傳統行業工作幾個月體驗一下。= =我就是得到了深刻的教訓,一個函數2w行,見過嗎?可以從以下幾個角度來評判:
1. 正確性(Correctness) 系統滿足規格說明和用戶目標的程度,即在預定環境下能正確地完成預期功能的程度。 如軟體有沒有按照需求規格來完成,計算出的結果是否正確,計算結果是否精確。
2.健壯性/魯棒性(Robustness) 健壯性是指在異常情況下如硬體發生故障、輸入的數據無效或操作錯誤等軟體能夠正常運行的能 力。 健壯性有兩層含義:一是容錯能力,二是恢復能力。 容錯是指發生異常情況時系統不出錯誤的能力,對於應用於航空航天、武器、金融等領域的這類高風險 系統,容錯設計非常重要。 而恢復則是指軟體發生錯誤後(不論死活)重新運行時,能否恢復到沒有發生錯誤前的狀態的能力。 例如:因輸入數據不正確,引起系統異常,這是容錯能力不高引起的健壯性問題;操作系統死機了,重 啟後能夠正常使用,說明具有一定恢復能力,具有一定的健壯性;資料庫發生故障後,再次啟動時一般能 夠恢復到正常的狀態,恢復能力比較好。
3. 可靠性(Reliability) 軟體系統在一定的時間內無故障運行的能力。 可靠性是一個與時間相關的屬性,指的是在一定環境下,在一定的時間段內,程序不出現故障的概率, 因此是一個統計量,通常用平均無故障時間(MTTF, mean-time to fault)來衡量。 可靠性不同於正確性和健壯性,軟體可靠性問題通常是由於設計中沒有料到的異常和測試中沒有暴露的 代碼缺陷引起的。 例:由於某個地方資料庫連接沒有釋放,在長時間運行的時候,出現活動的資料庫連接數過多,造成系 健壯性/魯棒性(Robustness) 健壯性是指在異常情況下(如硬體發生故障、輸入的數據無效或操作錯誤等),軟體能夠正常運行的能統越來越慢,甚至系統停止服務。
4. 性能(Performance) 性能是指軟體及時提供相應服務的能力。 具體而言, 性能包括速度、 吞吐量和持續高速性三方面的要求: 速度往往通過平均響應時間來度量; 吞吐量通過單位時間處理的交易數來度量; 持續高速性是指保持高度處理速度的能力。 效率(Efficiency)指軟體對 CPU 處理能力和存儲能力這兩大類計算機資源的使用效率。效率和性能反 映了同一問題的「表」、「里」,性能為「表」,效率為「里」。 如系統運算一個報表,需要很長時間,這就是性能問題。
5. 安全性(Security) 指軟體同時兼顧向合法用戶提供服務,以及阻止非授權使用軟體及資源的能力。 安全性既屬於技術問題又屬於管理問題。一般地,如果黑客為非法入侵花費的代價(考慮時間、費用、 風險等多種因素)高於得到的好處,那麼這樣的系統就可以認為是安全的。 例:有人可以訪問非授權的資源,這就是安全性問題。
6. 易用性(Usability) 易用性是指用戶使用軟體的容易程度。 軟體的易用性要讓用戶來評價。 例:對於一般用戶而言,Windows 的易用性比 Linux 的高。
7. 可用性(Availability) 指的是產品對用戶來說有效、易學、高效、好記、少錯和令人滿意的程度,即用戶能否用軟體完成他的 任務,效率如何,主觀感受怎樣。 ISO 9241-11 國際標準對可用性作了如下定義:產品在特定使用環境下為特定用戶用於特定用途時所具 有的有效性(effectiveness)、效率(efficiency)和用戶主觀滿意度(satisfaction)。其中: 有效性:用戶完成特定任務和達到特定目標時所具有的正確和完整程度; 效率:用戶完成任務的正確和完整程度與所使用資源(如時間)之間的比率; 滿意度:用戶在使用產品過程中所感受到的主觀滿意和接受程度。
8. 互操作性(Interoperability) 指本軟體與其他系統交換數據和相互調用服務用以協同運作的難易程度。 例:利用 Web Service 增加軟體的互操作性。
9. 易理解性(Understandability) 理解和使用系統的難易程度。
10. 可擴展性(Extensibility)/靈活性(Flexibility)/適應性(Adaptability)/可伸縮性(Scalability) 反映軟體適應「變化」的能力。調整、修改或改進正在運行的軟體系統以適應新需求、變化了的需求 的難易程度。 例:如報銷系統原來不需要總經理審批,現在要改為總經理審批,可擴展性強的系統不需要作太多 調整;如用戶和數據量增加時,通過增加伺服器來提高系統性能,這樣可伸縮性比較強。
11. 可重用性(Resuability) 重用軟體或其中一部分的難易程度。
12. 可測試性(Testability) 對軟體測試以證明其滿足需求規約的難易程度。
13. 可維護性(Maintainability) 為修改 Bug、增加功能、提高質量而診斷並修改軟體的難易程度。
14. 可移植性(Portability) 軟體不經修改或稍加修改就可以運行於不同軟硬體環境的難易程度,主要體現為代碼的可移植性。
《C語言核心30天突破》
入門級別而言,做到2點:
1:堅持寫注釋。每個方法都要寫清楚是做什麼的。2:用單詞命名變數,使用統一的命名規則。很多小公司的代碼都不一定能做到以上兩條。寫完放下一段時間後自己能看得懂,別人也能看得懂
代碼結構比較好吧
初學者的代碼,往往還會出現明顯的內存泄漏,多餘的循環或分支,把一個很簡單的問題代碼寫的很複雜。所以不能光是想著完成功能就行,檢查一下有沒有改進的地方,反正一開始也就幾十行一百來行,最終要讓代碼結構明確簡潔。
謝邀,依據源碼,向源碼看齊
有很多吧,不過這些要根據實際情況了。大一注意代碼風格就行了。一定要較真的話,嘗試把代碼行數和數量減少,把多餘的代碼去掉,冗餘的合併。不過,這個只是一種鍛煉。實際上大量縮減代碼行數會導致調試困難和可讀性差。試試看,在這之間找找平衡吧。不過,做這些還不如多去旁聽別的專業的課程。。。
推薦閱讀:
※如何真的零基礎入門Python?(前提篇)
※應該如何理解 Erlang 的「任其崩潰」思想?
※Android - Spring Animation