除非必要,我拒絕在Markdown裏使用HTMLios
審查基本信息
代碼審查(Code Investigation)
文件結構(File System)
頭文件和定義文件的名稱是否合理? |
× |
- |
無自定義頭文件 |
頭文件和定義文件的目錄結構是否合理? |
× |
- |
同上 |
版權和版本聲明是否完整? |
× |
- |
此代碼用於課程設計,沒有重視版本控制 |
頭文件是否使用了 ifndef /define /endif 預處理塊?(或頭文件保護符#pragma once ) |
√ |
- |
無自定義頭文件 |
頭文件中是否只存放「聲明」而不存放「定義」? |
× |
- |
同上 |
代碼風格(Code Style)
空行是否得體? |
× |
× |
子程序彼此之間無空行,而相對應的一些本不當分開的語句中間存在不適當的空行 |
長行拆分是否得體? |
× |
- |
運算符與運算元之間缺乏合理的空格 |
{ 和 } 是否各佔一行而且對齊於同一列? |
× |
√ |
絕大部分作到了,但有少數位置被多縮進了一次 |
一行代碼是否只作一件事?如只定義一個變量,只寫一條語句。 |
√ |
√ |
|
if 、for 、while 、do 等語句自佔一行,不論執行語句多少都要加 {} 。 |
√ |
× |
少數位置沒有放置{} |
在定義變量(或參數)時,是否將修飾符 * 和 & 緊靠變量名?註釋是否清晰而且必要? |
√ |
√ |
|
註釋是否有錯誤或者可能致使誤解? |
√ |
√ |
|
類結構的public, protected, private順序是否在全部的程序中保持一致? |
√ |
- |
程序中沒有定義類 |
命名規範(Naming Convention)
命名規則是否與所採用的操做系統或開發工具的風格保持一致? |
√ |
√ |
|
標識符是否直觀且能夠拼讀? |
× |
× |
有些標識符僅用一個字母 |
標識符的長度應當符合「min-length && max-information」原則? |
× |
√ |
僅限於知足上一條的內容 |
程序中是否出現相同的局部變量和所有變量? |
√ |
√ |
|
類名、函數名、變量和參數、常量的書寫格式是否遵循必定的規則? |
× |
√ |
|
靜態變量、全局變量、類的成員變量是否加前綴? |
× |
× |
|
表達式與基本語句 (Expressions & Statements)
若是代碼行中的運算符比較多,是否已經用括號清楚地肯定表達式的操做順序? |
√ |
× |
|
是否編寫太複雜或者多用途的複合表達式? |
× |
× |
|
是否將複合表達式與「真正的數學表達式」混淆? |
× |
× |
|
是否用隱含錯誤的方式寫if 語句? |
√ |
× |
|
case 語句的結尾是否忘了加break ? |
√ |
- |
無switch-case 語句 |
是否忘記寫switch 的default 分支? |
√ |
- |
同上 |
使用goto 語句時是否留下隱患? 例如跳過了某些對象的構造、變量的初始化、重要的計算等。 |
√ |
- |
沒使用goto |
常量(Constants)
是否使用含義直觀的常量來表示那些將在程序中屢次出現的數字或字符串? |
× |
√ |
僅定義了一個宏常量 |
在C++ 程序中,是否用const常量取代宏常量? |
× |
× |
|
若是某一常量與其它常量密切相關,是否在定義中包含了這種關係? |
√ |
- |
僅定義了一個宏常量 |
是否誤解了類中的const數據成員?由於const數據成員只在某個對象生存期內是常量,而對於整個類而言倒是可變的。 |
√ |
- |
沒有定義const 成員 |
函數(Functions)
參數的書寫是否完整?不要貪圖省事只寫參數的類型而省略參數名字。 |
× |
√ |
|
參數命名、順序是否合理? |
× |
√ |
|
參數的個數是否太多? |
× |
√ |
|
是否使用類型和數目不肯定的參數? |
× |
√ |
|
是否省略了函數返回值的類型? |
× |
× |
|
函數名字與返回值類型在語義上是否衝突? |
× |
× |
|
是否將正常值和錯誤標誌混在一塊兒返回?正常值應當用輸出參數得到,而錯誤標誌用return語句返回。 |
× |
√ |
這些函數沒有返回錯誤標誌,正常值直接返回得出 |
在函數體的「入口處」,是否用assert 對參數的有效性進行檢查? |
√ |
× |
沒有使用assert |
濫用了assert ? 例如混淆非法狀況與錯誤狀況,後者是必然存在的而且是必定要做出處理的。 |
× |
√ |
同上 |
return 語句是否返回指向「棧內存」的「指針」或者「引用」? |
√ |
× |
|
是否使用const提升函數的健壯性?const能夠強制保護函數的參數、返回值,甚至函數的定義體。 |
× |
× |
|
內存管理(Memory Management)
用malloc或new申請內存以後,是否當即檢查指針值是否爲NULL?(防止使用指針值爲NULL的內存) |
√ |
- |
沒有使用動態分配 |
是否忘記爲數組和動態內存賦初值?(防止將未被初始化的內存做爲右值使用) |
√ |
- |
同上 |
數組或指針的下標是否越界? |
√ |
× |
|
動態內存的申請與釋放是否配對?(防止內存泄漏) |
√ |
- |
沒有使用動態分配 |
是否有效地處理了「內存耗盡」問題? |
√ |
- |
同上 |
是否修改「指向常量的指針」的內容? |
√ |
- |
沒有使用指向常量的指針 |
是否出現野指針? |
√ |
× |
|
是否將malloc/free 和 new/delete 混淆使用? |
√ |
- |
沒有使用動態分配 |
malloc語句是否正確無誤?例如字節數是否正確?類型轉換是否正確? |
√ |
- |
同上 |
在建立與釋放動態對象數組時,new/delete的語句是否正確無誤? |
√ |
- |
同上 |
C++函數的高級特性 (Advanced Features)
重載函數是否有二義性? |
√ |
- |
沒有用到函數重載 |
是否混淆了成員函數的重載、覆蓋與隱藏? |
√ |
- |
沒有用到類 |
運算符的重載是否符合制定的編程規範? |
√ |
- |
沒有重載運算符 |
是否濫用內聯函數?例如函數體內的代碼比較長,函數體內出現循環。 |
× |
- |
沒有使用內聯函數 |
是否用內聯函數取代了宏代碼? |
√ |
- |
同上 |
類(Classes)
是否違背編程規範而讓C++ 編譯器自動爲類產生四個缺省的函數 |
√ |
- |
沒有使用類(或者說沒有以類的方式使用struct ) |
構造函數中是否遺漏了某些初始化工做? |
√ |
- |
同上 |
是否正確地使用構造函數的初始化表? |
√ |
- |
同上 |
析構函數中是否遺漏了某些清除工做? |
√ |
- |
同上 |
是否錯寫、錯用了拷貝構造函數和賦值函數? |
√ |
- |
同上 |
是否違背了繼承和組合的規則? |
√ |
- |
同上 |
其它常見問題(Miscellaneous)
變量的數據類型有錯誤嗎? |
√ |
× |
|
存在不一樣數據類型的賦值嗎? |
√ |
× |
|
存在不一樣數據類型的比較嗎? |
√ |
× |
|
變量的初始化或缺省值有錯誤嗎? |
√ |
× |
|
變量發生上溢或下溢嗎? |
√ |
× |
|
變量的精度夠嗎? |
√ |
√ |
|
因爲精度緣由致使比較無效嗎? |
√ |
× |
|
表達式中的優先級有誤嗎? |
√ |
× |
|
邏輯判斷結果顛倒嗎? |
√ |
× |
|
循環終止條件不正確嗎? |
√ |
× |
|
沒法正常終止(死循環)嗎? |
√ |
× |
|
存在偏差累積嗎? |
√ |
× |
|
忘記進行錯誤處理嗎? |
√ |
√ |
代碼中沒有對錯誤情形作處理 |
錯誤處理程序塊一直沒有機會被運行? |
√ |
- |
同上 |
錯誤處理程序塊自己就有問題嗎?如報告的錯誤與實際錯誤不一致,處理方式不正確等等 |
√ |
- |
同上 |
錯誤處理程序塊是「馬後炮」嗎?如在被它被調用以前軟件已經出錯。 |
√ |
- |
同上 |
對不存在的或者錯誤的文件進行操做嗎? |
√ |
× |
儘管測試文件實際上存在,但沒有考慮此文件不存在的風險 |
文件以不正確的方式打開嗎? |
√ |
× |
|
文件結束判斷不正確嗎? |
√ |
× |
|
沒有正確地關閉文件嗎? |
√ |
× |
|
評價(Assessment)
此代碼意圖使用文件輸入的方式進行無向圖的深度優先遍歷(DFS Traverse)git
優勢(Pros)
- + 將各子功能分模塊編寫,而沒有所有擠在
main
函數中
- + 合理地使用了縮進(儘管個別位置的縮進存在一些問題),代碼的可讀性良好
- + 在關鍵點處備以合理的註釋
缺點(Cons)
- - 命名不成規範,函數命名混雜着camelCase、PascalCase和snake_case,變量名中也混雜着ALLCAPS風格
- - 儘管沒有都擠到main函數裏,全部的功能所有都寫在了同一文件下,當功能模塊不少的時候會致使工做效率降低(絕大部分時間被鼠標滾輪吃掉了)
- - 使用了大量的全局變量,這對於程序的併發是有害的
- - 沒有考慮異常的情形,例如文件不存在、文件內容錯誤(如邊的數量輸出負數)等,而且缺少這些情形的提示和處理
- - 混合使用了
iostream
和cstdio
的標準及文件輸入輸出流
- - 缺少對內存資源的充分利用和有效管理,直接使用了一個100×100的
int
數組一了百了(約40KB),這同時致使了程序的不可擴展性(若是節點數遠超過100?)
- - 做爲C++程序直接使用了C語言的頭文件(如
stdio.h
)而沒有使用C風格頭文件(如cstdio
)
- - 功能函數和功能性的結構體沒有作到接口與實現相分離(頭文件)
- - 程序設計很大程度上體現了面向過程的思想,但C++提倡的是面向對象,所以
Undigraph
徹底能夠定義爲一個類,諸如addVertex
等操做能夠做爲其成員函數。
- - 行
for
語句圖省事沒有放置{}
- - 缺少封裝,這致使用戶可能無心識或有意識地使用到不應使用的中間函數
結論(Conclusion)
做爲一個課程設計而言,這是一個寫的還算不錯的程序,由於實現了所須要的功能,而且代碼算法清晰簡潔,也具有了一些結構化的思想,可是做爲一個項目而言,這個項目同時有不少潛在的不規範的地方,忽略了項目長遠的可能性,是有待改進的。算法