简体   繁体   English

为什么printf打印错误的值?

[英]Why does printf print wrong values?

Why do I get the wrong values when I print an int using printf("%f\\n", myNumber) ? 为什么在使用printf("%f\\n", myNumber)打印一个int时为什么得到错误的值?

I don't understand why it prints fine with %d , but not with %f . 我不明白为什么它在%d可以正常打印,但在%f却不能正常打印。 Shouldn't it just add extra zeros? 它不应该只是添加额外的零吗?

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

well of course it prints the "weird" stuff. 当然,它会打印“怪异”的东西。 You are passing in int s, but telling printf you passed in float s. 您正在传递int ,但是告诉printf您已传递float Since these two data types have different and incompatible internal representations, you will get "gibberish". 由于这两种数据类型具有不同且不兼容的内部表示形式,因此您将获得“乱码”。

There is no "automatic cast" when you pass variables to a variandic function like printf , the values are passed into the function as the datatype they actually are (or upgraded to a larger compatible type in some cases). 当您将变量传递给变量函数如printf ,没有“自动强制转换”,这些值将按其实际的数据类型传递给该函数(或在某些情况下升级为更大的兼容类型)。

What you have done is somewhat similar to this: 您所做的工作与此类似:

union {
    int n;
    float f;
} x;

x.n = 10;

printf("%f\n", x.f); /* 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 and e aren't floats. a,b,c,d和e不是浮点数。 printf() is interpreting them as floats, and this would print weird stuff to your screen. printf()将它们解释为浮点数,这会将奇怪的东西打印到屏幕上。

Using incorrect format specifier in printf() invokes Undefined Behaviour printf()使用不正确的格式说明符会调用Undefined Behaviour

For example: 例如:

 int n=1;
 printf("%f", n); //UB

 float x=1.2f;
 printf("%d", x); //UB

 double y=12.34;
 printf("%lf",y); //UB 

Note: format specifier for double in printf() is %f . 注意: printf() double格式说明符为%f

the problem is... inside printf . 问题是...在printf内部。 the following happens 发生以下情况

if ("%f") {
 float *p = (float*) &a;
 output *p;  //err because binary representation is different for float and int
}

the way printf and variable arguments work is that the format specifier in the string eg "%f %f" tells the printf the type and thus the size of the argument. printf和变量参数的工作方式是字符串中的格式说明符,例如“%f%f”,它告诉printf类型以及参数的大小。 By specifying the wrong type for the argument it gets confused. 通过为参数指定错误的类型,会引起混淆。

look at stdarg.h for the macros used to handle variable arguments 在stdarg.h中查看用于处理变量参数的宏

For "normal" (non variadac functions with all the types specified) the compiler converts integer valued types to floating point types where needed. 对于“普通”(指定了所有类型的非variadac函数),编译器将在需要时将整数类型转换为浮点类型。

That does not happen with variadac arguments, which are always passed "as is". 对于variadac参数则不会发生这种情况,这些参数始终按 “原样”传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM