##运算符在这个C宏中的含义是什么?

时间:2015-06-20 07:19:23

标签: c function macros

#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。

3 个答案:

答案 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)包装器是使宏像行为一样的常用方法,如果它们被用作ifwhile主体的唯一表达式,这一点非常重要。< / LI>
  • 最后的反斜杠允许您在各行上传播宏。习惯上最后很好地排列它们,这样它们就不会使代码混乱。

鉴于宏不能用于复合表达,你不会用它买多少。它也不是通用类型,因为当您调用宏时,必须知道该类型。写一个小的静态函数进行交换;在我看来,这一点更加清晰。

C FAQ对类型通用交换宏也有疑问和强烈意见。