2

我是 C/C++ 新手,但很想知道我看到的问题。

typedef union
{
   int a;
   float c;
   char b[20];
}
Union;

int main()
{
 Union y = {100};
 printf("Union y :%d - %s - %f \n",y.a,y.b,y.c);
}

输出是

 Union y :100 - d - 0.000000

我的问题是……为什么要打印“d”?我改变了联合中的顺序仍然是相同的输出。但如果我在联合之外声明一个 char f[20] ,则不会打印任何内容。我有 MacBook lion 图像并使用 xcode。提前致谢

4

3 回答 3

10

的 ASCII 码'd'是 100。设置a为 100 相当于设置b{'d', '\0', '\0', '\0', …noise…}(在 32 位 little-endian 机器上),将其printf视为"d".

于 2013-04-20T02:30:17.560 回答
4

以下程序可以帮助您更好地理解:

#include <stdio.h>

typedef union
{
    int a;
    float c;
    char b[20];
}
Union;

void dump(const void* buffer, size_t length)
{
    size_t i;
    for (i = 0; i < length;) {
        printf("%.2x ", reinterpret_cast<const unsigned char*>(buffer)[i]);
        ++i;
        if (i % 16 == 0) {
            putchar('\n');
        } else if (i % 8 == 0) {
            putchar(' ');
        }
    }
    if (i % 16 != 0) {
        putchar('\n');
    }
}

int main()
{
    Union y = {100};
    printf("Union y :%d - %s - %f \n",y.a,y.b,y.c);
    printf("The content of the Union is: \n");
    dump(&y, sizeof y);
}

输出是:

联合 y :100 - d - 0.000000
联盟的内容是:
64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00

实际上, a(即 a int)的二进制表示是64 00 00 00, 100 的 little-endian 十六进制。b的二进制表示是64 00 ...,0x00 结束字符串,而 0x64 是 'd'。c的二进制表示是64 00 00 00,在IEEE 浮点表示中是 0.0,因为非零部分是指数。

于 2013-04-20T03:54:31.130 回答
2

我改变了联合中的顺序仍然是相同的输出。

联合中元素的顺序不会改变任何东西,因为联合中的所有元素都使用同一块内存。您的代码打印100fory.adfory.b因为两个表达式解释相同的字节。因此,例如,如果您添加一行设置y.b然后再次打印:

Union y = {100};
printf("Union y :%d - %s - %f \n",y.a,y.b,y.c);
y.b = 'f';
printf("Union y :%d - %s - %f \n",y.a,y.b,y.c);

你会看到这一点,y.ay.c.在任何时候y.b改变,反之亦然。y.a应该在第二个中更改为 102 printf(),因为那是'f'.

于 2013-04-20T05:38:03.980 回答