#define swap(t, x, y) \
do { \
t safe ## x ## y; \
safe ## x ## y = x; \
x = y; \
y = safe ## x ## y; \
} while (0)
代码交换类型为t的参数x和y。
答案 0 :(得分:2)
##(双数字符号)运算符在宏定义中给出的宏调用(文本和/或参数)中连接两个标记。 的 Read More 强>
答案 1 :(得分:2)
双磅符号##
用于标记连接。
为简单起见,这就是你的代码在没有井号的情况下的外观。
#define swap(t, x, y) \
do { \
t safexy; \
safexy = x; \
x = y; \
y = safexy; \
} while (0)
使用##
##
运算符不能是第一项或最后一项
宏定义的替换列表。 ##
运算符前面项目的最后一个标记是
与##
之后的项目的第一个标记连接
运营商。 在参数中的任何宏之前进行连接 扩大。如果连接的结果是有效的宏 名称,即使出现也可以进一步更换 在通常不可用的环境中。
如果出现了多个##
运算符和/或#
运算符
宏定义的替换列表,评估的顺序
运营商没有定义。
更多了解read here。
答案 2 :(得分:2)
调用此宏时,例如:
swap(double, a, b);
它被替换为内联代码以交换这两个值,即:
do {
double safeab;
safeab = a;
a = b;
b = safeab;
} while (0);
注意事项:
typeof(a)
,但这不是标准的,因此不可移植。)##
交换的变量的名称组成。此运算符仅在宏体中可用,并通过将相邻的标记粘贴在一起来创建新标记。请注意,如果其中一个交换操作数是复合的,则名称创建将失败,例如a[i]
或p->x
。串联创建的名称有点过于谨慎。因为交换发生在它自己的范围内,所以阴影变量是安全的,除了那些被交换的变量。只需在常规命名约定之外选择一个名称并交叉手指。do { ... } while (0)
包装器是使宏像行为一样的常用方法,如果它们被用作if
或while
主体的唯一表达式,这一点非常重要。< / LI>
鉴于宏不能用于复合表达,你不会用它买多少。它也不是通用类型,因为当您调用宏时,必须知道该类型。写一个小的静态函数进行交换;在我看来,这一点更加清晰。
C FAQ对类型通用交换宏也有疑问和强烈意见。