微控制器的C語言程式設計中所用的語言推薦規範
阿新 • • 發佈:2019-02-06
一、程式風格:
1、嚴格採用階梯層次組織程式程式碼:
各層次縮排的分格採用VC的預設風格,即每層次縮排為4格,括號位於下一行。
要求相匹配的大括號在同一列,對繼行則要求再縮排4格。例如:
2、提示資訊字串的位置
在程式中需要給出的提示字串,為了支援多種語言的開發,除了一些給除錯用的臨時資訊外,其他所有的提示資訊必須定義在資源中。
3、對變數的定義,儘量位於函式的開始位置。
二、命名規則:
1、變數名的命名規則
①、變數的命名規則要求用“匈牙利法則”。即開頭字母用變數的型別,其餘部分用變數的英文意思或其英文意思的縮寫,儘量避免用中文的拼音,要求單詞的第一個字母應大寫。 即: 變數名=變數型別+變數的英文意思(或縮寫) 對非通用的變數,在定義時加入註釋說明,變數定義儘量可能放在函式的開始處。 見下表:
模組中函式命名規則:
模組名_ + 函式名(動名結構),如:
tmr_GetCurTime() // 時鐘模組中,獲取當前時間的函式
sport_TxData() // SPORT驅動模組中,傳送資料的函式
對未給出的變數型別要求提出並給出命名建議給技術委員會。 ②、指標變數命名的基本原則為: 對一重指標變數的基本原則為: “p”+變數型別字首+命名 如一個float*型應該表示為pfStat 對多重指標變數的基本規則為: 二重指標: “pp”+變數型別字首+命名 三重指標: “ppp”+變數型別字首+命名 ...... ③、全域性變數用g_開頭,如一個全域性的長型變數定義為g_lFailCount,即:變數名=g_+變數型別+變數的英文意思(或縮寫) ④、靜態變數用s_開頭,如一個靜態的指標變數定義為s_plPerv_Inst,即: 變數名=s_+變數型別+變數的英文意思(或縮寫) ⑤、成員變數用m_開頭,如一個長型成員變數定義為m_lCount;即:變數名=m_+變數型別+變數的英文意思(或縮寫) ⑥、對列舉型別(enum)中的變數,要求用列舉變數或其縮寫做字首。並且要求用大寫。 如:enum cmEMDAYS { EMDAYS_MONDAY; EMDAYS_TUESDAY; …… }; ⑦、對struct、union、class變數的命名要求定義的型別用大寫。並要加上字首,其內部變數的命名規則與變數命名規則一致。 結構一般用S開頭 如:struct ScmNPoint { int nX;//點的X位置 int nY; //點的Y位置 }; 聯合體一般用U開頭 如: union UcmLPoint { long lX; long lY; } 類一般用C開頭 如: class CcmFPoint { public: float fPoint; }; 對一般的結構應該定義為類模板,為以後的擴充套件性考慮 如: template class CcmTVector3d { public: TYPE x,y,z; }; ⑧、對常量(包括錯誤的編碼)命名,要求常量名用大寫,常量名用英文表達其意思。 如:#define CM_FILE_NOT_FOUND CMMAKEHR(0X20B) 其中CM表示類別。 ⑨、對const 的變數要求在變數的命名規則前加入c_,即:c_+變數命名規則;例如: const char* c_szFileName;
2、 函式的命名規範:
函式的命名應該儘量用英文表達出函式完成的功能。遵循動賓結構的命名法則,函式名中動詞在前,並在命名前加入函式的字首,函式名的長度不得少於8個字母。
例如:
long cmGetDeviceCount(……);
3、函式引數規範:
①、 引數名稱的命名參照變數命名規範。 ②、 為了提高程式的執行效率,減少引數佔用的堆疊,傳遞大結構的引數,一律採用指標或引用方式傳遞。 ③、 為了便於其他程式設計師識別某個指標引數是入口引數還是出口引數,同時便於編譯器檢查錯誤,應該在入口引數前加入const標誌。如: ……cmCopyString(const char * c_szSource, char * szDest)
4、引出函式規範:
對於從動態庫引出作為二次開發函式公開的函式,為了能與其他函式以及Windows的函式區分,採用類別字首+基本命名規則的方法命名。例如:在對動態庫中引出的一個圖象編輯的函式定義為 imgFunctionname(其中img為image縮寫)。
現給出三種庫的命名字首:
①、 對通用函式庫,採用cm為字首。
②、 對三維函式庫,採用vr為字首。
③、 對圖象函式庫,採用img為字首。
對巨集定義,結果程式碼用同樣的字首。
5、檔名(包括動態庫、元件、控制元件、工程檔案等)的命名規範:
檔名的命名要求表達出檔案的內容,要求檔名的長度不得少於5個字母,嚴禁使用象file1,myfile之類的檔名。
三、註釋規範:
1、函式頭的註釋
對於函式,應該從“功能”,“引數”,“返回值”、“主要思路”、“呼叫方法”、“日期”六個方面用如下格式註釋:
//程式說明開始
//================================================================//
// 功能: 從一個String 中刪除另一個String。
// 引數: strByDelete,strToDelete
// (入口) strByDelete: 被刪除的字串(原來的字串)
// (出口) strToDelete: 要從上個字串中刪除的字串。
// 返回: 找到並刪除返回1,否則返回0。(對返回值有錯誤編碼的要// 求列出錯誤編碼)。
// 主要思路:本演算法主要採用迴圈比較的方法來從strByDelete中找到
// 與strToDelete相匹配的字串,對多匹配strByDelete
// 中有多個strToDelete子串)的情況沒有處理。請參閱:
// 書名......
// 呼叫方法:......
// 日期:起始日期,如:2000/8/21.9:40--2000/8/23.21:45
//================================================================//
函式名(……)
//程式說明結束
①、 對於某些函式,其部分引數為傳入值,而部分引數為傳出值,所以對引數要詳細說明該引數是入口引數,還是出口引數,對於某些意義不明確的引數還要做詳細說明(例如:以角度作為引數時,要說明該角度引數是以弧度(PI),還是以度為單位),對既是入口又是出口的變數應該在入口和出口處同時標明。等等。
②、 函式的註釋應該放置在函式的標頭檔案中,在實現檔案中的該函式的實現部分應該同時放置該註釋。
③、 在註釋中應該詳細說明函式的主要實現思路、特別要註明自己的一些想法,如果有必要則應該寫明對想法產生的來由。對一些模仿的函式應該註釋上函式的出處。
④、 在註釋中詳細註明函式的適當呼叫方法,對於返回值的處理方法等。在註釋中要強調呼叫時的危險方面,可能出錯的地方。
⑤、 對日期的註釋要求記錄從開始寫函式到結束函式的測試之間的日期。
⑥、 對函式註釋開始到函式命名之間應該有一組用來標識的特殊字串。
如果演算法比較複雜,或演算法中的變數定義與位置有關,則要求對變數的定義進行圖解。對難以理解的演算法能圖解儘量圖解。
2、變數的註釋:
對於變數的註釋緊跟在變數的後面說明變數的作用。原則上對於每個變數應該註釋,但對於意義非常明顯的變數,如:i,j等迴圈變數可以不註釋。
例如: long lLineCount //線的根數。
3、檔案的註釋:
檔案應該在檔案開頭加入以下注釋:
/////////////////////////////////////////////////////////////////////
// 工程: 檔案所在的專案名。
// 作者:**,修改者:**
// 描述:說明檔案的功能。
// 主要函式:…………
// 版本: 說明檔案的版本,完成日期。
// 修改: 說明對檔案的修改內容、修改原因以及修改日期。
// 參考文獻: ......
/////////////////////////////////////////////////////////////////////
為了標頭檔案被重複包含要求對標頭檔案進行定義如下:
#ifndef __FILENAME_H__
#define __FILENAME_H__
其中FILENAME為標頭檔案的名字。
4、其他註釋:
在函式內我們不需要註釋每一行語句。但必須在各功能模組的每一主要部分之前新增塊註釋,註釋每一組語句,在迴圈、流程的各分支等,儘可能多加以註釋。
其中的迴圈、條件、選擇等位置必須註釋。
對於前後順序不能顛倒的情況,建議在註釋中增加序號。
例如:
在其他順序執行的程式中,每隔3—5行語句,必須加一個註釋,註明這一段語句所組成的小模組的作用。對於自己的一些比較獨特的思想要求在註釋中標明。
四、程式健壯性:
## 1、函式的返回值規範:
對於函式的返回位置,儘量保持單一性,即一個函式儘量做到只有一個返回位置。(單入口單出口)。
要求大家統一函式的返回值,所有的函式的返回值都將以編碼的方式返回。
例如編碼定義如下:
#define CM_POINT_IS_NULL CMMAKEHR(0X200)
:
:
建議函式實現如下:
long 函式名(引數,……)
{
long lResult; //保持錯誤號
lResult=CM_OK;
//如果引數有錯誤則返回錯誤號
if(引數==NULL)
{
lResult=CM_POINT_IS_NULL;
goto END;
}
……
END:
return lResult;
}
## 2、關於goto的應用:
對goto語句的應用,我們要求儘量少用goto語句。對一定要用的地方要求只能向後轉移。
3、資源變數的處理(資源變數是指消耗系統資源的變數):
對資源變數一定賦初值。分配的資源在用完後必須馬上釋放,並重新賦值。
4、對複雜的條件判斷,為了程式的可讀性,應該儘量使用括號。
例:if(((szFileName!=NULL)&&(lCount>=0)))||(bIsRead==TRUE))
五、可移植性:
1、高質量的程式碼要求能夠跨平臺,所以我們的程式碼應該考慮到對不同的平臺的支援,特別是對windows 98和windows nt的支援。
2、由於C語言的移植性比較好,所以對演算法函式要求用C程式碼,不能用C++程式碼。
3、對不同的硬體與軟體的函式要做不同的處理