#define 定义中的特殊运算符 # 和 ##

在宏定义中,可以使用两个特殊的运算符:

  • 宏参数名称前的单个哈希符号 # 会将该参数的内容转换为字符串;只允许在函数宏中使用该符号;
  • 两个单词(标记)之间的双哈希符号 ## 会将这两个单词组合在一起,如果标记是宏参数,则替换其值,但如果标记是宏名称,则按原样替换,不展开宏;如果“粘合”后产生了另一个宏名称,则宏被扩展;

在本书的例子中,我们经常使用以下宏:

#define PRT(APrint(#A"=", (A))

它调用 Print 函数,在这个函数中,传递的表达式通过 #A 显示为一个字符串,在等号符号之后打印出 A 的实际值。

为了演示 ##,我们来分析另一个宏:

#define COMBINE(A,B,XA##B(X)

使用这个宏,我们实际上可以生成对上文定义的 SQN 宏的调用:

Print(COMBINE(SQ,N,2)); // 4

SQ 和 N 字面量连接在一起,之后 SQN 宏扩展为 ((2)*(2)) 并生成结果 4。

以下宏允许您在代码中创建变量定义,方法是在给定宏参数的情况下生成变量名称:

#define VAR(TYPE,NTYPE var##N = N

代码行:

VAR(int3);

相当于以下代码行:

int var3 = 3;

通过连接标记,可以使用宏在数组元素上实现循环速记。

#define for_each(IAfor(int I = 0max_##I = ArraySize(A); I < max_##I; ++I)
  
// describe and somehow fill in the array x
double x[];
// ...
// implement loop through the array
for_each(ix)
{
   x[i] = i * i;
}