我从第二个0.23
获得输出printf
。但是类型转换可以提供所需的输出。如果我没有使用类型转换,则打印前一个值。编译器版本是GCC 6.3
#include <stdio.h>
int main() {
printf("%f ", 0.23);
printf("%f", 0);
return 0;
}
在
> printf("%f",0);
你要打印一个双,但你给一个int,这是矛盾的
你不是生成的代码从int得到一个双倍的情况,因为printf不是int printf(const char *, double);
而是int printf ( const char * format, ... );
并且编译器没有查看格式来进行必要的转换(但在很多情况下编译器警告你)
当print对第二个参数的访问是使用64b获取double并且可能你的int只使用32b时,行为是未定义的。
(编辑,谢谢@chqrlie)
当我打印新值时,我得到以前的浮点值
在你的情况下,printf可以从MMX寄存器中检索一个double值,而不是通过堆栈或常规寄存器传递的int值...这可以解释为什么相同的值被打印两次。但当然,由于总是存在未定义的行为,其他任何事情都可能随时发生
问题是两个因素的结合:
第一个是对于像printf
这样的vararg函数,编译器不会对参数进行任何隐式转换。所以参数列表中的0
是一个整数常量(类型为int
)。
第二个因素是不匹配的格式说明符。除了格式字符串中指定的内容之外,printf
函数对传递的参数一无所知。不匹配的格式和参数类型导致undefined behavior。由于"%f"
说明符使printf
期望double
类型的值,并且你给出了int
值,你有这样的不匹配。