联合和结构初始化

我偶然发现了一个基于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 。 如果有人能够详细解释这里到底发生了什么,那就太好了。

我在Windows 7上使用32位处理器。

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

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

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

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

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

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

代码将usax[0]为12,将usax[1]为1. usax覆盖到u.st.a因此u.st.a的最低有效字节设置为12,最高有效字节设置为1 (所以你必须在小端架构上运行)给出值0x010C或268。

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

所以在一个32位的int中它是1 * 256 + 12 = 268

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