int main()
{
union {
struct {
char c[2];
char ch[2];
} s;
struct {
int i;
int j;
} st;
} u = { (12, 1), (15, 1) };
printf("%d %d ", u.st.i, u.st.j);
}
以上是如何打印" 257 0"?
使用{}
代替()
会产生什么差异?
答案 0 :(得分:14)
{}
表示初始化子对象。
()
是一个对表达式进行分组的运算符,例如(1+3)*2
。您混淆地使用了逗号运算符,该运算符丢弃其左侧操作数并返回右侧操作数。 (12,1)
与1
相同。
初始化union
始终设置其第一个成员并忽略其他成员。这是因为一次只能有一个成员存储一个值。
初始化具有标量值的数组子对象,如通过1
初始化c[2]
,会自动跳转到数组中。这称为大括号。下一个1
将初始化数组的第二个成员。
您为1
中的每个字符分配了c[2]
,然后将结果字节字符串作为little-endian int
读回。数组ch[2]
根本没有明确初始化;在C ++中,它将设置为零,但我不完全确定在C中。
初始化程序{ {12, 1}, {15, 1} }
不起作用,因为显然,括号elision会解释第一个}
以关闭整个union
。
初始化程序{{ {12, 1}, {15, 1} }}
将避免括号缩写并设置两个数组。 { 12, 1, 15, 1 }
也应该这样做。
请注意,标量值和字节字符串之间的转换是实现定义的;特别是它取决于字节顺序和int
的大小。
答案 1 :(得分:3)
(12, 1)
和(15, 1)
都简化为(奇怪的)1
。这是因为,正如Omkant所说,你正在使用逗号运算符,它运行它所分割的每个表达式,但返回最终表达式的值。 Wikipedia entry实际上很好地解释了这一点。
结果,u.s.c[0]
填充了第一个1,u.s.c[1]
填充了第二个1.因为联合在u.st.i
和u.c[2]
上覆盖了u.ch[2]
u.st.i
1}}(假设8位字符和32位整数),并且架构是little-endian(从结果中得知),在256*1 + 1 = 257
的最低字节中有1,在第二个字节中有1最低字节,值为u.st.j
。
同时,没有值写入{{1}}的内存,因此第二个输出为0.
答案 2 :(得分:0)
what the difference will it create if i use {} instead of ().
如果您使用的是()
,则,
将为Comma operator
,并且指定的值将是括号内最右边的值。
但是如果{}
,
是Comma seperator
,并且每个单独的值都分配给相应的成员。但在这种情况下,它不会编译并抛出错误:
extra brace group at end of initializer.
答案 3 :(得分:0)
似乎你误解了工会的观点,工会中的对象共享他们的记忆,所以你只能初始化其中一个对象而不是两者,换句话说底层内存是相同的,并且正如另一个答案中所提到的那样初始化union总是设置它的第一个成员,所以如果你想初始化第二个成员,你可以使用C99指定的初始化器:
u = {.st={15, 1} };
初始化第一个结构中的数组:
u = { .s={{12, 1}, {15, 1}} };
或者第一个结构没有.s
:
u = { {{12, 1}, {15, 1}} };