我偶然发现了一个基于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时,最终会得到128
和0
结果。
需要了解更多c/c++开发分享联合和结构初始化,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享联合和结构初始化相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979790.html