-
C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数,这点和函数有些类似。
-
对带参数的宏,宏展开和用实参替代形参,发生在预处理阶段。
-
示例1:
-
#define SUM(x, y) x+x*y+y // 定义宏
-
10 * SUM(2+2, 3+3)
-
预期结果为:10 * (4 + 4 * 6 + 6) = 340
-
实际结果为:10 * 2 + 2 + 2 + 2 * 3 + 3 +3 + 3 = 39
-
修改后的宏定义:#define SUM(x, y) ((x) + (x) * (y) + (y))
-
修改的内容:
-
每个形参在宏定义字符串中都需要由小括号括起来。原因:宏展开时,不对实参表达式做任何计算。即SUM(2+2, 3+3) !=SUM(4, 6)。
-
将宏定义的整个字符串包含在括号中。
-
-
-
-
-
示例2:使用宏定义,交换两个参数的值。
-
方法一:使用异或运算。
-
方式1:
-
定义:#define SWAP(a, b) (a = a^b, b = a^b, a = a^b) // 该宏定义为逗号表达式。
-
调用:SWAP(a, b); // 宏调用后需加分号。因为逗号表达式不是可执行的语句。
-
-
方式2:
-
定义:#define SWAP(a, b) {a = a^b; b = a^b; a = a^b;} // 该宏定义为三条语句构成的语句块。
-
调用:SWAP(a, b) // 宏调用后不需要加分号。加了分号也不会有错误,仅表示在宏展开的三条语句执行完成后,执行了一条空语句。
-
-
-
方法二:在宏定义中定义临时变量。
-
#define SWAP(x, y) {int tmp; tmp = a; a = b; b = tmp;}
-
注意:宏定义字符串中包含大括号,且在使用SWAP时不需要添加额外的分号:
-
int a = 1, b = 2;
-
SWAP(a, b) // 注意没有分号。
-
-
-
-
可变参数宏:#define PINFO(fmt, args...) printf(fmt, ##args)