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

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

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

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完全不同,并且以整数forms访问float不会为您提供任何特别有意义的数据。

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

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

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

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

当你的“东西”可以是许多不同的东西中的一个而不是一次只有一个时,你就使用了一个联盟

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

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

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

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

我已经看到这在编译器中使用,其中令牌可以是数字常量,关键字,变量名,字符串和许多其他词法元素(但是,当然,每个令牌都是其中之一 ,你不能有一个令牌既是变量名也是数字常量。

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

 struct { widget w; gizmo g; } 

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

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

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

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

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

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