access union member in c

江枫思渺然 提交于 2019-12-05 19:53:28

Yes, that is correct. In your example (ignoring the uninitialised pointer) the value of type1.a and type2.b will always be the same for any given instance of Select.

This is guaranteed to work by ISO/IEC 9899:1999 (see the draft here), 6.5.2.3 5:

One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the complete type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.

In your example it will work since both are types int

Normally you need a discriminator to know which union is used at a time.

The union has the size of the largest data type (if I recall corectly) and you set/check the type each time to know which data type to access:

struct myStruct {   
    int type;   
    union Select {   
      Type1 type1;   
      Type2 type2;   
     };  
};  

You would do a check before accessing to know how to use the union:

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
    }

Also before you should have done: aStruct->type = TYPE1

Yeah, you can access both of them when ever you want. basically select->type1 and select->type2 are pointers to the same location in memory. It's the progeammer job to know what sits in that location in memory, Usually by a flag:

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);
}

Yes we can. it's value does not change in this case. It's not wrong, but it is meaningless. by the way, You forget to allocate memory for the pointer 'select'?

I really want to help, but my english is not very good. And this is my first post. So if I have said something wrong, tell me.

Yes, you can, because main has the scope for your union declaration.

Quote from the final version of the C99 standard.

The following is not a valid fragment (because the union type is not visible within function 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);
}

all members in union reside in the same memory location. its usually to access the same block of memory it more than one way.

for example , you can define:

union {

char a[100];

int b[50];

}x;

union size will be 100 bytes , and read from b[0] is like reading a[0] and a[1] together

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!