本文介紹下x巨集的使用
首先簡單介紹下巨集的幾種用法
#define strcat(x,y) x##y
#define _str(x) #@x
#define str(x) #x
#define log(...)
/* * x##y 拼接xy
* #@x 單引號包裹'x'
* #x 字串化,雙引號包裹"x"
* __va_args__會擴充套件引數...
*/
ansi c標準中有幾個標準預定義巨集(也是常用的):
line:在源**中插入當前源**行號;
file:在原始檔中插入當前源檔名;
date:在原始檔中插入當前的編譯日期
time:在原始檔中插入當前編譯時間;
stdc:當要求程式嚴格遵循ansi c標準時該標識被賦值為1;
__cplusplus:當編寫c++程式時該識別符號被定義。常常被用來判斷編譯器是否符合c++11,c++14等標準,方便運用新特性
編譯器在進行原始碼編譯的時候,會自動將這些巨集替換為相應內容。
舉個例子大家體會下
#define log_err(m,...) fprintf(stderr,"%s %s [err]"m"\n",__file__,__line__,##__va_args__)
我們首先看乙個日誌系統的場景
enum loglevel ;
string getloglevel(loglevel level)
}
我們定義了乙個結構體,表示日誌級別。然後定義了乙個函式,返回乙個字串,用於獲取日誌級別對應的名稱。
例子比較簡單,但我們發現,這個**有「重複」的部分。case的每個條件的寫法是相似。既然格式相同,那麼我們就可以簡化:
#define x(name) \
case name: \
return #name; \
break;
string getloglevel(loglevel level)
}
前面也說過了,#name是字串化,name如果是info的話,#name就會轉化成"info"
看上去**已經清爽多了。為避免其他地方也用到x巨集,我們可以在使用完畢立刻undef掉,巨集就寫在函式內,使**更加緊湊,改進後如下:
string getloglevel(loglevel level)
}
這樣**就緊湊多了。至於為什麼這種巨集叫x沒考究過,可能是約定俗成的習慣吧。
#define maploglevel \
x(debug, "debug") \
x(info, "info") \
x(warn, "warn") \
x(error, "error") \
x(unknow, "unknow")
#define x(a, b) a,
enum loglevel ;
#undef x
#define x(a, b) b,
const char* strloglevel = ;
#undef x
int main()
C語言巨集定義技巧
1,防止乙個標頭檔案被重複包含 ifndef comdef h define comdef h 標頭檔案內容 endif 2,重新定義一些型別,防止由於各種平台和編譯器的不同,而產生的型別位元組數差異,方便移 植。typedef unsigned char boolean boolean value...
C語言 巨集定義,預處理巨集
巨集是學習任何語言所不可缺少的,優秀的巨集定義可以使得 變得很簡潔且高效,有效地提高程式設計效率。巨集是一種預處理指令,它提供了一種機制,可以用來替換源 中的字串,直譯器或編譯器在遇到巨集時會自動進行這一模式替換 c語言有簡單的巨集系統,由編譯器或彙編器的預處理器實現。c的巨集預處理器的工作只是簡單...
C 語言 巨集定義和巨集函式
在軟體開發過程中,經常有一些常用或者通用的功能或者 段,這些功能既可以寫成函式,也可以封裝成為巨集定義。那麼究竟是用函式好,還是巨集定義好?這就要求我們對二者進行合理的取捨。我們來看乙個例子,比較兩個數或者表示式大小,首先我們把它寫成巨集定義 define max a,b a b a b 其次,把它...