如果我有
printf("%f\n", 3);
我得到了
3.000000
如果我有:
printf("%f\n", 3.0);
我得到了同样的答案。
但是这就是事情,3和3.0应该是完全不同的,有点明智。
3.0应该类似于01000000010000000000000000000000
(但由于vararg函数中的隐式转换,因此是双精度)
3应该是00000000000000000000000000000011
3必须以某种方式转换为浮动才能显示。
所以我的问题是,这是怎么做到的?编译器是否以某种方式作弊?我如何在我自己的变量args函数中实现它?
答案 0 :(得分:2)
如果您的源代码包含printf("%f\n", 3);
且结果输出为“3”,那么最有可能发生的是:
x = 3.;
之类的赋值语句或printf
等其他printf("%f\n", 3.0);
调用。printf
之前的代码执行此操作,也可能是为printf
之后的代码做准备。printf("%f\n", 3);
时,该浮点3位于寄存器中,当使用double
转换说明符调用printf
时,应该是%f
参数%f
参数的寄存器恰好有一个浮点3,printf
使用该值并产生“3”的结果。换句话说,你的程序很大程度上是通过偶然而非设计来“工作”的。事实上你确实错误地调用了printf
,它只产生了“3”,因为不相关的因素恰好发生了。如果该浮点寄存器中的值为5或-3.25,则printf将打印该值。
printf
例程无法确定传递它的值的类型。 (好的编译器会在编译时检查类型,如果格式字符串是文字[而不是在运行时计算的东西]。但这是由编译器查看调用的源代码而不是{ {1}}常规本身。)
答案 1 :(得分:0)
How does
printf()
distinguish between floating point arguments and integer type arguments?
printf()
relies on the calling code to to pass objects of the expected type.
printf()
analyzes the format string, which in this case is "%f\n"
.
The "%f"
steers code to expect that the next parameter is a double
.
If a float
is passed, it is converted to a double
as part of the usual conversion of arguments to the ...
part of a function.
With a float/double
passed by the calling code, printf()
will properly get that data as a double
and print it. If the calling code passed some other type, the result is undefined behavior (UB). This UB is well explain by @Eric Postpischil.
how is this done? Does the compiler cheat somehow?
How would I implement this in my own variable args function?
The unexpected undefined behavior seen by OP is not certainly reproducible with user code.