【实验向】问题:假设计算机A和计算机B通信,计算机A给计算机B发送一串16个字节的二进制字节串,以数组形式表示:

简介: 【实验向】问题:假设计算机A和计算机B通信,计算机A给计算机B发送一串16个字节的二进制字节串,以数组形式表示:

问题:


假设计算机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群中的大佬,给了以上代码

简单分析一下上面的代码

4ac19c36192b91a2b6c61b0b03650cfd_f44513bb1d6ef9fdb701bd90746e054c.png

联合体和结构体套用, 读取float 就自动读取4字节数据,接下来就是对字节的交换操作了,由于是大端存储(字节逆序:将最低有效字节放在大地址单元中),数据逆置。

swap(unsigned char data[4]),简单容易理解,就不过多叙述了。

逆序后

269144160d14035f317aa29b1f17bf40_b99f3289c80bad3a892a0dd63cdd72a5.png

OK了!


细节


55c3f029e8efe011f2afe99592b16714_f96f125e5ff90c7b0d77750373747b6e.png

a6bde3c97400615b7f8cd68c158034d2_7a825ffa8b35bba8edda6bc0f0b6a0ec.png

d3993f375fc7ea5832df08feb056f5d8_72f24101f3d2b22ad1050e55eee3909c.png

a354fc65edbf85321630c98652d90a96_fe3061bf6b54854778c4cc5976d899a9.png

2c8c8e39f40c6970adfaa03f28784376_36cd9940250f9b86d3a798b178baffaa.png

6cb3bef8a3b91e8bf790f70ea6f5defe_b44cedaab3de3317a3bb167e8ed9cdbc.png

d35e0c113d0b9a9f3d82ce1b0dde9f2e_0a4a455abbb3a804fa5947039bd8f0e9.png

0389e70c541e48592fc6d4d8af8e75f2_886fe017fc947a110a45b1f55012e834.png

3a9536c96acd61df3255120242ee701d_1fdb69ca8b22488a8c0ac6629ccede75.png

1843018a0e2d5810750c921773815246_d1d68f466905470236c195b24554e3ed.png

ps:对话来自qq群一个好友回答 只是个人见解 如有错误可请谅解


相关文章
|
SQL HIVE
Hive分区+根据分区查询
Hive分区+根据分区查询
|
数据可视化 前端开发 JavaScript
可视化工具D3.js
可视化工具D3.js
379 2
|
负载均衡 网络协议 Unix
Nginx七层(应用层)反向代理:SCGI代理scgi_pass篇
Nginx七层(应用层)反向代理:SCGI代理scgi_pass篇
220 1
|
8月前
|
JavaScript 前端开发 开发者
Vue中的class和style绑定
在 Vue 中,class 和 style 绑定是基于数据驱动视图的强大功能。通过 class 绑定,可以动态更新元素的 class 属性,支持对象和数组语法,适用于普通元素和组件。style 绑定则允许以对象或数组形式动态设置内联样式,Vue 会根据数据变化自动更新 DOM。
|
12月前
|
机器学习/深度学习 人工智能 安全
智能时代的隐私守护者:AI加密技术的崛起与挑战###
本文深入探讨了人工智能(AI)在数据加密领域的创新应用,分析了AI如何增强数据安全性,同时也指出了面临的挑战和未来发展趋势。通过具体案例分析,展现了AI加密技术在保护个人隐私与促进数据安全方面的潜力,为读者提供对未来智能时代隐私保护的深刻洞见。 ###
|
移动开发 监控 前端开发
如何从0-1的建设云上稳定性?
本文将从前后端的视角整体看下我们在云上稳定性治理的一些路径和经验。首先从平台的系统架构模型出发,站在全局视角看下整个平台的风险。
|
存储 SQL 关系型数据库
MySQL存储过程和存储函数的使用
MySQL的存储过程和存储函数在功能和用法上有明显的区别。存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,通过指定名称和参数(如果有)来调用执行,可以返回多个值或结果集,但不直接返回值。而存储函数则是一个有返回值的特殊存储过程,它返回一个值或表对象,可以直接嵌入SQL语句中使用,如SELECT语句中。两者都是为了提高SQL代码的重用性和性能,但使用场景和方式有所不同。
4446 4
|
机器学习/深度学习 图计算
R语言广义线性模型(GLM)、全子集回归模型选择、检验分析全国风向气候数据
R语言广义线性模型(GLM)、全子集回归模型选择、检验分析全国风向气候数据
|
Linux C++
【代码片段】Linux C++打印当前函数调用堆栈
【代码片段】Linux C++打印当前函数调用堆栈
432 0

热门文章

最新文章