C 何时使用并集以及何时使用结构

C 何时使用并集以及何时使用结构,c,structure,unions,C,Structure,Unions,我知道联合和结构之间的区别。 但是从设计和编码的角度来看,使用联合而不是结构有哪些不同的用例?一是空间优化。使用它们还有什么好处吗?当你的“东西”可以是许多不同事物中的一种,但一次只能是一种时,你就使用了一个联合体 当你的“事物”应该是一组其他事物时,你使用一个结构 例如,可以使用联合来表示小部件或小控件(通过一个字段,我们可以知道它是什么),例如: struct { int isAGizmo; union { widget w; gizmo g;

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

当你的“东西”可以是许多不同事物中的一种,但一次只能是一种时,你就使用了一个联合体

当你的“事物”应该是一组其他事物时,你使用一个结构

例如,可以使用联合来表示小部件或小控件(通过一个字段,我们可以知道它是什么),例如:

struct {
    int isAGizmo;
    union {
        widget w;
        gizmo g;
    }
}
struct mixed {
  enum { TYPE_INT, TYPE_FLOAT } type;
  union {
    int    int_value;
    float  float_value;
  } data;
};
union ipv4addr {
  unsigned  address;
  char      octets[4];
};
在本例中,
w
g
将在内存中重叠

我在编译器中看到过这种情况,其中标记可以是数值常量、关键字、变量名、字符串和许多其他词汇元素(但是,当然,每个标记都是其中之一,您不能有一个同时是变量名和数值常量的标记)

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

struct {
    widget w;
    gizmo g;
}
在这种情况下,
g
将位于不同的内存位置,在
w
之后的某个位置(无重叠)


这方面的用例比比皆是,例如包含电话簿应用程序的记录布局的结构,这无疑将从首选应用程序商店中为您赚取数百万美元:-)

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


i、 如果我们使用int和char,那么union将为具有较大大小的char分配空间,int也将存储在相同的空间中,覆盖上一个空间。

实际上只有两个主要用途。首先是建立一个歧视性的联盟。这可能是你在“空间优化”中所想的,但还有更多。您需要一个额外的数据位来知道联合的哪个成员是“活动的”(其中包含有效数据),因为编译器不会为您这样做。您通常会看到这样的代码在结构内部有一个并集,类似于:

struct {
    int isAGizmo;
    union {
        widget w;
        gizmo g;
    }
}
struct mixed {
  enum { TYPE_INT, TYPE_FLOAT } type;
  union {
    int    int_value;
    float  float_value;
  } data;
};
union ipv4addr {
  unsigned  address;
  char      octets[4];
};
当分配给data.int_值或data.float_值时,您需要将类型成员也设置为适当的枚举值。然后,使用混合值的代码可以确定是读取int_值还是float_值

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

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

struct {
    int isAGizmo;
    union {
        widget w;
        gizmo g;
    }
}
struct mixed {
  enum { TYPE_INT, TYPE_FLOAT } type;
  union {
    int    int_value;
    float  float_value;
  } data;
};
union ipv4addr {
  unsigned  address;
  char      octets[4];
};
大多数代码只希望传递32位整数值,但有些代码希望读取单个八位字节(字节)。这在指针强制转换中都是可行的,但是它更容易,更自我记录,因此以这种方式使用联合稍微安全一些


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

你无法将工会与结构进行比较,就像将苹果与桔子进行比较一样,它们用于不同的事情。联合通常用于空间很宝贵的情况,但更重要的是用于专用的备用数据。联合有助于消除打字错误,并确保互斥状态保持互斥,因为当我们使用联合处理互斥数据时,编程逻辑中的错误会更快地显现出来


此外,在处理组件之间传递的复杂数据时,联合可以使指针数学计算变得更加简单。例如,在使用LEX和YACC开发编译器时,值以联合形式从lexer传递到解析器。由于使用了union,解析器实现和随后的类型转换变得非常简单。

如果您知道其中的区别,那么您应该能够理解应该在哪里使用。。这将帮助你“就像把苹果和桔子比较一样,它们被用来做不同的事情”——当然这就是比较它们的全部意义,找出它们在哪些方面相似,哪些方面不同。顺便说一句,我想冒昧地说,苹果和橙子之间的相似之处多于差异:-)@paxdiablo:-)这是真的。