The output is 7.1, i was wondering if someone could explain why the
output is 7.1 and not 3.5.
The members of a union all share the same memory address. When you set the value of any member of a union, then it will modify the value at that memory address, and since all members are mapped to this address, when you read the value then it'll reflect the last value that was written to that address.
With this line:
mydata.var1 = 'B';
You set the value of that memory to 0x42 then with the next line:
mydata.var2 = 12;
You set the value of that memory to 12 so that when you get here:
if(mydata.var1 == 'B')
mydata.var3 = 3.5;
else
mydata.var3 = 7.1;
The else
clause is executed and now the value of that memory is set to 7.1.
Here's the bigger problem with your code: the use of a union between a char, int, and float doesn't really make sense
The reason is relatively straight forward: the memory size needed for the members is different.
The memory that is needed for a char
is 1 byte as it is the smallest addressable unit for the machine the code is running on. The memory that is needed for a int
(aka signed int) is at least 2 bytes or 16 bits, but on most machines these days is 4 bytes or 32 bits. The memory needed for a float
on most machines is 4 bytes or 32 bits because of IEEE 754 single-precision binary floating-point format. The values that the members themselves can represent is also completely different. A signed char
is usually [-128, 127]. A signed int
, assuming 32 bits, is [−2,147,483,647, +2,147,483,647], and a float
is [1.2 * 10^-38, 3.4 * 10^38]. However, at least a float
and int
are likely to have the same size so a union
containing these makes more sense.
I understand this is probably an educational or beginner exercise, however it is an exercise that has failed to highlight the purpose of a union
and the correct use of one.
The way a union
is used is to interpret the same data in different ways.
A common example is how many networking APIs will define a union for IPv4 addresses
union ipv4addr {
unsigned address;
char octets[4];
};
This allows flexibility when passing this information to a function. Perhaps a particular function only cares about the 32-bit value while another cares only about specific bytes in that 32-bit value.
I recommend you read this answer and this one too for more information on why a union
is useful and how it is correctly applied.