寫一個(gè)簡(jiǎn)單的宏定義:
#define MIN(a,b) ((a) > (b) ? (a) : (b))
指令與作用:
# 空指令,無(wú)任何效果
#define 定義宏
#undef 取消已定義的宏
#if 如果給定條件為真,則編譯下面代碼
#ifdef 如果宏已經(jīng)定義,則編譯下面代碼
#ifndef 如果宏沒有定義,則編譯下面代碼
#elif 如果前面的#if給定條件不為真,當(dāng)前條件為真,則編譯下面代碼
#endif 結(jié)束一個(gè)#if……#else條件編譯塊
#error 停止編譯并顯示錯(cuò)誤信息
運(yùn)算符:
例如: #define demo1(n) "123"#n
出現(xiàn)在宏定義中的#運(yùn)算符把跟在其后的參數(shù)轉(zhuǎn)換成一個(gè)字符串。有時(shí)把這種用法的#稱為字符串化運(yùn)算符
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%s",demo1(abc));
}
//打印會(huì)輸出 123abc
例如:#define demo2(m,n,j) m##n##j
##運(yùn)算符用于把參數(shù)連接到一起。預(yù)處理程序把出現(xiàn)在##兩側(cè)的參數(shù)合并成一個(gè)符號(hào)
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%d",demo2(1, 2, 3));
}
//打印會(huì)輸出 123
VA_ARGS 是一個(gè)可變參數(shù)的宏,很少人知道這個(gè)宏,這個(gè)可變參數(shù)的宏是新的C99規(guī)范中新增的,目前似乎只有g(shù)cc支持(VC6.0的編譯器不支持)。
實(shí)現(xiàn)思想就是宏定義中參數(shù)列表的最后一個(gè)參數(shù)為省略號(hào)(也就是三個(gè)點(diǎn))。這樣預(yù)定義宏_ VA_ARGS _就可以被用在替換部分中,替換省略號(hào)所代表的字符串。比如:
#define PR(...) printf(__VA_ARGS__)
int main()
{
int wt=1,sp=2;
PR("hello\n");
PR("weight = %d, shipping = %d",wt,sp);
return 0;
}
輸出結(jié)果:
hello
weight = 1, shipping = 2
省略號(hào)只能代替最后面的宏參數(shù)。
#define W(x,…,y)錯(cuò)誤!
注意:##__VA_ARGS__ 宏前面加上##的作用在于,當(dāng)可變參數(shù)的個(gè)數(shù)為0時(shí),這里的##起到把前面多余的","去掉的作用,否則會(huì)編譯出錯(cuò)

20180727111856842.png
宏定義的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
提高了程序的可讀性,同時(shí)也方便進(jìn)行修改,用戶只需要在一處定義,多處使用,修改也只需要修改一處
提高程序的運(yùn)行效率:使用帶參的宏定義既可完成函數(shù)調(diào)用的功能,又能避免函數(shù)的出棧與入棧操作,減少系統(tǒng)開銷,提高運(yùn)行效率,如果有一個(gè)函數(shù)會(huì)在工程中頻繁使用,可以考慮一下宏定義
缺點(diǎn)
由于是直接嵌入的,所以代碼可能相對(duì)多一點(diǎn)
嵌套定義過多可能會(huì)影響程序的可讀性,而且很容易出錯(cuò);
對(duì)帶參的宏而言,由于是直接替換,并不會(huì)檢查參數(shù)是否合法,存在安全隱患。
預(yù)編譯語(yǔ)句僅僅是簡(jiǎn)單的值代替,缺乏類型的檢測(cè)機(jī)制