C 编写使用所传递参数名称的变量宏

C 编写使用所传递参数名称的变量宏,c,macros,variadic-functions,variadic-macros,C,Macros,Variadic Functions,Variadic Macros,我想写一个变量宏,它知道传递的参数的名称。 例如: 守则: int x = 2; float f = 4.6; char c = 'A'; char* str = "Bla bla"; PRINT("%d %f %c %s", x, f, c, str); // calling the macro 将产生输出 x=2 f=4.6 c=A str=Bla bla. 希望有人知道答案。仔细阅读的文档。特别是,关于、和。这里有很好的解释 您可能无法完全实现您想要的,因为您需要拆分格式字

我想写一个变量宏,它知道传递的参数的名称。 例如:

守则:

int x = 2;
float f = 4.6;
char c = 'A';
char* str = "Bla bla";
PRINT("%d  %f %c  %s", x, f, c, str);     // calling the macro
将产生输出

x=2 f=4.6 c=A str=Bla bla.
希望有人知道答案。

仔细阅读的文档。特别是,关于、和。这里有很好的解释

您可能无法完全实现您想要的,因为您需要拆分格式字符串

也许降低你的目标(例如只接受一个参数用于<代码>打印<代码>,查看或回答),或者考虑使用一个更强大的预处理器,比如


您也可以使用自定义GCC(通过添加内置项),例如,但这可能不值得(对于新手)花费数周的时间来完成。

GCC 4.7中的下一步工作:

#include <stdio.h>
#define PRINT(...) fprintf (stderr, __VA_ARGS__)

int main()
{
int x = 2;
float f = 4.6;
char c = 'A';
char* str = "Bla bla";
PRINT("%d  %f %c  %s", x, f, c, str); // calling the macro
}
#包括
#定义打印(…)fprintf(标准格式,参数)
int main()
{
int x=2;
浮点数f=4.6;
字符c='A';
char*str=“Bla-Bla”;
打印(“%d%f%c%s”,x,f,c,str);//调用宏
}
(请注意,我已编辑宏调用,将%s更改为%c)

将询问者要求的内容视为接近但不完全(仅适用于单一表达式):

#define PRINT(fmt, var) printf(#var " = " fmt, (var))
以下是一个例子:

#include <stdio.h>
#include <stdlib.h>

#define PRINT(fmt, var) printf(#var " = " fmt, (var))

int
main(int argc, char *argv[])
{
    int x = 2, y = 3;
    float f = 4.6;
    char c = 'A';
    char *str = "Bla bla";
    PRINT("%d\n", x);
    PRINT("%f\n", f);
    PRINT("%c\n", c);
    PRINT("%s\n", str);
    PRINT("%d\n", x+y);
    exit(EXIT_SUCCESS);
}
#包括
#包括
#定义PRINT(fmt,var)printf(#var“=”fmt,(var))
int
main(int argc,char*argv[])
{
int x=2,y=3;
浮点数f=4.6;
字符c='A';
char*str=“Bla-Bla”;
打印(“%d\n”,x);
打印(“%f\n”,f);
打印(“%c\n”,c);
打印(“%s\n”,str);
打印(“%d\n”,x+y);
退出(退出成功);
}

我认为你无法实现你想要的

但像这样的东西可能是你的:

#define PRINT(fmt, val) fprintf(stderr, "%s=" fmt, #val, val)

...

int x = 2;
float f = 4.6;
char c = 'A';
char* str = "Bla bla";
// calling the macro:
PRINT("%d  ", x);
PRINT("%f ", f);
PRINT("%c  ", c);
PRINT("%s\n", str);

您可能需要的是:

#include <stdio.h>

#define STRINGIFY(x) #x, (x)
#define FPRINTF(file, fmt, ...) fprintf(file, fmt, __VA_ARGS__)
#define PRINTF(fmt, ...) FPRINTF(stdout, fmt, __VA_ARGS__)

int main(void)
{
  int i = 42;
  char ch = 'a';
  char str[4] = "alk";

  PRINTF("%s=%s, %s=%c, %s=%d\n", 
    STRINGIFY(str), 
    STRINGIFY(ch), 
    STRINGIFY(i)
  );

  /* of just use printf directly: */
  printf("%s=%s, %s=%c, %s=%d\n", 
    STRINGIFY(str), 
    STRINGIFY(ch), 
    STRINGIFY(i)
  );

  return 0;
}
#包括
#定义STRINGIFY(x)#x,(x)
#定义FPRINTF(文件,fmt,…)FPRINTF(文件,fmt,_uva_u参数)
#定义PRINTF(fmt,…)FPRINTF(stdout,fmt,u_VA_参数)
内部主(空)
{
int i=42;
char ch='a';
char str[4]=“alk”;
PRINTF(“%s=%s,%s=%c,%s=%d\n”,
STRINGIFY(str),
严格化(ch),
严格化(一)
);
/*当然,直接使用printf即可:*/
printf(“%s=%s,%s=%c,%s=%d\n”,
STRINGIFY(str),
严格化(ch),
严格化(一)
);
返回0;
}

/戴上印第安纳·琼斯的帽子/

我可能有点晚了,但我在这里要说的是,这个问题确实有一个适当的解决方案

首先,一些先决条件定义():

然后是代码,实际上是@alk答案的扩展:

#include <stdio.h>

#define STRING1(n, a) #a, (a)
#define STRING0(n, a) , STRING1(n, a)
#define PRINTF(fmt, ...) printf(fmt, L(STRING, __VA_ARGS__))

int main(int argc, char *argv[]) {
    int i = 42;
    char ch = 'a';
    char str[4] = "alk";
    /** every var must be preceded with '%s' for its name to be shown **/
    PRINTF("%s=%s, %s=%c, %s=%d\n", str, ch, i);
    return 0;
}
#包括
#定义STRING1(n,a)#a,(a)
#定义STRING0(n,a)、STRING1(n,a)
#定义PRINTF(fmt,…)PRINTF(fmt,L(字符串,变量)
int main(int argc,char*argv[]){
int i=42;
char ch='a';
char str[4]=“alk”;
/**每个变量前面必须有“%s”才能显示其名称**/
PRINTF(“%s=%s,%s=%c,%s=%d\n”,str,ch,i);
返回0;
}
此版本仅适用于[0..16]个参数,但可以轻松扩展到任何参数计数,尤其是2的幂。然而,它支持的论点越多,它看起来就越不优雅


附言:@BasileStarynkevitch已经提供了所有正确的链接来说明这是如何工作的。

对于字符打印iss%c而不是%S,我更新了这个问题,我很确定这是不可能的。对于OP:你确定要这样做吗?这不容易做到!(但是如果你花了几天或几周的工作,你可能会得到一些接近)。你试图解决哪一个问题?这在你的例子中是不可能的:一个字符串文字,比如<代码>“%D%F%C%S”不能被分开,在中间增加或被C预处理器修改。它只能用于单个参数,因为字符串串联允许将另一个字符串前置到字符串文字。它不显示OP想要的名称
x
(仅显示其值)。@Dipto是的,你是对的,这就是为什么我说“关闭但不完全”:-)打字:不是信号,而是单个变量@leeduhem可以随意回滚。看起来我的编辑删除了你的。@remyabel“single”很好。但我认为“单表达式”更准确,这个宏也适用于
x+y
#include <stdio.h>

#define STRING1(n, a) #a, (a)
#define STRING0(n, a) , STRING1(n, a)
#define PRINTF(fmt, ...) printf(fmt, L(STRING, __VA_ARGS__))

int main(int argc, char *argv[]) {
    int i = 42;
    char ch = 'a';
    char str[4] = "alk";
    /** every var must be preceded with '%s' for its name to be shown **/
    PRINTF("%s=%s, %s=%c, %s=%d\n", str, ch, i);
    return 0;
}