为什么“联合测试{短a,b; char c1,c2,c3,c4;};”将c1,c2,c3,c4存储在同一个字节中,两个可用吗?

时间:2013-05-17 21:15:47

标签: c char unions

在我的程序中,我可以理解为什么联合的short成员存储在相同的2个字节中(因为联合的大小是最大成员的大小)。但是我只是不明白为什么所有4个字符成员都存储在同一个字节中,而人们会假设它们将分布在两个字节中并存储为

c1,c3--->first byte
c2,c4--->2nd byte

或者更清楚

Byte1     Byte2
----short a----
----short b----
--c1--    --c2--
--c3--    --c4--

将它们存储为

的原因是什么
Byte1     Byte2
----short a----
----short b----
--c1-- 
--c2--
--c3--    
--c4--

这背后的原因是什么?她的计划是:

#include<stdio.h>

int main(void)
{
    union test
    {
        short a,b;
        char c1,c2,c3,c4;
    } var= {65};
    printf("%hd,%hd,%c,%c,%c,%c",var.a,var.b,var.c1,var.c2,var.c3,var.c4);
}

结果:

   65,65,A,A,A,A

4 个答案:

答案 0 :(得分:3)

因为联合不起作用。

如果你希望它像这样工作,你应该混合匿名结构和联合,如:

union test
{
    short a,b;
    struct { char c1,c2; };
    struct { char c3,c4; };
};

编辑:

看起来像anonymous structs are non-standard。如果您需要符合标准的代码,则必须使用普通结构,并处理更长的语法。

union test
{
    short a,b;
    struct c { char _1,_2; };
    struct d { char _3,_4; };
};

test var;
if(var.c._1 == var.d._3) {}

答案 1 :(得分:2)

  

可以假设它们将分布在两个字节

为什么有人会认为呢?这当然是错的。联盟的所有成员都必须从同一个内存位置开始。

C11 standard,第6.7.2.1.6节:

  
      
  1. 如6.2.5中所讨论的,结构是由一系列成员组成的类型   存储按有序顺序分配, union是由序列组成的类型   存储重叠的成员。
  2.   

第6.7.2.1.16节:

  
      
  1. 联盟的大小足以容纳其中最大的成员。 at的值   大多数成员可以随时存储在union对象中。 指向a的指针   适当转换的联合对象指向其每个成员(或者如果成员有点 -   现场,然后到它所在的单位),反之亦然。
  2.   

答案 2 :(得分:0)

因为这正是联盟所做的:所有成员都占用相同的地址,并且联合的大小将等于具有最大大小的变量的大小。 (听起来很奇怪)

例如:

union group {
    double d;
    char c;
} u;

该联合的大小将是double的大小,因为所有成员都将从内存中的相同位置开始,double的大小将保证大于char {1}}。

编辑:实现此目的的一个好理由是节省内存。 C是在70年代发明的,当时内存非常稀缺,所以当时,如果你只需要一个数据而不是两个数据,你就可以通过在一个联合中组合两个变量来发挥作用。

答案 3 :(得分:0)

C中的联盟只能与其最大的包含类型一样大。它们的每个类型都覆盖在相同的内存空间中。

您提供的代码会创建size短的联合,其中包含两个short引用和四个char引用。