本標準規定了程序設計者在設計程序時必須遵循的規範。本規範主要針對C51編程語言和keil編譯器,包括排版、注釋、命名、變量使用、代碼可測試性、程序效率、質量保證等。
3 微控製器C51 編程規範- 一般原則
l 格式清晰
l 評論簡明扼要
l 命名規範易於理解
l 功能模塊化
l 程序易於閱讀和維護
l 功能精準實現
l 代碼空間效率和時間效率高
l 適度的可擴展性
4 單片機C51編程規範-數據類型定義
編程時,使用以下新類型名稱來定義數據類型。
創建datatype.h 文件並在文件中定義以下內容:
typedef 位BOOL; //位變量//
typedef 無符號字符INT8U; //無符號8位整型變量//
typedef 有符號字符INT8S; //有符號8 位整型變量//
typedef 無符號整型INT16U; //無符號16 位整型變量//
typedef 有符號int INT16S; //有符號16 位整型變量//
typedef 無符號長INT32U; //無符號32 位整型變量//
typedef 有符號長INT32S; //有符號32 位整型變量//
typedef 浮點FP32; //單精度浮點數(32 位長度) //
typedef 雙FP64; //雙精度浮點數(64 位長度) //
5 微控製器C51編程規範-標識符命名
5.1 命名的基本原則
l 命名應簡潔明了,含義明確,使用完整的詞語或約定的縮寫。通常,較短的單詞通過刪除元音來縮寫;較長的單詞通過刪除單詞的前幾個字母來縮寫。即“見名知意”。
l 命名風格自始至終保持一致。
l 如果命名中使用特殊約定或縮寫,必須注明。
l 除編譯開關/頭文件等特殊應用外,避免使用以下劃線開頭和/或結尾的定義。
l 同一軟件產品內模塊之間的接口部分的標識符名稱前麵帶有模塊標識符。
5.2 宏和常量命名
宏和常量均使用大寫字母命名,並用下劃線分隔單詞。使用有意義的枚舉或宏來替換程序中使用的數字。
5.3 變量命名
變量名以小寫字母命名,每個單詞的第一個字母大寫。類型前綴(u8\s8 等)全局變量以g_ 為前綴。
局部變量應該簡潔明了。局部循環體控製變量優先使用i、j、k等;局部長度變量優先使用len、num等;臨時中間變量優先使用temp、tmp等。
5.4 函數命名
命名函數時使用小寫字母,每個單詞的首字母大寫,並將模塊標識符放在前麵。
5.5 文件命名
一個文件包含一類函數或一個模塊的所有函數,文件名應清楚地表明其功能或性質。
每個.c 文件都應該有一個與頭文件同名的.h 文件。
6 微控製器C51 編程規範- 注釋
6.1 注釋的基本原理
l 有助於閱讀和理解程序,解釋程序在做什麼,並解釋代碼的目的、功能和方法。
l 一般來說,源程序中有效注釋的數量約為30%。
l 注釋語言必須準確、易懂、簡潔。
l 邊寫代碼邊注釋,修改代碼的同時修改相應的注釋,刪除不再有用的注釋。
6.2 文件注釋
文件注釋必須描述文件名、函數功能、創建者、創建日期、版本信息等相關信息。
修改文件代碼時,應在文件注釋中記錄修改日期、修改人以及修改目的的簡要說明。所有修改記錄必須完整保存。
文件注釋位於文件頂部並包含在“/*.*/”格式中。
每行注釋文本應縮進4個空格;每個評論文本項的名稱應對齊。
/******************************************************** ***** **********
文件名:
作者:
版本:
闡明:
修改記錄:
****************************************************** * *********/
6.3 函數注釋
6.3.1 函數頭注釋
函數頭注釋應包括函數名稱、函數功能、入口參數、出口參數等,必要時還可以添加作者、創建日期、修改記錄(注釋)等相關項。
函數頭注釋位於每個函數的頂部,並以“/*.*/”的格式包含。函數名應縮寫為FunctionName(),並且不要添加導出參數、導出參數等信息。
/******************************************************** ***** **********
函數名稱:
功能功能:
入口參數:
導出參數:
評論:
****************************************************** * *********/
6.3.2 代碼注釋
代碼注釋應緊鄰被注釋的代碼,放置在其上方或右側,而不是下方。如果放在上麵,則必須用空行將其與上麵的代碼分隔開。一般應在被注釋語句的行尾添加少量注釋,函數內多條注釋應左對齊;上麵應該添加更多注釋,並且注釋行應與注釋語句左對齊。
功能代碼注釋使用“//.//”格式。
通常,分支語句(條件分支、循環語句等)必須被注釋。應在程序塊結束行“}”的右側添加表示程序塊結束的標記“end of.”,特別是有多重嵌套時。
6.4 變量、常量和宏的注釋
同一類型的標識符應集中定義,其共同特征應在定義前統一注釋一行。各個標識符的注釋添加在定義語句行的末尾。
全局變量必須有詳細的注釋,包括其作用、取值範圍、哪些函數或過程訪問它們以及訪問它們時的注意事項。
注釋的格式為“//…//”。
7 單片機C51編程規範-功能
7.1 設計原則
功能基本要求:
l 正確性:程序必須實現設計要求的功能。
l 穩定安全:程序運行穩定、可靠、安全。
l 可測試性:程序易於測試和評估。
l 標準/可讀性:程序編寫風格、命名規則等符合標準。
l 可擴展性:代碼為下一步的升級和擴展留下了空間和接口。
l 全局效率:軟件係統整體效率高。
l 局部效率:某個模塊/子模塊/功能是高效的。
函數編程的基本原則:
l 單個函數的大小限製在200行(不包括注釋和空行)。一個函數隻能完成一個功能。
l 函數的局部變量個數一般不超過5~10個。
l 函數內部局部變量定義區和函數實現區(包括變量初始化)之間有一個空行。
l 函數名應準確描述函數的功能。通常使用動賓短語來命名執行操作的函數。
l 函數的返回值必須明確,尤其是錯誤返回值的含義必須準確。
l 不要使用編譯係統的默認轉換方法或強製轉換方法返回與函數返回值不同類型的變量作為返回值。
l 減少函數內部或函數之間的遞歸調用。
l 盡量不要使用函數參數作為工作變量。
7.2 函數定義
l 如果函數沒有入口參數或出口參數,則應顯式聲明為void。
l 函數名和導出參數類型定義之間隻能有一個空格。
l 函數名和中括號()之間不能有空格。
l 函數參數必須給出明確的類型定義。
l 對於多個形參的函數,後一個形參與前一個形參的逗號分隔符之間添加空格。
l 函數體前後的大括號“{}”各占一行。
7.3 局部變量定義
l 不要在同一行定義過多的變量。
l 同一類型的變量定義在同一行或相鄰行。
l 先定義數據類型變量,再定義idtata類型變量,最後定義xdata類型變量。
l 數組、指針等複雜類型的定義放在定義區的末尾。
l 變量定義區沒有更複雜的變量賦值。
7.4 功能實現區規範
l 每行隻寫一條語句。
l 注意運算符的優先級,使用括號明確表達式的運算順序,避免使用默認優先級。
l 各程序段之間用空行分隔,並添加必要的注釋。程序段是指能夠完成較具體功能的一行或多行代碼。程序部分中的代碼行彼此高度依賴。
l 不要使用難以理解和技術性很強的語句。
l 源程序中密切相關的代碼應盡可能相鄰。
l 完成簡單功能且關係密切的一條或幾條語句可以寫成函數,也可以定義成宏。
8 微控製器C51 編程規範- 排版
8.1 縮進
每層代碼向右縮進4個空格。
8.2 分支機構
太長的語句(超過80個字符)應分多行書寫;長表達式應在低優先級運算符處分成新行,運算符應放置在新行的開頭,並且劃分的新行應適當縮進。使布局整潔,句子可讀。避免在分支行中插入注釋。
8.3 空行
l 文件注釋區、頭文件引用區、函數中必須有1個空行。
l 相鄰函數之間必須有一個空行。
l 函數體內相對獨立的程序塊可以用空行或注釋分隔。
l 函數注釋和對應的函數體之間不能有空行。
l 文件末尾恰好有一個空行。
8.4 空格
l 函數語句末尾或注釋後不能有空格。
l 括號內(即左括號之後、右括號之前)不能有空格,多個括號之間不能有空格。
l 函數參數之間必須有一個空格(形參逗號後麵的一個空格)。
l 同一行定義的多個變量之間必須有一個空格(變量逗號後的空格)。
l 表達式中,如果有多個連續書寫的運算符,需要用空格分隔:
當兩個或多個關鍵字、變量、常量進行等價運算時,它們之間的運算符前後各加一個空格;當兩個或多個關鍵字、變量、常量執行非等價運算時,運算符前後各加一個空格。不得添加空格;
逗號後麵僅跟一個空格;
二元運算符,如比較運算符、賦值運算符'='、'+='、算術運算符'+'、'%'、邏輯運算符''、''、位運算符''、'^'等,加一個前後有空格;
一元運算符,如'!'、'~'、'++'、'-'、''(地址運算符)等,前後不能有空格;
'-' 和'.' 前後不能有空格;
if、for、while、switch 等關鍵字與後麵的括號之間添加空格;
8.5 大括號
l if、else if、else、for、while語句無論執行體是一條語句還是多條語句,都必須用大括號括起來,並且左右大括號各占一行。
l 在do{}while()結構中,'do'和'{'各占一行,'}'和'while();'各占一行一起占據一行。
如果()做
{ {
} }盡管( );
別的
{
}
8.6 switch語句
l 每個案例及其條件占一行。
l 每個case程序塊必須以break結束。除特殊情況需要從一個case塊依次執行到下一個case塊外,需要在連接處明確注釋出該操作的原因,以防止出錯。
l 案例程序塊之間有1個空行,且隻有1個空行。
l 每個case塊的執行語句縮進4個空格。
l 一般情況下,應該包含默認分支。
轉變( )
{
案例x:
休息;
案例x:
休息;
默認:
休息;
}
9 單片機C51編程規範-程序結構
9.1 基本要求
l 帶有main()函數的.c文件應該把main()放在前麵,並用void顯式聲明參數和返回值。
l 對於由多個.c文件組成的模塊程序或完整的監控程序,建立公共引用頭文件,包含需要引用的庫頭文件、標準寄存器定義頭文件、自定義頭文件、全局變量等。供每個文件參考。通常,標準函數庫頭文件使用尖角來標記文件名,自定義頭文件使用雙撇號“”來標記文件名。
l 每個.c文件都有一個對應的.h文件。在.c文件的注釋之後,首先定義了一個唯一的文件標誌宏,並在對應的.h文件中解析該標誌。
在.c文件中:
#定義FILE_FLAG
在.h文件中:
#ifdef 文件標誌
#defineXXX
別的
#定義XXX 外部
萬一
l 確定僅由某個.c文件調用的定義可以列出在單獨的頭文件中並單獨調用。
9.2 可重入函數
如果在可重入函數中使用全局變量,應該通過關閉中斷、信號量和其他操作來保護它們。
9.3 功能參數
l 函數調用者負責檢查形參的合法性。
l 盡量避免使用形式參數作為工作變量。
9.4 循環
l 盡量減少循環嵌套層數
l 在多個循環中,最繁忙的循環應放在最內層
l 循環體內的工作量極小
l 盡量避免循環體中的判斷語句