0
#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); \
}

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

我这样称呼这个宏:

SEND_VALUE(ONE, ONE, ONE, ONE);

有人可以帮助以可变的方式实现这一目标吗?

4

1 回答 1

1

假设您还获得fmt了宏参数,这里是您的宏的一个大大缩短的版本:

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

如果您想明确使用格式,您还可以执行以下操作:

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

但你应该注意这,##__VA_ARGS__是一个 gcc 扩展。

几点注意事项:

  • 用于do { } while(0)扩展为代码块的宏以防万一;它们可以作为单个语句放在if/ while/etc 块中,它们也可以;在没有运行时开销的情况下接受。
  • 用于#param获取其值为参数名称的字符串。在您的示例SEND_VALUE(ONE, ONE, ONE, ONE)中,#num将是"ONE".
  • 在 C"some"" string"中相当于"some string".
  • 如果您也将fp作为参数传递给宏会更好。

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

SEND_VALUE(ONE, ONE, ONE, ONE, "");
SEND_VALUE(ONE, TWO, ONE, THREE, "%d", 10);
SEND_VALUE(THREE, TWO, ONE, TWO, "format string! %s %s", "param1", "param2");
于 2014-01-27T10:50:45.223 回答