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


当前回答

联合在嵌入式编程或需要直接访问硬件/内存的情况下特别有用。这里有一个简单的例子:

typedef union
{
    struct {
        unsigned char byte1;
        unsigned char byte2;
        unsigned char byte3;
        unsigned char byte4;
    } bytes;
    unsigned int dword;
} HW_Register;
HW_Register reg;

然后,您可以按如下方式访问reg:

reg.dword = 0x12345678;
reg.bytes.byte3 = 4;

字节顺序和处理器体系结构当然很重要。

另一个有用的特性是位修饰符:

typedef union
{
    struct {
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        unsigned char reserved:4;
    } bits;
    unsigned char byte;
} HW_RegisterB;
HW_RegisterB reg;

使用这段代码,您可以直接访问寄存器/内存地址中的单个位:

x = reg.bits.b2;

其他回答

联合允许互斥的数据成员共享相同的内存。当内存比较稀缺时,例如在嵌入式系统中,这是非常重要的。

示例如下:

union {
   int a;
   int b;
   int c;
} myUnion;

这个联合将占用一个int值的空间,而不是3个独立的int值。如果用户设置了a的值,然后设置了b的值,它将覆盖a的值,因为它们都共享相同的内存位置。

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

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

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

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

我在几个库中看到过它作为面向对象继承的替代品。

E.g.

        Connection
     /       |       \
  Network   USB     VirtualConnection

如果你想让Connection“类”是上面的任何一个,你可以这样写:

struct Connection
{
    int type;
    union
    {
        struct Network network;
        struct USB usb;
        struct Virtual virtual;
    }
};

libinfinity示例:http://git.0x539.de/?p=infinote.git;a=blob;f=libinfinity/common/inf-session.c;h=3e887f0d63bd754c6b5ec232948027cbbf4d61fc;hb=HEAD#l74

包含不同记录类型的文件。 包含不同请求类型的网络接口。

看一下这个:X.25缓冲区命令处理

许多可能的X.25命令中的一个被接收到缓冲区中,并通过使用所有可能结构的UNION进行适当的处理。