Micro definition ---C語言中宏定義使用總結

Micro definition ---C語言中宏定義使用總結

1、用於定義代碼中不會變化的常量

#define  MAX_LEN  1024

2、用於封裝某些常用的代碼塊(不是函數,類似於函數的作用)

#define  MAX(x,y) (((x)>(y)) ? (x) : (y)) 
#define  MIN(x,y) (((x) < (y)) ? (x) : (y)) 

比如這樣的寫法:

#define    DRAW_TEXT(f, t, d, use_bg)                                \
if (d)                                                               \ 
{                                                                    \
    CvSize _size;                                                    \  
    cvGetTextSize(t, &font, &_size, NULL);                           \  
    if (use_bg)                                                      \  
    {                                                                \  
        cvRectangle(f, cvPoint(0, f->height),                        \  
                    cvPoint(_size.width + 5,                         \  
                            f->height - _size.height * 2),           \  
                    CV_RGB(255, 0, 0), CV_FILLED, 8, 0);             \  
    }                                                                \  
    cvPutText(f, t, cvPoint(2, f->height - _size.height / 2),        \  
              &font, CV_RGB(255,255,0));                             \  
    d--;                                                             \  
}  
再比如這種:

#define DRAW_RECTS(f, d, rw, ro)                                   \
{                                                                  \ 
    cvRectangle(f, POINTS(rw), CV_RGB(255, 0, 0), 1, 8, 0);        \  
    cvRectangle(f, POINTS(ro), CV_RGB(0, 255, 0), 1, 8, 0);        \  
    cvRectangle(d, POINTS(rw), cvScalarAll(255),  1, 8, 0);        \  
    cvRectangle(d, POINTS(ro), cvScalarAll(255),  1, 8, 0);        \  
} 

對於有多個操作,多行代碼最好使用do{...}while(0)包含,防止意外的錯誤。

例如:

有問題的定義:

#define DUMP_WRITE(addr,nr) {memcpy(bufp,addr,nr); bufp += nr;} 
應該使用的定義: 

#difne DO(a,b) do{a+b;a++;}while(0)  
例如:

if(addr)
    DUMP_WRITE(addr,nr);
else
    do_somethong_else(); 
宏展開以後變成這樣:

if(addr)
    {memcpy(bufp,addr,nr); bufp += nr;}; 
else
    do_something_else(); 
gcc 在碰到else前面的“;”時就認爲if語句已經結束,因而後面的else不在if語句中。而採用do{} while(0)的定義,在任何情況下都沒有問題。

有do{...}while(0)時的情況:

if(addr)
    do{
          memcpy(bufp, addr, nr);
          bufp += nr;
      }
    while(0);
else
    do_something_else();
3、用於防止頭文件被重複引用

#ifndef  _FILE_HEAD_H_
#define  _FILE_HEAD_H_
#endif
還有另外一種方式也可以達到目的(依賴於編譯器,不推薦),有些編譯器不支持

#pragma once
4、消除某些頭文件中已經定義的宏參數

#ifdef  MICRO_NAME
#undef  MICRO_NAME
#endif
5、用於註釋和打開代碼塊

#if 0
/*your code, want not use*/
#endif
如果需要打開代碼塊,只需將0改成1即可。

若工程中有多處這樣的代碼,需同時打開或同時關閉,可以這樣。

#define  DEBUG_FLAG 0

#if DEBUG_FLAG
/*your code*/
#endif

#if DEBUG_FLAG
/*your code*/
#endif

#if DEBUG_FLAG
/*your code*/
#endif
6、使用宏進行跟蹤調試,記錄日誌

ANSI標準說明了五個預定義的宏名。它們是:

__LINE__ 
__FILE__         /*在MSVC編譯器中__FILE__ 在Debug模式下是帶全路徑的文件名(full path name)  Release模式下僅有文件名(file name)*/
                 /*在vac gcc編譯器中__FILE__ 僅代表文件名(file name)*/
__DATE__ 
__TIME__ 
__STDC__
C++中還定義了 __cplusplus
如果編譯器不是標準的,則可能僅支持以上宏名中的幾個,或根本不支持。記住編譯程序也許還提供其它預定義的宏名。
__LINE__ 及 __FILE__ 宏指示,#line指令可以改變它的值,簡單的講,編譯時,它們包含程序的當前行數和文件名。
__DATE__ 宏指令含有形式爲月/日/年的串,表示源文件被翻譯到代碼時的日期。

__TIME__ 宏指令包含程序編譯的時間。時間用字符串表示,其形式爲: 分:秒

__STDC__ 宏指令的意義是編譯時定義的。一般來講,如果__STDC__已經定義,編譯器將僅接受不包含任何非標準擴展的標準C/C++代碼。如果實現是標準的,則宏__STDC__含有十進制常量1。如果它含有任何其它數,則實現是非標準的。

 __cplusplus 與標準c++一致的編譯器把它定義爲一個包含至少6爲的數值。與標準c++不一致的編譯器將使用具有5位或更少的數值。 可以定義宏,例如:
當定義了_DEBUG,輸出數據信息和所在文件所在行

#ifdef _DEBUG
#define DEBUGMSG(msg,date)
printf(msg);
printf(“%d%d%d”,date,_LINE_,_FILE_) #else
#define DEBUGMSG(msg,date)
#endif 

7、關於#pragma

上面有提到過#pragma once可以用於避免頭文件被重複引用。

#pragma comment則更強大:

①windows環境添加lib靜態庫

#pragma comment(lib, "ws2_32.lib")

②windows環境設置控制檯程序連接入口

#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )	/*設置入口地址, 隱藏控制檯窗口*/

總結:

1.宏名和參數的括號間不能有空格;
2.宏替換隻作替換,不做計算,不做表達式求解;
3. 函數調用在編譯後程序運行時進行,並且分配內存。宏替換在編譯前進行,不分配內存;
4.函數只有一個返回值,利用宏則可以設法得到多個值;
5.宏展開使源程序變長,函數調用不會;
6.宏展開不佔運行時間,只佔編譯時間,函數調用佔運行時間(分配內存、保留現場、值傳遞、返回值);
7.使用條件編譯可以使目標程序變小,運行時間變短;
8.預編譯使問題或算法的解決方案增多,有助於我們選擇合適的解決方案。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章