软件工程——结对编程第一次作业
目錄
- 1. 代碼地址
- 2. C/C++代碼審查表
- 3. 代碼評價
1. 代碼地址
這個項目由王宗波編寫,并且已提交至Coding.net系統中,該項目實現的是霍夫曼編碼(霍夫曼樹)的算法,使用C/C++語言開發。
2. C/C++代碼審查表
參照這篇CSDN博文中的內容設計了如下的C/C++代碼審查表,并根據此項目的代碼進行審查和填寫。
| 項目名稱 | 霍夫曼編碼 | |||
| 審查人 | 張浩宇 | 審查日期 | 2019/4/21 | |
| 代碼名稱 | 結對作業1.cpp | 代碼作者 | 王宗波 | |
| 文件結構 | ||||
| 序號 | 審查項目 | 重要性 | 結論 | 備注 |
| 1 | 頭文件和定義文件的名稱是否合理? | √ | ||
| 2 | 頭文件和定義文件的目錄結構是否合理? | √ | ||
| 3 | 版權和版本聲明是否完整? | 不適用 | 作為作業,不需要版權信息 | |
| 4 | 頭文件是否使用了 ifndef/define/endif 預處理塊? | 重要 | 不適用 | 未使用自訂的頭文件 |
| 5 | 頭文件中是否只存放“聲明”而不存放“定義”? | 不適用 | 未使用自訂的頭文件 | |
| 程序版式 | ||||
| 序號 | 審查項目 | 重要性 | 結論 | 備注 |
| 6 | 代碼段間的空行是否得體? | × | 代碼前預處理部分和正式代碼間未換行,每個函數間未換行 | |
| 7 | 代碼行內的空格是否得體? | √ | ||
| 8 | 長行拆分是否得體? | × | 部分較長語句未換行 | |
| 9 | “{” 和 “}” 是否各占一行并且對齊于同一列? | √ | ||
| 10 | 一行代碼是否只做一件事?如只定義一個變量,只寫一條語句。 | 重要 | × | 部分語句定義了多個變量 |
| 11 | If、for、while、do等語句自占一行,不論執行語句多少都要加 “{}”。 | 重要 | × | 部分只有一句有效語句的判斷、循環未加大括號 |
| 12 | 在定義變量(或參數)時,是否將修飾符 * 和 & 緊靠變量名? | 重要 | 不適用 | 未使用指針變量 |
| 13 | 注釋是否清晰并且必要? | 重要 | √ | |
| 14 | 注釋是否沒有錯誤且不會導致誤解? | 重要 | √ | |
| 15 | 類結構的public, protected, private順序是否在所有的程序中保持一致? | 重要 | 不適用 | 未使用類 |
| 命名規則 | ||||
| 序號 | 審查項目 | 重要性 | 結論 | 備注 |
| 16 | 命名規則是否與所采用的操作系統或開發工具的風格保持一致? | 重要 | √ | |
| 17 | 標識符是否直觀且可以拼讀? | × | 標識符直觀,但部分不可拼讀 | |
| 18 | 標識符的長度應當符合“min-length && max-information”原則? | √ | ||
| 19 | 程序中是否出現相同的局部變量和全部變量? | 重要 | × | 部分計數變量重復、命名相同 |
| 20 | 類名、函數名、變量和參數、常量的書寫格式是否遵循一定的規則? | √ | ||
| 21 | 靜態變量、全局變量、類的成員變量是否加前綴? | × | ||
| 表達式與基本語句? | ||||
| 序號 | 審查項目 | 重要性 | 結論 | 備注 |
| 22 | 如果代碼行中的運算符比較多,是否已經用括號清楚地確定表達式的操作順序? | 重要 | √ | 未出現較為復雜的運算 |
| 23 | 是否未編寫太復雜或者多用途的復合表達式? | √ | ||
| 24 | 是否未將復合表達式與“真正的數學表達式”混淆? | 重要 | √ | |
| 25 | 是否用正確的方式寫if語句? 例如 | 重要 | ||
| 1) 不將布爾變量直接與TRUE、FALSE或者1、0進行比較。 | √ | 未使用bool型變量 | ||
| 2) 不將浮點變量用“==”或“!=”與任何數字比較。 | √ | 未使用浮點變量 | ||
| 3) 不將指針變量用“==”或“!=”與NULL比較。 | √ | 未使用指針變量 | ||
| 26 | 如果循環體內存在邏輯判斷,并且循環次數很大,是否已經將邏輯判斷移到循環體的外面? | √ | 循環體內的邏輯判斷均為必須處在循環內的 | |
| 27 | Case語句的結尾是加了break? | 重要 | √ | |
| 28 | 是否寫了switch的default分支? | 重要 | √ | |
| 29 | 使用goto 語句時是否留下隱患? 例如跳過了某些對象的構造、變量的初始化、重要的計算等。 | 重要 | 不適用 | 未使用goto語句 |
| 常量 | ||||
| 序號 | 審查項目 | 重要性 | 結論 | 備注 |
| 30 | 是否使用含義直觀的常量來表示那些將在程序中多次出現的數字或字符串? | √ | ||
| 31 | 是否誤解了類中的const數據成員?因為const數據成員只在某個對象 | 不適用 | 未使用類 | |
| 32 | 如果某一常量與其它常量密切相關,是否在定義中包含了這種關系? | 重要 | √ | |
| 33 | 生存期內是常量,而對于整個類而言卻是可變的。 | √ | ||
| 函數設計 | ||||
| 序號 | 審查項目 | 重要性 | 結論 | 備注 |
| 34 | 參數的書寫是否完整?不要貪圖省事只寫參數的類型而省略參數名字。 | √ | ||
| 35 | 參數命名、順序是否合理? | √ | ||
| 36 | 參數的個數是否太多? | × | ||
| 37 | 是否使用類型和數目不確定的參數? | × | ||
| 38 | 是否省略了函數返回值的類型? | × | ||
| 39 | 函數名字與返回值類型在語義上是否沖突? | × | ||
| 40 | 是否將正常值和錯誤標志混在一起返回?正常值應當用輸出參數獲得,而錯誤標志用return語句返回。 | 重要 | √ | |
| 41 | 在函數體的“入口處”,是否用assert對參數的有效性進行檢查? | 重要 | × | |
| 42 | 使用濫用了assert? 例如混淆非法情況與錯誤情況,后者是必然存在的并且是一定要作出處理的。 | 重要 | × | 未使用assert |
| 43 | return語句是否返回指向“棧內存”的“指針”或者“引用”? | 重要 | × | |
| 44 | 是否使用const提高函數的健壯性?const可以強制保護函數的參數、返回值,甚至函數的定義體。 | × | ||
| 內存管理 | ||||
| 序號 | 審查項目 | 重要性 | 結論 | 備注 |
| 45 | 用malloc或new申請內存之后,是否立即檢查指針值是否為NULL? | 重要 | 不適用 | 未使用malloc |
| 46 | 是否忘記為數組和動態內存賦初值? | 重要 | × | 數組未賦初值,未使用動態內存 |
| 47 | 數組或指針的下標是否越界? | 重要 | × | |
| 48 | 動態內存的申請與釋放是否配對? | 重要 | 不適用 | 未使用動態內存 |
| 49 | 是否有效地處理了“內存耗盡”問題? | 重要 | √ | |
| 50 | 是否修改“指向常量的指針”的內容? | 重要 | 不適用 | 未使用指針 |
| 51 | 是否出現野指針?例如 | 重要 | 未使用指針 | |
| 1) 指針變量沒有被初始化 | × | |||
| 2) 用free或delete釋放了內存之后,忘記將指針設置為NULL。 | × | |||
| 52 | 是否將malloc/free 和 new/delete 混淆使用? | 重要 | × | 未使用malloc/free和new/delete |
| 53 | malloc語句是否正確無誤?例如字節數是否正確?類型轉換是否正 確? | 重要 | 不適用 | 未使用malloc語句 |
| 54 | 在創建與釋放動態對象數組時,new/delete的語句是否正確無誤? | 重要 | 不適用 | 未使用動態對象數組 |
| 其它常見問題? | ||||
| 序號 | 審查項目 | 重要性 | 結論 | 備注 |
| 55 | 數據類型問題: | 重要 | ||
| 1) 變量的數據類型有錯誤嗎? | × | |||
| 2) 存在不同數據類型的賦值嗎? | × | |||
| 3) 存在不同數據類型的比較嗎? | × | |||
| 56 | 變量值問題: | 重要 | ||
| 1) 變量的初始化或缺省值有錯誤嗎? | √ | |||
| 2) 變量發生上溢或下溢嗎? | × | 取決于輸入的數字大小,一般情況下不會,但未作容錯處理 | ||
| 3) 變量的精度夠嗎? | √ | 均為整型,不存在精度問題 | ||
| 57 | 邏輯判斷問題: | 重要 | ||
| 1) 由于精度原因導致比較無效嗎? | × | |||
| 2) 表達式中的優先級有誤嗎? | × | |||
| 3) 邏輯判斷結果顛倒嗎?? | × | |||
| 58 | 循環問題: | 重要 | ||
| 1) 循環終止條件不正確嗎? | × | |||
| 2) 無法正常終止(死循環)嗎? | × | |||
| 3) 錯誤地修改循環變量嗎? | × | |||
| 4) 存在誤差累積嗎? | × | |||
| 59 | 錯誤處理問題: | 重要 | ||
| 1) 忘記進行錯誤處理嗎? | × | |||
| 2) 錯誤處理程序塊一直沒有機會被運行? | × | |||
| 3) 錯誤處理程序塊本身就有毛病嗎? | × | |||
| 4) 錯誤處理程序塊是“馬后炮”嗎?如在被它被調用之前軟件已經出錯。 | × | |||
| 60 | 文件I/O問題: | 重要 | 未對文件進行操作 | |
| 1) 對不存在的或者錯誤的文件進行操作嗎? | × | |||
| 2) 文件以不正確的方式打開嗎? | × | |||
| 3) 文件結束判斷不正確嗎? | × | |||
| 4) 沒有正確地關閉文件嗎? | × | |||
3. 代碼評價
王宗波同學的這個項目的代碼,使用C/C++語言進行開發,整體結構較為工整清晰,命名和書寫等較有條理,代碼風格具有一定的規范性,但也有部分的不足。
其主要優點如下。
首先對代碼的整體結構有較為清晰的把握,只聲明了所使用的庫函數的頭文件,沒有頭文件被聲明而未被使用。
語句與語句間使用換行明確區分,縮進得當,且大部分的循環體、判斷結構均用“{”和“}”加以明示,代碼可讀性較強。
每一個循環體都是有效、正確且可以正常結束的循環。
注釋清晰簡潔且通俗易懂,增加了代碼的可讀性。
變量的命名雖未遵循某些約定俗成的規則,如匈牙利命名法等,但仍有規律可循,且大部分的變量均體現出了該變量的作用或含義。
例如代碼中這一段的變量命名均含義清楚準確
typedef struct {char data; //結點值int weight; //權值int parent; //雙親節點int left; //左節點int right; //右節點int flag ; //訪問標志 } huffnode; //哈夫曼樹的結點在使用switch選擇時,正確使用了比較容易忽視的default語句,且在每個case選項后均正確使用的break,保證了選擇結果的正確性。
例如代碼中的這一段,對switch的使用十分準確
switch(key){case '1':n=Input_haffuman();break;case '2':display_huffcode(n);break;case '3':Huffman_code(n);break;case '4':Equilong_code(n);break;case '5':Compare_code(n);break;case '6':Encoder(n);break;case '0':Print3();break;default:cout<<"選擇無效,請重新選擇!!"<<endl;break;在程序的開始部分,使用#define MAXSIZE 10000語句較為清楚的聲明了整個程序中使用次數較多的數字1000為MAXSIZE,方便了后續的使用且能有效地避免出錯。
在函數設計方面,正確、合理且有序的設計了各項傳遞的參數,沒有偷工減料的省略參數的名字而只是用參數類型。
在數據結構和數據類型的設計方面,選擇了正確的數據類型和合理的數據結構來儲存要處理和計算的數據。
設計了容錯機制和錯誤處理程序,有效的增強了程序的健壯性。
但是仍然存在部分缺點和不足。
首先是所有的功能函數和主函數都設計在同一個cpp文件內,不利于程序的遷移等,可以嘗試將功能函數聲明在定義的頭文件內,并在頭文件對應的cpp文件內進行設計,主程序單獨的設計在一個cpp文件內,并通過添加頭文件對功能函數進行調用。
其次部分只有一句的判斷結構和循環體沒有大括號,雖然正確,但是不利于后期的修改。
另外,建議在命名變量時,在符合規則和易懂的基礎上,設計為容易拼讀的變量名,這樣可增加程序的可讀性。
在函數設計方面,可以在函數入口處使用assert進行參數的有效性檢查,并可在適當的時候使用const,這樣可以提高函數的健壯性。
另外整個項目在未知需要處理的數據的個數的前提下,使用了固定的數組大小并不合適,簡易使用動態的內存分配,以便優化內存大小。
最后,雖然設計了容錯機制但是并不完備,忽視了一些極小概率發生的錯誤,如整型變量數值溢出的處理。
總的來說這個項目的代碼,在沒有系統學習過某種特定的代碼規范的情況下,還是相當的不錯的,但是仍有很大的進步空間。
轉載于:https://www.cnblogs.com/martinzhang98/p/10746946.html
總結
以上是生活随笔為你收集整理的软件工程——结对编程第一次作业的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#中的 隐式与显式接口实现
- 下一篇: [转] 图解Seq2Seq模型、RNN结