0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言編碼規(guī)范,這才是最理想的!

朱老師物聯(lián)網(wǎng)大講堂 ? 2024-07-06 08:11 ? 次閱讀

編碼規(guī)范,沒有最好,只有最合適,有但不執(zhí)行不如沒有。

一、編碼原則

01

可讀性

清晰第一

清晰性是易于維護程序必須具備的特征。維護期變更代碼的成本遠遠大于開發(fā)期,編寫程序應(yīng)該以人為本,計算機第二。一般情況下,代碼的可閱讀性高于性能,只有定性能是瓶頸時,才應(yīng)該主動優(yōu)化。

簡潔為美

簡潔就是易于理解并且易于實現(xiàn)。代碼越長越難以看懂,也就越容易在修改時引入錯誤。提倡通過簡潔明了的代碼來提升代碼可靠性。廢棄的代碼要及時清除,重復(fù)代碼應(yīng)該盡可能提煉成函數(shù)。

風(fēng)格一致

所有人共同分享同一種風(fēng)格,為后期維護,和代碼交接帶來便捷。

02

設(shè)計原則

  • 開放封閉原則對于擴展是開放的,對于修改是封閉的。
  • 單一職責(zé)原則每一個子函數(shù)或者類似的代碼塊應(yīng)該只有一個職責(zé),所以只有一個原因會使其改變。
  • 接口隔離原則接口盡量細化,同時接口中的方法盡量少。
  • 最少知道原則一個子模塊應(yīng)該與其它模塊保持最少的了解。
  • 依賴倒置原則高層模塊,低層模塊,細節(jié)(實現(xiàn))都應(yīng)該依賴抽象(即接口)。

二、編碼規(guī)范

01

文件頭申明

新增.c必須添加注釋,標(biāo)注公司名稱、文件功能說明,創(chuàng)建日期、作者,后續(xù)修改說明范例如下:

3b2f14ba-3b2c-11ef-a655-92fbcf53809c.png

可配置Source Insight 自動生成模板。

02

文件

所有.h頭文件必須采取阻止內(nèi)容被包含多于一次的機制。

3be5d29a-3b2c-11ef-a655-92fbcf53809c.png

  • 頭文件對外接口,應(yīng)放置對外部的聲明,如對外提供的函數(shù)聲明、宏定義、類型定義等。

內(nèi)部使用的函數(shù)聲明不應(yīng)放在頭文件中。

內(nèi)部使用的宏、枚舉、結(jié)構(gòu)定義不應(yīng)放入頭文件中。

變量定義禁止在頭文件中,應(yīng)放在.c文件中。

模塊內(nèi)使用的全局變量,不應(yīng)通過在頭文件中聲明的方式直接暴露給外部。

頭文件中只包含接口的聲明,不含實現(xiàn)。

頭文件應(yīng)當(dāng)職責(zé)單一,頭文件過于復(fù)雜,依賴過于復(fù)雜是導(dǎo)致編譯時間過長的主要原因。

每一個.c文件應(yīng)有一個同名.h文件,用于聲明需要對外公開的接口。

禁止頭文件循環(huán)依賴,禁止包含用不到的頭文件。

每個.c源文件內(nèi)容片段按如下順序,文件注釋-包含頭文件-宏定義-數(shù)據(jù)結(jié)構(gòu)定義-變量定義-引用外部變量-引用外部函數(shù)-本地函數(shù)-全局函數(shù)。

03

函數(shù)

  • 一個函數(shù)僅完成一件功能。
  • 重復(fù)代碼應(yīng)該盡可能提煉成函數(shù)。說明:重復(fù)代碼提煉成函數(shù)可以帶來維護成本的降低。重復(fù)代碼是不良代碼最典型的特征之一。在“代碼能用就不改”的指導(dǎo)原則之下,新需求增加帶來的代碼拷貝和修改,隨著時間的遷移,產(chǎn)品中堆砌著許多類似或者重復(fù)的代碼。

避免遞歸函數(shù)的代碼塊嵌套過深。

對函數(shù)的錯誤返回碼要全面處理。說明:一個函數(shù)(標(biāo)準(zhǔn)庫中的函數(shù)/第三方庫函數(shù)/用戶定義的函數(shù))能夠提供一些指示錯誤發(fā)生的方法,可以通過使用錯誤標(biāo)記、特殊的返回數(shù)據(jù)或者其他手段,調(diào)用程序應(yīng)該在函數(shù)返回時立刻檢查錯誤指示。

廢棄函數(shù)要及時清除。說明:程序中的廢棄代碼不僅占用額外的空間,而且還常常影響程序的功能與性能,很可能給程序的測試、維護等造成不必要的麻煩。

函數(shù)傳入的不變參數(shù)使用const限制。

函數(shù)的參數(shù)個數(shù)不超過5個,檢查輸入?yún)?shù)的有效性。說明:函數(shù)的參數(shù)過多,會使得該函數(shù)易于受外部(其他部分的代碼)變化的影響,從而影響維護工作。函數(shù)的參數(shù)過多同時也會增大測試的工作量。函數(shù)的參數(shù)個數(shù)不要超過5個,如果超過了建議拆分為不同函數(shù);函數(shù)的輸入主要有兩種:一種是參數(shù)輸入;另一種是全局變量、數(shù)據(jù)文件的輸入,即非參數(shù)輸入。函數(shù)在使用輸入?yún)?shù)之前,應(yīng)進行有效性檢查。

源文件范圍內(nèi)聲明和定義的所有函數(shù),除非外部可見,否則增加static關(guān)鍵字,針對單元測試的特殊情況,對這類函數(shù)盡量封裝一層再使用。

傳入?yún)?shù)表意有3種以上的禁止使用魔法數(shù),必須使用枚舉值且附帶注釋。

函數(shù)內(nèi)部要對參數(shù)的合法性進行檢查。說明:函數(shù)的輸入主要有兩種:一種是參數(shù)輸入;另一種是全局變量、數(shù)據(jù)文件的輸入,即非參數(shù)輸入。函數(shù)在使用輸入?yún)?shù)之前,應(yīng)進行有效性檢查。

除打印類函數(shù)外,不要使用可變長函數(shù)。說明:可變長參函數(shù)的處理過程比較復(fù)雜容易引入錯誤,而且性能也比較低,使用過多的可變長參函數(shù)將導(dǎo)致函數(shù)的維護難度大大增加。

每個函數(shù)都要返回錯誤碼,調(diào)用程序必須在函數(shù)返回時檢查錯誤碼。

標(biāo)識符的命名要清晰明了,有明確含義,使用完整的單詞,盡量避免名字中出現(xiàn)數(shù)字編號或特殊符號。

函數(shù)名稱需體現(xiàn)出函數(shù)具體功能,均由功能單詞拼接組成,絕不允許出現(xiàn)中文拼音。

函數(shù)命名應(yīng)以函數(shù)要執(zhí)行的動作命名,一般采用動詞或者動詞+名詞的結(jié)構(gòu)。

04

變量

  • 不用或者少用全局變量。說明:單個文件內(nèi)部可以使用static的全局變量,可以將其理解為類的私有成員變量。全局變量應(yīng)該是模塊的私有數(shù)據(jù),不能作用對外的接口使用,使用static類型定義,可以有效防止外部文件的非正常訪問。直接使用其他模塊的私有數(shù)據(jù),將使模塊間的關(guān)系逐漸走向“剪不斷理還亂”的耦合狀態(tài),這種情形是不允許的。

避免局部變量與全局變量同名。說明:盡管局部變量和全局變量的作用域不同而不會發(fā)生語法錯誤,但容易使人誤解。

嚴(yán)禁使用未經(jīng)初始化的變量。

明確全局變量的初始化順序,避免跨模塊的初始化依賴。說明:系統(tǒng)啟動階段,使用全局變量前,要考慮到該全局變量在什么時候初始化,兩者之間的時序關(guān)系,誰先誰后,一定要分析清楚,不然后果往往是低級而又災(zāi)難性的。

數(shù)據(jù)必須對外開放時,應(yīng)封裝接口函數(shù)來讀寫,同時注意全局?jǐn)?shù)據(jù)的訪問互斥。說明:避免直接暴露內(nèi)部數(shù)據(jù)給外部模型使用,是防止模塊間耦合最簡單有效的方法。

一個變量只有一個功能,不能把一個變量用作多種用途。說明:一個變量只用來表示一個特定功能,不能把一個變量作多種用途,即同一變量取值不同時,其代表的意義也不同。

數(shù)據(jù)結(jié)構(gòu)功能單一,不要設(shè)計面面俱到的數(shù)據(jù)結(jié)構(gòu)。說明:相關(guān)的一組信息才是構(gòu)成一個結(jié)構(gòu)體的基礎(chǔ),結(jié)構(gòu)的定義應(yīng)該可以明確的描述一個對象,而不是一組相關(guān)性不強的數(shù)據(jù)的集合。設(shè)計結(jié)構(gòu)時應(yīng)力爭使結(jié)構(gòu)代表一種現(xiàn)實事務(wù)的抽象,而不是同時代表多種。結(jié)構(gòu)中的各元素應(yīng)代表同一事務(wù)的不同側(cè)面,而不應(yīng)把描述沒有關(guān)系或關(guān)系很弱的不同事務(wù)的元素放到同一結(jié)構(gòu)體中。

盡量減少沒有必要的數(shù)據(jù)類型默認(rèn)轉(zhuǎn)換與強制轉(zhuǎn)換。說明:當(dāng)進行數(shù)據(jù)類型強制轉(zhuǎn)換時,其數(shù)據(jù)的意義、轉(zhuǎn)換后的取值等都有可能發(fā)生變化,而這些細節(jié)若考慮不周,就很有可能留下隱患。

示例:如下賦值,多數(shù)編譯器不產(chǎn)生告警,但值的含義有變化。

3bf51d86-3b2c-11ef-a655-92fbcf53809c.png

確認(rèn)未使用的變量應(yīng)當(dāng)刪除。對于變量自增 ++ 和自減--,禁止在宏定義中使用,禁止和其他語句復(fù)合,因拆分單獨執(zhí)行。示例:if(++i>10) 錯誤寫法,必須改為i++;if(i>10)

05

宏和常量

宏定義和常量使用大寫字母或下劃線。

用宏定義表達式時,要使用完備的括號,如下:

3c076ce8-3b2c-11ef-a655-92fbcf53809c.png

宏定義中盡量不要使用return、goto、continue、break等改變程序流程的語句。

常量建議使用const定義代替宏,如下:

3c3cb376-3b2c-11ef-a655-92fbcf53809c.png

除非必要,應(yīng)盡可能使用函數(shù)代替宏 。

將宏定義的多條表達式放在大括號中。

使用宏時,不允許參數(shù)發(fā)生變化。

盡量少用魔法數(shù),或者必須加注釋說明,或者修改方案,如內(nèi)存長度操作禁止使用常數(shù),非特殊情況必須使用sizeof自動處理。

06

命名

命名采用unix like風(fēng)格,單詞用小寫字母,每個單詞之間用下劃線分割,引用的第三方的代碼可保持原有風(fēng)格,命名盡量使用通用英文單詞或縮寫。

文件:

文件名命名可根據(jù)平臺自有規(guī)則命名,一般采用小寫字符,字段之間使用下劃線分隔;相同功能的 .c和.h文件名相同。

枚舉:

枚舉定義:宏定義和枚舉值禁止使用小寫字母,不能以下劃線開頭,字段之間使用下劃線分隔,若邏輯中要標(biāo)注多種狀態(tài),狀態(tài)不允許用數(shù)字表示。

結(jié)構(gòu)體:

結(jié)構(gòu)體定義,若同一功能所使用到的參數(shù),盡量用結(jié)構(gòu)體來定義表示,便于相關(guān)參數(shù)獲取和設(shè)置。

純業(yè)務(wù)邏輯代碼,與平臺無關(guān)的,必須使用小寫字符和下劃線分隔。

函數(shù)函數(shù)名定義:

函數(shù)名稱需體現(xiàn)出函數(shù)具體功能,均由功能單詞拼接組成,使用小寫字母和下劃線拼接,其中全局函數(shù)必須以xx_為前綴,在.h里面申明全局函數(shù),補充完整注釋;局部函數(shù)使用static限制。

變量:

禁止使用全大寫字母命名變量,全局變量至少5個字母,使用高頻次的全局變量盡量簡短。

全局變量命名表達其作用,且以小寫字母g_開頭,后面拼接功能英文,如地址:g_addr。

變量名的拼接,全部使用小寫字母和下劃線拼接,函數(shù)內(nèi)局部變量允許使用單個字母。

多個同類的變量封裝成結(jié)構(gòu)體。

推薦命名:

3c4dbb76-3b2c-11ef-a655-92fbcf53809c.png

07

注釋

注釋應(yīng)放在其代碼上方相鄰位置或右方,不可放在下面。

注釋的內(nèi)容要清楚明了,防止注釋二義性。

修改代碼時同步更新注釋,保證注釋與代碼的一致性。

函數(shù)聲明處注釋描述函數(shù)功能、性能及用法,提供參考范本如下:

3c5a30fe-3b2c-11ef-a655-92fbcf53809c.png

全局變量要有較詳細的注釋:

函數(shù)內(nèi)部不是注釋越多越好,而是變量命名和邏輯清晰,自注釋最好,特殊情況或者需要特別注意的地方才加注釋,并且注釋要放在代碼行的上方。

基于SDK開發(fā),在基線工程上改動代碼,不允許刪除源代碼,修改代碼必須增加注釋,必須使用關(guān)鍵字“XX_CODE”標(biāo)注修改原因,方便后續(xù)打補丁,范例如下:

3c7477d4-3b2c-11ef-a655-92fbcf53809c.png

對于非c源碼的文件,在這個注釋格式的基礎(chǔ)上,每行添加對應(yīng)的注釋符號。

修改與外設(shè)驅(qū)動、通信協(xié)議、系統(tǒng)底層等相關(guān)的代碼,具有特殊隱含限制的代碼,必須提交詳細的修改原因,便于后續(xù)版本回溯查找原因。

復(fù)雜且相對獨立的功能,單獨使用markdown文檔說明開發(fā)方案、實現(xiàn)技術(shù)、應(yīng)用場景、使用限制等,隨代碼提交。

08

排版與格式

程序塊采用縮進風(fēng)格編寫,每級縮進為4個空格。

相對獨立的程序塊之間、變量說明之后必須加空行。

多個短語句不允許寫在同一行內(nèi),長語句不能拆分需要分行寫。

if、for、do、while、case、switch、default等語句獨占一行,{換行且獨占一行。

賦值語句不要寫在if等語句中,或者作為函數(shù)的參數(shù)使用。

邏輯表達式每個子項都使用()。

if與else if/else必須以’{}’分隔,且 ‘{’與‘}’各占一行,if-else分3層以上必須以else子句結(jié)束,即使操作為空,并增加注釋://do nothing

3c8b973e-3b2c-11ef-a655-92fbcf53809c.png

switch語句必須有default分支。

在兩個以上的關(guān)鍵字、變量、常量進行對等操作時,它們之間的操作符之前、之后或者前后要加空格;進行非對等操作時(如->),后面不應(yīng)加空格。

文件編寫完成后,統(tǒng)一使用Astyle自動格式化工具整理一遍再提交到版本庫。

3ca784ee-3b2c-11ef-a655-92fbcf53809c.png

三、編碼要求

3caed712-3b2c-11ef-a655-92fbcf53809c.png

01

安全性

對用戶輸入數(shù)值進行有效范圍檢查。

對輸入?yún)?shù)進行邊界判斷,尤其對指針變量。

嚴(yán)禁使用未經(jīng)初始化的變量作為右值,所有變量都要初始化。

每個普通變量(整型、字符型)的定義都要考慮范圍,嚴(yán)防溢出。

每個數(shù)組的定義和使用都要嚴(yán)防越界的發(fā)生。

要盡量避免隱式或者顯式的類型轉(zhuǎn)換,防止截斷的發(fā)生或者符號的丟失。

動態(tài)申請的內(nèi)存盡量在本函數(shù)內(nèi)釋放,特殊情況下,必須補充注釋提醒外界釋放內(nèi)存。

02

可移植性

不能定義、重定義或取消定義標(biāo)準(zhǔn)庫/平臺中保留的標(biāo)識符、宏和函數(shù)。

提取與平臺有關(guān)的通用函數(shù),封裝后統(tǒng)一放在固定文件,方便后期替換升級。

源文件必須使用原有平臺、SDK一致的文件編碼(GB2312/UTF8),有效代碼中不得出現(xiàn)中文字符。

通用功能使用功能宏控制,且代碼集中。

使用系統(tǒng)接口,尤其是不同平臺API不同的,使用函數(shù)名中帶pal的接口封裝并注釋,便于后續(xù)移植到其他平臺。

引用第三方開源代碼,允許保留其原始風(fēng)格,客制化修改必須補充完整注釋。

四、規(guī)范實施

3caed712-3b2c-11ef-a655-92fbcf53809c.png

編碼規(guī)范是軟件開發(fā)團隊合作的標(biāo)準(zhǔn),但實際開發(fā)過程中存在各種不可控因素,尤其是項目進度壓力和開發(fā)者水平與認(rèn)知的差異,導(dǎo)致軟件規(guī)則不能嚴(yán)格執(zhí)行。隨著軟件工程規(guī)模的擴大,軟件交期、代碼同步、重構(gòu)或交接,其風(fēng)險也逐漸放大。因此,存在合適的編碼規(guī)則并不能解決問題,只有強制代碼格式化,才能真正落實編碼規(guī)范統(tǒng)一。
軟件質(zhì)量是項目成敗的關(guān)鍵點之一,在開發(fā)周期有限,人力資源不足的情況下,使用工具實現(xiàn)代碼自動掃描,分析出潛在隱患點,從源頭減少軟件bug,是軟件如期交付的重要保證。實現(xiàn)代碼自動格式化和靜態(tài)分析,可以有效規(guī)避軟件風(fēng)險。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7581

    瀏覽量

    135542
  • 編碼
    +關(guān)注

    關(guān)注

    6

    文章

    920

    瀏覽量

    54707
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4256

    瀏覽量

    62223
收藏 人收藏

    評論

    相關(guān)推薦

    安富萊C語言編碼規(guī)范

    所謂無規(guī)矩不成方圓。任何團隊,規(guī)范都是怎么也繞不開的話題。特別是在我們搞嵌入式C開發(fā)的,代碼規(guī)范乃是開發(fā)的重中之重。有太多的理由去做規(guī)范,因為每個人的代碼編寫喜好不同,代碼風(fēng)格也迥然不
    發(fā)表于 07-19 15:19 ?1227次閱讀

    【Intel Edison申請】這才是物聯(lián)網(wǎng)開發(fā)設(shè)備

    )等堆砌性能不同,接口缺乏、系統(tǒng)不完備,可是深入理解之后,你會發(fā)現(xiàn),和樹莓派那種偏向編程與娛樂,這才是真正的物聯(lián)網(wǎng)設(shè)備,這才是心中理想的物聯(lián)網(wǎng)開發(fā)。趕緊打開網(wǎng)頁過來申請,還好沒結(jié)束,還好有機會。本人
    發(fā)表于 07-13 16:21

    C語言規(guī)范標(biāo)準(zhǔn)

    C語言規(guī)范標(biāo)準(zhǔn),,,
    發(fā)表于 11-07 17:14

    C語言編程規(guī)范

    1、據(jù)說是華為的C語言編程規(guī)范;2、本文件來自互聯(lián)網(wǎng)。
    發(fā)表于 02-22 16:36

    iPad最理想的充電方法

    按蘋果官網(wǎng)教導(dǎo),iPad的電池是不宜放電的。最理想的充電方法,是使用附帶的10W充電插頭,由交流電直接充。想充電時間縮短,可關(guān)了機來充,會快約三分一時間。 使用USB接口充電,若在同步情況下,充電會十分緩慢。并要留意,以下幾種情況,會令電池放電而不是充電:1.當(dāng)電腦處于關(guān)機或休眠...
    發(fā)表于 09-14 09:24

    C語言代碼規(guī)范相關(guān)資料推薦

    C語言代碼規(guī)范參考安富萊C語言編碼規(guī)范1.文件與目錄
    發(fā)表于 12-14 08:30

    ARM C語言擴展規(guī)范

    ARM C語言擴展(ACLE)規(guī)范指定源語言擴展和實現(xiàn)C/C++編譯器可以實現(xiàn)的選項,以便讓程序
    發(fā)表于 08-02 06:27

    C語言書寫的常用規(guī)范

    C語言書寫的常用規(guī)范
    發(fā)表于 10-26 10:43 ?26次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>書寫的常用<b class='flag-5'>規(guī)范</b>

    C語言編寫規(guī)范之注釋

    C語言變成規(guī)范
    發(fā)表于 05-24 14:36 ?13次下載

    C++語言編碼規(guī)范詳細說明

    本文檔的主要內(nèi)容詳細介紹的是C++語言編碼規(guī)范詳細說明。
    發(fā)表于 01-07 16:19 ?14次下載
    <b class='flag-5'>C</b>++<b class='flag-5'>語言</b><b class='flag-5'>編碼</b><b class='flag-5'>規(guī)范</b>詳細說明

    微軟Win10用戶交互體驗會是最理想

    這或許是最理想/好用的Windows 10系統(tǒng)交互體驗了。
    的頭像 發(fā)表于 03-09 13:39 ?1828次閱讀

    華為C語言編程規(guī)范

    關(guān)于華為C語言編程規(guī)范說明免費下載。
    發(fā)表于 06-23 14:47 ?61次下載

    嵌入式軟件之c語言編碼規(guī)范

    嵌入式軟件之c語言編碼規(guī)范
    發(fā)表于 10-28 18:13 ?28次下載

    GSPS ADC的最理想時鐘源參考設(shè)計

    電子發(fā)燒友網(wǎng)站提供《GSPS ADC的最理想時鐘源參考設(shè)計.zip》資料免費下載
    發(fā)表于 09-05 11:44 ?2次下載
    GSPS ADC的<b class='flag-5'>最理想</b>時鐘源參考設(shè)計

    嵌入式C語言編碼規(guī)范

    作為程序開發(fā)者,避免不了閱讀別人代碼,那么就會涉及到到一門語言的編程規(guī)范規(guī)范雖然不是語言本身的硬性要求,但是已經(jīng)是每一個語言使用者約定俗成
    的頭像 發(fā)表于 04-23 10:13 ?609次閱讀
    嵌入式<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>編碼</b><b class='flag-5'>規(guī)范</b>