C 将参数传递给变量宏

C 将参数传递给变量宏,c,c-preprocessor,variadic-macros,C,C Preprocessor,Variadic Macros,到目前为止,这个宏不需要是可变的。但为了将来的使用,我希望它是可变的。我不知道如何在变量宏中写入/定义参数列表以及如何使用它们。如上例所示,应设置并打印p1、p2 我这样称呼这个宏: #define SEND_VALUE(num, point1, point2, point3...) \ { \ char number[6]; \ char p1[6];\ char p2[6];\ char p3[6];\ if(num == ONE) {sprintf(number, "O

到目前为止,这个宏不需要是可变的。但为了将来的使用,我希望它是可变的。我不知道如何在变量宏中写入/定义参数列表以及如何使用它们。如上例所示,应设置并打印p1、p2

我这样称呼这个宏:

#define SEND_VALUE(num, point1, point2, point3...) \
{ \
  char number[6]; \
  char p1[6];\
  char p2[6];\
  char p3[6];\
  if(num == ONE) {sprintf(number, "ONE");}\
  if(num == TWO) {sprintf(number, "TWO");}\
  if(num == THREE) {sprintf(number, "THREE");}\
  if(point1 == ONE) {sprintf(p1, "ONE");}\
  if(point1 == TWO) {sprintf(p1, "TWO");}\
  if(point1 == THREE) {sprintf(p1, "THREE");}\
  if(point2 == ONE) {sprintf(p2, "ONE");}\
  if(point2 == TWO) {sprintf(p2, "TWO");}\
  if(point2 == THREE) {sprintf(p2, "THREE");\
  if(point3 == ONE) {sprintf(p3, "ONE");}\
  if(point3 == TWO) {sprintf(p3, "TWO");}\
  if(point3 == THREE) {sprintf(p3, "THREE");\
  fprintf(fp,"%s:%s:%s:%s:\n",number, p1,p2,p3);\
  fflush(fp); \
  fprintf(fp,fmt,##__VA_ARGS__);\
  fflush(fp); \
  fprintf(fp,"\n");\
  fflush(fp); \
}
#define SEND_VALUE(num, point1, point2, point3, fmt, ...) \
do { \
  fprintf(fp,#num":"#point1":"#point2":"#point3":\n");\
  fflush(fp); \
  fprintf(fp,fmt,##__VA_ARGS__);\
  fflush(fp); \
  fprintf(fp,"\n");\
  fflush(fp); \
} while(0)

有没有人可以帮助您以可变方式实现这一点?

假设您也将
fmt
作为宏参数,下面是一个大大缩短的宏版本:

SEND_VALUE(ONE, ONE, ONE, ONE);
如果要明确使用格式,还可以执行以下操作:

#define SEND_VALUE(num, point1, point2, point3, ...) \
do { \
  fprintf(fp,#num":"#point1":"#point2":"#point3":\n");\
  fflush(fp); \
  fprintf(fp,__VA_ARGS__);\
  fflush(fp); \
  fprintf(fp,"\n");\
  fflush(fp); \
} while(0)
但是您应该注意,
,##uu_uva_uargs_u
是一个gcc扩展

几点注意:

  • 使用
    do{}while(0)
    对扩展到代码块的宏进行防错;当/
    处于
    /etc块时,它们可以作为单个语句放入
    中,并且它们也可以接受
    没有运行时开销
  • 使用
    #param
    获取值为参数名的字符串。在您的示例中,
    SEND\u值(一,一,一,一)
    \num
    将是
    “一”
  • 在C
    中,“some”string
    相当于
    “some string”
  • 如果将
    fp
    作为参数传递给宏,效果会更好

编辑:最后,您的宏可以这样使用:

#define SEND_VALUE(num, point1, point2, point3...) \
{ \
  char number[6]; \
  char p1[6];\
  char p2[6];\
  char p3[6];\
  if(num == ONE) {sprintf(number, "ONE");}\
  if(num == TWO) {sprintf(number, "TWO");}\
  if(num == THREE) {sprintf(number, "THREE");}\
  if(point1 == ONE) {sprintf(p1, "ONE");}\
  if(point1 == TWO) {sprintf(p1, "TWO");}\
  if(point1 == THREE) {sprintf(p1, "THREE");}\
  if(point2 == ONE) {sprintf(p2, "ONE");}\
  if(point2 == TWO) {sprintf(p2, "TWO");}\
  if(point2 == THREE) {sprintf(p2, "THREE");\
  if(point3 == ONE) {sprintf(p3, "ONE");}\
  if(point3 == TWO) {sprintf(p3, "TWO");}\
  if(point3 == THREE) {sprintf(p3, "THREE");\
  fprintf(fp,"%s:%s:%s:%s:\n",number, p1,p2,p3);\
  fflush(fp); \
  fprintf(fp,fmt,##__VA_ARGS__);\
  fflush(fp); \
  fprintf(fp,"\n");\
  fflush(fp); \
}
#define SEND_VALUE(num, point1, point2, point3, fmt, ...) \
do { \
  fprintf(fp,#num":"#point1":"#point2":"#point3":\n");\
  fflush(fp); \
  fprintf(fp,fmt,##__VA_ARGS__);\
  fflush(fp); \
  fprintf(fp,"\n");\
  fflush(fp); \
} while(0)

你是说这样的方式吗?改用可变函数。我不熟悉可变宏。有人能把上面的代码变位并贴在这里吗?什么是
fmt
?另外,您在
之前缺少一个
。我不确定fmt是什么。从其他地方获取代码并尝试修改。fmt是一个关键词还是什么?或者只是一个接收变量,比如点1,点2?那么fprintf(fp,fmt,###########VA#u ARGS#)是什么呢;do?@aod,
fmt
应该是一个格式字符串。因此
fprintf(fp,fmt,######(VA#u ARGS)
预计将扩展到类似于
fprintf(fp,%d%s,x,str)
(假设假想参数
%d%d”
x
str)。如果您不了解
fprintf
的功能,请参阅。