20個c語言中常用巨集定義總結
2012-09-16 10:52:57
分享:01: 防止乙個標頭檔案被重複包含
#ifndef comdef_h
#define comdef_h
//標頭檔案內容
#endif
02: 重新定義一些型別
防止由於各種平台和編譯器的不同,而產生的型別位元組數差異,方便移植。
typedef unsigned char boolean;
typedef unsigned long int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef signed long int int32;
typedef signed short int16;
typedef signed char int8;
//下面的不建議使用
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;
typedef unsigned char uint1;
typedef unsigned short uint2;
typedef unsigned long uint4;
typedef signed char int1;
typedef signed short int2;
typedef long int int4;
typedef signed long sint31;
typedef signed short sint15;
typedef signed char sint7;
03: 得到指定位址上的乙個位元組或字
#define mem_b(x) (*((byte *)(x)))
#define mem_w(x) (*((word *)(x)))
04: 求最大值和最小值
#define max(x,y) (((x)>(y)) ? (x) : (y))
#define min(x,y) (((x) < (y)) ? (x) : (y))
05: 得到乙個field在結構體(struct)中的偏移量
#define fpos(type,field) ((dword)&((type *)0)->field)
06: 得到乙個結構體中field所占用的位元組數
#define fsiz(type,field) sizeof(((type *)0)->field)
07: 按照lsb格式把兩個位元組轉化為乙個word
#define flipw(ray) ((((word)(ray)[0]) * 256) + (ray)[1])
08: 按照lsb格式把乙個word轉化為兩個位元組
#define flopw(ray,val) (ray)[0] = ((val)/256); (ray)[1] = ((val) & 0xff)
09: 得到乙個變數的位址(word寬度)
#define b_ptr(var) ((byte *) (void *) &(var))
#define w_ptr(var) ((word *) (void *) &(var))
10: 得到乙個字的高位和低位位元組
#define word_lo(***) ((byte) ((word)(***) & 255))
#define word_hi(***) ((byte) ((word)(***) >> 8))
11: 返回乙個比x大的最接近的8的倍數
#define rnd8(x) ((((x) + 7) / 8 ) * 8 ) // 返回 >=x 的8的倍數
12: 將乙個字母轉換為大寫
#define upcase(c) (((c)>='a' && (c) <= 'z') ? ((c) – 0×20) : (c))
13: 判斷字元是不是10進值的數字
#define decchk(c) ((c)>='0' && (c)<='9')
14: 判斷字元是不是16進值的數字
#define hexchk(c) (((c) >= '0' && (c)<='9') ((c)>='a' && (c)<= 'f') \
((c)>='a' && (c)<='f'))
15: 防止溢位的乙個方法
#define inc_sat(val) (val=((val)+1>(val)) ? (val)+1 : (val))
16: 返回陣列元素的個數
#define arr_size(a) (sizeof((a))/sizeof((a[0])))
17: 返回乙個無符號數n尾的值mod_by_power_of_two(x,n)=x%(2^n)
#define mod_by_power_of_two( val, mod_by ) ((dword)(val) & (dword)((mod_by)-1))
18: 對於io空間對映在儲存空間的結構,輸入輸出處理
#define inp(port) (*((volatile byte *)(port)))
#define inpw(port) (*((volatile word *)(port)))
#define inpdw(port) (*((volatile dword *)(port)))
#define outp(port,val) (*((volatile byte *)(port))=((byte)(val)))
#define outpw(port, val) (*((volatile word *)(port))=((word)(val)))
#define outpdw(port, val) (*((volatile dword *)(port))=((dword)(val)))
19: 使用一些巨集跟蹤除錯
ansi標準說明了五個預定義的巨集名。它們是:
__line__
__file__
__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
20: 巨集定義防止錯誤使用小括號包含。
例如:有問題的定義:#define dump_write(addr,nr)
應該使用的定義: #difne do(a,b) dowhile(0)
例如:if(addr)
dump_write(addr,nr);
else
do_somethong_else();
巨集展開以後變成這樣:
if(addr)
;else
do_something_else();
gcc 在碰到else前面的「;」時就認為if語句已經結束,因而後面的else不在if語句中。而採用do{} while(0)的定義,在任何情況下都沒有問題。而改為 #difne do(a,b) dowhile(0) 的定義則在任何情況下都不會出錯。
C語言中常用巨集定義
下面是一些比較重要的巨集定義,記錄一下 assert斷言 define assert cond cond void 0 assert cond,file line void assert char cond,char filename,long lineno 獲得結構體中域的偏移量 define o...
c 語言中的巨集定義
巨集定義 巨集定義是c提供的三種預處理功能的其中一種,這三種預處理包括 巨集定義 檔案包含 條件編譯 1.不帶引數的巨集定義 巨集定義又稱為巨集代換 巨集替換,簡稱 巨集 格式 define 識別符號 字串 其中的識別符號就是所謂的 符號常量,也稱為 巨集名 預處理 預編譯 工作也叫做巨集展開 將巨...
C語言中的巨集定義
下列c 中包含兩種巨集定義,例如 include define max connection 1000 define mng port 5000 define min a,b a b a b define max a,b a b a b int main 方法1 gcc e 引數預編譯 gcc e ...