访问c中的联盟成员

时间:2011-10-05 15:17:29

标签: c unions

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

}

7 个答案:

答案 0 :(得分:4)

这保证可以通过ISO / IEC 9899:1999(见the draft here),6.5.2.3 5:

  

为了简化工会的使用,我们提出了一项特殊保证:如果工会包含   几个结构共享一个共同的初始序列(见下文),如果是联盟   对象当前包含这些结构中的一个,允许检查公共结构   任何一个声明完整类型的联盟的任何地方的初始部分   可见。如果相应的成员有两个结构共享一个共同的初始序列   对于一个或多个序列的兼容类型(以及对于位字段,相同的宽度)   初始成员。

答案 1 :(得分:2)

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

答案 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]一样