union test
{
int i;
char ch;
}t;
int main()
{
t.ch=20;
}
假设sizeof(int)==2
,设分配给t的内存地址为2000、2001。
那么 20 即 t.ch
存储在哪里 - 在 2000 或 2001 或取决于机器的字节顺序?
最佳答案
C99 标准 (§6.7.2.1.14) 说:
The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit- field, then to the unit in which it resides), and vice versa.
(强调)
大胆的说法实际上是说联盟的每个成员都有相同的地址,所以他们都“开始”在同一个地址。 t
,作为t.ch
作为t.i
,应该在地址2000,因此t.ch
与t.i
的第一个字节(按地址顺序)。
在现实世界中,“如果我在设置 t.c
后尝试读取 t.i
会得到什么”,这意味着什么取决于平台字节序,事实上根据 C 标准(§6.2.6.1.6/7,在 §J.1.1 重述),当您在另一个 union 体中写入时尝试读取一个 union 体的成员是未指定的行为。
更有助于理解机器的字节顺序(至少,我认为它更容易理解)的是有一个像这样的 union :
union
{
int i;
unsigned char ch[sizeof(i)];
} t;
做
t.i=20;
然后在 t.ch
中查看两个字符中的内容。如果你在小端机器上,你会得到 t.ch[0]==20
和 t.ch[1]==0
,反之如果您使用的是大端计算机(如果 sizeof(int)==2
)。请注意,如前所述,这是一个特定于实现的细节,该标准甚至没有提及字节顺序。
为了让它更清楚:如果你有一个 2 字节的 int
var 设置为 20,在小端机器上,以地址顺序转储与其关联的内存,你会get(十六进制表示,字节按空格分割):
14 00
在大端机器上你会得到
00 14
从我们的角度来看,大端表示看起来“更正确”,因为在小端表示中,组成整个 int
的字节以相反的顺序存储。
Moreover I am saying that if I do this:
int a=20;
printf("%d",* (char*)&a);
Then doesn't the output depend on endian-ness i.e. whether 20 is stored at 2000 or 2001 ?
是的,确实如此,但在您的问题中您是在问另一件事;这看起来更像是我的例子。
关于c - union 成员如何存储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4540638/