什么时候应该使用工会?我们为什么需要它们?


当前回答

低级系统编程就是一个合理的例子。

IIRC中,我使用联合将硬件寄存器分解为组件位。因此,您可以访问一个8位寄存器(在我这样做的那天;-)到组件位。

(我忘记了确切的语法,但是……)这种结构将允许控制寄存器作为control_byte或通过单个位来访问。对于给定的字节顺序,确保位映射到正确的寄存器位是很重要的。

typedef union {
    unsigned char control_byte;
    struct {
        unsigned int nibble  : 4;
        unsigned int nmi     : 1;
        unsigned int enabled : 1;
        unsigned int fired   : 1;
        unsigned int control : 1;
    };
} ControlRegister;

其他回答

COM接口中使用的VARIANT呢?它有两个字段——“type”和一个包含实际值的联合,该值根据“type”字段进行处理。

我在为嵌入式设备编码时使用union。我有一个16位的C整数。当我需要从/存储到EEPROM时,我需要检索高8位和低8位。所以我用了这种方法:

union data {
    int data;
    struct {
        unsigned char higher;
        unsigned char lower;
    } parts;
};

它不需要移动,所以代码更容易阅读。

另一方面,我看到一些旧的c++ stl代码使用联合的stl分配器。如果您感兴趣,可以阅读sgi stl源代码。下面是其中的一段:

union _Obj {
    union _Obj* _M_free_list_link;
    char _M_client_data[1];    /* The client sees this.        */
};

在学校里,我是这样使用联合的:

typedef union
{
  unsigned char color[4];
  int       new_color;
}       u_color;

我用它来更容易地处理颜色,而不是使用>>和<<操作符,我只需要遍历我的char数组的不同索引。

工会是伟大的。我所见过的联合的一个聪明用法是在定义事件时使用它们。例如,您可能决定一个事件是32位的。

现在,在这32位中,您可能希望将前8位指定为事件发送方的标识符……有时你要把事件作为一个整体来处理,有时你要剖析它并比较它的组成部分。工会让你可以灵活地做到这两点。

union Event
{
  unsigned long eventCode;
  unsigned char eventParts[4];
};

当您希望对由硬件、设备或网络协议定义的结构进行建模时,或者当您要创建大量对象并希望节省空间时,可以使用联合。不过,在95%的情况下,你真的不需要它们,坚持使用易于调试的代码。