嵌入式C語言編碼規(guī)范_第1頁
嵌入式C語言編碼規(guī)范_第2頁
嵌入式C語言編碼規(guī)范_第3頁
嵌入式C語言編碼規(guī)范_第4頁
嵌入式C語言編碼規(guī)范_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、1嵌入式嵌入式C C語言編碼規(guī)范語言編碼規(guī)范 zhao-2引言引言 嵌入式系統(tǒng)在各行各業(yè)都得到了廣泛應(yīng)用,C 語言的使用也越來越體現(xiàn)出廣泛性,因此嵌入式軟件的安全可靠性變得尤為重要。制定本規(guī)范的目的與意義在于: 1、樹立良好的編程習(xí)慣和編程思路 ,摒棄那些可能存在風(fēng)險的編程行為。保證編寫出安全健壯的代碼,進而保證嵌入式產(chǎn)品的安全性、可靠性。 2、使編寫的代碼更加容易閱讀、容易理解而且容易維護。 3、良好的編程風(fēng)格是提高程序可靠性非常重要的手段,也是大型項目多人合作開發(fā)的技術(shù)基礎(chǔ)。 4、遵循良好的共通的編碼規(guī)范,也是提高編碼能力,保證軟件工程這個階段質(zhì)量的一個重要手段。同時也是衡量一個組織軟件開

2、發(fā)能力的一個重要指標(biāo)。3規(guī)范內(nèi)容規(guī)范內(nèi)容內(nèi)容內(nèi)容課時(課時(H H)1 1、文件組織和內(nèi)部構(gòu)成、文件組織和內(nèi)部構(gòu)成0.10.12 2、命名規(guī)范、命名規(guī)范0.20.23 3、標(biāo)識符和常量、標(biāo)識符和常量0.10.14 4、類型和類型轉(zhuǎn)換、類型和類型轉(zhuǎn)換0.20.25 5、初始化、聲明和定義、初始化、聲明和定義0.20.26 6、控制語句和表達式、控制語句和表達式0.20.27 7、函數(shù)、函數(shù)0.10.18 8、指針和數(shù)組、指針和數(shù)組0.20.29 9、結(jié)構(gòu)與聯(lián)合、結(jié)構(gòu)與聯(lián)合0.10.11010、預(yù)處理指令、預(yù)處理指令0.10.141 1、文件組織和內(nèi)部構(gòu)成、文件組織和內(nèi)部構(gòu)成EPF_PARTSPF

3、Frameworkinclude subsystem_Ainclude subsystem_Binclude subsystem_CincludeOS及共通調(diào)用封裝函數(shù)群及共通調(diào)用封裝函數(shù)群 TASK起動等相關(guān)起動等相關(guān). 管腳控制和讀寫等管腳控制和讀寫等include包含如下共通頭文件:包含如下共通頭文件: PF共通宏定義共通宏定義 PF共通結(jié)構(gòu)體定義共通結(jié)構(gòu)體定義 OS接口封裝函數(shù)聲明接口封裝函數(shù)聲明CA機能模塊實現(xiàn)部分機能模塊實現(xiàn)部分 TRCincludeDEBUG MESSAGE的平臺化的平臺化實現(xiàn)部分。實現(xiàn)部分。51 1、文件組織和內(nèi)部構(gòu)成、文件組織和內(nèi)部構(gòu)成 用于存儲源代碼的C 程

4、序文件可以分為兩類:源文件和頭文件。源文件和頭文件中包含的內(nèi)容是不同的。 源文件主要包括以下內(nèi)容:源文件主要包括以下內(nèi)容:只在本文件內(nèi)部使用的(對外部隱藏的)類型;只在本文件內(nèi)部使用的(對外部隱藏的)常量;只在本文件內(nèi)部使用的(對外部隱藏的)宏定義;全局變量和文件級(static)變量的定義;函數(shù)原型聲明和函數(shù)定義; 包含文件部分,文件頭的說明,函數(shù)頭的說明。 頭文件中包含如下內(nèi)容:頭文件中包含如下內(nèi)容:提供給外部參照的類型;提供給外部參照常量;提供給外部參照宏定義;提供給外部參照(全局)函數(shù)原型聲明;提供給外部參照全局變量的外部聲明; 包含文件部分,文件頭的說明。但頭文件中不要定義變量。但頭

5、文件中不要定義變量。6/* File Name : DP_DrawE.c* Model Name : MF7878/R/J* Module Name : Draw Engine/Display* uCom : Mitsubishi M16C/80 series* Create Date : 1999/10/01* Author/Corporation : WhoAmI/NAS* Abstract Description : Place some description here.*-Revision History-* No Version Date Revised By Item Descr

6、iption* 1 V0.95 00.05.18 WhoAmINAS abcdefghijklm WhatUDo*/Source/ Header File Header Section各部分內(nèi)容的含義說明,請參考下面內(nèi)容。1) 文件名信息;2) 適用的產(chǎn)品型號(Model)名稱:可以是多個型號;3) 所屬的模塊(Module)名稱:當(dāng)模塊很大時,可以考慮在大模塊內(nèi)增加子模塊的標(biāo)示;4) 適用的處理器(Com)型號:可以是多個型號;5) 預(yù)先包含頭文件:只有在頭文件的描述中使用,注明包含本文件之前應(yīng)該首先包含的頭文件;6) 文件創(chuàng)建日期;7) 文件創(chuàng)建者/公司名稱;8) 概要描述:概要的描述文件

7、的功能、構(gòu)成等信息,如果存在特殊的考慮,也請注明;9) 修改履歷,其中請標(biāo)明: 1) 修改序號(No.); 2) 修改對應(yīng)版本號(Version); 3) 修改日期(Date); 4) 修改人(Revised By); 5) 修改項(Item); 6) 修改描述(Description):請注明修改的原因和對策,如果存在特殊的考慮,也請注明;注意點:修改履歷的紀(jì)錄一般在V0.80 之后開始。但是,如果目前ver0.80 的完成度和質(zhì)量普遍很低,因此在具體的項目中可以考慮提高開始紀(jì)錄修改履歷的版本號。文件頭說明實例文件頭說明實例72 2、命名規(guī)范、命名規(guī)范規(guī)范規(guī)范2.1 2.1 關(guān)于文件標(biāo)識符命

8、名規(guī)則,請遵照以下規(guī)范:關(guān)于文件標(biāo)識符命名規(guī)則,請遵照以下規(guī)范: 文件標(biāo)識符分為兩部分,即文件名前綴和后綴。格式如下:. . 1、文件名前綴表示該文件的內(nèi)容或作用,可以由項目組成員統(tǒng)一約定。最好不要超過8 個字符;文件名前綴的最前面要使用范圍限定符模塊名(文件名)縮寫; 2、文件名后綴表示該文件的類型,該部分最多為3個字符: 源文件:.c; 頭文件:.h; 其它類型文件:如.tbl文件等,使用之前進行統(tǒng)一規(guī)定。 3、前綴和后綴這兩部分字符應(yīng)僅使用字母、數(shù)字和下劃線。文件標(biāo)識的長度不能超過32 個字符,以便于識別; 4、本規(guī)范建議文件名全部使用大寫。82 2、命名規(guī)范、命名規(guī)范規(guī)范規(guī)范2.2 2

9、.2 關(guān)于模塊標(biāo)識符命名規(guī)則:關(guān)于模塊標(biāo)識符命名規(guī)則: 1、模塊名就是范圍限定符,各種全局全局標(biāo)識符(文件名、全局函數(shù)名、全局變量名等)的命名,必須使用范圍限定符作 為前綴。 2、模塊名必須進行適當(dāng)?shù)目s寫。例如Stand By 模塊,省略縮寫為STBY; 3、模塊名要求全部為大寫。規(guī)范規(guī)范2.3 2.3 關(guān)于關(guān)于C C標(biāo)識符命名規(guī)則,請按照標(biāo)識符前綴標(biāo)識符命名規(guī)則,請按照標(biāo)識符前綴 含含義標(biāo)識規(guī)范進行命名。義標(biāo)識規(guī)范進行命名。 標(biāo)識符前綴由以下元素構(gòu)成,各部分內(nèi)容需要遵守相應(yīng)定義: 范圍限定符前綴 作用域前綴 數(shù)據(jù)類型前綴 含義標(biāo)識 標(biāo)識符前綴 范圍限定符前綴的形式為:模塊名 + 下劃線,即模

10、塊名_92 2、命名規(guī)范、命名規(guī)范作用域前綴:NO標(biāo)識符類型作用域前綴1Global Variable W 2File Static Variable n 3Function Static Variable fn 4Auto Variable a 5Global Function w 6Static Function n 數(shù)據(jù)類型前綴:1、參照Microsoft 的匈牙利標(biāo)記法;2、對于用戶自定義的類型(enum、struct、union),變量類型不做區(qū)分,統(tǒng)一使用“st”。102 2、命名規(guī)范、命名規(guī)范No. Data Type Prefix Example 1bit btbit btVa

11、riable; 2boolean bboolean bVariable; 3char cchar cVariable; 4intiint i; 5shortint sshortint sVariable; 6longint llongint lVariable; 7unsignedint uunsignedint uiVariable; 8double ddouble dVariable; 9float ffloat fVariable; 10pointer pvoid *pvVariable; 11void v/vdvoid *pvVariable; 12array of achar acV

12、ariableTABLE_MAX; 112 2、命名規(guī)范、命名規(guī)范含義標(biāo)識的命名: 1、各單詞的開頭用大寫字母,其余用小寫字母,省略用語除 外; 2、禁止在數(shù)據(jù)命名的一部分插入數(shù)字(數(shù)學(xué)公式例外); 3、進行命名的時候,在充分把握數(shù)據(jù)對象(變量、函數(shù)等) 的內(nèi)容含義的基礎(chǔ)上,進行能明確顯示其內(nèi)容的命名(見 名知意)。 1)變量含義標(biāo)識符構(gòu)成:目標(biāo)詞+動詞(過去分詞)+狀語+目 的地; 2)函數(shù)含義標(biāo)識符構(gòu)成:動詞(一般現(xiàn)時)+目標(biāo)詞+狀語+目 的地; Example:變量:DataGotFromCD /*從CD中取得的數(shù)據(jù)*/ DataDeletedFromCD /*從CD中刪除數(shù)據(jù) */ 函

13、數(shù):GetDataFromCD DeleteDataFromCD122 2、命名規(guī)范、命名規(guī)范NO.分類舉例說明1變量定義具有全局作用域 INT8U AMM_wucDDMDataEnable;2變量定義具有局部作用域 INT8U aucBeepType;3函數(shù)定義具有局部作用域static void nvdAPIAmmKeyOutUp(void)4結(jié)構(gòu)體定義具有局部作用域 typedef struct INT8U ucSize;INT8U aucReceiverIDRECEIVERID_SIZE;INT8U *pucReceiverBuff;SDARS_DispReceiverID_st,*p

14、SDARS_DispRec eiverID_st;pSDARS_DispReceiverID_st apstDispReceiverI 133 3、標(biāo)識符和常量、標(biāo)識符和常量規(guī)范規(guī)范3.1 3.1 標(biāo)識符的內(nèi)部有效字符和外部有效字符不能多于標(biāo)識符的內(nèi)部有效字符和外部有效字符不能多于31 31 。 便于編譯器識別,代碼清晰易讀,并保證可移植性。規(guī)范規(guī)范3.2 3.2 具有內(nèi)部作用域的標(biāo)識符,不應(yīng)與具有外部作用域的標(biāo)具有內(nèi)部作用域的標(biāo)識符,不應(yīng)與具有外部作用域的標(biāo)識符重名,這會隱藏了外部標(biāo)識符(同一文件)識符重名,這會隱藏了外部標(biāo)識符(同一文件)。 在嵌套的范圍中使用相同名稱的標(biāo)識符會使得代碼非常

15、混亂,例如: INT16U i; /* 該變量具有外部作用域 */INT16U i; /* 定義了一個具有內(nèi)部作用域的變量*/i = 3; /* NG :外部作用域變量被隱藏,容易引起代 碼混亂 */規(guī)范規(guī)范3.3 3.3 靜態(tài)變量和全局變量的標(biāo)識符不能重名(不同文件)。靜態(tài)變量和全局變量的標(biāo)識符不能重名(不同文件)。143 3、標(biāo)識符和常量、標(biāo)識符和常量例file1.cstatic INT8U nucVar1; /* NG:多個 file 中進行了定義 */void nvdfunc1(void)file2.cINT8U nucVar1; /* NG:多個 file 中進行了定義 */INT8

16、U nucVar2;void nvdfunc2(void)153 3、標(biāo)識符和常量、標(biāo)識符和常量規(guī)范規(guī)范3.4 3.4 一個命名空間中與另外一個命名空間中不應(yīng)存在拼寫相一個命名空間中與另外一個命名空間中不應(yīng)存在拼寫相同的標(biāo)識符,除了結(jié)構(gòu)和聯(lián)合中的成員名字。同的標(biāo)識符,除了結(jié)構(gòu)和聯(lián)合中的成員名字。 例例1: NG:在不同命名空間之間的標(biāo)識符再次被使用:在不同命名空間之間的標(biāo)識符再次被使用 struct stag INT8U ucVar1; INT8U ucVar2; stag_st; void nvdnvdfunc2(void) INT8U stag; /* NG:與結(jié)構(gòu)體重名:與結(jié)構(gòu)體重名 *

17、/ INT8U ucVar1; /* NG:與結(jié)構(gòu)體成員重名:與結(jié)構(gòu)體成員重名*/ 例例2 OK:結(jié)構(gòu)體或者共用體的成員名分別命名:結(jié)構(gòu)體或者共用體的成員名分別命名 struct stag1 INT8U ucVar1; INT8U ucVar2; ; struct stag2 INT8U ucVar1; /* OK */ INT8U ucVar2; /* OK */;union stag3 INT8U ucVar1; /* OK */ INT16U uiVar2; ;163 3、標(biāo)識符和常量、標(biāo)識符和常量規(guī)范規(guī)范3.5 3.5 標(biāo)簽字段標(biāo)簽字段( (成員列表的名字成員列表的名字) )必須是唯一

18、的標(biāo)識符。程序必須是唯一的標(biāo)識符。程序中標(biāo)簽的名字不可重用。例如:中標(biāo)簽的名字不可重用。例如:typedef struct stag INT8U ucOption1;INT8U ucOption2;MSG_st;typedef struct stag /* NG: stag 標(biāo)簽定義重復(fù)了*/INT8U ucWidth;INT8U ucHeight;BOX_st;規(guī)范規(guī)范3.6 3.6 不應(yīng)使用八進制常量不應(yīng)使用八進制常量( (零除外零除外) )和八進制轉(zhuǎn)義序列。和八進制轉(zhuǎn)義序列。 提高程序的可讀性,避免產(chǎn)生混淆。因為八進制非零常量和轉(zhuǎn)義字符必須以“0”開始。174 4、類型和類型轉(zhuǎn)換、類型和

19、類型轉(zhuǎn)換規(guī)范規(guī)范4.1 4.1 不要單獨的使用不要單獨的使用charchar類型,應(yīng)該使用類型,應(yīng)該使用signed charsigned char和和unsigned charunsigned char類型替代。類型替代。例char aacVar = “abcde”; /* NG */INT8U aucVar = 234; /* OK */INT8S ascVar = a; /* OK */規(guī)范規(guī)范4.2 4.2 位域只能被定義為位域只能被定義為unsigned intunsigned int或或singed intsinged int類型。類型。 位域的存儲空間分配與各編譯器的實現(xiàn)有關(guān)。如

20、果位域類型 擴展(char, short, long 等 ),需要明確說明編譯器的支持 情況。規(guī)范規(guī)范4.3 4.3 應(yīng)該使用標(biāo)明了大小和符號的應(yīng)該使用標(biāo)明了大小和符號的typedeftypedef代替基本數(shù)據(jù)類代替基本數(shù)據(jù)類型。不應(yīng)使用基本數(shù)值類型型。不應(yīng)使用基本數(shù)值類型charchar、intint、shortshort、longlong、floatfloat和和doubledouble,而應(yīng)使用,而應(yīng)使用typedeftypedef進行類型的定義進行類型的定義( (見下表見下表) )。184 4、類型和類型轉(zhuǎn)換、類型和類型轉(zhuǎn)換No. 基本數(shù)據(jù)類型基本數(shù)據(jù)類型 typedef 定義定義 1

21、typedef unsigned charBOOLEAN; 2typedef unsigned char boolean; 3typedef unsigned char bit; 4typedef unsigned char INT8U; 5typedef signed char INT8S; 6typedef unsigned short int INT16U; 7typedef signed short int INT16S; 8typedef unsigned long int INT32U; 9typedef signed long int INT32S; 10typedef floa

22、t FP32; typedef 類型定義附表:194 4、類型和類型轉(zhuǎn)換、類型和類型轉(zhuǎn)換規(guī)范規(guī)范4.4 signed int4.4 signed int類型的位域至少應(yīng)該為類型的位域至少應(yīng)該為2 bits2 bits長度,因為長度,因為signed intsigned int類型數(shù)據(jù)的正負符號要占用一個類型數(shù)據(jù)的正負符號要占用一個bitbit。1 bit長度的有符號位域是無用的。例:struct stagsigned int uc4_bf1:1; /* NG */signed int uc4_bf2:4; /* OK */規(guī)范規(guī)范4.5 4.5 對于對于longlong型的整形常量應(yīng)該追加后綴

23、型的整形常量應(yīng)該追加后綴u(u(或或U),UL(U),UL(或或ul)ul)。提高代碼的可讀性。提高代碼的可讀性。例:INT32U aulVar32x;aulVar32x = aulVar32x + 3; /* NG*/aulVar32x = aulVar32x + 3u; /* OK*/注意點: 對char 和short類型沒有規(guī)定。204 4、類型和類型轉(zhuǎn)換、類型和類型轉(zhuǎn)換規(guī)范規(guī)范4.6 4.6 使用不同類型的變量進行賦值使用不同類型的變量進行賦值/ /運算的時候、一定要使運算的時候、一定要使用強制轉(zhuǎn)換運算符。防止由于隱式類型轉(zhuǎn)換,引起信息丟失。用強制轉(zhuǎn)換運算符。防止由于隱式類型轉(zhuǎn)換,引起

24、信息丟失。 例1 NG:數(shù)據(jù)被截斷extern INT16U nuifunc2( void );void nvdfunc1( )INT8U aucVar;aucVar = nuifunc2( ); /* NG:信息的一部丟失了*/ 例2 NG:浮點運算應(yīng)該注意的情況INT16U auiVar1, auiVer2;FP32 afVar3;auiVar1 = 1U;auiVer2 = 3U;afVar3 = auiVar1 / auiVer2; /* NG: 運算結(jié)果=0.0 */afVar3 = (FP32)auiVar1/(FP32)auiVer2; /* OK:運算結(jié)果=0.333 */21

25、4 4、類型和類型轉(zhuǎn)換、類型和類型轉(zhuǎn)換規(guī)范規(guī)范4.7 4.7 指針和整數(shù)之間的轉(zhuǎn)換、以及指針和浮點數(shù)之間的轉(zhuǎn)換指針和整數(shù)之間的轉(zhuǎn)換、以及指針和浮點數(shù)之間的轉(zhuǎn)換要避免。如果指針?biāo)赶虻念愋蛶в幸苊?。如果指針?biāo)赶虻念愋蛶в衏onst const 或或volatile volatile 限定符限定符,那么移除限定符的強制轉(zhuǎn)換是不允許的。,那么移除限定符的強制轉(zhuǎn)換是不允許的。下面的兩個例子:例1,意圖不明。例2,破壞數(shù)據(jù)的完整性。例1:NG,指針和整數(shù)間進行了轉(zhuǎn)換INT16U auiVar;INT8U *apucVar;apucVar = ( INT8U * ) auiVar; /* NG:整數(shù)和

26、指針間 進行轉(zhuǎn)換*/例2:NG,對volatile 限定符進行轉(zhuǎn)換volatile INT16U *wpuiVar;INT16U *apuiVar;apuiVar = (INT16U * ) wpuiVar; /* NG:對volatile 指 向的指針進行轉(zhuǎn)換*/ if( apuiVar = 0U )225 5、初始化聲明和定義、初始化聲明和定義規(guī)范規(guī)范5.1 5.1 自動變量在使用前都應(yīng)被賦值自動變量在使用前都應(yīng)被賦值。為避免錯誤嚴(yán)禁讀取未為避免錯誤嚴(yán)禁讀取未經(jīng)初始化的變量。經(jīng)初始化的變量。 本規(guī)范的意圖是,使所有變量在其被讀之前已經(jīng)寫過了,除了聲明中的初始化。自動存儲類型變量通常不是自動

27、初始化的。具有靜態(tài)存儲類型的變量,缺省地被自動賦予零值。 例 NG: 變量未初始化進行了使用void nvdfunc1( void )INT16U auiVar1 = 10;INT16U auiVar2;auiVar2 += auiVar1; /* NG */ 規(guī)范規(guī)范5.2 5.2 枚舉列表中不能顯式用于除首元素之外的元素枚舉列表中不能顯式用于除首元素之外的元素, ,除非所除非所有的元素都是顯式初始化的。有的元素都是顯式初始化的。 如果枚舉列表的成員沒有顯式地初始化,那么C將為其分配一個從0開始的整數(shù)序列。首元素為0,后續(xù)元素依次加1,這樣確保所用初始化值一定要足夠小,這樣列表中的后續(xù)值就不

28、會超出該枚舉常量所用的int存儲量。避免自動與手動分配的混合時易產(chǎn)生的錯誤。235 5、初始化聲明和定義、初始化聲明和定義規(guī)范5.2例: enum colour red = 3, blue, green, yellow = 5 ; /* NG : green 和 yellow 代表了相同的值,可能是非預(yù)期的 */ enum colour red = 3, blue = 4, green = 5, yellow = 5 ;/* OK : green 和 yellow 代表了相同的值,預(yù)期的 */規(guī)范規(guī)范5.3 5.3 局部變量的大小不要超過局部變量的大小不要超過64 bytes64 bytes。

29、以避免。以避免stackstack溢出溢出。如果局部變量確實過大,應(yīng)該定義成。如果局部變量確實過大,應(yīng)該定義成staticstatic全局變量或從堆中全局變量或從堆中分配。分配。245 5、初始化聲明和定義、初始化聲明和定義規(guī)范規(guī)范5.4 5.4 數(shù)組和結(jié)構(gòu)的非零初始化應(yīng)該使用大括號。數(shù)組和結(jié)構(gòu)的非零初始化應(yīng)該使用大括號。 數(shù)組結(jié)構(gòu)和聯(lián)合的初始化列表,要以一對大括號括起來。本規(guī)范更進一步地要求使用附加的大括號來指示嵌套的結(jié)構(gòu)。它迫使程序員顯式地考慮和描述復(fù)雜數(shù)據(jù)類型元素,另外也可以避免產(chǎn)生錯誤,提高程序的可讀性。比如多維數(shù)組的初始化次序:例:INT16U y32 = 1, 2, 3, 4, 5

30、, 6 ; /* NG: 未有效使用 */INT16U y32 = 1, 2 , 3, 4 , 5, 6 ; /* OK */struct stagINT16U uiMary11;INT16U uiMary22;struct stag astVar = 2, 2,3 ;255 5、初始化聲明和定義、初始化聲明和定義規(guī)范規(guī)范5.5 5.5 函數(shù)應(yīng)當(dāng)具有原型聲明,原型聲明在函數(shù)的定義范圍和函數(shù)應(yīng)當(dāng)具有原型聲明,原型聲明在函數(shù)的定義范圍和調(diào)用范圍內(nèi)都是可見的。調(diào)用范圍內(nèi)都是可見的。 原型的使用使得編譯器能夠檢查函數(shù)定義和調(diào)用的完整性。如果沒有原型就不會迫使編譯器檢查出函數(shù)調(diào)用當(dāng)中的一定錯誤(比如函數(shù)

31、體具有不同的參數(shù)數(shù)目,調(diào)用和定義之間參數(shù)類型的不匹配)。如下例:head.hextern void nvdfunc1( void );extern FP32 nvdfunc3( INT16U auiArg ); file_ok.c#include “head.h”void nvdfunc2( void );void nvdfunc2( void )afVar = nvdfunc3( auiVar ); /* OK:原型聲明可見 */265 5、初始化聲明和定義、初始化聲明和定義規(guī)范規(guī)范5.6 5.6 函數(shù)不應(yīng)該聲明為具有塊作用域。函數(shù)不應(yīng)該聲明為具有塊作用域。 在塊作用域中聲明函數(shù)會引起混淆,

32、并可能導(dǎo)致未定義的行為。例: void nvdfunc1( void ) extern INT32U nvdfunc2( void ); /* NG : 函數(shù)內(nèi)進行了聲明 */ static INT32U nvdfunc3( void ); /* NG : 函數(shù)內(nèi)進行了聲明 */nvdfunc3( ); 275 5、初始化聲明和定義、初始化聲明和定義規(guī)范規(guī)范5.7 5.7 如果對象的訪問只是在單一的文件(函數(shù))中,那么對如果對象的訪問只是在單一的文件(函數(shù))中,那么對象應(yīng)該在文件(函數(shù))范圍內(nèi)使用象應(yīng)該在文件(函數(shù))范圍內(nèi)使用staticstatic進行聲明。良好的編程進行聲明。良好的編程實踐

33、是盡量避免使用全局標(biāo)識符。實踐是盡量避免使用全局標(biāo)識符。 使用static存儲類標(biāo)識符將確保標(biāo)識符只是在聲明它的文件中是可 見的。避免了和其他文件或庫中的相同標(biāo)識符發(fā)生混淆的可能性。 例: 只在內(nèi)部使用的變量或者函數(shù),進行static定義static INT8U nucVar; /* OK */static void nvdfunc1( void )nucVar 1u;return nucVar;static void nvdfunc2( void ); /* OK:static定義 */static void nvdfunc1( void )nvdfunc2( );285 5、初始化聲明和定

34、義、初始化聲明和定義規(guī)范規(guī)范5.8 5.8 對外提供的變量或函數(shù)應(yīng)該在唯一的一個頭文件中進行對外提供的變量或函數(shù)應(yīng)該在唯一的一個頭文件中進行聲明,不要在源文件內(nèi)部直接聲明,更不允許在不同文件中進行聲明,不要在源文件內(nèi)部直接聲明,更不允許在不同文件中進行多次定義。多次定義。例:extern INT16U wuiVar1; head.h /* OK */file1.cINT16U wuiVar1; INT16U wuiVar2;file2.cINT16U wuiVar1; /* NG */規(guī)范規(guī)范5.9 5.9 當(dāng)一個數(shù)組聲明為具有外部鏈接當(dāng)一個數(shù)組聲明為具有外部鏈接, ,它的大小應(yīng)該顯式聲它的大

35、小應(yīng)該顯式聲明或者通過初始化進行隱式定義。明或者通過初始化進行隱式定義。例:INT8U array110; /* OK */extern INT8U array2; /* NG:未指定數(shù)組大小 */INT8U array2 = 0, 10, 15 ; /* OK: */規(guī)范規(guī)范5.10 5.10 所有的對象和函數(shù)標(biāo)識符在使用前必須聲明。所有的對象和函數(shù)標(biāo)識符在使用前必須聲明。296 6、控制語句和表達式、控制語句和表達式規(guī)范規(guī)范6.16.1不要過分依賴不要過分依賴C C表達式中缺省的運算符優(yōu)先級。表達式中缺省的運算符優(yōu)先級。 使用相當(dāng)復(fù)雜的C 運算符優(yōu)先級,很容易引起錯誤,使用括號可以避免這樣

36、的錯誤,并且可以使得代碼更為清晰,可讀。 例:下面表達式的計算結(jié)果為:INT8U aucVar,aucVarLow1, aucVarHi2;aucVar = aucVarHi 4 + aucVarLow; A. 33 B. 64 C. 17規(guī)范規(guī)范6.2 6.2 不能在具有副作用的表達式中使用不能在具有副作用的表達式中使用sizeof sizeof 運算符。運算符。 當(dāng)一個表達式使用了sizeof 運算符,并期望計算表達式的值時,表達式是不會被計算的。sizeof 只對表達式的類型有用。 例:auiVar2 = sizeof (auiVar1= 1234); /* NG:auiVar1 并沒有

37、被賦 值1234 */規(guī)范規(guī)范6.3 6.3 邏輯運算符邏輯運算符 & & 或或 | | 的右手操作數(shù)不能包含副作用。的右手操作數(shù)不能包含副作用。 例:INT16U auiVar1, auiVar2, auiVar3; if( (auiVar1 != 0U) & (auiVar2 = auiVar3+ ) ) /* NG :auiVar3+包含副作用*/306 6、控制語句和表達式、控制語句和表達式規(guī)范規(guī)范6.4 6.4 邏輯運算(邏輯運算(&、| | | | 和和 ! ! )直接用到的操作數(shù)應(yīng)該是)直接用到的操作數(shù)應(yīng)該是布爾類型的,而布爾類型表達式也不能用做非

38、邏輯運算。布爾類型的,而布爾類型表達式也不能用做非邏輯運算。規(guī)范規(guī)范6.5 6.5 位運算符不能用于基本類型位運算符不能用于基本類型(underlying type)(underlying type)是有符是有符號的操作數(shù)上號的操作數(shù)上 。位運算。位運算(,& &, 和和 | )| )對有符號整數(shù)對有符號整數(shù)通常是無意義的。比如,如果右移運算把符號位移動到數(shù)據(jù)位上通常是無意義的。比如,如果右移運算把符號位移動到數(shù)據(jù)位上,或者左移運算把數(shù)據(jù)位移動到符號位上就會產(chǎn)生問題,或者左移運算把數(shù)據(jù)位移動到符號位上就會產(chǎn)生問題 。規(guī)范規(guī)范6.6 6.6 在一個表達式中,自增在一個表達式中,自

39、增+和自減和自減-運算符運算符, ,不應(yīng)同其他不應(yīng)同其他運算符混合在一起。運算符混合在一起。 不建議使用同其他算術(shù)運算符混合在一起的自增和自減運算符是因為1)它顯著削弱了代碼的可讀性; 2)在不同的變異環(huán)境下,會執(zhí)行不同的運算次序,產(chǎn)生不同結(jié)果。 例:INT16U auiVar, auiCnt, auiAry10; auiVar = auiAryauiCnt + auiCnt+; /* NG */316 6、控制語句和表達式、控制語句和表達式規(guī)范規(guī)范6.7 6.7 浮點表達式不能做相等或不等的判斷。浮點表達式不能做相等或不等的判斷。 浮點型變量無論是float還是double類型的變量,都有精

40、度限制。規(guī)范規(guī)范6.8 for6.8 for語句的三個表達式應(yīng)該只關(guān)注循環(huán)控制。語句的三個表達式應(yīng)該只關(guān)注循環(huán)控制。for 語句的三個表達式都給出時它們應(yīng)該只用于如下目的:第一個表達式初始化循環(huán)計數(shù)器;第二個表達式包含對循環(huán)計數(shù)器和其他可選的循環(huán)控制變量的測試;第三個表達式循環(huán)計數(shù)器的遞增或遞減。 例:for( auiCnt = 0U; auiCnt =10U; auiVar = 2U * auiVar + auiCnt * 10U, auiCnt+ ) /* NG*/ 規(guī)范規(guī)范6.9 for6.9 for循環(huán)中用于計數(shù)的變量不應(yīng)在循環(huán)體中修改。但是循環(huán)中用于計數(shù)的變量不應(yīng)在循環(huán)體中修改。但是

41、,如果變量不是用作計數(shù)器而是用于循環(huán)結(jié)束,那么可以修改。,如果變量不是用作計數(shù)器而是用于循環(huán)結(jié)束,那么可以修改。 例:aucflag = 1;for ( i = 0; ( i 5 ) & (aucflag = 1 ); i+)aucflag = 0; /* OK */i = i + 3; /* NG*/ 326 6、控制語句和表達式、控制語句和表達式規(guī)范規(guī)范6.10 6.10 組成組成switchswitch、whilewhile、do.while do.while 或或for for 結(jié)構(gòu)體的語結(jié)構(gòu)體的語句應(yīng)該是復(fù)合語句。即使該復(fù)合語句只包含一條語句也要擴在句應(yīng)該是復(fù)合語句。即使該復(fù)

42、合語句只包含一條語句也要擴在里。里。例:NG,沒有包括在大括號里for ( i = 0 ; i N_ELEMENTS ; +i )bufferi = 0;規(guī)范規(guī)范6.11 if /else6.11 if /else應(yīng)該成對出現(xiàn)。所有的應(yīng)該成對出現(xiàn)。所有的if . else if if . else if 結(jié)構(gòu)結(jié)構(gòu)應(yīng)該由應(yīng)該由else else 子句結(jié)束。子句結(jié)束。規(guī)范規(guī)范6.12 switch 6.12 switch 語句中如果語句中如果case case 分支的內(nèi)容不為空,那么必分支的內(nèi)容不為空,那么必須以須以break break 作為終了。作為終了。 如果case 分支的內(nèi)容不以brea

43、k 終了的話,開發(fā)者的意圖不是很 明確,存在編程錯誤的可能性,代碼的可讀性降低。規(guī)范規(guī)范6.13 switch 6.13 switch 語句的最后分支應(yīng)該是語句的最后分支應(yīng)該是defaultdefault分支。分支。337 7、函數(shù)、函數(shù)規(guī)范規(guī)范7.1 7.1 一定要顯示聲明函數(shù)的返回值類型,及所帶的參數(shù)。如一定要顯示聲明函數(shù)的返回值類型,及所帶的參數(shù)。如果沒有要聲明為果沒有要聲明為voidvoid。 C語言中不加類型說明的函數(shù),一律自動按整型處理。規(guī)范規(guī)范7.2 7.2 在函數(shù)的原型聲明中應(yīng)包含所有參數(shù),不允許只包含參在函數(shù)的原型聲明中應(yīng)包含所有參數(shù),不允許只包含參數(shù)類型的聲明方式;沒有參數(shù)

44、時以數(shù)類型的聲明方式;沒有參數(shù)時以“void”void”填充。填充。 提高移植性,避免在某些編譯器下編譯不過的情況。例: void nvdfunc( INT32U aulArg1, INT16U, INT32U aulArg4 ); /*NG*/ void nvdfunc( INT32U aulSrc, INT16U auiWidth, INT32U aulList ); /* OK */ void nvdfunc( INT32U, INT16U, INT32U ); /* NG*/規(guī)范規(guī)范7.3 7.3 函數(shù)的聲明和定義中使用的標(biāo)識符函數(shù)的聲明和定義中使用的標(biāo)識符( (參數(shù)名參數(shù)名) )應(yīng)該

45、一致。應(yīng)該一致。規(guī)范規(guī)范7.4 7.4 函數(shù)原型中的指針參數(shù)函數(shù)原型中的指針參數(shù) ,如果不是用于修改所指向的,如果不是用于修改所指向的對象,就應(yīng)該聲明為指向?qū)ο螅蛻?yīng)該聲明為指向const const 的指針。的指針。 例:void nvdfunc ( INT16U *piParam1, const INT16U *piParam2, INT16U *piParam3 )*piParam1 = *piParam2 + *piParam3; /* NG:param3 沒有聲 明為const */ 347 7、函數(shù)、函數(shù)規(guī)范規(guī)范7.5 7.5 函數(shù)調(diào)用時,只能使用加前綴函數(shù)調(diào)用時,只能使用加前綴&

46、amp; &,或者使用括起來的參,或者使用括起來的參數(shù)列表,沒有參數(shù)時,列表可以為空。數(shù)列表,沒有參數(shù)時,列表可以為空。 例:extern INT16U nvdfunc2( void ); void nvdfunc( void ) if (nvdfunc2) /* NG:請使用nvdfunc2( ) 或者&nvdfunc2 */ 規(guī)范規(guī)范7.6 7.6 不提倡使用遞歸函數(shù)調(diào)用。遞歸本身存在堆??臻g使不提倡使用遞歸函數(shù)調(diào)用。遞歸本身存在堆??臻g使用過度的危險,這能導(dǎo)致嚴(yán)重的錯誤。除非遞歸經(jīng)過了非常嚴(yán)格用過度的危險,這能導(dǎo)致嚴(yán)重的錯誤。除非遞歸經(jīng)過了非常嚴(yán)格的控制。的控制。規(guī)范規(guī)范

47、7.7 7.7 如果不需要修改輸入?yún)?shù)的值,將變量值作為參數(shù)進行如果不需要修改輸入?yún)?shù)的值,將變量值作為參數(shù)進行函數(shù)參數(shù)傳遞,而不是地址。提高代碼性能和效率,防止誤修函數(shù)參數(shù)傳遞,而不是地址。提高代碼性能和效率,防止誤修改。改。357 7、函數(shù)、函數(shù)規(guī)范規(guī)范7.8 7.8 注意控制參數(shù)的數(shù)量,一般來說不要超過注意控制參數(shù)的數(shù)量,一般來說不要超過5 5個,當(dāng)參數(shù)個,當(dāng)參數(shù)過多時,應(yīng)該考慮將參數(shù)定義為一個結(jié)構(gòu)體,并且將結(jié)構(gòu)體指針過多時,應(yīng)該考慮將參數(shù)定義為一個結(jié)構(gòu)體,并且將結(jié)構(gòu)體指針作為參數(shù)。作為參數(shù)。 這樣可以減少對堆棧的占用量。規(guī)范規(guī)范7.9 7.9 函數(shù)傳遞的參數(shù)中結(jié)構(gòu)體使用指針,可以減少參

48、數(shù)本身函數(shù)傳遞的參數(shù)中結(jié)構(gòu)體使用指針,可以減少參數(shù)本身處理的開銷處理的開銷, , 減少堆棧的占用量。減少堆棧的占用量。 這樣也可以使代碼更加規(guī)范。規(guī)范規(guī)范7.10 7.10 函數(shù)的大小不要過長,一般定為函數(shù)的大小不要過長,一般定為200200行以內(nèi)(除去注釋行以內(nèi)(除去注釋,空行,變量定義,調(diào)試開關(guān)等)。,空行,變量定義,調(diào)試開關(guān)等)。 限制函數(shù)的規(guī)模有助于函數(shù)功能的正確性和維護。368 8、指針和數(shù)組、指針和數(shù)組規(guī)范規(guī)范8.18.1除了指向同一數(shù)組的指針外,不能用指針進行數(shù)學(xué)運算除了指向同一數(shù)組的指針外,不能用指針進行數(shù)學(xué)運算。規(guī)范規(guī)范8.28.2除了指向同一數(shù)組的指針外,不能用指針進行關(guān)系

49、運算除了指向同一數(shù)組的指針外,不能用指針進行關(guān)系運算。 這樣做的目的一是使代碼清晰易讀,另外避免訪問無效的內(nèi)存地址。規(guī)范規(guī)范8.3 8.3 指針在使用前一定要賦值,避免產(chǎn)生野指針。指針在使用前一定要賦值,避免產(chǎn)生野指針。 例:void nvdfunc( void ) int i; int *p; i = 10; *p = i; /*NG*/ 規(guī)范規(guī)范8.4 8.4 分配內(nèi)存后要立刻判斷指針是否為分配內(nèi)存后要立刻判斷指針是否為NULLNULL。 如果對一個NULL指針進行間接訪問,它的結(jié)果因編譯器而異,有些機器它會訪問內(nèi)存位置零;有些機器將引發(fā)一個錯誤并終止程序。指針變量不能自動被初始化為NUL

50、L。378 8、指針和數(shù)組、指針和數(shù)組規(guī)范規(guī)范8.5 8.5 不要返回局部變量的地址。不要返回局部變量的地址。 局部變量是在棧中分配的,函數(shù)返回后占用的內(nèi)存會釋放,繼續(xù)使用這樣的內(nèi)存是危險的。因此,應(yīng)該避免出現(xiàn)這樣的危險。例:extern void nvdfunc1( INT16U * );INT16U *npuiVar;void nvdfunc1(INT16U * apuiArg )npuiVar = apuiArg; /* NG */規(guī)范規(guī)范8.6 8.6 字符數(shù)組的定義和初始化要考慮字符數(shù)組的定義和初始化要考慮00。 例: char hello5 = Hello; /* NG */規(guī)范規(guī)范8.7 8.7 指針指向的內(nèi)存被釋放后,該指針要立刻賦值為指針指向的內(nèi)存被釋放后,該指針要立刻賦值為NUL

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論