为什么printf打印出错误的数值?

3

当我使用 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

1
整数不是浮点值... - mjv
我理解这一点。但我想知道为什么它会打印其他东西?是否存在某种溢出?打印它所做的事情背后的原因是什么? - user69514
2
-1 对于又一个无用的“为什么会发生这种情况?”问题,其中包含无效代码/未定义行为。 - R.. GitHub STOP HELPING ICE
@NedBatchelder 你似乎认为自学C语言基础是不可能的。这并不正确,只要付出努力就可以学会。 - The Paramagnetic Croissant
@user3477950,我不确定你为什么标记了我,我根本没有在这个问题上发表评论。 - Ned Batchelder
显示剩余5条评论
7个回答

13

当然它会输出“奇怪”的东西。你正在传递int,但告诉printf你传递了float。由于这两种数据类型具有不同且不兼容的内部表示,因此你会得到“无意义的话语”。

在向像printf这样的可变参数函数传递变量时,不存在“自动转换”,值以它们实际的数据类型传递到函数中(或在某些情况下升级为更大的兼容类型)。

你所做的事情有点类似于这样:

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 */

5
当你将变量传递给可变参数函数时,不存在"自动转换"。这是关键,我认为它值得重复强调,因为它非常微妙(如果你来自一种高级语言)且非常重要。 - caf

4
如果您想将它们作为浮点数打印出来,您可以在将它们传递给printf函数之前将它们强制转换为float类型。
printf("%f %f %f %f %f\n", (float)a, (float)b, (float)c, (float)d, (float)e);

3

a、b、c、d和e不是浮点数。printf()将它们解释为浮点数,这会在屏幕上打印出奇怪的内容。


2

printf()中使用不正确的格式说明符会引起未定义行为

例如:

 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

那么“float”的说明符是什么? - Hemant

1

问题出在...printf内部。发生了以下情况

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

0

printf和可变参数的工作原理是,在字符串中的格式说明符(例如“%f%f”)告诉printf类型,因此也知道参数的大小。如果为参数指定了错误的类型,则会使其混淆。

请查看stdarg.h以获取用于处理可变参数的宏。


0
对于“正常”的(非可变参函数,所有类型都已指定),编译器会在需要时将整数类型转换为浮点类型。
对于可变参函数,这种情况不会发生,它们始终是“按原样”传递的。

1
除非它们被提升为更大的类型。 - bk1e

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接