一、定义
带参数的宏指令定义起来和函数很像,你只需要在宏名称后面的一对括号中插入参数,当然,参数必须是合法的C标识符,用逗号隔开,空格可加可不加。
如:
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
二、调用
带参数的宏指令调用起来也和函数差不多,写下宏名称和紧跟其后的参数列表即可,调用时插入的参数个数要和定义中参数个数一样,当宏指令开始替换时,宏体内的参数都会被相关的变量替代,在宏体内不一定要使用全部的参数。
如:
x = min(a, b); ==> x = ((a) < (b) ? (a) : (b));
y = min(1, 2); ==> y = ((1) < (2) ? (1) : (2));
z = min(a + 28, *p); ==> z = ((a + 28) < (*p) ? (a + 28) : (*p));
三、注意事项
- 向宏中传入的每个参量前后的空白符都会被去掉,一个参量中的所有空白符都会被替换成一个空格。
- 每个参量中的前后园括号数要平衡,在圆括号中的逗号并不会表示参量的结束。
- 不要求方括号前后平衡,而且它们不能防止逗号分隔参量。例如:
macro (array[x = y, x + 1])
,这里给macro传入了两个参量array[x = y
和x+1]
,如果你想将array[x = y, x + 1]
作为一个参量来使用,你可以这样写array[(x = y, x + 1)]
,这和C语言一样。 - 宏替换会做两次,例如
min (min (a, b), c)
会先被替换成min (((a) < (b) ? (a) : (b)), (c))
,然后被替换成((((a) < (b) ? (a) : (b))) < (c) ? (((a) < (b) ? (a) : (b))) : (c))
,详见Argument-Prescan - 你可以留空宏参数,对于与处理器来说这不是一个错误,但很多宏展开后会变成不合语法的代码
- 宏参数以字符串字面值形式出现时并不会被相关参量替换。
例:
#define foo(x) x, "x"
foo(bar) ==> bar, "x"