程式設計規範第三條,我們一起來啃一啃讓程式設計師又愛又恨的注釋風格。
關於注釋,網路上眾說紛紜,有些觀點建議盡可能多寫注釋,而另外一些觀點建議少寫注釋,追求**即注釋。
工作多年,我的團隊在反覆迭代中形成了一整套關於注釋的理解,很難單純的用多或少來區分,我們一一和大家道來。
檔案頭部注釋,用於描述該檔案的功能;
節注釋,描述節的用途;
分段注釋,描述大段**的用途。
除此之外,我們還有如下幾條關於注釋的形式化要求:
4. 對所有的未知變數(包括列舉,變數定義,結構,巨集,函式等)進行注釋;
5. 約定函式注釋風格;
6. 對關鍵**段進行注釋;
7. 打破規則處需要注釋加以說明。
在詳細描述這些注釋之前,先和大家**一下注釋的形式化問題。
在c89規範中約定「/* */」塊注釋風格,在c99規範中增加了「//」行注釋風格。目前,雖然有些編譯器不完全支援c99所有特徵,但基本都支援「//」注釋風格。
不知大家是否有這樣的經歷,除錯**時,經常需要快速寫一些臨時**,或者快速注釋掉某段**。很不幸,我們匆忙做的改變經常忘記收尾。在我的職場生涯中,已經出現過多次因臨時**未刪除,或被注釋的**未取消注釋而引起的產品異常了。
為了盡可能規避這個問題,我們團隊採用了如下形式化要求:
所有的正式注釋僅允許使用「/* */」風格,其中兩邊增加一空格,用於凸顯注釋內容;
除錯過程中的臨時大塊或單行**,使用//@風格注釋;
通過該形式化約定後,**提交前簡單搜尋一下「//」或「@」,就能發現是否還有臨時**段。
這兩條形式化要求,表面看增加了大家寫**的難度,但便於工具化統一,該部分內容在3.6節介紹。其中使用符號「@」,是因為這是c程式中幾乎唯一不應該出現的符號了。
關於注釋,我們團隊形成的第一條形式化約定是:對未知進行中文注釋。其中,未知這個概念包含了節,檔案,函式,變數,結構等等之類,前面關於檔案頭、節、塊的注釋都屬於這一條。
在《編寫可讀**的藝術》一書中,作者強烈建議使用明確的單詞來命名,這樣就可以達到**即注釋了。我認為這條規範比較適合西方人,並不適合我們。我不能假設我們招聘的每個人英語都ok,也不能假設你用字典查出來的名字是合理的,更不能假設你會從多個相似語義的單詞中選出最合適的那乙個。因此,最好的策略就是形式化約定對所有未知進行中文注釋。
擷取一段產品中的**,便於大家理解基於這種約定的**風格。
/* 接收緩衝區大小, 考慮最大容納完整兩幀資料情況 */
#define rxd_buf_size 512
/* 傳送緩衝區大小, 為了防止干擾資料, 比256適度擴大,也可用於記憶體溢位檢測 */
#define txd_buf_size (256+16)
/* 傳送緩衝區個數 */
#define txd_buf_count 4
/* 傳送緩衝區 */
typedef struct ttxdbuf
ttxbuf;
/* 串列埠屬性結構 */
typedef struct tuartinf
tuartinf;
/* 維護口例項 */
static tuartinf s_maintaininf;
在c語言中的函式經常位於兩處,一是宣告位置,一是定義位置。前文提及需要對未知進行注釋,但是在宣告處,還是定義處對函式進行注釋呢?
一般變數注釋都比較短小,因此可以兩邊保持一致。但函式注釋經常經常需要描述每個引數的含義,整塊的**複製會帶來冗餘,一不小心弄不一致,更易混淆。
針對這個問題,我們團隊提出了一條約定:對外函式在宣告處使用完整或簡化注釋,定義處使用簡化注釋。如下示例:
/*
* description: 讀取eeprom內容
* input:
* dword dwoffset: 偏移位置
* byte* pbuf: 資料緩衝區位址
* dword dwlen: 讀取長度
* return: 成功返回true,否則返回false;
*/bool hwreadeeprom(dword dwoffset, byte *pbuf, dword dwlen);
/* 讀取eeprom內容 */
bool hwreadeeprom(dword dwaddr, byte *pbuf, dword dwlen)
至此,我們基本約定了整個程式結構的注釋風格,在閱讀一段**時,至少不會出現不知所云的名稱。但在具體編碼級別,難免會有各種關鍵**並非閱讀友好的,此時就需要額外的增加注釋,便於**理解。
真實產品的**大多服從冪次分布,也就是說大概80%的都是簡單流程**,僅20%是關鍵**。**審核時,流程**大致晃一眼就可以了,重點應該放在關鍵**上。這樣既可以節約**審核工作量,又可以達到較好的審核效果。
何為關鍵**,何為流程**呢?我們團隊約定:在關鍵段右側增加強調注釋。換句話說,只要加了注釋的,都可能是關鍵**,值得我們細細讀一下。
我舉一些真實產品**示例,便於大家感受這種注釋風格,其中程式右側的注釋都屬於關鍵**段注釋。
/* 比例差動延時定值 */
if (set_dw2harmblock == selset_block_no)
dwtime = 20-10; /* 內部-10ms,用於補償繼電器動作時間,實際為20ms */
else
dwtime = 10; /* 有諧波閉鎖時,減少啟動延時時間 */
recomparer_setvalue(&s_ratiodifta, dwtime, 20);
recomparer_setvalue(&s_ratiodiftb, dwtime, 20);
/* 記錄數字錄波資訊 */
dw = s_byrelaywordmap[dwindex];
if (dw < 32)
為了幫助新人快速上手,也為了簡化約定風格,便於審核,前面幾乎所有的約定我們都採用了形式化的策略,簡單來說就是一刀切。
程式是為產品服務的,真實產品中總是會有各種例外,如自動生成的**,用tab縮排不如用空格縮排易控制;又如某些**使用外部函式庫,希望介面**盡量同外部函式庫風格保持一致等。
此時,我們額外約定:所有的約定都可以打破,但需要通過注釋描述理由,以便於審核。
返回目錄
C 程式設計風格約定
我一直自認為,自己在程式設計功力還算說的過去,昨天乙個老師看了我以前寫的 說功力還需加強 當時我很鬱悶,其實我知道的可能還比他多 很多時候我們 都太注重高水平 尖端的技術,其實很多公司叫你寫一段簡單的程式,可能就會決定要不要你。他們是從 中看出了你的閱歷,你的水平。這些水平不是體現你的 尖端技術 況...
C 程式設計風格約定
參考 net設計規範 krzysztof cwalina,brad abrams著 1 必須是實際開發人員使用的約定。為了實現這個目標,我們審查了由.net框架的開發人員編寫的 有些約定並未在框架中普遍應用,對此我們不予採納。2 約定應該盡可能的合理 簡潔。我們認為只要不犧牲 的可讀性,在更少的行數...
C 程式設計風格約定
我一直自認為,自己在程式設計功力還算說的過去,昨天乙個老師看了我以前寫的 說功力還需加強 當時我很鬱悶,其實我知道的可能還比他多 很多時候我們 都太注重高水平 尖端的技術,其實很多公司叫你寫一段簡單的程式,可能就會決定要不要你。他們是從 中看出了你的閱歷,你的水平。這些水平不是體現你的 尖端技術 況...