问题:
假设计算机A和计算机B通信,计算机A给计算机B发送一串16个字节的二进制字节串,以数组形式表示:
unsigned char[16] = {0x3f, 0xa0, 0x00, 0x00, 0xbf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xff, 0xff, 0xff, 0x9c};
其中:
0~3:4个字节为float f1,大端表示,IEEE754格式
4~7:4个字节为float f2,大端表示,IEEE754格式
8~11:4个字节为int i3,大端表示
12~15:4个字节为int i4,大端表示
要求:
- (1)编写一个C语言代码,求出f1、f2、i3、i4的值;
- (2)贴出源代码,以及打印结果。
#include <stdio.h> void swap(unsigned char data[4]) { unsigned char t = data[0]; data[0] = data[3]; data[3] = t; t = data[1]; data[1] = data[2]; data[2] = t; } int main() { union { unsigned char bytes[16]; struct { union { float f1; unsigned char f1_data[4]; }; union { float f2; unsigned char f2_data[4]; }; union { int i3; unsigned char i3_data[4]; }; union { int i4; unsigned char i4_data[4]; }; }; } data = { .bytes = { 0x3f, 0xa0, 0x00, 0x00, 0xbf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xff, 0xff, 0xff, 0x9c } }; swap(data.f1_data); swap(data.f2_data); swap(data.i3_data); swap(data.i4_data); printf("%f %f %d %d\n", data.f1, data.f2, data.i3, data.i4); return 0; }
如果想检查类型,那就
void swap(_) unsigned char _[4]; { unsigned char t = _[0]; _[0] = _[3]; _[3] = t; t = _[1]; _[1] = _[2]; _[2] = t; } int main() { union { unsigned char bytes[16]; struct { float f1; float f2; int i3; int i4; }; } data = { .bytes = { 0x3f, 0xa0, 0x00, 0x00, 0xbf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xff, 0xff, 0xff, 0x9c } }; swap(&data.f1); swap(&data.f2); swap(&data.i3); swap(&data.i4); printf("%f %f %d %d\n", data.f1, data.f2, data.i3, data.i4); return 0; }
思路历程:
首先想到的是利用指针从第三字节读到第零字节,存储到float类型变量中,然后打印。逐下同理。由于存储数据的类型是char[] 最小单位是1字节,利用地址(也就是指针)对字节进行操作(对字节进行操作是正确的),随之,确定了操作的基本单位—————字节
那么,指针的数据类型就确定了 unsigned char*;
随后,就没有随后了 代码打不出来 问了下qq群中的大佬,给了以上代码
简单分析一下上面的代码
联合体和结构体套用, 读取float 就自动读取4字节数据,接下来就是对字节的交换操作了,由于是大端存储(字节逆序:将最低有效字节放在大地址单元中),数据逆置。
swap(unsigned char data[4]),简单容易理解,就不过多叙述了。
逆序后
OK了!
细节
ps:对话来自qq群一个好友回答 只是个人见解 如有错误可请谅解!