何时使用联合以及何时使用结构

时间:2011-10-31 06:51:23

标签: c structure unions

我知道联盟和结构之间的区别。 但是从设计和编码的角度来看,使用union而不是结构的各种用例是什么?一个是空间优化。使用它们还有什么好处吗?

4 个答案:

答案 0 :(得分:10)

实际上只有两个主要用途。首先是建立一个有区别的联盟。这可能就是你所想到的“空间优化”,但还有更多内容。您需要一些额外的数据才能知道union的哪个成员是“活着的”(其中包含有效数据),因为编译器不会为您执行此操作。您通常会看到类似于在结构内部具有联合的代码,例如:

struct mixed {
  enum { TYPE_INT, TYPE_FLOAT } type;
  union {
    int    int_value;
    float  float_value;
  } data;
};

分配给data.int_value或data.float_value时,您还需要将类型成员设置为适当的枚举值。然后使用混合值的代码可以确定是否读取int_value或float_value。

联盟的第二个重要用途是提供一个允许用户以多种方式访问​​相同数据的API。这是非常有限的,因为它要求联合中的所有类型以相同的方式放在内存中。例如,int和float完全不同,并且以整数形式访问float不会为您提供任何特别有意义的数据。

有关此用例的有用示例,请参阅有多少网络API将为IPv4地址定义联合,例如:

union ipv4addr {
  unsigned  address;
  char      octets[4];
};

大多数代码只想传递32位整数值,但有些代码想要读取单个八位字节(字节)。这一切都可以通过指针转换来实现,但它更容易,更自我记录,因此以这种方式使用联合更安全。

总的来说,如果你不确定你是否需要工会,你几乎肯定不需要工会。

答案 1 :(得分:5)

当你的“东西”可以是许多不同的东西之一时你使用联盟,但一次只有一个。

当你的“东西”应该是一组其他东西时,你会使用一个结构。

例如,一个联合可用于表示小部件小玩意儿(带有允许我们知道它是什么的字段),例如:

struct {
    int isAGizmo;
    union {
        widget w;
        gizmo g;
    }
}

在此示例中,wg将在内存中重叠。

我在编译器中看到过这种情况,其中令牌可以是数字常量,关键字,变量名,字符串和许多其他词法元素(当然,每个令牌都是一个那些东西,你不能有一个既是变量名又是数字常量的令牌。

或者,在没有小部件的情况下处理小玩意可能是违法的,在这种情况下你可以使用:

struct {
    widget w;
    gizmo g;
}

在这种情况下,g将位于不同的内存位置,位于w之后(不重叠)。

这个用例很多,例如包含电话簿应用程序记录布局的结构,无疑会从您首选的应用程序商店中获得数以千计的美元: - )

答案 2 :(得分:0)

在某些情况下,我们可能一次只能使用一个变量,但不同的结果必须以不同的名称存储。在这种情况下,union将通过为每个变量在最大可变大小的一个位置分配相同的空间来提供帮助。

即如果我们使用int和char,那么union将为具有更大大小的char分配空间,并且int也将存储在覆盖最后一个空间的相同空间中。

答案 3 :(得分:0)

您无法将结合与结构进行比较,就像将苹果与橙子进行比较一样,它们可用于不同的事物。工会通常用于空间有限的情况,但更重要的是仅用于备用数据。联盟有助于消除拼写错误,并确保互斥状态保持互斥,因为当我们使用联合用于互斥数据时,编程逻辑中的错误将更快地出现。

当处理组件之间传递的复杂数据时,工会也可以使指针数学变得更容易。在使用LEX和YACC开发编译器时,这些值会从词法分析器传递到联合中的解析器。由于使用了union,解析器实现和后续的类型转换变得非常容易。