这是如何计划的?

#include <stdio.h> int main() { float a = 1234.5f; printf("%d\n", a); return 0; }

它显示一个0 这怎么可能? 什么道理?



我特意放了%dprintf声明,研究行为printf

--------------解决方案-------------

这是因为%d期待一个int但您提供一个浮动。

使用%e %f %g打印浮动。



为什么0打印:将浮点数转换为double发送给之前printf 数上双的代表性1234.5在小尾数是

00 00 00 00 00 4A 93 40

%d消耗的32位整数,所以一个零被打印。 (作为一个测试,你可以printf("%d, %d\n", 1234.5f);你可以得到的输出0, 1083394560



至于为什么float转换为double ,如printf的原型为int printf(const char*, ...)从6.5.2.2/7,

在函数原型的省略号声明符引起的参数类型转换的最后一个声明参数后,停止的默认参数促销活动对尾随参数执行。

从6.5.2.2/6,

如果这表示调用函数的表达式具有不包括一个原型类型,整数促销活动的每个参数执行具有类型参数的float都提升到double这些被称为默认参数促销

(感谢阿洛克查找了这一点。)

从技术上讲是没有 printf ,每个库实现了自己的,因此,你的努力学习方法printf做你正在做什么的行为是不会多大用处。 你可能会试图研究行为printf您的系统上,如果是这样,你应该阅读文档和看的源代码printf如果可用)为您的图书馆。

例如,在我的MacBook,我得到的输出1606416304与您的程序。

话虽如此,当你通过一个float到一个可变参数的功能,该float被作为一个double 。 所以,你的程序就等于已经宣告a作为double

要检查的字节double ,你可以看到这个答案,在这里因此,一个最近的问题。

让我们做到这一点:

#include <stdio.h>

int main(void)
{
double a = 1234.5f;
unsigned char *p = (unsigned char *)&a;
size_t i;

printf("size of double: %zu, int: %zu\n", sizeof(double), sizeof(int));
for (i=0; i < sizeof a; ++i)
printf("%02x ", p[i]);
putchar('\n');
return 0;
}

当我运行上面的程序,我得到:

size of double: 8, int: 4
00 00 00 00 00 4a 93 40

所以,前四个字节的double竟然是0,这可能是为什么你有0作为你的输出printf调用。

欲了解更多有趣的结果,我们可以改变程序了一下:

#include <stdio.h>

int main(void)
{
double a = 1234.5f;
int b = 42;

printf("%d %d\n", a, b);
return 0;
}

当我在我的MacBook运行上面的程序,我得到:

42 1606416384

随着Linux机器上的同一个节目,我得到:

0 1083394560

%d符告诉printf期望一个整数。 因此,前四个(或两个,取决于平台)浮动字节intepreted为整数。 如果它们碰巧是零,零被打印

的1234.5二进制表示法是一样的东西

1.00110100101 * 2^10 (exponent is decimal ...)

对于C编译器,代表float实际是IEEE754双精度值,该字节会(如果我没有弄错)

01000000 10010011 01001010 00000000 00000000 00000000 00000000 00000000

在一个Intel(x86)的系统与小字节序(即至少显著​​字节未来第一),则该字节序列被颠倒,使得前四个字节是零。 也就是说,什么样printf打印出...

请参见本作根据IEEE754浮点表示维基百科的文章。

因为你调用未定义行为:您违反了printf()的方法的合同,骗其关于它的参数类型,所以编译器可以自由地为所欲为。 它可以使程序输出“dksjalk是ninnyhead !!!” 并在技术上它仍然是正确的。

这是因为在二进制浮点数的表示。 转换为整数0离开它。

原因在于printf()是一个非常愚蠢的功能。 它根本不检查类型。 如果你说的第一个参数是一个int这是你说的话与%d它认为你和它只需为所需的字节int 在这种情况下,asuming机器使用四字节int和八字节double (所述float被转换为一个doubleprintf()前四个字节的a将只是零,而这被打印。

这将不转换自动浮到整数。 因为这两个拥有不同的存储格式。 所以,如果你要转换,使用(INT)类型转换。

#include <stdio.h>

int main() {
float a = 1234.5f;
printf("%d\n", (int)a);
return 0;
}

既然你用C ++标签一样好,这个代码的转换,你可能期望:

#include <iostream.h>

int main() {
float a = 1234.5f;
std::cout << a << " " << (int)a << "\n";
return 0;
}

输出:

1234.5 1234

%d是小数

%f是浮动

看多了这些在这里。

你得到0,因为花车和整数的表示不同。

你只需要使用适当的格式指示符(%D,%F,%S等)相关的数据类型(整型,浮点,字符串,等等)。

你想要%F而不是%d

嘿,它必须打印东西,所以它印0。还记得在C 0是一切!

这不是一个整数。 尝试使用%f

分类:C# 时间:2015-03-15 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 3.802 (s). 10 q(s)