printf显示出奇怪的东西

时间:2011-09-15 16:58:31

标签: c

有这样的代码:

#include <stdio.h>

int main() {
  float d = 1.0;
  int i = 2;
  printf("%d %d", d, i);
  getchar();
  return 0;
}

输出是:

0 1072693248

我知道printf中存在错误,第一个%d应该替换为%f。但为什么变量i打印错误(1072693248而不是2)?

5 个答案:

答案 0 :(得分:11)

由于您指定了%d而不是%f,因此您真正看到的是d的二进制表示形式。

此外,由于数据类型不匹配,因此代码实际上具有未定义的行为。

编辑:

现在解释为什么你没有看到2

float被提升到堆栈上的double。类型double是(在这种情况下)8字节长。但是,由于printf指定了两个整数(在这种情况下均为4个字节),因此您将1.0的二进制表示视为类型double。 2不会被打印,因为它超出了printf期望的8个字节。

答案 1 :(得分:4)

printf不只是使用格式代码来决定如何打印其参数。它使用它们来决定如何访问其参数(它在内部使用va_arg)。因此,当您为第一个参数(%d而不是%f)提供错误的格式代码时,您不仅要弄乱第一个参数的打印,而是让它看起来在所有后续参数的错误位置。这就是你为第二个论点弄得胡说八道的原因。

答案 2 :(得分:1)

您需要了解printf的工作原理。调用者将所有参数放在堆栈上。当它通过fmt字符串进行解析时,第一次看到%d时,它会选择堆栈上的第一个4字节字并将其打印为整数。第二次看到%d时,它会选择下一个4字节的字。您所看到的是原始浮点字节显示为两个整数。

答案 3 :(得分:0)

答案 4 :(得分:0)

浮点数以特殊格式存储在内存中,它不仅仅是一个数字,还有一些小数位,请参阅How to represent FLOAT number in memory in C