联盟中的成员不是独家的,如果你已经引用了其中一个,你就不能引用另一个吗?
union Ptrlist
{
Ptrlist *next;
State *s;
};
void
patch(Ptrlist *l, State *s)
{
Ptrlist *next;
for(; l; l=next){
next = l->next;
l->s = s;
}
}
但上述同时指代next
和s
,任何人都可以解释这个问题吗?
答案 0 :(得分:5)
联盟只定义
&l->next == &l->s
就是这样。首次访问没有语言限制。
答案 1 :(得分:2)
正如其他人已经指出的那样,所有成员在所有时都处于活动状态。唯一要考虑的是成员是否都处于有效状态。
如果你想要某种程度的排他性,你需要一个标记的联盟。基本思想是将union包装在一个struct中,struct有一个成员标识应该使用union中的哪个元素。举个例子:
enum Tag {
FIRST,
SECOND
};
struct {
Tag tag;
union {
int First;
double Second;
};
} taggedUnion;
现在taggedUnion
可以像:
if(taggedUnion.tag == FIRST)
// use taggedUnion.First;
else
// use taggedUnion.Second
答案 2 :(得分:1)
您正在从next
执行l->next
的作业。然后,您通过作业l->s
“覆盖”l->s = s
。
当您分配到l->s
时,它会覆盖l->next
中保留的内存。如果next
和s
的“大小”相同,则两者可能同时处于“有效”状态。
答案 3 :(得分:1)
是的,它应该是那样的。 * s和* next都指向相同的内存位置。而且你可以同时使用它们......它们并不是唯一的。
答案 4 :(得分:1)
不,这不是真的。您可以随时使用union的任何成员,但如果您读取的成员不是最近编写的成员,那么结果会有点复杂。但是,在您的代码示例中甚至没有发生这种情况,并且它绝对没有任何问题。对于列表中的每个项目,将读取其next
成员,然后编写其s
成员,覆盖其next
。
答案 5 :(得分:0)
有关工会的介绍性讨论,请参阅http://publications.gbdirect.co.uk/c_book/chapter6/unions.html。
基本上,这是一种提前进行打字的简单方法。所以,而不是
int query_my_data(void *data, int data_len) {
switch(data_len) {
case sizeof(my_data_t): return ((my_data_t *)data)->value;
case sizeof(my_other_data_t): return ((my_other_data_t *)data)->other_val;
default: return -1;
}
你可以通过
来简化它typedef struct {
int data_type;
union {
my_data_t my_data;
my_other_data_t other_data;
} union_data;
} my_union_data_t;
int query_my_data(my_union_data_t *data) {
switch(data->data_type) {
case TYPE_MY_DATA: return data->union_data.my_data.value;
case TYPE_MY_OTHER_DATA: return data->union_data.other_data.other_val;
default: return -1;
}
my_data和other_data在内存中的起始地址相同。
答案 6 :(得分:0)
union类似于struct,但它只为变量分配内存。 union的大小将等于存储在其中的最大类型的大小。例如:
union A {
unsigned char c;
unsigned short s;
};
int sizeofA = sizeof(A); // = 2 bytes
union B {
unsigned char c[4];
unsigned short s[2];
unsigned int i;
};
int sizeofB = sizeof(B); // = 4 bytes
在第二个示例中,s[0] == (c[1] << 8) & #ff00 | c[0];
。变量c,s和i重叠。
B b;
// This assignment
b.s[0] = 0;
// is similar to:
b.c[0] = 0;
b.c[1] = 0;
union仅限于原始类型和指针。在C ++中,您不能在联合中存储类。所有其他规则基本上与结构相同,例如公共访问,堆栈分配等。
因此,在您的示例中,您必须使用结构而不是联合。