如何存储在工会成员? [英] How are the union members stored?

查看:114
本文介绍了如何存储在工会成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 联合测试
{
 INT I;
 焦炭CH;
}吨;
诠释的main()
{
 t.ch = 20;
}

假设的sizeof(int)的== 2 ,让分配T的内存地址是2000年,2001年结果
那么哪里是20,即 t.ch 存储 - 在2000年或2001年或依赖于机器的字节顺序


解决方案

C99标准(§6.7.2.1.14)说:


  

工会的大小足以容纳最大的成员。在价值
   成员最多有一个可以在任何时间被存储在联合对象。 一个指向
  联合对象,适当转换,分给每个成员
(或者如果成员是比特
  字段,然后在它所在的单元),反之亦然。


(强调)

该大胆的声明实际上是说,该联盟的每个成员都有相同的地址,所以他们都开始在同一地址。 T ,因为 t.ch TI ,应该是地址2000,从而 t.ch TI 的第一个字节(地址顺序)重叠。

这意味着来讲什么我能得到什么,如果我尝试读 TI 设置后TC 在现实世界中依赖于平台的字节序,并在事实尝试,当你在另外一书中写道读取工会成员是根据C标准(§6.2.6.1.6/ 7,在§J.1.1重申未指定的行为)。


什么帮助更多的了解机器的字节顺序(至少,我认为这是更直接的理解)就是有这样一个联盟:

 工会
{
    INT I;
    无符号字符CH [sizeof的(ⅰ)];
}吨;

  t.i = 20;

,然后找两个字符里面有什么在 t.ch 。如果你是一个小端的机器上,你会得到 t.ch [0] == 20 t.ch [1] == 0 ,如果你是一个big-endian的机器上的相反(如的sizeof(int)的== 2 )。请注意,前面已经说了,这是一个具体的实施细节,该标准甚至没有提到字节顺序。

为了使它更清楚:如果你有一个2个字节的 INT VAR设置为20,小端机器上,倾销地址与之相关的记忆阶,你会得到(十六进制再presentation,按字节分割空间):

  14 00

而大端机器上,你会得到

  00 14

大端再presentation看起来从我们的角度来看更正确,因为在小尾数重新presentation,使整个字节 INT 存储在相反的顺序



  

此外,我说,如果我这样做:


  int类型的= 20;
的printf(%d个*(字符*)及一);


  

然后不输出取决于字节序,即20是否存储在2000年或2001年?


是的,这里确实如此,但在你的问题你问另一件事;这看起来更加的我的的例子。

union test
{
 int i;
 char ch;
}t;
int main()
{
 t.ch=20;
}

Suppose sizeof(int)==2 and let the memory addresses allocated for t are 2000, 2001.
Then where is 20 i.e. t.ch stored - at 2000 or 2001 or depends on endianness of machine?

解决方案

The C99 standard (§6.7.2.1.14) says:

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.

(emphasis added)

The bold statement actually says that each member of the union has the same address, so they all "begin" at the same address. t, as t.ch as t.i, should be at address 2000, thus t.ch overlaps with the first byte (in address order) of t.i.

What this means in terms of "what do I get if I try to read t.i after setting t.c" in the real world depends on platform endianness, and in facts trying to read a member of a union when you wrote in another one is Unspecified Behavior according to the C standard (§6.2.6.1.6/7, restated at §J.1.1).


What helps more to understand the endianness of the machine (at least, I think it's more straightforward to understand) is to have a union like this:

union
{
    int i;
    unsigned char ch[sizeof(i)];
} t;

doing

t.i=20;

and then looking what's inside the two chars at t.ch. If you are on a little-endian machine you'll get t.ch[0]==20 and t.ch[1]==0, and the opposite if you're on a big-endian machine (if sizeof(int)==2). Notice that, as already said, this is an implementation specific detail, the standard does not even mention endianness.

To make it even clearer: if you have a 2-byte int var set to 20, on a little-endian machine, dumping the memory associated to it in address-order, you'll get (in hexadecimal representation, bytes split by space):

14 00

while on a big-endian machine you'll get

00 14

The big-endian representation looks "more right" from our point of view, because in the little endian representation the bytes that make the whole int are stored in reverse order.


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 ?

Yes, here it does, but in your question you're asking another thing; this looks more my example.

这篇关于如何存储在工会成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆