參考文獻:https://www.cnblogs.com/henjay724/p/12259328.html
一. 引言
制定此編碼風格指導手冊的目的是為了使按此規范編寫出的C/C++代碼極易被閱讀和理解。
二. 與其他編碼風格對比
三. 基本排版格式
1. 需要以4個空格為單位的縮進
2. 堅決不用Tab鍵,要用空格鍵
3. 所有文件結尾必須空一行
4. 文本文件必須使用UTF-8編碼
5. 每一行不能超過100個字符
四. 文檔與注釋
1. 恰當地進行代碼注釋
2. 關於注釋長度沒有具體限制,只要能提供幫助,就盡可能地注釋
3. 注釋應該解釋代碼為什么要這么做,而不是如何去做(代碼本身已經表明了如何去做)
4. 選擇Doxygen文檔系統來完成注釋,除了在函數中的注釋之外(因為Doxygen不適合個別代碼的注釋),Doxygen也不適用於匯編
5. 頭文件定義
C語言頭文件為了避免多次重復包含,需要定義一個符號。這個符號的定義形式請采用如下 的風格:
#ifndef __FILE_H__ #define __FILE_H__ /* header file content */ #endif
6. 在每個源文件文件頭上,應該包括相應的版權信息,Change Log 記錄:
/* * File : rtthread.h * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes * 2006-03-18 Bernard the first version * 2006-04-26 Bernard add semaphore APIs * ... */
五. 標准數據類型
1. 僅使用C99標准給出的整型(定義見stdint.h文件),如uint32_t,int16_t等,不要typedef自己的整型類型,如u8,int_32,WORD等,
2. 使用char或wchar_t來表示字符串,但二進制緩存仍應使用uint8_t
3. 僅使用C99標准給出的bool型(定義見stdbool.h文件)來表示布爾變量,true和false表示其值。(PS:windows 平台下編譯時需要自行定義,因為windows下不包含stdbool.h文件)
六. 標識符發命令
6.1 以下是C/C++下變量,函數,typedef,宏命名的基本規則,命名規則可以接受細微改動,但要保證在同一模板中的一致性:
1. 全局函數名:全小寫,單詞用下划線隔開,
如:i2c_receive_data()
2. 普通變量名: Camel命名法,
如:thisIsMyVariable
3. 結構體名和類名:Pascal命名法,
如:BigBoxOfTools
4. 類成員函數名:Camel命名法,
如:initialLongProcess()
5. 用typedef重命名:全小寫,單詞用下划線隔開,加_t后綴,
如:big_box_of_tools_t
6. 用宏命名:單詞全大寫(僅在宏中使用,且必須使用)
6.2 描述性強的,可讀性強的變量名非常重要:
1. 大部分單詞都不應該縮寫,比如應用block而不是blk,應用count而不是cnt,一些流行的縮寫還是可以的,比如init或config
2. 完全可以接受較長的,描述性的變量名
3. 布爾型變量可以使用”is”,”did”等前綴,這會清晰地表明其是一個布爾型
4. 變量名應該可以表達其目的,但堅決反對匈牙利命名(加數據類型前綴)
正確: temporaryParameters, startBlock, nodeKey, isAlarmEnabled
錯誤:u32BlkNum, bEnabled
6.3. 有時候為了表明范圍和目的,有些變量命名是可以加前綴和后綴的:
局部變量:無需前綴
全局變量:加g_前綴
靜態變量:加s_前綴
類成員變量:加m_前綴
常量:加k前綴
1):如kUnconstrained, kFirstPage, kMaxBufferBytes
2):k前綴使常量很容易被識別
typedef型變量:加_t后綴
PS:切記不要用匈牙利命名法,因為其會導致變量名難於閱讀,且類型前綴常常會與變量真正類型不同步,微軟曾是此命名法的擁躉,但其已意識到此命名法的缺陷,目前正在逐漸脫離此方法
七. 可調試性
7.1. 一系列的整型常量應該用枚舉來表示,而不是用宏來定義
1. 在調試時,常量被顯示為真實的標識,而不是數字
2. 便於常量的邏輯分組
7.2. 大部分情況下,使用內聯函數來代替宏功能
1. 在調試中,內聯函數可以被禁用,故可以跳過
2. 內聯函數參數有類型,而宏中參數不可以有類型
3. 這個規則僅適用於當用宏來表示一段代碼時,不適用於在表達式中表示某部分的宏
PS: 頭文件中,內聯功能啟用應用static inline來完成
八. C/C++通用性
8.1. 頭文件中的公用函數原型必須包含在下列語句中
#if defined(__cplusplus) extern "C" { #endif // __cplusplus // 此處放函數原型 #if defined(__cplusplus) } #endif // __cplusplus
C中一般都用typedef來重命名結構體和枚舉數據類型,不要提及原始的結構體或枚舉型名
C++中,則不需用typedef來重命名,直接用原始的結構體或枚舉型名;但是如果代碼被C/C++共享,則應遵從C風格
對於被用在C++中的函數(比如類成員)而言,如果函數不帶任何參數,則不需要一個專門的void參數來表明,而在C中這是需要的
九. 花括號的使用
9.1. 花括號的使用雖重要性不高,但經常起爭議
a. 通常情況下,花括號應該單獨起一行,不需要額外的縮進
b. 有時為了保持可讀性,可以不遵守上一規則
c. 花括號使用的關鍵點在於不要將代碼湊在一起,從而使得代碼比較難閱讀;也不要因為具體格式的限定,從而打破視覺流程
9.2. 使用規則可以接受細微改動,但要保證在同一模塊中的一致性,以及易於閱讀

結構體和類示例: 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; 函數示例: void foo() { printf("hi\n"); } If語句示例: if (baz >= kMaximumBaz) { baz = kMaximumBaz; } else if (!ready) { makeItReady(); } else { abort(); } For語句示例: for (i=0; i < 10; ++i) { printf("%d", i); } While語句示例: while (!done) { doSomething(); } Do-while語句示例: do { doSomething(); } while (!done); Switch語句示例: 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語句示例: try { } catch (std::exception & e) { } catch (...) { }