为什么printf打印错误的值?
当我使用printf("%f\n", myNumber)
打印int
时,为什么会得到错误的值?
我不明白为什么它用%d
打印好,但不用%f
打印。 它不应该只是添加额外的零?
int a = 1; int b = 10; int c = 100; int d = 1000; int e = 10000; printf("%d %d %d %d %d\n", a, b, c, d, e); //prints fine printf("%f %f %f %f %f\n", a, b, c, d, e); //prints weird stuff
当然,它打印出“怪异”的东西。 你正在传入int
s,但告诉printf
你传递了float
s。 由于这两种数据类型具有不同且不兼容的内部表示,因此您将获得“乱码”。
将变量传递给printf
这样的可变函数时,没有“自动转换”,这些值作为它们实际的数据类型传递给函数(或者在某些情况下升级为更大的兼容类型)。
你所做的有点类似于:
union { int n; float f; } x; xn = 10; printf("%f\n", xf); /* pass in the binary representation for 10, but treat that same bit pattern as a float, even though they are incompatible */
如果要将它们作为浮点数打印,可以在将它们传递给printf函数之前将它们转换为浮点数。
printf("%f %f %f %f %f\n", (float)a, (float)b, (float)c, (float)d, (float)e);
a,b,c,d和e不是浮点数。 printf()将它们解释为浮点数,这会将奇怪的东西打印到屏幕上。
在printf()
使用不正确的格式说明符调用Undefined Behaviour
例如:
int n=1; printf("%f", n); //UB float x=1.2f; printf("%d", x); //UB double y=12.34; printf("%lf",y); //UB
注意: printf()
double
格式说明符是%f
。
问题是……在printf
内部。 发生以下情况
if ("%f") { float *p = (float*) &a; output *p; //err because binary representation is different for float and int }
printf和variable参数的工作方式是字符串中的格式说明符,例如“%f%f”告诉printf类型,从而告诉参数的大小。 通过为参数指定错误的类型,它会变得混乱。
查看stdarg.h,了解用于处理变量参数的宏
对于“normal”(指定了所有类型的非variadac函数),编译器会将整数值类型转换为需要的浮点类型。
variadac参数不会发生这种情况,它们总是 “按原样”传递。