3
#include<stdio.h>

union node {
     int i;
     char c[2];
};

main() {

    union node n;
    n.c[0] = 0;
    n.c[1] = 2;
    printf("%d\n", n.i);
    return 0;
}

我认为它给出了512输出,因为 c[0] 值存储在第一个字节中,而 c[1] 值存储在第二个字节中,但是给出了1965097472. 为什么 ?。我在 Windows 的代码块中编译了这个程序。

4

5 回答 5

8

您的联合分配四个字节,开始为:

[????] [????] [????] [????]

您设置了至少两个有效字节:

[????] [????] [0x02] [0x00]

然后将所有四个字节打印为整数。你不一定会得到512,因为任何东西都可以在最重要的两个字节中。在这种情况下,您有:

[0x75] [0x21] [0x02] [0x00]
于 2012-07-07T07:12:35.077 回答
3

因为未定义的行为。访问一个union未设置的成员就是这样做的,就这么简单。它可以做任何事情,打印任何内容,甚至崩溃。

于 2012-07-07T07:07:04.007 回答
1

未定义的行为,嗯……未定义。

我们可以尝试回答为什么给出了特定的结果其他答案通过猜测编译器实现细节来做到这一点),但我们不能说为什么没有给出另一个结果。据我们所知,编译器可能会打印 0、格式化您的硬盘、放火烧房子或将 100,000,000 美元转入您的银行账户。

于 2012-07-07T07:27:44.587 回答
0

请注意,您int的字节数可能至少为 4 个字节(而不是 2 个字节,就像过去那样)。要让大小匹配,请将类型更改iuint16_t

即使在此之后,该标准实际上也不允许设置一个联合成员,然后访问另一个成员以尝试重新解释字节。但是,您可以使用reinterpret_cast.

union node {
    uint16_t i;
    uint8_t c[2];
};

int main() {
    union node n;
    n.c[0] = 0;
    n.c[1] = 2;
    std::cout << *reinterpret_cast<uint16_t *>(&n) << std::endl;
    return 0;
}
于 2012-07-07T07:13:54.633 回答
0

int编译为 32 位数字,小端。通过将两个较低的字节分别设置为 2 和 0,然后读取 int,您将得到 1965097472。如果您查看十六进制表示 7521 0200,您会再次看到您的字节,此外它是未定义的行为,其中一部分取决于内存架构程序运行的平台。

于 2012-07-07T07:18:30.987 回答