天天看點

用宏建構自己的printf函數

用宏建構自己的printf函數

用宏建構自己的printf函數 作者 Andy_lv

用宏建構自己的printf函數

在調試程式時,通過螢幕輸出一些輔助資訊,可大大友善調試。但是調試完畢後,這些語句可能就不再需要了。如果一條條的删除會是件很痛苦的事

情。那怎麼快速的在調試狀态和釋出狀态切換呢?通常我們使用預編譯加宏定義來處理這個問題,例如:

#ifdef DEBUG

調試代碼

#endif

如果我們使用printf來顯示一些調試資訊,那麼每個地方都加上#ifdef和#endif就很麻煩了。我們可以定義一個自己PRINTF函數來專門處理這些事情

,隻在PRINTF函數内放上#ifdef和#endif就行了。但是這樣代碼在運作時,還是有調用一次函數的,浪費了時間。那麼可不可以利用宏定義,實作完

全沒有編譯代碼産生的宏呢?答案是肯定的,綜合網上的幾個例子,大體有以下三種實作方式:

形式一:

#ifdef DEBUG

#define PRINTF(x) printf x

#else

#define PRINTF(x) ((void)0)

#endif

使用時,PRINTF(( "Hello World!\n\r" ));

注意這裡是兩個括号,一個會報錯。而且如果忘記寫某個括号的話,會報很多莫名其妙的錯誤。這種方式的缺點就是要寫兩個括号。

形式二:

#ifdef DEBUG

#define PRINTF printf

#else

#define PRINTF /\

/PRINTF

#endif 

如果DEBUG已經定義了,那麼不用說,當然是用printf去代替PRINTF了。

下面隻分析DEBUG未定義的情形,這個宏定義實際上是将“PRINTF”定義成了“// PRINTF”。由于續行符的作用,在展開到代碼之後,就成了注釋符

“//”了。也就是說,原來的代碼是PRINTF ("%d",x).經過這個宏展開後成了// PRINTF ("%d",x),相當于自動在前面加了注釋符“//”。要注意的

是,續行符後面的“/”一定要頂格寫,否則就不是“//”了。另外,這個宏隻能單獨一行使用,因為它将該行後面的代碼都注釋掉了。

這種方法在編譯時會出現很多的警告資訊,比較煩人。

形式三:

//#define DEBUG

#ifdef DEBUG

#define DBG(CODE) CODE

#else

#define DBG(CODE)

#endif

就是寫代碼的時候,對于調試資訊加上DBG,稍微麻煩點,例如

DBG(printf("%d",x);)

這樣就不會出什麼問題了,而且還可以在裡面寫很多行代碼。

形式四:

//#define __DEBUG_MSG

#ifdef __DEBUG_MSG

#define DEBUG_MSG printf 

#else

#define DEBUG_MSG(...)

#endif

綜合比較,方法4最好