我对c语言中的联合有疑问
例如:
typedef struct {
int a;
float c;
}Type1;
typedef struct {
int b;
char d;
}Type2;
union Select {
Type1 type1;
Type2 type2;
};
void main() {
Select* select;
//can we access type1 first and then access type2 immediately? like this way:
select->type1.a;
select->type2.b;
//在访问type1之后,然后立即访问type2,我们可以得到type2的值b吗? //我稍微修改了第一篇文章,因为它在开头是无意义的。
}
答案 0 :(得分:4)
这保证可以通过ISO / IEC 9899:1999(见the draft here),6.5.2.3 5:
为了简化工会的使用,我们提出了一项特殊保证:如果工会包含 几个结构共享一个共同的初始序列(见下文),如果是联盟 对象当前包含这些结构中的一个,允许检查公共结构 任何一个声明完整类型的联盟的任何地方的初始部分 可见。如果相应的成员有两个结构共享一个共同的初始序列 对于一个或多个序列的兼容类型(以及对于位字段,相同的宽度) 初始成员。
答案 1 :(得分:2)
是的,这是正确的。在您的示例中(忽略未初始化的指针),对于type1.a
的任何给定实例,type2.b
和Select
的值将始终相同。
答案 2 :(得分:0)
在您的示例中,它将起作用,因为它们都是int
通常你需要一个鉴别器来知道一次使用哪个联合。
union具有最大数据类型的大小(如果我记得核心),并且每次设置/检查类型以了解要访问的数据类型:
struct myStruct {
int type;
union Select {
Type1 type1;
Type2 type2;
};
};
在访问之前,您需要检查以了解如何使用联合:
myStruct* aStruct;
//init pointer
if(aStruct->type == TYPE1)//TYPE1 is defined to indicate the coresponding type
{
//access fields of type1
aStruct->type1.a = //use it
}
在您应该完成之前:aStruct->type = TYPE1
答案 3 :(得分:0)
是的,你可以随时访问它们。基本上select-> type1和select-> type2是指向内存中相同位置的指针。知道该位置在内存中的位置通常是一个标志:
union Select {
Type1 type1;
Type2 type2;
};
struct SelectType {
bool isType1;
Select select;
};
int getValue (struct SelectType s){
if (s.IsType1){
return s.type1.a;
} else {
return s.type2.b;
}
}
void main() {
struct SelectType select;
int value;
select.type1.a = 5;
select.isType1 = true;
select.type2.4 = 5;
select.isType1 = false;
value = getValue (select);
}
答案 4 :(得分:0)
是的,我们可以。在这种情况下,它的价值不会改变。这没错,但没有意义。 顺便说一句,你忘了为指针'select'分配内存?
我真的想帮忙,但我的英语不是很好。这是我的第一篇文章。所以,如果我说错了,请告诉我。
答案 5 :(得分:0)
是的,你可以,因为main有你工会声明的范围。
引用C99标准的最终版本。
以下不是有效的片段(因为联合类型在函数f中不可见)
struct t1 { int m; };
struct t2 { int m; };
int f(struct t1 *p1, struct t2 *p2)
{
if (p1->m < 0)
p2->m = -p2->m;
return p1->m;
}
int g()
{
union {
struct t1 s1;
struct t2 s2;
} u;
/* ... */
return f(&u.s1, &u.s2);
}
答案 6 :(得分:0)
联合中的所有成员都驻留在相同的内存位置。 它通常以不止一种方式访问同一块内存。
例如,你可以定义:联合 {
char a [100];
int b [50];
} X;
union大小为100字节,从b [0]读取就像读取[0]和[1]一样