C语言中double类型数据通过串口发送到上位机问题
一、问题引出
众所周知,串口发送数据一次是一个字节,那么如何将一个double类型数据(8字节)通过串口发送到上位机呢?
二、问题思考
首先考虑使用位运算的方式将8字节的数据逐一取出,然后逐一发送,但是没有想到浮点型的数据是不可以位运算的。
然后这个时候可以引出联合体了,已知联合体的特性:各成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度
,那么联合体中变量内存空间共享了,那么给其中一个变量赋值,势必会造成其他变量的值的改变。(这里还需要了解小端存储概念)
如下程序所示:
#include <stdio.h>
union
{
unsigned int var1;
unsigned char var2[4];
}data;
int main(int argc, char const *argv[])
{
data.var1 = 0x12345678;
for (int i = 3; i >= 0; i--)
{
printf("%p : %x \n",&data.var2[i] , data.var2[i]);
}
return 0;
}
在上述程序中,定义了一个联合体,虽然我只将var1定义为0x12345678,但是由于联合体变量共用内存,由基于系统是小端存储,因此,连续四字节从低到高分别存储0x78、0x56、0x34、0x12。如下图所示:
三、问题解决
基于上述的验证,我们在对不能位运算的浮点型数据有把它拆成一个字节一个字节需求时,可以使用联合体去处理,如下所示:
#include <stdio.h>
union
{
double var1;
unsigned char var2[8];
}data;
int main(int argc, char const *argv[])
{
data.var1 = 1.265341;
for (int i = 7; i >= 0; i--)
printf("%p : %#x \n",&data.var2[i] , data.var2[i]);
return 0;
}
如上所示,double型的1.265341在内存上的各个字节的分布,我们可以反过来验证一下。程序如下所示:
#include <stdio.h>
union
{
double var1;
unsigned char var2[8];
}data;
int main(int argc, char const *argv[])
{
/*实现将double数据转成拆开的单字节数据*/
/*
data.var1 = 1.265341;
for (int i = 7; i >= 0; i--)
printf("%p : %#x \n",&data.var2[i] , data.var2[i]);
*/
/*反向验证将拆开的字节数据放入联合体变量,是否会让double变量恢复*/
data.var2[0] = 0x63;
data.var2[1] = 0x9b;
data.var2[2] = 0x54;
data.var2[3] = 0x34;
data.var2[4] = 0xd6;
data.var2[5] = 0x3e;
data.var2[6] = 0xf4;
data.var2[7] = 0x3f;
printf("data.var1 = %lf \n",data.var1);
return 0;
}
运行结果如下图所示,说明该方法可行。