【问题标题】:Alternative to memcpy替代 memcpy
【发布时间】:2014-05-10 18:21:25
【问题描述】:

我正在使用 Arduino 解析从本地网络上的应用程序发送的 UDP 包。这些消息包含 36 个字节的信息。前四个字节代表一个(单精度)浮点数,接下来的四个字节代表另一个,等等。

Arduino 函数 udp.read() 将数据读取为字符,我最终得到一个数组

char data[36] = { ... };

我现在正在寻找一种方法将其转换为相应的九个浮点数。我找到的唯一解决方案是重复使用这个技巧:

float f;
char b[] = {data[0], data[1], data[2], data[3]};
memcpy(&f, &b, sizeof(f));

但是,我相信一定有更好的方法。除了复制内存块,我可以只使用指针并以某种方式告诉 C 将 b 解释为浮点数吗?

谢谢

【问题讨论】:

  • 为什么不建立一个联合来将 char 数组与浮点数组对齐?
  • @Jim 你能提供一些细节吗?我是 C 的新手,所以我不习惯这种非常低级的东西。谢谢。
  • 我刚刚发布了一个答案。
  • 请注意,memcpy(&f, b, sizeof f);唯一解决方案,不对对齐/填充做任何假设。对于解包网络数据包和二进制文件格式,这是要走的路。
  • 对于所有这些解决方案,请确保发送应用程序使用与 Arduino 相同的浮点表示。

标签: c pointers floating-point arduino memcpy


【解决方案1】:

你可以直接读入缓冲区

float data[9];
udp.read((char*)data, sizeof(data));

【讨论】:

    【解决方案2】:
    union Data
    {
       char  data[36];
       float f[9];
    };
    
    
    union Data data;
    data.data[0] = 0;
    data.data[1] = 0;
    data.data[2] = 0;
    data.data[3] = 0;
    
    fprintf(stdout,"float is %f\n",data.float[0]);
    

    【讨论】:

    • 谢谢。以前没听说过工会。很聪明的小东西!
    • 真的很老了。人们不再使用它了。对于 int to bits 也很有用。
    【解决方案3】:

    这是危险的,技术上没有很好的定义,你这样做的方式更好。

    也就是说,在某些平台上你可以逃脱:

    float *f1 = (float *)data;
    float *f2 = (float *)(data + 4);
    

    另外,在你的代码中,我看不出你为什么不直接从data + offsetmemcpy

    【讨论】:

    • 您认为您所展示的 sn-p 究竟有哪些未定义的地方?
    • @delnan 一个特定的实现可能有一些特殊性,例如为浮点数留出一些存储空间,而为其他东西留出一些“通用”存储空间。当您将float * 指向一般存储时,可能会引起欢闹。
    • 谢谢!这正是我想要的。我尝试了一些相同的方法,但我设法弄乱了我的指针。感谢 memcpy 提示;我以前从未使用过该功能。
    • @delnan:是的,这就是这里发生的事情。 datachar 的数组,作为 float 的数组访问。这是非法的,但您可以采取其他方式——您可以通过char * 访问float 的数组。
    • @delnan:你的记忆是正确的。查看 n1124,6.5 第 6 点定义了“有效类型”,而 6.5 第 7 点谴责您访问具有非 char 类型的不兼容类型的对象时未定义的行为。
    猜你喜欢
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    • 2018-04-10
    • 2012-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多