代碼編程規(guī)范-擴展(宏/常量)
掃描二維碼
隨時隨地手機看文章
前言
這篇重點介紹一下代碼編程規(guī)范的擴展要求-宏/常量規(guī)范要求
要求
【規(guī)范1】用宏定義表達式時,要使用完備的括號
因為宏只是簡單的代碼替換,不會像函數一樣先將參數計算后,再傳遞。
// 錯誤示例 #define RECTANGLE_AREA(a, b) a * b // RECTANGLE_AREA(1 + 2, 3 + 6) 替換時為 1 + 2 * 3 + 6, 因為符號優(yōu)先級此時和想要的結果完全不同 #define RECTANGLE_AREA(a, b) (a * b) #define RECTANGLE_AREA(a, b) (a) * (b) // 10 / RECTANGLE_AREA(1 + 2, 3 + 6) 替換時為 10 / (1 + 2) * (3 + 6), 結果不同 // 正確示例 #define RECTANGLE_AREA(a, b) ((a) * (b)) // RECTANGLE_AREA(1 + 2, 3 + 6) 替換時為 ((1 + 2) * (3 + 6)), 結果一致
【規(guī)范2】將宏所定義的多條表達式放在大括號中
若宏定義函數表達式,則記得加換行符 \,建議使用do{...}while(0)的方式
#define DOSOMETHING() \ do \ { \ fool1(); \ fool2(); \ }while(0)
【規(guī)范3】不允許直接使用魔鬼數字
使用魔鬼數字的弊端:代碼難以理解;如果一個有含義的數字多處使用,一旦需要修改這個數值,代價慘重。
使用明確的物理狀態(tài)或物理意義的名稱能增加信息,并能提供單一的維護點。
解決途徑:對于局部使用的唯一含義的魔鬼數字,可以在代碼周圍增加說明注釋,也可以定義局部const變量,變量命名自注釋。對于廣泛使用的數字,必須定義const全局變量/宏;同樣變量/宏命名應是自注釋的。0作為一個特殊的數字,作為一般默認值使用沒有歧義時,不用特別定義
【規(guī)范4】除非必要,應盡可能使用函數代替宏
宏對比函數,有一些明顯的缺點:
宏缺乏類型檢查,不如函數調用檢查嚴格;
宏展開可能會產生意想不到的副作用,如#define SQUARE(a) (a) * (a)這樣的定義,如果是SQUARE(i++),就會導致i被加兩次;如果是函數調用double square(double a) {return a * a;}則不會有此副作用;
以宏形式寫的代碼難以調試難以打斷點,不利于定位問題;
宏如果調用的很多,會造成代碼空間的浪費,不如函數空間效率高。
【規(guī)范5】常量建議使用const定義代替宏
當編譯報錯時,只會顯示常量,不會顯示宏定義的名字,查找時很費勁(因為宏是替換,在編譯過程中稱為“預處理”)
一般情況下在意常量的類型,就使用const,如果是頭文件對外提供的常量,使用宏定義
【規(guī)范6】宏定義中盡量不使用return、goto、continue、break等改變程序流程的語句
如果在宏定義中使用這些改變流程的語句,很容易引起資源泄漏問題,使用者很難自己察覺。
錯誤示例:在某頭文件中定義宏CHECK_AND_RETURN:





