Union:
Memory representaion of union (overlapping memory)
Memory representation if its structure:(contiguous memory)
purpose of union:
Resource:
typedef struct {
int typ;
union {
char *str;
int val;
}
} tElem;
Memory representaion of union (overlapping memory)
+-----------+
0x1010 | |
0x1011 | typ |
0x1012 | |
0x1013 | |
+-----+-----+
0x1014 | | |
0x1015 | str | val |
0x1016 | | |
0x1017 | | |
+-----+-----+
Memory representation if its structure:(contiguous memory)
+-------+
0x1010 | |
0x1011 | typ |
0x1012 | |
0x1013 | |
+-------+
0x1014 | |
0x1015 | str |
0x1016 | |
0x1017 | |
+-------+
0x1018 | |
0x1019 | val |
0x101A | |
0x101B | |
+-------+
purpose of union:
- This allows the size of
struct S
to be only 12 bytes, instead of 28. - implement pseudo-polymorphism in C
enum Type { INTS, FLOATS, DOUBLE };
struct S
{
Type s_type;
union
{
int s_ints[2];
float s_floats[2];
double s_double;
};
};
void do_something(struct S *s)
{
switch(s->s_type)
{
case INTS: // do something with s->s_ints
break;
case FLOATS: // do something with s->s_floats
break;
case DOUBLE: // do something with s->s_double
break;
}
}
- 've seen it in a couple of libraries as a replacement for object oriented inheritance.E.g.
Connection / | \ Network USB VirtualConnection
If you want the Connection "class" to be either one of the above, you could write something like:struct Connection { int type; union { struct Network network; struct USB usb; struct Virtual virtual; } };
- Unions are particularly useful in Embedded programming or in situations where direct access to the hardware/memory is needed. Here is a trivial example:
typedef union { struct { unsigned char byte1; unsigned char byte2; unsigned char byte3; unsigned char byte4; } bytes; unsigned int dword; } HW_Register; HW_Register reg;
Then you can access the reg as follows:reg.dword = 0x12345678; reg.bytes.byte3 = 4;
Endianness (byte order) and processor architecture are of course important.
- you can access directly a single bit in the register/memory address:
typedef union { struct { unsigned char b1:1; unsigned char b2:1; unsigned char b3:1; unsigned char b4:1; unsigned char reserved:4; } bits; unsigned char byte; } HW_RegisterB; HW_RegisterB reg;
With this code you can access directly a single bit in the register/memory address:x = reg.bits.b2;
- you're only supposed to read the field which was most recently written in the union
Resource:
No comments:
Post a Comment