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

kar*_*ran 5 c structure unions

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

Sea*_*tch 10

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

struct mixed {
  enum { TYPE_INT, TYPE_FLOAT } type;
  union {
    int    int_value;
    float  float_value;
  } data;
};
Run Code Online (Sandbox Code Playgroud)

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

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

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

union ipv4addr {
  unsigned  address;
  char      octets[4];
};
Run Code Online (Sandbox Code Playgroud)

大多数代码只想传递32位整数值,但有些代码想要读取单个八位字节(字节).这对于指针转换都是可行的,但是它更容易,更自我记录,因此以这种方式使用union更安全.

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


pax*_*blo 5

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

当你的"东西"应该是一组其他东西时,你使用一个结构.

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

struct {
    int isAGizmo;
    union {
        widget w;
        gizmo g;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,w并将g在内存中重叠.

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

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

struct {
    widget w;
    gizmo g;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,g将在某个不同的内存位置,在某个地方之后w(没有重叠).

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