宏语句在预编译的时候被处理,也就是在预编译时被宏体所替代。
它在某些地方与函数相似,但可省去函数调用的代价,但是代码长度会大一些。因为不管宏语句在代码中出现了多少次,每次都被完整的宏体所替代,而函数码在程序中只存在一次就可以了。
宏是一段完成特定功能的代码,和C++的内联函数相似。
与函数的区别,是宏将代码复制到调用处,而函数是转去执行,如调用10次,则宏的代码被复制10次,而函数的代码只有一份。使用宏的速度快,但程序较大,使用函数程序较小,但相对速度要慢。
所以比较短小又使用频繁的功能适合做成宏,而相对大些的写成函数。
就是一些在编译时首先处理的替换规则。
比如:
#define NUMBER 8
那么,在编译开始时,编译器将首先把该源文件中的NUMBER全部换成8。
所以,你千万别定义
#define n 8,
那样一来,文件中所有的晓小字母n将全被换成8。
当然,还有类似函数的替换,比如,
#define PRINT(INT) printf("%d/n" , INT)
后面就可以使用PRINT(i)来打印i的值了。
但你同样需要注意,不能图简单,来一个
#define PRINT(n) printf("%d/n" , n)
那样一来,当调用PRINT(8)时,编译器会把它替换成:
printf("%d/8" , 8)
明白了吧,宏定义执行的仅仅是简单的字符串替换。
当然,还有个问题需要注意,比如,你自己定义一个乘法宏:
#define PRODUCT(M , N) M*N
后面,你调用PRODUCT(3+2 , 5+4)
会被编译器替换成:
3+2*5+4,你本来想得到45,却得到了17。
所以上面的宏应该定义成
#define PRODUCT(M , N) (M)*(N)
宏定义主要就是上述的这两类:带参数的宏定义和不带参数的宏定义,有时候还会用到仅仅定义一个字符串,却不定义成任何东西的情况。如:
#define _DEBUG
这样的宏定义主要用来做条件编译。
比如,你调试程序的时候,可能会让程序输出许多中间结果,你就可以在前面来一个#define _DEBUG,然后把这些输出语句都编程下面的形式。
#ifdef _DEBUG
printf("%d" , tmp);
#endif
这样,等你的程序调试得差不多了,要发布了,不再需要输出这些中间结果了,你只需把文件头上的那句:
#define _DEBUG
注释掉,再编译一遍,就一些搞定了。
关于条件编译的知识,你还是找本书自己看看吧,随便一本C/C++书上都有,当然VC的编译预处理还要复杂的多。