联合和结构初始化

时间:2011-12-07 15:22:44

标签: c unions

我偶然发现了基于C中的工会的代码。这是代码:

    union    {  
        struct  {  
            char ax[2];  
            char ab[2];  
        } s;  
        struct  {  
            int a;  
            int b;  
        } st;  
    } u ={12, 1}; 

    printf("%d %d", u.st.a, u.st.b);  

我只是不明白输出是怎么来的268 0。这些值是如何初始化的? 工会如何运作?输出不应该是12 1。如果有人能够详细解释这里究竟发生了什么,那就太棒了。

我使用的是32位处理器和Windows 7。

5 个答案:

答案 0 :(得分:17)

代码不符合你的想法。 Brace-initializes初始化第一个联盟成员,即u.s。但是,现在初始化程序不完整并且缺少大括号,因为u.s包含两个数组。它应该是一些思考:u = { { {'a', 'b'}, { 'c', 'd' } } };

你应该编译所有警告,一个体面的编译器应该告诉你有些不对劲。例如,GCC说missing braces around initialiser (near initialisation for ‘u.s’)missing initialiser (near initialisation for ‘u.s.ab’)。非常有帮助。

在C99中,您可以利用命名成员初始化来初始化第二个union成员:u = { .st = {12, 1} };(顺便说一下,这在C ++中是不可能的。)第一种情况的相应语法是{{1} },这可以说是更明确和可读!

答案 1 :(得分:4)

您的代码使用union的默认初始值设定项,它是第一个成员。 12和1都进入ax的字符,因此你看到的结果(这是非常依赖编译器的。)

如果你想通过第二个记忆(st)进行初始化,你可以使用指定的初始值设定项:

union {  
    struct {  
        char ax[2];  
        char ab[2];  
    } s;  
    struct {  
        int a;  
        int b;  
    } st;  
} u ={ .st = {12, 1}}; 

答案 2 :(得分:4)

代码集u.s.ax[0]为12,u.s.ax[1]为1. u.s.ax重叠到u.st.a,因此u.st.a的最低有效字节设置为12和最重要的字节为1(所以你必须在小端架构上运行)给出值0x010C或268。

答案 3 :(得分:1)

它可能会将{12,1}分配给 s.ax 中的前2个字符。

因此在32位int中,它是1 * 256 + 12 = 268

答案 4 :(得分:1)

union的大小是组成union的最大元素的最大大小。因此,在这种情况下,您的联合类型在32位平台上的大小为8字节,其中int类型各为4字节。但是,联合的第一个成员s只占用2个字节,因此与st.a成员的前2个字节重叠。由于您使用的是小端系统,这意味着我们将st.a的两个低位字节重叠。因此,当您使用值{12, 1}完成初始化联合时,您只是初始化st.a的两个低位字节中的值...这样会留下{{1}的值初始化为st.b。因此,当您尝试打印包含两个0而不是int成员的结构时,您最终会得到char128的结果。