我想使用这个宏来放置(如果'i'大于零)符号'^'和我传给(i)到宏的数字
#define ESP(i) ((i>0) ? ("^"(i)) : "")
我想以这种方式称呼它
printf("%+d%s", n1, ESP(i));
其中'i'是循环的索引,但编译报告错误; 如何修改代码才对?
答案 0 :(得分:1)
有点脏,但应该有效:
#include <stdio.h>
#define DYNFORMAT(n, i) (i>0) ?"%+d%s%d\n" :"%+d%s%s\n", n, (i>0) ?"^" :"", (i>0) ?i :""
int main(void)
{
int i = 0;
printf(DYNFORMAT(42, i));
i = 1;
printf(DYNFORMAT(42, i));
}
这应该打印:
+42
+42^1
免责声明:我不确定这是否符合标准,以及如何摆脱编制过程中发出的警告。
干净的方法是使用两次printf()
的调用。
这可以实现为宏或函数。
我喜欢预处理器,宏版本在这里:
#define PRINT_ESP(n, i) \
do { \
if (i = 0) \
printf("%+d", n); \
else \
printf("%+d^%d", n, i); \
} while (0);
答案 1 :(得分:1)
宏在编译时运行,而不是在运行时运行。他们可以执行各种文本修改技巧,但他们不会评估任何东西。 (但它们当然可以扩展到评估某些内容的代码。)将变量i
的格式化值放入字符串中涉及评估i
;没有宏可以做到这一点。
您可以扩展宏的范围以包含整个printf()
调用:
#define PRINT_ESP(n1, i) do { \
printf(((i > 0) ? "%+d^%d" : "%+d"), n1, i); \
} while (0)
或者,您可以使用宏来表达上面宏定义中包含的格式选择,或者您可以将完整的printf()
调用直接放在代码中。
所有这些变化都是基于以下事实:超出给定格式所要求的参数在调用之前进行评估,但被printf()
本身忽略。
答案 2 :(得分:-2)
你不需要在“^”之后的(i)。将您的宏更改为此值,它应该有效#define ESP(i) ((i>0) ? ("^") : (""))
。然后在你的printf语句中,如果你想在“^”之后打印i的值,那么就像这样printf("%s%d", ESP(i), i);
据我所知,我不认为你可以格式化一个字符串以包含一个整数宏,因为这将需要调用其他函数,所以你必须将i带入printf中的字符串。