有这样的代码:
#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)?
答案 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)
是签名还是未签名?
使用此作为参考: http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/FUNCTIONS/format.html
答案 4 :(得分:0)
浮点数以特殊格式存储在内存中,它不仅仅是一个数字,还有一些小数位,请参阅How to represent FLOAT number in memory in C