Skip to main content

編寫高質量程序的檢查清單

Original Essay: http://cs.engr.uky.edu/~raphael/checklist.html, by Raphael Finkel, University of Kentucky

 

本檢查清單應幫助您編寫高質量的程式.
Raphael Finkel, 8/17/2005

  • 識別字:確保所有識別字都有意義.
    1. 一個字母的識別字幾乎從不具有意義.
    2. 類似flagtemp的名稱很少有意義。與其使用flag,不如考慮命名布爾條件,如valueFound.
    3. 考慮使用多詞識別字,如nameIndex. 較長的識別字(在合理範圍內)往往非常易讀.
  • 裸文字:除了在定義常量時使用0和1以及除了""之外的字串,避免在程式中使用數字和字串.
    1. 不要將字面整數用作數組邊界.
    2. 不要將字面整數用作運行參數,例如超時或端口號.
    3. 不要使用字面整數選擇菜單條目.
    4. 不要使用字面整數測量字串或某些數據的大小:在C和C++中使用sizeof()strlen(),在Java中使用.length().size.
    5. 不要將字面字串用作檔案名.儘管可以輸出字面字串.
    6. 不要將字面整數用於索引包含異構數據的數組.
    7. 不要使用表示字面量的名稱聲明識別字,如 "thirty".
  • 模組化:程式由相互作用的組件構建而成.
    1. 不要將所有代碼放入main()函數中.
    2. 實際上,不要讓任何函數承擔太多工作.如果超過約50行,可能太長了.
    3. 如果你多次複製代碼,請考慮是否使用迴圈更合適,或者可能是副程式.
    4. 如果發現自己縮進得很深,很可能是沒有在需要的時候使用副程式.
    5. 不要重新發明庫函數(除非任務需要).查閱手冊瞭解如sprintf()atoi()等函數.
    6. 在C和C++中使用頭檔(頭檔案名以.h結尾)定義所有需要在多個檔中使用的常量,並聲明所有在檔之間導出的副程式。但不要將副程式的主體放在頭檔中(內聯副程式除外).
  • 格式化:程式應易於閱讀.
    1. 參閱http://geosoft.no/development/javastyle.html以獲取關於格式化和其他展示問題的明確建議。此參考資料專門針對Java,但對其他語言也有價值.
    2. 儘量將所有行限制在80個字元內;出於歷史原因,許多人在80列窗口中查看代碼.
    3. 不要同時使用跳位字元和空格進行縮進,因為並非所有文本編輯器都將跳位字元視為8個空格.
    4. 確實要遵循一種反映程式控制結構的一致的縮進模式.
    5. 不要在程式中放置許多空行。副程式之間一個空行就足夠了.
    6. 不同的操作系統以不同的方式終止行。如果您在Win32(使用\r\n)、Unix(使用\n)和MacOS(使用\r)之間切換,請將檔重新格式化以使用一致的終止方法.
    7. 不要在原始檔案上設置可執行位(Unix).
  • 編碼:您希望編碼清晰、可維護且高效,按此順序。這裏的一些規則非常具體;其他規則更通用.
    1. 如果只有一個可以匹配的if語句,不要使用一系列沒有else的if語句;使用else if.
    2. 當您需要對文本輸入進行分類時,不要列舉所有可能的第一個字元.
    3. 使用位移運算符而非乘法構建位模式.
    4. 在switch語句中,始終檢查默認情況。同樣,在一系列if-then-else語句中,使用最後一個else.
    5. 所有系統調用都可能失敗。始終檢查返回代碼,並使用perror()報告失敗.
    6. 布爾值應始終在Java中使用布爾類型,在C++中使用bool,在C中使用0/1整數。不要使用字元t和f,也不要使用-1和1.
    7. 如果可能的話,使用迴圈初始化數據結構.
    8. 每個變數和結構的每個字段只用於一個目的。除非有充分理由,否則不要重載它們.
    9. 不要為類型、變數和文件名使用相同的識別字,即使更改了大小寫。這太令人困惑了.
    10. 如果您在網路傳輸之前使用htonl()或類似的程式修改數據,請勿直接修改數據。創建一個新的數據結構.
    11. 儘量不要使用全局或非局部變數。盡可能在最小範圍內聲明每個變數。非局部變數有合理的用途,但請確保您真正需要它們.
    12. Shell, Perl, 和Python程式的#! 行應作為檔的第一行;否則,該行僅作為注釋.
    13. 儘量避免編寫特殊情況。您通常可以使用偽數據或其他數據結構方法將特殊情況融入常規情況中.
  • 編譯器:讓它們幫助您發現錯誤。始終使用所有警告選項調用編譯器.
    1. 對於C和C++,使用-Wall標誌.
    2. 對於Java,使用-Xlint:all  -deprecation,並使用pmd程式獲得更好的風格建議.
    3. 對於Python,使用-t  -W  all.
    4. 對於Perl,使用-w標誌並指定use strict。Cgi-bin腳本還應具有-T標誌.
  • make實用程式:使用它,並善於使用它.
    1. Makefile應始終具有一個"clean"配方,該配方應刪除Makefile中其他配方可以重建的所有檔,包括對象和可執行檔.
    2. 如果專案具有多個原始檔案,Makefile應根據需要生成對象(.o)檔並將它們鏈接在一起.
    3. Makefile應編寫得當,以便如果連續運行兩次make,第二次運行不會重新編譯.
    4. 每個配方都應創建其目標中指定的檔.
    5. 每個配方都應使用其先決條件列表中指定的所有檔.
    6. 學會使用類似.c.o的目標規則,以避免重複的makefiles.
    7. 如果只有一個C或C++原始檔案,可執行檔應具有相同的名稱(不帶.c.cpp擴展名).
    8. 確保在需要的地方將所有.h檔列為先決條件。可以考慮使用makedepend為您生成先決條件列表.
  • 文檔:不僅僅是為了評分。在編寫程式時,它還可以幫助您!
    1. 在編寫程式時添加文檔。隨著設計的變化,您可以隨時修改它.
    2. 編寫外部文檔:如何編譯和運行程式以及程式的預期功能?外部文檔通常在單獨的README檔中;對於小專案,可以將其作為單個原始檔案中的注釋.
    3. 包含內部文檔:您使用了哪些演算法和數據結構?概述可以在單獨的README檔中,但通常將內部文檔放在描述特定例程、聲明和步驟的位置.
    4. 檢查整個程式和文檔中的拼寫錯誤。提交拼寫錯誤的工作是不禮貌的,表明對細節的疏忽.
    5. 檢查所有文檔(和輸出消息)中的語法錯誤.
    6. 如果在關閉括弧上放一個簡短的注釋,程式會更易讀。例如,可以在結束條件的括弧上加上一個注釋,如"if value looks good"。在結束迴圈的括弧上可以加上一個注釋,如"for each input line"。結束一個過程的括弧上可以加上一個注釋,只是給出過程的名稱。結束一個類的括弧上可以有一個注釋,說"類"然後是類的名稱.