#define是C語言中提供的宏定義指令:
用來将一個辨別符定義為一個字元串,該辨別符被稱為宏名,被定義的字元串稱為替換文本。
#define<宏名> <字元串>
#define<宏名> (<參數表>)<宏體>
宏展開是在預處理階段完成的,這個階段把替換文本隻是看作一個字元串,并不會有任何的計算發生
#define中的三個特殊符号:#,##,#@
- #define Cat(x,y) x##y //token-pasting 符号連接配接操作符
- #define ToChar(x)#@x // charizing 字元化操作符
- #define ToString(x)#x // stringizing 字元串化操作符
ANSI标準說明了五個預定義的宏名。它們是:
- _LINE_
- _FILE_
- _DATE_
- _TIME_
用#pragma導出DLL函數
__declspec(dllexport) //導出函數
__declspec(dllimport) //申明導入函數
重命名導出函數 #pragma comment(linker,"/EXPORT:[email protected]")
/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
@ordinal 指定順序;NONAME 指定隻将函數導出為序号;DATA 關鍵字指定導出項為資料項。
指定連結庫 #pragma comment(lib, "WSock32.lib")
#pragma warning( disable : 4507 34; once : 4385; error : 164 ) //編譯器忽略4507 和34, 僅報告1次4385 把164警告作為錯誤。
#pragma message(“消息文本”) //當編譯器遇到這條指令時就在編譯輸出視窗中将消息文本列印出來。
另一個使用得比較多的pragma參數是code_seg。格式如:
#pragma code_seg( ["section-name"[,"section-class"] ] )
它能夠設定程式中函數代碼存放的代碼段,當我們開發驅動程式的時候就會使用到它。
#pragma once (比較常用)
#pragma hdrstop表示預編譯頭檔案到此為止,後面的頭檔案不進行預編譯。
#pragma resource "*.dfm"表示把*.dfm檔案中的資源加入工程。
常用的一些宏定義
1 防止一個頭檔案被重複包含
- #ifndef BODYDEF_H
- #define BODYDEF_H
- //頭檔案内容
- #endif
2 得到指定位址上的一個位元組或字
- #define MEM_B( x) ( *( (byte*) (x) ))
- #define MEM_W( x) ( *( (word*) (x) ))
例子:
- int main()
- {
- int bTest = 0x123456;
- byte m = MEM_B((&bTest));
- int n = MEM_W((&bTest));
- return 0;
- }
3 得到一個field在結構體(struct)中的偏移量
- #defineOFFSETOF( type, field) ( (size_t) &(( type*) 0)-> field)
得到一個field在結構體(struct type)中的偏移量
- #define OFFSETOF(type, field) ((size_t)&(((type *)0)->field))
- (type *)0:把0位址當成type類型的指針。
- ((type *)0)->field:對應域的變量。
- &((type *)0)->field:取該變量的位址,其實就等于該域相對于0位址的偏移量。
- (size_t)&(((type *)0)->field):将該位址(偏移量)轉化為size_t型資料。
ANSI C标準允許任何值為0的常量被強制轉換成任何一種類型的指針,并且轉換結果是一個NULL指針,是以((s*)0)的結果就是一個類型為s*的NULL指針。如果利用這個NULL指針來通路s的成員當然是非法的,但&(((s*)0)->m)的意圖并非想存取s字段内容,而僅僅是計算當結構體執行個體的首址為((s*)0)時m字段的位址。聰明的編譯器根本就不生成通路m的代碼,而僅僅是根據s的記憶體布局和結構體執行個體首址在編譯期計算這個(常量)位址,這樣就完全避免了通過NULL指針通路記憶體的問題。
注:
1. 有人這樣表達:
- #define OFFSETOF(type, field) ((size_t) \
- ((char *)&((type *)0)->field - (char *)(type *)0))
4 得到一個結構體中field所占用的位元組數
- #define FSIZ( type, field) sizeof(((type *) 0)->field)
5 得到一個變量的位址(word寬度)
- #define B_PTR( var) ( (byte *)(void *) &(var))
- #define W_PTR( var) ( (word *)(void *) &(var))
6 将一個字母轉換為大寫
- #define UPCASE( c) ( ((c)>= ''a'' &&(c) <= ''z'')? ((c)- 0x20) : (c))
7 判斷字元是不是10進值的數字
- #define DECCHK( c) ((c)>= ''0'' &&(c) <= ''9'')
8 判斷字元是不是16進值的數字
- #define HEXCHK( c) ( ((c)>= ''0'' &&(c) <= ''9'')||((c)>= ''A'' &&(c) <= ''F'')||((c)>= ''a'' &&(c) <= ''f''))
9 防止溢出的一個方法
- #define INC_SAT( val) (val = ((val)+1> (val))? (val)+1: (val))
10 傳回數組元素的個數
- #define ARR_SIZE( a) ( sizeof( (a)) / sizeof( (a[0])) )
多層替換 #define DECVAL_1 0
#define DECVAL_2 1
#define DECVAL_3 2
#define DECVAL_4 3
#define DECVAL_5 4
#define DECVAL_6 5
#define DECVAL_7 6
#define DECVAL_8 7
#define DECVAL_9 8
#define DECVAL( n ) DECVAL_##n
參考: http://blog.csdn.net/witch_soya/article/details/7645493 http://blog.chinaunix.net/uid-21372424-id-120086.html