C 宏中字符串和数字的混合
我想使用此宏将符号“^”和我传递给宏的数字(I)放入(如果“I”大于零)C 宏中字符串和数字的混合,c,string,macros,numbers,C,String,Macros,Numbers,我想使用此宏将符号“^”和我传递给宏的数字(I)放入(如果“I”大于零) #define ESP(i) ((i>0) ? ("^"(i)) : "") 我想这样称呼它 printf("%+d%s", n1, ESP(i)); 其中“i”是一个周期的索引,但汇编报告了我的错误; 如何修改代码使其正确?您不需要在“^”后面加上(I)。将您的宏更改为此,它应该可以工作#定义ESP(i)((i>0)?(^”):(“”)。然后,在printf语句中,如果要在“^”后面打印i的值,则可以使用类似以
#define ESP(i) ((i>0) ? ("^"(i)) : "")
我想这样称呼它
printf("%+d%s", n1, ESP(i));
其中“i”是一个周期的索引,但汇编报告了我的错误;
如何修改代码使其正确?您不需要在“^”后面加上(I)。将您的宏更改为此,它应该可以工作
#定义ESP(i)((i>0)?(^”):(“”)
。然后,在printf语句中,如果要在“^”后面打印i的值,则可以使用类似以下内容的printf(“%s%d”,ESP(i),i)据我所知,我不认为可以将字符串格式化为在宏中包含整数,因为这需要调用其他函数,所以必须将I放入printf中的字符串中 有点脏,但应该可以:
#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));
}
免责声明:我不确定这是否符合标准,以及如何消除编译过程中给出的警告
干净的方法是使用两个调用
printf()
这可以实现为宏或函数
由于我喜欢前置处理器,这里的宏版本:
#define PRINT_ESP(n, i) \
do { \
if (i = 0) \
printf("%+d", n); \
else \
printf("%+d^%d", n, i); \
} while (0);
宏在编译时运行,而不是在运行时。它们可以执行各种文本篡改技巧,但它们不评估任何内容。(但是,它们当然可以扩展到计算某事物的代码。)将变量
i
的格式化值放入字符串中涉及计算i
;没有宏可以做到这一点
您可以扩展宏的范围,以包括整个printf()
调用:
#define PRINT_ESP(n1, i) do { \
printf(((i > 0) ? "%+d^%d" : "%+d"), n1, i); \
} while (0)
或者,您可以使用宏来表示上述宏定义中包含的格式选择,也可以将上面的完整printf()
调用直接放入代码中
所有这些变化都是基于这样一个事实,即超过给定格式所需参数的参数在调用之前进行求值,但被
printf()
本身忽略。“您不需要(i)…。”就我理解的问题而言,i
的(值)是一个明确的必选项。不,他希望i
的值出现在宏展开中。哦,我的错从他的解释中我想他只是想要打印“^”,好的,让我删除这个答案,然后我想他必须将i打印到printf中,因为将其留在宏中会导致编译错误,所以我编辑了答案。抱歉造成混淆请注意,(i)
不等同于(i>0)
,如果i
是有符号类型。好的,当然可以。但这是一个细节。但是,我们将纠正这一点@约翰伯林格瑞我想象你的警告来自这样的表达:(i>0)?i:
。如果从第二个格式字符串中删除尾随的%s
字段描述符,则可以避免警告并将该表达式更改为普通的i
。这将不起作用,至少因为%s
需要一个参数列表中不存在的“字符串”。更直截了当的是,我的答案。也更干净,因为它产生的警告很少。
#define PRINT_ESP(n1, i) do { \
printf(((i > 0) ? "%+d^%d" : "%+d"), n1, i); \
} while (0)