我在if
宏中有一个typedef,类似于:
#ifdef BLA_BLA
typedef int typeA
#elseif
typedef double tyeA
#endif
printf("%d" , a); printf("%l" , a);
我想知道在为这个案例编写printf时最好的方法是什么? (%d
或%l
)。
我知道我也可以在宏中定义一个固定的字符串。但这是最好的方式吗?
答案 0 :(得分:7)
使用宏来定义格式字符串。
#ifdef BLA_BLA
typedef int typeA;
#define FORMAT "%d"
#elseif
typedef double typeA;
#define FORMAT "%f"
#endif
...
typeA a = ...;
printf("Hello " FORMAT " there", a); printf(FORMAT , a);
答案 1 :(得分:2)
您真的想要将类型定义为整数或浮点数吗?它们都是数字的,但它们的行为在很多方面都是如此不同,以至于编写在任何一种情况下都能正常工作的代码将会很困难。
在许多情况下,您可以转换为足够宽的类型,以涵盖两种可能类型的范围。一个简单的例子:
#include <stdio.h>
#ifdef BLA_BLA
typedef int num_type;
#else
typedef long num_type;
#endif
int main(void) {
num_type x = 42;
printf("x = %ld\n", (long)x);
return 0;
}
更一般地说,您可以分别使用intmax_t
或uintmax_t
转换为<stdint.h>
或<inttypes.h>
中定义的"%jd"
或"%ju"
你可以几乎通过将所有内容转换为long double
来做同样的事情,但是对于大整数值可能会失去精确度。
答案 2 :(得分:0)
如果是我,我不会直接将typeA
参数传递给printf
;我创建另一个函数,返回一个typeA
值的字符串表示,并将该字符串传递给printf
(或显示它所需的任何其他函数)。
char *formatTypeA(typeA val, char *buf, size_t len)
{
#ifdef BLA_BLA
#define FORMATCHAR d
#else
#define FORMATCHAR f
#endif
char formatStr[SIZE]; // where SIZE is large enough to handle the longest
// possible size_t value plus "%" plus the format
// character plus the 0 terminator
sprintf(formatStr, "%%%zu" FORMATCHAR, len - 1);
sprintf(buf, formatStr, val);
return buf;
}
int main(void)
{
typeA foo;
char output[10];
...
printf("foo = %s\n", formatTypeA(foo, output, sizeof output));
...
}
可能有更好的方法。
修改强>
这是我不经常使用typedef的原因之一,顺便说一下;如果表示很重要(例如在这种情况下),那么你真的不想隐藏那些使用它的人的信息。
答案 3 :(得分:-1)
另一种选择 - 定义一个简短的帮助函数,这样你就不必在整个代码中遍布ifdef:
#ifdef BLA_BLA
typedef int typeA
#else
typedef double typeA
#endif
inline void print_typeA(const typeA val) {
#ifdef BLA_BLA
printf("%d" , val);
#else
printf("%e" , val);
#endif
}
somefunc()
{ typeA xyz;
print_typeA(xyz);
}