打印联合变量 - 奇数行为

Gee*_*kyJ 4 c printf unions type-punning

#include <stdio.h>

union p{
    int x;
    float y;
};

int main()
{
    union p p;
    p.x = 10; 
    printf("%f\n", p.y);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

0.000000

当我尝试编译上面的程序时,即使在main函数中也没有显示任何警告.为什么printf不打印价值10.00000

我已经阅读了一些关于stackoverflow的相关问题,它解释了printf在没有使用float说明符进行类型转换的情况下打印整数时的行为,但我认为这是一个不同的情况.我用float说明符打印浮点数.它应该打印正确的值.任何人都可以解释这里发生了什么?

Grz*_*ski 5

这是因为两者intfloat对象都具有不同的二进制表示.假设32位intfloat小端和IEEE-754表示,您有二进制模式:

0000 1010 0000 0000 0000 0000 0000 0000
Run Code Online (Sandbox Code Playgroud)

这是(在浮点数的上下文中)非常小的数字,其具有0.000000使用%f格式说明符的打印值(可以说是舍入的printf).您可以尝试使用%efs,这会产生另一个输出:

1.401298e-44
Run Code Online (Sandbox Code Playgroud)

C99引入了%afs,它表示与存储时完全相同的浮点数,即2-base浮点数(即带有尾数和指数):

0x1.4p-146
Run Code Online (Sandbox Code Playgroud)


dev*_*ull 4

将 10 个整数放入 x 中。如果你写 px = 1092616192 而不是 px = 10 你会看到会发生什么也请阅读https://en.wikipedia.org/wiki/IEEE_floating_point

10在内存中不等于10.f。

  • 假设 `int` 是 4 个字节,但情况可能并非如此 (2认同)
  • @dev_null 每年(2014 年)生产超过十亿个嵌入式处理器,其中 C 非常流行。数以百万计的此类处理器是 16 位甚至 8 位的。许多此类编译器都使用 16 位“int”。所以当然不是 2014 年所有常见的架构都有 4 字节“int”。 (2认同)