C及C++通过预处理器提供了一些语言功能, 最常用的有#include指令, 用于包含头文件, 其他如#define及宏定义, 也被称为宏替换, 当编译器编译到带宏定义的语句时, 会直接替换为定义语句.例如, 假如我定义有#define MAXLENGTH 100, 那么, 在编译器编译到所有MAXLENGTH时则会自动替换为100.
宏定义的形式如下:
#define 定义名 替换文本
比较简单的用法则为定义一些在程序中比较常用的常量, 以节省内存. 当然根据宏定义的特性, 我们也可以衍生出一些比较特殊的用法, 如图
我定义了一个名为PRINT的宏, 并可对其传入参数, 它将被替换为一个控制台输出参数的语句, 实际上有点像定义了一个用于控制台输出的方法, 对其调用如图
实际上, 在编译器编译到PRINT(“hello world”)时, 将会被替换为cout << “hello world” << endl;
那么很显然, 宏定义与函数调用还是有所不同的, 比如当我们传入带有计算表达式的实参时, 它得出的结果将与函数调用的结果有所不同.如图:
定义了一个宏和一个函数, 都是用于选择两个参数中更大的数(宏定义中必须对三目表达式用括号进行包裹, 否则会因为运算符优先级而发生错误), 首先我们调用宏进行输出, 得到输出结果如图
因为语句被替换为(i++) > (j++) ? (i++) : (j++), 所以无论输出i还是j 其值都将被自增两次, 只不过由于++运算符的特性, 它在当值被使用后才进行自增, 所以控制台输出为2而不是3. 再用max函数对i++, j++进行调用, 得到输出结果如图
由于函数调用只传递值, 所以当i, j 还未自增时已被传递, 得到输出结果为1.
当然, 宏定义还有其他有趣的用法, 如图
将#置于宏定义参数前, 则会将传入参数转换为字符串形式, 对其调用如图
则控制台将输出hello world, 如图
宏定义还可以对参数进行连接, 如图