大家好,,我是痞子衡,是正經(jīng)搞技術(shù)的痞子,。今天痞子衡給大家講的是飛思卡爾軟件開發(fā)C語(yǔ)言編碼規(guī)范,。 2020鼠年春節(jié)是個(gè)漫長(zhǎng)的假期,痞子衡在家百無(wú)聊賴,,翻出了2016年10月1日(這個(gè)時(shí)間是痞子衡正式開始用markdown+github寫技術(shù)文章并發(fā)表到博客園上的紀(jì)念日)之前寫的技術(shù)文檔,,不翻不知道,一翻嚇一跳,,從2007年上大學(xué)開始到2016年這十年間,,我真的寫了非常多的技術(shù)類文章,但都不夠完整,,沒有成系統(tǒng),,排版上也不優(yōu)雅,底下有時(shí)間我會(huì)慢慢整理出來(lái),,不能讓以前的辛苦都被埋沒了,。 痞子衡2016年之前所寫的那些技術(shù)文章除了原創(chuàng)外,也有一些是翻譯的,,比如今天要分享的這篇就是2013年痞子衡剛?cè)肼氾w思卡爾半導(dǎo)體MCU軟件團(tuán)隊(duì)時(shí)為了學(xué)習(xí)C編碼規(guī)范所翻譯的(外企嘛,,各種資料都是洋文),當(dāng)時(shí)飛思卡爾剛成立MCU軟件團(tuán)隊(duì)不久,,那時(shí)候Kinetis SDK也還沒有正式推出,,整個(gè)團(tuán)隊(duì)必須要有一個(gè)統(tǒng)一且良好的編碼風(fēng)格,這樣寫出來(lái)的SDK才符合大廠身份,。廢話不多說,,下面是編碼規(guī)范原文: 1.引言 制定此編碼風(fēng)格指導(dǎo)手冊(cè)的目的是為了使按此規(guī)范編寫出的C/C++代碼極易被閱讀和理解。 2.與其他編碼風(fēng)格對(duì)比3.基本排版格式需要以4個(gè)空格為單位的縮進(jìn). 堅(jiān)決不用Tab鍵,,要用空格鍵. 所有文件結(jié)尾必須空一行. 文本文件必須用UTF-8編碼. 每一行不能超過100個(gè)字符.
4.文檔與注釋恰當(dāng)?shù)剡M(jìn)行代碼注釋. 關(guān)于注釋長(zhǎng)度沒有具體限制,,只要能提供幫助,就盡可能地注釋. 注釋應(yīng)該解釋代碼為什么要這么做,,而不是如何去做(代碼本身已經(jīng)表明了如何去做). 選擇Doxygen文檔系統(tǒng)來(lái)完成注釋,,除了在函數(shù)中的注釋之外(因?yàn)镈oxygen不適用于個(gè)別代碼行的注釋),Doxygen也不適用于匯編.
5.標(biāo)準(zhǔn)數(shù)據(jù)類型僅使用C99標(biāo)準(zhǔn)給出的整型(定義見stdint.h文件),,如uint32_t,,int16_t等,不要typedef自己的整型類型,,如u8,,int_32,,WORD等. 使用char 或wchar_t來(lái)表示字符串,但二進(jìn)制緩存仍應(yīng)使用uint8_t 僅使用C99標(biāo)準(zhǔn)給出的bool型(定義見stdbool.h文件)來(lái)表示布爾變量,,true和false表示其值. (ps: windows平臺(tái)下編譯時(shí)需自行定義,,因?yàn)閣indows下不包含stdbool.h文件)
6.標(biāo)識(shí)符的命名 以下是C/C++下變量、函數(shù),、typedef、宏命名的基本規(guī)則,,命名規(guī)則可以接受細(xì)微改動(dòng),,但要保證在同一模塊中的一致性: 全局函數(shù)名:全小寫,單詞用下劃線隔開 如:i2c_receive_data() 普通變量名:Camel命名法 如:thisIsMyVariable 結(jié)構(gòu)體名和類名:Pascal命名法 如:BigBoxOfTools 類成員函數(shù)名:Camel命名法 如:initialLongProcess() 用typedef重命名:全小寫,,單詞用下劃線隔開,,加_t后綴 如:big_box_of_tools_t 用宏命名:單詞全大寫(僅在宏中使用,且必須使用)
描述性強(qiáng)的,,可讀性強(qiáng)的變量名非常重要: 大部分單詞都不應(yīng)該縮寫,,比如應(yīng)用block而不是blk,應(yīng)用count而不是cnt. 一些流行的縮寫還是允許的,,如init或config 完全可以接受較長(zhǎng)的,,描述性的變量名 布爾型變量可以使用”is”,”did”等前綴,,這會(huì)清晰地表明其是一個(gè)布爾型 變量名應(yīng)該可以表達(dá)其目的,,但堅(jiān)決反對(duì)匈牙利命名(加數(shù)據(jù)類型前綴) 正確: temporaryParameters, startBlock, nodeKey, isAlarmEnabled 錯(cuò)誤:u32BlkNum, bEnabled
有時(shí)候?yàn)榱吮砻鞣秶湍康模行┳兞棵强梢约忧熬Y和后綴的: 備注:切記不要用匈牙利命名法,,因?yàn)槠鋾?huì)導(dǎo)致變量名難于閱讀,,且類型前綴常常會(huì)與變量真正類型不同步,微軟曾是此命名法的擁躉,,但其已意識(shí)到此命名法的缺陷,,目前正在逐漸脫離此方法。 7.可調(diào)試性一系列的整型常量應(yīng)該用枚舉來(lái)表示,,而不是用宏來(lái)定義 1):在調(diào)試時(shí),,常量被顯示為真實(shí)的標(biāo)識(shí),而不是數(shù)字 2):便于常量的邏輯分組 大部分情況下,,使用內(nèi)聯(lián)函數(shù)來(lái)代替宏功能 1):在調(diào)試中,,內(nèi)聯(lián)函數(shù)可以被禁用,故可以跳過 2):內(nèi)聯(lián)函數(shù)參數(shù)有類型,,而宏中參數(shù)不可以有類型 3):這個(gè)規(guī)則僅適用于當(dāng)用宏來(lái)表示一段代碼時(shí),,不適用于在表達(dá)式中表示某部分的宏
8. C99標(biāo)準(zhǔn)需要使用C99 C99被允許使能C++或C89語(yǔ)義內(nèi)聯(lián) 在盡量靠近變量被使用的地方來(lái)聲明變量,而不是一律在函數(shù)頂部聲明 1):這可以很容易地找到變量的定義 2):可以方便編譯器進(jìn)行優(yōu)化 單行注釋應(yīng)使用//而不是/* …*/ 1):大部分人認(rèn)為//式注釋方便閱讀 2):免去注釋嵌套的煩惱 多行注釋/* …*/可以被用作大段確定的內(nèi)容注釋,,就像Doxygen注釋頭一樣,,以使得被注釋的內(nèi)容突出,。
9.內(nèi)聯(lián)功能 頭文件中,內(nèi)聯(lián)功能啟用應(yīng)用static inline來(lái)完成 10. C/C++通用性 頭文件中的公用函數(shù)原型必須包含在下列語(yǔ)句中 #if defined(__cplusplus) extern 'C' { #endif // __cplusplus
// 此處放函數(shù)原型
#if defined(__cplusplus) } #endif // __cplusplus
C中一般都用typedef來(lái)重命名結(jié)構(gòu)體和枚舉數(shù)據(jù)類型,,不要提及原始的結(jié)構(gòu)體或枚舉型名 C++中,,則不需用typedef來(lái)重命名,直接用原始的結(jié)構(gòu)體或枚舉型名,;但是如果代碼被C/C++共享,,則應(yīng)遵從C風(fēng)格 對(duì)于被用在C++中的函數(shù)(比如類成員)而言,如果函數(shù)不帶任何參數(shù),,則不需要一個(gè)專門的void參數(shù)來(lái)表明,,而在C中這是需要的 11.花括號(hào)的使用 花括號(hào)的使用雖重要性不高,但經(jīng)常起爭(zhēng)議 通常情況下,,花括號(hào)應(yīng)該單獨(dú)起一行,,不需要額外的縮進(jìn) 有時(shí)為了保持可讀性,可以不遵守上一規(guī)則 花括號(hào)使用的關(guān)鍵點(diǎn)在于不要將代碼湊在一起,,從而使得代碼比較難閱讀,;也不要因?yàn)榫唧w格式的限定,從而打破視覺流程
使用規(guī)則可以接受細(xì)微改動(dòng),,但要保證在同一模塊中的一致性,,以及易于閱讀 結(jié)構(gòu)體和類示例: struct Monkey { int x; };
typedef struct MonkeyTwo { int y; } monkey_two_t;
class Cube { public: Cube(int theSize);
private: int m_size; }; 枚舉示例: enum _my_enum { kValueOne = 1, kValueTwo = 2 };
typedef enum _another { kAnotherOne = 10, kAnotherTwo = 20 } another_t; 函數(shù)示例: void foo() { printf('hi\n'); } If語(yǔ)句示例: if (baz >= kMaximumBaz) { baz = kMaximumBaz; } else if (!ready) { makeItReady(); } else { abort(); } For語(yǔ)句示例: for (i=0; i < 10; ++i) { printf('%d', i); } While語(yǔ)句示例: while (!done) { doSomething(); } Do-while語(yǔ)句示例: do { doSomething(); } while (!done); Switch語(yǔ)句示例: switch (value) { case 0: x += 1; break;
case 1: { int y; calculateIt(&y); break; }
default: return; } 命名空間示例: namespace fsl { // Don't indent namespace contents! } Try-catch語(yǔ)句示例: try { } catch (std::exception & e) { } catch (...) { }
12. 關(guān)于MISRA-C規(guī)范 代碼風(fēng)格基本遵照MISRA-C:20xx規(guī)范,但除了以下例外(這些例外是基于MISRA-C:2004規(guī)范的) 至此,,飛思卡爾軟件開發(fā)C語(yǔ)言編碼規(guī)范痞子衡便介紹完畢了,,掌聲在哪里~~~
|