新聞中心

EEPW首頁(yè) > 設(shè)計(jì)應(yīng)用 > 一文讀懂|C語(yǔ)言編碼規(guī)范

一文讀懂|C語(yǔ)言編碼規(guī)范

作者: 時(shí)間:2024-12-17 來(lái)源: 收藏

剛開(kāi)始學(xué)STM32的時(shí)候,看到一些比較規(guī)范的代碼中的一些變量命名為ucValue 、g_ucPara等形式,為什么要加ucg_uc等,這些前綴都有其約定俗成的意思,可以方便的知道變量的數(shù)據(jù)類(lèi)型。如:uc代表的是unsigned char,所以一個(gè)變量命名為ucValue就可以清楚的表明其為unsigned char的變量 。同樣的,g代表global,即全局的g_ucPara表明其為unsigned char類(lèi)型的全局變量。

本文引用地址:http://2s4d.com/article/202412/465559.htm

每個(gè)公司都有每個(gè)公司的規(guī)范,今天我們來(lái)看網(wǎng)上的一些比較權(quán)威的規(guī)范,比如安富萊的規(guī)范:

文件與目錄

(1)文件的命名

文件的命名要準(zhǔn)確清晰地表達(dá)其內(nèi)容,同時(shí)文件名應(yīng)該精練,防止文件名過(guò)長(zhǎng)而造成使用不便。在文件名中可以適當(dāng)?shù)厥褂每s寫(xiě)。以下提供兩種命名方式以供參考:

  • 各程序模塊的文件命名開(kāi)頭 2 個(gè)消協(xié)字母代表本模塊的功能:

如:主控程序?yàn)?nbsp;mpMain.c,mpDisp.c 等。

  • 不寫(xiě)模塊功能標(biāo)識(shí):

如:主控程序?yàn)?nbsp;Main.c,Disp.c 等。

(2)頭文件中段落安排順序

// 1、文件頭注釋
// 2、防止重復(fù)引用頭文件的設(shè)置
// 3、#include 部分
// 4、enum 常量聲明
// 5、類(lèi)型聲明和定義,包括 struct、union、typedef 等
// 6、全局變量聲明
// 7、文件級(jí)變量聲明
// 8、全局或文件級(jí)函數(shù)聲明
// 9、函數(shù)實(shí)現(xiàn)。按函數(shù)聲明的順序排列
// 10、文件尾注釋

(3)在引用頭文件時(shí),不要使用絕對(duì)路徑

如果使用絕對(duì)路徑,當(dāng)需要移動(dòng)目錄時(shí),必須修改所有相關(guān)代碼,繁瑣且不安全;使用相對(duì)路徑,當(dāng)需要移動(dòng)目錄時(shí),只需修改編譯器的某個(gè)選項(xiàng)即可。例如:

#include “/project/inc/hello.h” /* 不應(yīng)使用絕對(duì)路徑 */
#include “../inc/hello.h”            /* 可以使用相對(duì)路徑 */

(4)在引用頭文件時(shí) ,使用<>還是""        

#include <stdio.h>          /* 標(biāo)準(zhǔn)頭文件 */
#include <projdefs.h>     /* 工程制定目錄頭文件 */
#include “global.h”         /* 當(dāng)前目錄頭文件 */
#include “inc/config.h” /* 路徑相對(duì)于當(dāng)前目錄的頭文件 */

(5)防止頭文件被重復(fù)引用

#ifndef __DISP_H /* 文件名前名加兩個(gè)下劃線“__”,后面加 “_H”
#define __DISP_H
...
...
#endif

(6)頭文件中只存放“聲明”而不存放“定義”

640.png

(7)文件的長(zhǎng)度

文件的長(zhǎng)度沒(méi)有非常嚴(yán)格的要求,但應(yīng)盡量避免文件過(guò)長(zhǎng)。一般來(lái)說(shuō),文件長(zhǎng)度應(yīng)盡量保持在 1000 行之內(nèi) 。

排版

(1)程序塊要采用縮進(jìn)風(fēng)格編寫(xiě),縮進(jìn)的空格數(shù)為 4 個(gè)。

(2)相對(duì)獨(dú)立的程序塊之間、變量說(shuō)明之后必須加空行 。

640-2.png

(3) 較長(zhǎng)的語(yǔ)句或函數(shù)過(guò)程參數(shù)(>80 字符)要分成多行書(shū)寫(xiě),長(zhǎng)表達(dá)式要在低優(yōu)先級(jí)操作符處劃分新行,操作符放在新行之首,劃分出的新行要進(jìn)行適當(dāng)?shù)目s進(jìn),使排版整齊,語(yǔ)句可讀。

640-3.png

(4) 不允許把多個(gè)短語(yǔ)句寫(xiě)在一行中,即一行只寫(xiě)一條語(yǔ)句

640-4.png

(5)程序塊的分界符(如大括號(hào)‘{’和‘}’ )應(yīng)各獨(dú)占一行并且位于同一列

640-5.png

(6) 在兩個(gè)以上的關(guān)鍵字、變量、常量進(jìn)行對(duì)等操作時(shí),它們之間的操作符之前、之后或者前后要加空格;進(jìn)行非對(duì)等操作時(shí),如果是關(guān)系密切的立即操作符(如->),后不應(yīng)加空格。

示例:

  • 逗號(hào)、分號(hào)只在后面加空格。

640-6.png

  • 比較操作符,賦值操作符"="、 "+=",算術(shù)操作符"+"、"%",邏輯操作符"&&"、"&",位域操作符"<<"、"^"等雙目操作符的前后加空格。

640-7.png

  • "!"、"~"、"++"、"--"、"&"(地址運(yùn)算符)等單目操作符前后不加空格。

640-8.png

  • "->"、"."前后不加空格。

640-9.png

  • if、for、while、switch 等與后面的括號(hào)間應(yīng)加空格,使 if 等關(guān)鍵字更為突出、明顯,函數(shù)名與其后的括號(hào)之間不加空格,以與保留字區(qū)別開(kāi)。

640-10.png

注釋

(1) 一般的,源程序有效注釋量必須在 20%以上。

說(shuō)明:注釋的原則是有助于對(duì)程序的閱讀理解,在該加的地方都加,注釋不宜太多也不能太少,注釋語(yǔ)言必須準(zhǔn)確、易懂、簡(jiǎn)潔 。

(2) 在文件的開(kāi)始部分,應(yīng)該給出關(guān)于文件版權(quán)、內(nèi)容簡(jiǎn)介、修改歷史等項(xiàng)目的說(shuō)明。

在創(chuàng)建代碼和每次更新代碼時(shí),都必須在文件的歷史記錄中標(biāo)注版本號(hào)、日期、作者、更改說(shuō)明等項(xiàng)目。下面是一個(gè)范例,當(dāng)然,并不局限于此格式,但上述信息建議要包含在內(nèi)。

640-11.png

(3)對(duì)于函數(shù),在函數(shù)實(shí)現(xiàn)之前,應(yīng)該給出和函數(shù)的實(shí)現(xiàn)相關(guān)的足夠而精練的注釋信息。

示例:

下面這段函數(shù)的注釋比較標(biāo)準(zhǔn),當(dāng)然,并不局限于此格式,但上述信息建議要包含在內(nèi)。

640-12.png

(4) 邊寫(xiě)代碼邊注釋?zhuān)薷拇a同時(shí)修改相應(yīng)的注釋?zhuān)员WC注釋與代碼的一致性。不再有用的注釋要?jiǎng)h除。

(5) 注釋的內(nèi)容要清楚、明了,含義準(zhǔn)確,防止注釋二義性。

說(shuō)明:錯(cuò)誤的注釋不但無(wú)益反而有害。注釋主要闡述代碼做了什么(What),或者如果有必要的話(huà),闡述為什么要這么做(Why),注釋并不是用來(lái)闡述它究竟是如何實(shí)現(xiàn)算法(How)的。

(6) 避免在注釋中使用縮寫(xiě),特別是非常用縮寫(xiě)。

說(shuō)明:在使用縮寫(xiě)時(shí)或之前,應(yīng)對(duì)縮寫(xiě)進(jìn)行必要的說(shuō)明。

(7) 注釋?xiě)?yīng)與其描述的代碼靠近,對(duì)代碼的注釋?xiě)?yīng)放在其上方或右方(對(duì)單條語(yǔ)句的注釋?zhuān)┫噜徫恢茫豢煞旁谙旅?,如放于上方則需與其上面的代碼用空行隔開(kāi)。

示例:如下例子不符合規(guī)范。

例 1:不規(guī)范的寫(xiě)法

640-13.png

例 2:不規(guī)范的寫(xiě)法

640-14.png

例 3:規(guī)范的寫(xiě)法

640-15.png

例 4:不規(guī)范的寫(xiě)法,顯得代碼過(guò)于緊湊

640-16.png

例 5:規(guī)范的寫(xiě)法

640-17.png

(8) 注釋與所描述內(nèi)容進(jìn)行同樣的縮排。

說(shuō)明:可使程序排版整齊,并方便注釋的閱讀與理解。

例 1:如下例子,排版不整齊,閱讀稍感不方便。

640-18.png

例 2:正確的布局。

640-19.png

(9) 對(duì)變量的定義和分支語(yǔ)句(條件分支、循環(huán)語(yǔ)句等)必須編寫(xiě)注釋。

說(shuō)明:這些語(yǔ)句往往是程序?qū)崿F(xiàn)某一特定功能的關(guān)鍵,對(duì)于維護(hù)人員來(lái)說(shuō),良好的注釋幫助更好的理解程序,有時(shí)甚至優(yōu)于看設(shè)計(jì)文檔。

(10) 對(duì)于 switch 語(yǔ)句下的 case 語(yǔ)句,如果因?yàn)樘厥馇闆r需要處理完一個(gè) case 后進(jìn)入下一個(gè) case 處理,必須在該 case 語(yǔ)句處理完、下一個(gè) case 語(yǔ)句前加上明確的注釋。

說(shuō)明:這樣比較清楚程序編寫(xiě)者的意圖,有效防止無(wú)故遺漏 break 語(yǔ)句。

示例(注意斜體加粗部分):

640-20.png

(11) 注釋格式盡量統(tǒng)一,建議使用“/* …… */”,因?yàn)?C++注釋“//”并不被所有 C 編譯器支持。

(12) 注釋?xiě)?yīng)考慮程序易讀及外觀排版的因素,使用的語(yǔ)言若是中、英兼有的,建議多使用中文,除非能非常流利準(zhǔn)確的用英文表達(dá)。

說(shuō)明:注釋語(yǔ)言不統(tǒng)一,影響程序易讀性和外觀排版,出于對(duì)維護(hù)人員的考慮,建議使用中文。

(13) 標(biāo)識(shí)符的命名要清晰、明了,有明確含義,同時(shí)使用完整的單詞或大家基本可以理解的縮寫(xiě),避免使人產(chǎn)生誤解。

說(shuō)明:較短的單詞可通過(guò)去掉“元音”形成縮寫(xiě);較長(zhǎng)的單詞可取單詞的頭幾個(gè)字母形成縮寫(xiě);一些單詞有大家公認(rèn)的縮寫(xiě)。

示例:如下單詞的縮寫(xiě)能夠被大家基本認(rèn)可。

temp 可縮寫(xiě)為 tmp;
flag 可縮寫(xiě)為 flg;
statistic 可縮寫(xiě)為 stat;
increment 可縮寫(xiě)為 inc;
message 可縮寫(xiě)為 msg;


(14) 命名中若使用特殊約定或縮寫(xiě),則要有注釋說(shuō)明。

說(shuō)明:應(yīng)該在源文件的開(kāi)始之處,對(duì)文件中所使用的縮寫(xiě)或約定,特別是特殊的縮寫(xiě),進(jìn)行必要的注釋說(shuō)明。

(15) 自己特有的命名風(fēng)格,要自始至終保持一致,不可來(lái)回變化。

說(shuō)明:個(gè)人的命名風(fēng)格,在符合所在項(xiàng)目組或產(chǎn)品組的命名規(guī)則的前提下,才可使用。(即命名規(guī)則中沒(méi)有規(guī)定到的地方才可有個(gè)人命名風(fēng)格)

(16) 對(duì)于變量命名,禁止取單個(gè)字符(如 i、j、k…)

建議除了要有具體含義外,還能表明其變量類(lèi)型、數(shù)據(jù)類(lèi)型等,但 i、j、k 作局部循環(huán)變量是允許的。

變量,尤其是局部變量,如果用單個(gè)字符表示,很容易敲錯(cuò)(如i寫(xiě)成j),而編譯時(shí)又檢查不出來(lái),有可能為了這個(gè)小小的錯(cuò)誤而花費(fèi)大量的查錯(cuò)時(shí)間 。

(17) 命名規(guī)范必須與所使用的系統(tǒng)風(fēng)格保持一致,并在同一項(xiàng)目中統(tǒng)一

比如采用 UNIX 的全小寫(xiě)加下劃線的風(fēng)格或大小寫(xiě)混排的方式,不要使用大小寫(xiě)與下劃線混排的方式,用作特殊標(biāo)識(shí)如標(biāo)識(shí)成員變量或全局變量的 m_和 g_,其后加上大小寫(xiě)混排的方式是允許的。
示例:Add_User不允許,add_user、AddUser、m_AddUser允許。

(18) 除非必要,不要用數(shù)字或較奇怪的字符來(lái)定義標(biāo)識(shí)符。

示例:如下命名,使人產(chǎn)生疑惑。

640-21.png

應(yīng)改為有意義的單詞命名:

640-22.png

可讀性

(1) 注意運(yùn)算符的優(yōu)先級(jí),并用括號(hào)明確表達(dá)式的操作順序,避免使用默認(rèn)優(yōu)先級(jí)。

640-23.png

(2) 避免使用不易理解的數(shù)字,用有意義的標(biāo)識(shí)來(lái)替代。

示例:如下的程序可讀性差

640-24.png

應(yīng)改為如下形式 :

640-25.png

(3) 不要使用難懂的技巧性很高的語(yǔ)句,除非很有必要時(shí)。

說(shuō)明:高技巧語(yǔ)句不等于高效率的程序,實(shí)際上程序的效率關(guān)鍵在于算法。

示例:如下表達(dá)式,考慮不周就可能出問(wèn)題,也較難理解。

640-26.png

應(yīng)分別改為如下:

640-27.png

變量、結(jié)構(gòu)、常量、宏

(1) 為了方便書(shū)寫(xiě)及記憶,變量類(lèi)型采用如下重定義:

640-28.png

(2) 常見(jiàn)類(lèi)型的前綴

  • 對(duì)于一些常見(jiàn)類(lèi)型的變量,應(yīng)在其名字前標(biāo)注表示其類(lèi)型的前綴。前綴用小寫(xiě)字母表示。前綴的使用請(qǐng)參照下列表格中說(shuō)明。

640-29.png

(3) 變量作用域的前綴

為了清晰的標(biāo)識(shí)變量的作用域,減少發(fā)生命名沖突,應(yīng)該在變量類(lèi)型前綴之前再加上表示變量作用域的前綴,并在變量類(lèi)型前綴和變量作用域前綴之間用下劃線 - 隔開(kāi)。

具體的規(guī)則如下:

  • 對(duì)于全局變量(global variable),在其名稱(chēng)前加g和變量類(lèi)型符號(hào)前綴。

  uint32_t g_ulParaWord;
  uint8_t g_ucByte;
  • 對(duì)于靜態(tài)變量(static variable),在其名稱(chēng)前加s和變量類(lèi)型符號(hào)前綴。

  static uint32_t s_ulParaWord;
  static uint8_t s_ucByte;
  • 函數(shù)內(nèi)部等局部變量前不加作用域前綴。

  • 對(duì)于常量,當(dāng)可能發(fā)生作用域和名字沖突問(wèn)題時(shí),以上幾條規(guī)則對(duì)于常量同樣適用。注意,雖然常量名的核心部分全部大寫(xiě),但此時(shí)常量的前綴仍然用小寫(xiě)字母,以保持前綴的一致性。

(4) 結(jié)構(gòu)體命名規(guī)則

表示類(lèi)型的名字,所有名字以小寫(xiě)字母tag開(kāi)頭,之后每個(gè)英文單詞的第一個(gè)字母大寫(xiě)(包括第一個(gè)單詞的第一個(gè)字母),其他字母小寫(xiě),結(jié)尾_T 標(biāo)識(shí)。單詞之間不使用下劃線分隔,結(jié)構(gòu)體變量以 t 開(kāi)頭。如:

/* 結(jié)構(gòu)體命名類(lèi)型名 */
typedef struct tagBillQuery_T
{

...
}BillQuery_T;
/* 結(jié)構(gòu)體變量定義 */
BillQuery_T tBillQuery;

(5)對(duì)于枚舉定義全部采用大寫(xiě),結(jié)尾_E 標(biāo)識(shí)。

640-30.png

(6)常量、宏、模版的名字應(yīng)該全部大寫(xiě)。如果這些名字由多個(gè)單詞組成,則單詞之間用下劃線分隔。

#define LOG_BUF_SIZE 8000

函數(shù)

(1) 函數(shù)的命名規(guī)則。

每一個(gè)函數(shù)名前綴需包含模塊名,模塊名為小寫(xiě),與函數(shù)名區(qū)別開(kāi)。

如:uartReceive(串口接收)

備注:對(duì)于非常簡(jiǎn)單的程序,可以不加模塊名。

(2)函數(shù)的形參。

函數(shù)的的形參都以下劃線_開(kāi)頭,已示與普通變量進(jìn)行區(qū)分,對(duì)于沒(méi)有形參為空的函數(shù)(void)括號(hào)緊跟函數(shù)后面。

uint32_t uartConvUartBaud(uint32_t _ulBaud)
{
}

(3) 一個(gè)函數(shù)僅完成一件功能。

(4) 函數(shù)名應(yīng)準(zhǔn)確描述函數(shù)的功能,使用動(dòng)賓詞組為執(zhí)行某操作的函數(shù)命名。

說(shuō)明:避免用含義不清的動(dòng)詞如process、handle等為函數(shù)命名,因?yàn)檫@些動(dòng)詞并沒(méi)有說(shuō)明要具體做什么。

示例:參照如下方式命名函數(shù)。

640-31.png

(5)避免設(shè)計(jì)五個(gè)以上參數(shù)函數(shù),不使用的參數(shù)從接口中去掉。

說(shuō)明:目的減少函數(shù)間接口的復(fù)雜度,復(fù)雜的參數(shù)可以使用結(jié)構(gòu)傳遞。

(6)在調(diào)用函數(shù)填寫(xiě)參數(shù)時(shí),應(yīng)盡量減少?zèng)]有必要的默認(rèn)數(shù)據(jù)類(lèi)型轉(zhuǎn)換或強(qiáng)制數(shù)據(jù)類(lèi)型轉(zhuǎn)換。

說(shuō)明:因?yàn)閿?shù)據(jù)類(lèi)型轉(zhuǎn)換或多或少存在危險(xiǎn)。

(7) 防止把沒(méi)有關(guān)聯(lián)的語(yǔ)句放到一個(gè)函數(shù)中。

示例:如下函數(shù)就是一種隨機(jī)內(nèi)聚。

640-32.png

矩形的長(zhǎng)、寬與點(diǎn)的坐標(biāo)基本沒(méi)有任何關(guān)系,故以上函數(shù)是隨機(jī)內(nèi)聚。應(yīng)如下分為兩個(gè)函數(shù):

640-33.png


文章來(lái)源于網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵權(quán),請(qǐng)聯(lián)系刪除。



關(guān)鍵詞: C語(yǔ)言 編碼

評(píng)論


相關(guān)推薦

技術(shù)專(zhuān)區(qū)

關(guān)閉