Recently I am working on windows and I found that lot of data structures are defined as struct
with union
as member variables. Example of this would be
The union in a struct technique is generally used when you want a variant-style structure. It's generally accompanied by a type identifier, which is used to determine which item in the union to check. It's also seen in the opposite way, such as in Xlib on *NIX, where it's a union with structs, with the first member identical between all structs, defining which struct has the data you need.
When a struct
contains union
members it's generally done as a space saving mechanism. If the struct
can be of certain sub-types by which only certain members are valid then a union
is a good way to not waste space.
For example
enum NumberKind {
Integer,
FloatingPoint
};
struct Number {
NumberKind kind;
union {
int integerValue;
float floatValue;
};
};
In this scenario I've defined a struct
Number which can have type types of numeric values: floating point and integer. It's not valid to have both at the same time so rather than waste space by having both members always defined I created a union
which makes the storage of both equal to the size of the biggest.
Sample Usage of Above as requested
void PrintNumber(Number value) {
if (value.kind == Integer) {
printf("%d\n", value.integerValue);
} else {
printf("%f\n", value.floatValue);
}
}
union means you can have one of its members as its possible value. In the following example, you see the values for each one of them. But this union can be a member of some other structure, where it is enough to specify only one value- either float or integer not both. Hope this helps.
union {
float u_f;
int u_i;
}var;
var.u_f = 23.5;
printf("value is %f\n", var.u_f);
var.u_i = 5;
printf("value is %d\n", var.u_i)
As a relic of the days when 64KB was quite a lot of memory, you have a facility in C++ that allows more than one variable to share the same memory (but, obviously, not at the same time). This is called a union, and there are four basic ways in which you can use one:
You can use it so that a variable A occupies a block of memory at one point in a program, which is later occupied by another variable B of a different type, because A is no longer required. I recommend that you don't do this. It's not worth the risk of error that is implicit in such an arrangement. You can achieve the same effect by allocating memory dynamically.
Alternatively, you could have a situation in a program where a large array of data is required, but you don't know in advance of execution what the data type will be -- it will be determined by the input data. I also recommend that you don't use unions in this case, since you can achieve the same result using a couple of pointers of different types and, again, allocating the memory dynamically.
A third possible use for a union is one that you may need now and again -- when you want to interpret the same data in two or more different ways. This could happen when you have a variable that is of type long, and you want to treat it as two values of type short. Windows will sometimes package two short values in a single parameter of type long passed to a function. Another instance arises when you want to treat a block of memory containing numeric data as a string of bytes, just to move it around.
You can use a union as a means of passing an object or a data value around where you don't know in advance what its type is going to be. The union can provide for storing any one of the possible range of types that you might have.
If you think I am a genius in explaining what a union is and some of it's possible applications, I can not take credit for this. (: This information came from Ivor Horton's Beginning Visual C++ 2010 which I happen to have sitting here on my desk. I hope this was helpful.
Imagine you have a struct which holds a packet of data. The data in the packet can be of a few different types, so you store the type in a member called type. So to read the data in this packet, you first check the type, then you read the corresponding data member, which should contain the data in the packet.
Without unions the data struct would look like this:
struct data {
type_t type;
int number;
char * string;
double fraction;
long long big_number;
}
This would be a rather big data structure. It uses enough room to store one of every possible data type. That's a little unnecessary when you will definitely only have one of those members containing useful information at any point in time.
If we use unions:
struct data {
type_t type;
union payload {
int number;
char * string;
double fraction;
long long big_number;
}
}
Then the struct contains only enough space to store the type plus one of the payload members (i.e. you will have allocated an amount of memory equal to the size of type_t plus the size of the largest possible payload member). This saves a load of space and is much more efficient.
You do have to be careful however, because if the payload contains an int, you can still read it as a double. You will probably just get extremely strange numbers as your program tries to interpret the data wrongly