巨集定義#define括號使用的深入認識
阿新 • • 發佈:2019-01-26
巨集定義:注意x,y值都有一個括號,和特定的符號時 需要加上括號!
// SWAP(x, y) 交換x,y的值
#define SWAP(x, y) \
(y) = (x) + (y); \
(x) = (y) - (x); \
(y) = (y) - (x);
求最大值和最小值
#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )
#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )
返回陣列元素的個數
#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
對於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)))
得到一個字的高位和低位位元組
#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))
#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))
在巨集之中用do{}while(0)語句包含多語句防止錯誤。
巨集中"#"和"##"的用法 我們使用#把巨集引數變為一個字串,用##把兩個巨集引數貼合在一起.
// SWAP(x, y) 交換x,y的值
#define SWAP(x, y) \
(y) = (x) + (y); \
(x) = (y) - (x); \
(y) = (y) - (x);
求最大值和最小值
#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )
寫一個“標準”巨集MIN,這個巨集輸入兩個引數並返回較小的一個。另外,當你寫下面的程式碼時會發生什麼事?
least = MIN(*p++, b);
解答:
#define MIN(A,B) ((A) <= (B) ? (A) : (B)) 注意外面還有一層括號!!
MIN(*p++, b)會產生巨集的副作用
剖析:
這個面試題主要考查面試者對巨集定義的使用,巨集定義可以實現類似於函式的功能,但是它終歸不是函式,而巨集定義中括弧中的“引數”也不是真的引數,在巨集展開的時候對“引數”進行的是
一對一的替換。
程式設計師對巨集定義的使用要非常小心,特別要注意兩個問題:
(1)謹慎地將巨集定義中的“引數”和整個巨集用用括弧括起來。所以,嚴格地講,下述解答:
#define MIN(A,B) (A) <= (B) ? (A) : (B)
#define MIN(A,B) (A <= B ? A : B )
都應判0分;
(2)防止巨集的副作用。
巨集定義#define MIN(A,B) ((A) <= (B) ? (A) : (B))對MIN(*p++, b)的作用結果是:
((*p++) <= (b) ? (*p++) : (b))
這個表示式會產生副作用,指標p會作兩次++自增操作。
除此之外,另一個應該判0分的解答是:
#define MIN(A,B) ((A) <= (B) ? (A) : (B));
這個解答在巨集定義的後面加“;”,顯示編寫者對巨集的概念模糊不清。
#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )
返回陣列元素的個數
#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
對於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)))
得到一個字的高位和低位位元組
#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))
#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))
在巨集之中用do{}while(0)語句包含多語句防止錯誤。
巨集中"#"和"##"的用法 我們使用#把巨集引數變為一個字串,用##把兩個巨集引數貼合在一起.