c – 联盟正确使用

我对union的理解是它的所有值都分配在相同的内存地址中,并且内存空间与union的最大成员一样大.但我不明白我们将如何实际使用它们.
根据 The C++ Programming Language,这是一个使用联合的代码.

enum Type { str, num };

struct Entry {
     char* name;
     Type t;
     char* s;  // use s if t==str
     int i;    // use i if t==num
};

void f(Entry* p)
{
     if (p->t == str)
           cout << p->s;
     // ...
}

在此之后Bjarne说:

The members s and i can never be used at the same time, so space is wasted. It can be easily recovered by specifying that both should be members of a union, like this:

union Value {
char* s;
int i;
};

The language doesn’t keep track of which kind of value is held by a union, so the programmer must do that:

struct Entry {
char* name;
Type t;
Value v; // use v.s if t==str; use v.i if t==num
};

void f(Entry* p)
{
if (p->t == str)
cout v.s;
// …
}

谁能进一步解释生成的联合代码?如果我们把它变成一个联盟,会发生什么?

假设你有一台32位机器,有32位整数和指针.您的结构可能如下所示:

[0-3] name
[4-7] type
[8-11] string
[12-15] integer

这是16个字节,但由于类型(代码中的t)确定哪个字段有效,我们永远不需要同时实际存储字符串和整数字段.所以我们可以改变代码:

struct Entry {
  char* name;
  Type t;
  union {
    char* s;  // use s if t==str
    int i;    // use i if t==num
  } u;
};

现在的布局是:

[0-3] name
[4-7] type
[8-11] string
[8-11] integer

在C中,无论你最近分配给联盟的“有效”成员,但是没有办法知道哪一个是内在的,所以你必须自己存储它.这种技术通常被称为“区分联合”,“鉴别器”是类型字段.

所以第二个结构需要12个字节而不是16个字节.如果你要存储很多字节,或者它们来自网络或磁盘,你可能会关心这个.否则,它并不重要.

相关文章
相关标签/搜索