access union member in c
I have a question about union in c language
for example:
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;
//after access t开发者_JAVA百科ype1, and then access type2 immediately, can we get the value b of type2? //I modify the first post a little bit, because it is meanless at the beginning.
}
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.
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
.
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
精彩评论