访问c中的联盟成员

我对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吗? //我稍微修改了第一篇文章,因为它在开头是无意义的。

}

对,那是正确的。 在您的示例中(忽略未初始化的指针),对于任何给定的Select实例, type1.atype2.b的值将始终相同。

这保证可以通过ISO / IEC 9899:1999(见这里的草案 ),6.5.2.3 5:

为了简化联合的使用,我们做了一个特殊的保证:如果一个联合包含几个共享一个共同初始序列的结构(见下文),并且如果联合对象当前包含这些结构中的一个,则允许检查公共其中任何一个的初始部分都可以看到完整类型的联合声明。 如果对应的成员具有一个或多个初始成员的序列的兼容类型(并且对于位字段,具有相同的宽度),则两个结构共享共同的初始序列。

在您的示例中,它将起作用,因为两者都是int类型

通常你需要一个鉴别器来知道一次使用哪个联合。

联合具有最大数据类型的大小(如果我记得核心),并且每次设置/检查类型以了解要访问的数据类型:

 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

是的,你可以随时访问它们。 基本上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); } 

我们可以。 在这种情况下,它的价值不会改变。 这没错,但没有意义。 顺便说一下,你忘了为指针’select’分配内存?

我真的很想帮忙,但我的英语不是很好。 这是我的第一篇文章。 所以,如果我说错了,请告诉我。

是的,你可以,因为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); } 

联合中的所有成员都驻留在相同的内存位置。 它通常以不止一种方式访问​​同一块内存。

例如,您可以定义:

联盟{

char a [100];

int b [50];

}X;

union大小为100字节,从b [0]读取就像读取[0]和[1]一样