宏定义类型的c printf
我在if宏中有一个typedef,类似于:宏定义类型的c printf,c,C,我在if宏中有一个typedef,类似于: #ifdef BLA_BLA typedef int typeA #elseif typedef double tyeA #endif printf("%d" , a); printf("%l" , a); 我想知道当我为这个案例编写printf时,最好的方法是什么?%d或%l 我知道我也可以在宏中定义固定字符串。但是这是最好的方法吗?也使用宏定义格式字符串 #ifdef BLA_BLA typedef int typeA; #define FOR
#ifdef BLA_BLA
typedef int typeA
#elseif
typedef double tyeA
#endif
printf("%d" , a); printf("%l" , a);
我想知道当我为这个案例编写printf时,最好的方法是什么?%d或%l
我知道我也可以在宏中定义固定字符串。但是这是最好的方法吗?也使用宏定义格式字符串
#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);
也可以使用宏定义格式字符串
#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);
还有另一种选择-定义一个简短的助手函数,这样您就不必在代码中到处散布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);
}
还有另一种选择-定义一个简短的助手函数,这样您就不必在代码中到处散布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);
}
是否确实要将类型定义为整数或浮点?它们都是数字的,但它们的行为在许多方面是如此的不同,以至于编写在任何一种情况下都能正确工作的代码都是困难的 在许多情况下,您可以转换为足够宽的类型,以覆盖两种可能类型的范围。一个简单的例子:
#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;
}
更一般地说,您可以分别使用%jd或%ju转换为在或中定义的intmax_t或uintmax_t
通过将所有内容转换为长双精度几乎可以完成相同的操作,但对于大的整数值,这可能会失去精度。是否确实要将类型定义为整数或浮点?它们都是数字的,但它们的行为在许多方面是如此的不同,以至于编写在任何一种情况下都能正确工作的代码都是困难的 在许多情况下,您可以转换为足够宽的类型,以覆盖两种可能类型的范围。一个简单的例子:
#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;
}
更一般地说,您可以分别使用%jd或%ju转换为在或中定义的intmax_t或uintmax_t
几乎可以通过将所有内容转换为长双精度来完成相同的工作,但这可能会丢失大整数值的精度。如果是我,我不会直接将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的原因之一;如果表示像在本例中那样重要,那么您真的不想对使用它的人隐藏该信息。如果是我,我不会直接将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的原因之一;如果表示法很重要,例如在本例中,那么您确实不想对使用它的人隐藏该信息。在实际应用程序中,格式字符串很可能会更长。@ThiefMaster-同意,但是,该建议的目的是不必每次打印值时都使用ifdef,这与OP的例子是一致的。涉及其他值和字符串的更复杂的格式设置显然需要额外的工作…在实际应用程序中,格式字符串很可能更长。@ThiefMaster-同意,但是,该建议的目的是不必在每次打印值时都使用ifdef,并且与OP的示例一致。涉及其他值和字符串的更复杂格式显然需要额外工作…%l不正确;double的格式为%f、%g或%e,具体取决于您希望如何处理指数。%l不正确;double的格式为%f、%g或%e,具体取决于您希望如何处理指数。