原问答是这样的:
“ #include
main()
{ union data { long w; float x; char c; };
执行下列语句后a的十进制值是多少?
union data a;
a.x=3.1416;
a.w=123456;
a.c='x'; ”
我的回答:
共同体的最大特点就是多个数据共享一个内存。而内存的大小是看共同体里面最大成员而定。
问题中的共同体,long 和 float 所占的字节大小一样也是最大(char只占一个字节),为4个字节。
union data a;
a.x=3.1416;//这时内存中的值为0011.0010 0100 0011 1111 1111 1111 1111(这并不影响下面的结果)
a.w=123456;//这是内存中的值被覆盖,变为0000 0000 0000 0001 1110 0010 0100 0000
a.c='x';//因为'x'的在二进制中为0111 1000 所以覆盖部分只有最后一个字节,这时a的值为0000 0000 0000 0001 1110 0010 0111 1000
而这时a的十进制值对应为123512.
使用编译器编译后也是这个答案。
说实话,我一开始看到这道题时还是还是要想挺久的,因为最近一直在用Java,C语言有些忘了。
还有一点这道题目没有反应的还有一个问题,举个例子来说明吧。
union un{
char a[10]; //占10字节
double m; //占8字节
int n; //占4字节
}
在这里面的共同体中,大家是不是以为这个共同体un是占10个字节?但是,用编译器使用运算符sizeof来测试大小结果为:16。
按照正常来说是这样的,但是在这里有个字节对齐问题(C语言中的规定共同体中的对齐方式要适合其中的所有成员)。所以上面占的字节数分别是10、8、4。从这里可以看出共同体所占的空间不仅取决于最大成员,还和所有成员有关系,大小必须满足两个条件:(1)大小足够容纳最宽的成员;(2)大小能被其包含的所有基本数据类型的大小所整除。所以,字节数就被补充到16。
最后还有一点,就是共同体中的所有成员相对于基地址的偏移量都为0,每个成员的基地址就是共同体变量的首地址。(这一点使用指针时有用共同体要特别注意)