我想写一个变量宏,它以某种方式知道传递的参数的名称。 例如:
代码:
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.
希望有人知道答案。
答案 0 :(得分:5)
关闭但不完全(仅适用于单一表达)提问者需要的内容:
#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);
}
答案 1 :(得分:1)
仔细阅读 cpp的文档。特别是关于macro arguments,stringification,concatenation和variadic macros。这里有很好的解释。
您可能无法完全达到您想要的效果,因为您需要拆分格式字符串。
可能会降低您的目标(例如,仅接受PRINT
的一个参数,请参阅this或that个答案)或考虑使用更强大的预处理器,例如{ {3}}
您也可以自定义GCC(通过添加您的内置)与例如GPP但这可能不值得这几周的努力(对于新手)。
答案 2 :(得分:1)
我认为你无法达到你想要的效果。
但是这样的事情可能是你的:
#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);
答案 3 :(得分:1)
你可能想要的东西:
#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;
}
答案 4 :(得分:1)
/投入印第安纳琼斯的帽子/
我可能有点太晚了,但我在这里说这个问题确实有一个合适的( - )解决方案。
首先,一些先决条件定义(explanation here):
#define L(c, ...) \
L4(c,1,0,,,,,,,,,,,,,##__VA_ARGS__) L4(c,0,1,,,,,,,,,##__VA_ARGS__) \
L4(c,0,2,,,,, ##__VA_ARGS__) L4(c,0,3, ##__VA_ARGS__)
#define L4(c, f, n, ...) \
L3(c,f,n##0,,,,__VA_ARGS__) L3(c,0,n##1,,,__VA_ARGS__) \
L3(c,0,n##2,, __VA_ARGS__) L3(c,0,n##3, __VA_ARGS__)
#define L3(...) L2(__VA_ARGS__, \
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, )
#define L2(c, f, \
n00,n01,n02,n03, n04,n05,n06,n07, n08,n09,n0A,n0B, n0C,n0D,n0E,n0F, \
a00,a01,a02,a03, a04,a05,a06,a07, a08,a09,a0A,a0B, a0C,a0D,a0E,a0F, \
s, ...) L##s(c, f, n00, a00)
#define L1(c, f, n, a) c##f(n, a)
#define L0(c, f, n, a)
那么代码,实际上是@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;
}
此版本仅适用于[0..16]参数,但它可以很容易地扩展到任何参数计数,尤其是2的幂。但是,它支持的参数越多,它看起来就越不优雅。
P.S。:@BasileStarynkevitch已经提供了所有正确的链接,以阐明其工作原理。
答案 5 :(得分:-1)
接下来的工作对我来说是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
}
(请注意我编辑了宏调用,更改了%s的%s)
此致