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更安全.
一般来说,如果你不确定你是否需要工会,你几乎肯定不需要工会.
当你的"东西"可以是许多不同的东西中的一个而不是一次只有一个时,你就使用了一个联盟.
当你的"东西"应该是一组其他东西时,你使用一个结构.
例如,联合可以用于表示小部件或小玩意儿(带有允许我们知道它是什么的字段),例如:
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
(没有重叠).
这个用例比比皆是,例如包含电话簿应用程序记录布局的结构,这无疑会从您首选的应用程序商店中获得数以千计的美元:-)