##宏预处理程序的用法

时间:2018-11-23 16:31:48

标签: c macros

我正在尝试使用宏和##预处理进行以下操作

#define SUM_RESULT(SrcVar, Var1, Var2, Var3, Sum) \
SrcVar-> ## Var1 = 10;\
SrcVar-> ## Var2 = 10;\
SrcVar-> ## Var3 = 10;\
Sum = SrcVar-> ## Var1 + SrcVar-> ## Var2 + SrcVar-> ## Var3;

typedef struct _MyVariable
{
  int a;
  int b;
  int c;
}MyVariable;

int main()
{
  MyVariable *TotalVar;
  int Result = 0;

  //Allocating memory
  TotalVar = malloc(2 * sizeof(TotalVar));

  // Expecting to replace as below result
  // initialization
  // TotalVar->a=10;
  // TotalVar->b=10; 
  // TotalVar->c=10;
  // Sum = TotalVar->a + TotalVar->b + TotalVar->c;

  // macro replacement
  SUM_RESULT(TotalVar, a, b, c, Result);

  // Display result of sum of a, b, c
  printf("%d\n", Result);

  return 0;

}

但显示参数a,b,c,结果的未定义错误

SUM_RESULT(TotalVar, a, b, c, Result);

任何指针都鼓励继续前进...

1 个答案:

答案 0 :(得分:-1)

您的宏中不需要##。这是为了将两个字符串组合成一个令牌,例如当您要从foobarfoo构建标识符(变量,函数等)bar时,可能会作为单独的宏参数传递。

其他问题:

  • 您的typedef中的顺序错误。
  • MyVariable *TotalVar是未初始化的指针。您必须定义一些MyVariable变量。
  • 除非将宏参数产生语法错误,否则应将其放在括号内。
  • 您应将宏代码包含在do { ... } while(0)中,以使其在任何情况下均可工作。

结果可能取决于您使用的编译器。我尝试过https://www.onlinegdb.com/

这是您程序的修改后的版本,

/* Using this "do { ... } while(0)" construction allows the macro to
   work correct when used in e.g.
   if(foo)
     SUM_RESULT(TotalVarPtr, a, b, c, Result);
   else
     SUM_RESULT(somethingElse, a, b, c, Result);
 */
#define SUM_RESULT(SrcVar, Var1, Var2, Var3, Sum) \
do {\
(SrcVar)-> Var1 = 10;\
(SrcVar)-> Var2 = 11;\
(SrcVar)-> Var3 = 12;\
Sum = (SrcVar)-> Var1 + (SrcVar)-> Var2 + (SrcVar)-> Var3; \
} while(0)

typedef struct
{
  int a;
  int b;
  int c;
} MyVariable;

int main()
{
  MyVariable TotalVarValue = {0};
  MyVariable *TotalVarPtr = &TotalVarValue;
  int Result = 0;

  SUM_RESULT(TotalVarPtr, a, b, c, Result);
  printf("%d\n", Result);
  printf("a %d b %d c %d\n", TotalVarPtr->a, TotalVarPtr->b, TotalVarPtr->c );

  /* This requires to use (SrcVar) in the macro */
  SUM_RESULT(&TotalVarValue, a, b, c, Result);
  printf("%d\n", Result);
  printf("a %d b %d c %d\n", TotalVarValue.a, TotalVarValue.b, TotalVarValue.c );
}