One of the previous two answers must be incorrect - because the question is underspecified. We need to know if the structure contains the binary representation of the IEEE float components, or if it contains a numeric definition.
Based on the fact that they are integers, the first is more likely: -4.2 would be represented as {1,0x81,0x066666} or 0xC0866666. In this case, @ouah's answer is correct, and @pmg's will give 2.85e44.
On the other hand, in order for @pmg's code to be correct, the struct for -4.2 would be have to be stored as {-1,-21,0x433333}. And then applying @ouah's algorithm gives 0xF5C33333 which is -4.9489e32 when interpreted as an IEEE float.
If we assume that you are using the first representation, then there is a non-portable processor trick which can simplify your code. Redefine your struct as a union as follows.
union flt {
struct ieee754 {
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int sign:1;
} raw;
float f;
}
(You might need to reverse the order of arguments depending on your procesor - and ensure the packing is correct - that's the non-portable part)
Now your code can write directly to the memory as bits and read it back as floats:
union flt num;
num.raw.sign = 1;
num.raw.exponent = 129;
num.raw.mantissa = 0x66666;
printf("%f", num.f); //prints 4.2