memcpy没有按照预期的那样做

时间:2009-05-09 08:18:26

标签: c++ c memcpy

我有一些输出错误结果的代码。

#include <stdio.h>
#include <string.h>

int main() 
{
  unsigned char bytes[4];
  float flt=0;

  bytes[0]=0xde;
  bytes[1]=0xad;
  bytes[2]=0xbe;
  bytes[3]=0xef;

  memcpy( &flt, bytes, 4);

  printf("bytes 0x%x float %e\n", flt, flt);
  return 0;
}

我得到的输出是

  

字节0xc0000000浮点-2.000001e + 00

我期待得到

  

bytes 0xdeadbeef float -6.2598534e + 18

编辑#1 正如所指出的那样,字节序可能会有所不同,这将导致以下

  

bytes 0xefbeadde float -1.1802469e + 29

我不明白的是从float到unsigned int的转换导致0xc0000000(同一个printf语句中的float为-2.0000我将属于编译器优化)

之前在另一台计算机上工作过。这可能是一次架构改变。

5 个答案:

答案 0 :(得分:8)

这不是memcpy的问题。

  1. float在通过double printf传递时始终转换为...,因此您无法在大多数英特尔架构上获得4个字节。
  2. 当您在此代码中表达0xdeadbeef时,您认为您的体系结构是BIG端。有许多小端架构,例如Intel x86。

答案 1 :(得分:6)

你是否意识到当传递给像printf()这样的变量参数函数时,浮点数会被提升为double?所以当你说:

printf("bytes 0x%x float %e\n", flt, flt);

您正在尝试处理真正的两个8字节值,如两个4字节 价值观,给予(我相信)未定义的行为。

答案 2 :(得分:2)

printf中的“%x”需要一个unsigned int。你给它一个浮动,它会自动转换,这不是你想要的。你想做类似的事情:

printf("bytes 0x%x float %e\n", *((unsigned int *)&flt), flt);

哦,就像其他人指出的那样,如果你在x86上,你就不会看到0xdeadbeef,更像是0xefbeadde。

答案 3 :(得分:1)

看看这是否更好:

printf("bytes 0x%x float %e\n", *(int *)&flt, flt);

答案 4 :(得分:1)

要查看参数提升,请将声明从float更改为double。在我的机器上,打印:

bytes 0xefbeadde float -1.860545e+230

0xefbeadde是deadbeaf的大端。双精度的最后4个字节是未定义的,因此浮点数后显示的数字会有所不同。

你提到它在另一台计算机上运行,​​那是什么类型的计算机?一定是小端,其中sizeof(float)== sizeof(double):)