0
In C, you cannot reliably determine the type of an object. Hence, you'd have to introduce some mechanism to support generic programming, e.g. enclosing all objects in a structure which holds type information:
在C语言中,您不能可靠地确定对象的类型。因此,您必须引入一些机制来支持泛型编程,例如,将所有对象封装在一个包含类型信息的结构中:
enum {type_int, type_double, type_string, /* ... */ } type_t;
struct {
type_t type;
void *obj;
} generic_type;
Now, you can switch over ((generic_type)my_object).type. This is probably not what you're looking for.
现在,您可以切换到(generic_type)my_object .type。这可能不是你想要的。
However, there's a simple trick to tell whether a macro argument is a string literal or something else. With the macro quoting character '#', you can turn a macro argument into a string:
但是,有一个简单的技巧可以告诉宏参数是字符串文字还是其他东西。使用宏引用字符'#',您可以将宏参数转换为字符串:
#define DEBUG(x) if (#x[0] == '"') printf("%s\n", x); else printf("%d\n", x)
Now you can do the following:
现在你可以做以下事情:
DEBUG("foo bar"); // prints "foo bar"
DEBUG(23); // prints "23"
On the downside, this won't let you distinguish between e.g.ints and floats. Furthermore, pointers-to-char are not recognized as strings:
缺点是,这不会让您区分int和float。此外,对字符的指针不能识别为字符串:
char *foo = "bar";
DEBUG(foo); // prints the value of foo, not the string pointed to by foo
double salary;
DEBUG(salary); // prints (int)salary, not (double)salary
On some machines, sizeof(double) != sizeof(int). This might help to further distinguish between the different types of your macro arguments, but it's certainly not portable.
在某些机器上,sizeof(double) = sizeof(int)。这可能有助于进一步区分不同类型的宏参数,但它肯定不是可移植的。
Generally speaking, you won't be able to completely solve this problem without some serious effort towards generic programming support while also maintaining portability.
一般来说,如果不认真地提供通用编程支持并同时保持可移植性,您将无法完全解决这个问题。
My advice: simply get used to format specifiers.
我的建议是:只需习惯于格式化说明符。