此處引用csdn博客。鏈接如下、 http://blog.csdn.net/cp1300/article/details/7773239 http://blog.csdn.net/aobai219/article/details/6092292 我們在寫程式的時候,總是或多或少會加入一些printf ...
此處引用csdn博客。鏈接如下、
http://blog.csdn.net/cp1300/article/details/7773239
http://blog.csdn.net/aobai219/article/details/6092292
我們在寫程式的時候,總是或多或少會加入一些printf之類的語句用於輸出調試信息,但是printf語句有個很不方便的地方就是當我們需要發佈程式的時候要一條一條的把這些語句刪除,而一旦需要再次調試的時候,這些語句又不得不一條條的加上,這給我們帶來了很大的不便,浪費了我們很多的時間,也造成了調試的效率低下。所以,很多人會選擇使用巨集定義的方式來輸出調試語句。
作者通過兩文的閱讀,總結如下,並添加了自己的觀點。
引言
首先說明的是 printf("123!\n""!""243");
語法正確,即輸出等同printf("123!\n!243");
但是不似乎等同於printf("123!\n","!","243");
正文
1
假如有如下定義
#define EEPROM_ERROR(fmt,...) printf("<<-EEPROM-ERROR->> "fmt"\n",##__VA_ARGS__)
‘ … ’指可變參數。這類巨集在被調用時,它(這裡指‘ … ’)被表示成零個或多個符號,包括裡面的逗號,一直到到右括弧結束為止。當被調用時,在巨集體( macro body )中,那些符號序列集合將代替裡面的 保留名__VA_ARGS__ 標識符。如果可變參數被忽略或為空,‘ ## ’操作將使預處理器( preprocessor )去除掉它前面的那個逗號,這樣當巨集定義調用沒有變參時候,可以巨集替換時候沒有錯誤的逗號。
調用時候,使用如下語句
EEPROM_ERROR("a= %d,b=%d,c=%d",a,b,c);
這時替換結果為 "a= %d,b=%d,c=%d" 與 fmt
a,b,c 與 ... (即__VA_ARGS__)
替換後相當於printf("<<-EEPROM-ERROR->> ""a= %d,b=%d,c=%d""\n",a,b,c);
2
假如有如下定義
#define EEPROM_INFO(fmt,arg...) printf("<<-EEPROM-INFO->> "fmt"\n",##arg)
調用方法與1相同。不同的是,去掉了保留名__VA_ARGS__
3
為了使printf作為的調試信息更具體,將以上的調試方案更進一步
3.1
ANSI C標準中有幾個標準預定義巨集(也是常用的):
__LINE__:在源代碼中插入當前源代碼行號;
__FILE__:在源文件中插入當前源文件名;
3.2
在有些時候,\n並沒有輸出回車(環境為,win10+stc串口助手+stm32f429)。需要使用0x0d,0x0a之類的輸出回車。所以使用了\r\n作為一個回車效果
3.3
有如下定義:
#define EEPROM_ERROR(fmt,arg...) printf("\r\n<<-EEPROM-ERROR->> \r\n""LIFE NAME:"__FILE__ "\r\n""LINE:%d\r\n"fmt"\r\n\n",__LINE__,##arg)
調用如下:
EEPROM_ERROR("answer is c= %d c=%d c= %d",d,d,d);//假設c變數為uint8_t類型,值為6,並假設使用在第49行調用
輸出結果為下:
<<-EEPROM-ERROR->>
LIFE NAME:..\User\main.c
LINE:49
answer is c= 6 c=6 c= 6
4
為了可以打開和關閉調試信息,可以將巨集定義修改為:
#define EEPROM_ERROR(fmt,arg...) //printf("\r\n<<-EEPROM-ERROR->> \r\n""LIFE NAME:"__FILE__ "\r\n""LINE:%d\r\n"fmt"\r\n\n",__LINE__,##arg)
這樣子,在整個工程中的通過巨集定義方案輸出的調試信息全部消失。而不是去使用#ifdef之類的巨集定義開關語句開關巨集定義