Background
Serial data transfers in embedded systems are byte-oriented. Some data types, such as a float like 231.5, are stored in memory as a sequence of bytes. For example, the float value a = 231.5 is represented in memory as 0x43678000. The processor reads the four bytes and interprets them according to the IEEE 754 float representation to present the decimal value 231.5.
If four bytes {0x43, 0x67, 0x80, 0x00} are received from a serial interface, how can they be converted into a float? Directly writing float a = 0x43678000 is not valid C. In serial communication, when the transmitted data includes floating-point values, unions or structs can be used to reinterpret the byte sequence as a float.
Using a union
A union lets the same memory region be accessed as either a float or a byte array. Example code:
#include <stdio.h>
// union
// float f; // 4 bytes
// unsigned char s[4]; // 4 bytes
typedef union {
float f;
unsigned char s[4];
} Union_test;
typedef struct {
float f1;
} Struct_test;
int main(void) {
float a = 231.5f;
Union_test x;
Struct_test z;
x.f = a;
z = *(Struct_test*)(&(x.s));
printf("z=%.2f ", (double)z.f1);
printf("End of this program\n");
return 0;
}
The union field f and the array s[4] share the same memory. Setting f = 231.5 and then inspecting s[4] will show the four bytes that represent that float. The example above also demonstrates casting the byte array address to a struct pointer and reading the float back through the struct.

Using a struct
The same experiment can be done with a struct. For example, with an array s[4] = {0x00, 0x80, 0x67, 0x43}, casting the address of s[0] to a pointer to a struct containing a float and reading that float will produce 231.5 on a little-endian system.
Endianness
The observed byte order 00 80 67 43 instead of 43 67 80 00 is due to little-endian storage. For multi-byte objects, some architectures store the least significant byte at the lowest address (little-endian), while others store the most significant byte at the lowest address (big-endian).
For example, the 32-bit hexadecimal value 0x01234567 will be stored differently depending on machine endianness:

Endianness test function
You can use a simple function to determine whether a system is little-endian or big-endian. Example:
void idtest(void) {
int a = 1;
unsigned char *start = (unsigned char *)&a;
if (*start == 1)
printf("little endding");
else if (*start == 0)
printf("big endding");
}
Explanation: if the first byte equals 1, the system is little-endian; if it equals 0, the system is big-endian.
ALLPCB