-6

我不明白为什么数组 t1 是空的。据我所知, memcpy 不应该关心对象的底层类型。你怎么看?%)

cout << sizeof(float) << sizeof(int) << endl;

float *t1= (float *)malloc(20*sizeof(float));
memset(t1,0x00,20*sizeof(float)); 

int *t2= (int *)malloc(20*sizeof(int));
for (int i=0; i<20; i++) 
    t2[i]=i;  

memcpy(t1,t2,20*sizeof(int));

for (int i=0; i<20; i++) 
    printf("%f\t", (float)t1[i]); 

我知道类型转换是什么意思。好的,我犯了一些小错误。这是粗心!

PS 这是了解 memcpy 工作原理的示例!

4

6 回答 6

4

该函数逐字memcpy复制位。因此,您将位从整数数组复制到浮点数组:内容与浮点表示匹配的可能性很小。所以你得到一个数组,里面装满了对你的浮点格式没有意义的东西。

简而言之,在最低级别,1看起来1.0f完全不同。


演员表(float)t1[i])并没有真正做任何事情,因为t1[i]已经是float

于 2012-08-24T08:05:46.030 回答
3

尽管您提出抗议,但您的数组不是“空的”。它只包含一个非常非常小的值:您的机器使用 IEEE754 标准来表示浮点数。在该标准中,全零的单词表示值 0.0。下一个更大的字(即,通过将基础位加 1 获得的字)代表下一个最大的浮点值,这是一个非常小的非规范值。当您printf将此值设为标准精度(小数点后 6 位?)时,它只是四舍五入为零。

这是我对类似问题的切线相关答案。

于 2012-08-24T08:09:58.267 回答
1

您将整数值 0、1、2、3、4、5 .. 20 强制为浮点数。浮点数和整数使用不同的底层表示,而且我认为这些值非常小,除非您更改格式以包含很多精度,否则它们将打印为 0。

于 2012-08-24T08:09:57.307 回答
1

int 和 float 的位排列不同。即使复制得很好,您也无法理解它。

改成

for (int i=0; i<20; i++) 
  printf("%d\t", (int)t1[i]);

你会看到复制的东西。

于 2012-08-24T08:10:48.660 回答
0

memcpy 将内存复制为字节,并不关心内存位置存储了哪些底层类型。内存中的整数以不同于浮点数的格式存储,因此基本上以 t1 结尾的可能是但不一定是有效的浮点值。

于 2012-08-24T08:09:39.017 回答
0

由于您使用的是 C++,因此您可以使用 C++ 功能,例如std::vector

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;
int main(){
    cout << sizeof(float) << sizeof(int) << endl;
    std::vector<float> floatVector;
    std::vector<int> intVector;

    for (int i = 0; i < 20; i++)
    {
        intVector.push_back(i);
    }
    floatVector.resize(intVector.size());

    std::copy(intVector.begin(), intVector.end(), floatVector.begin());
    for (int i = 0; i < 20; i++)
    {
        cout << "element[" << i << "]: " << floatVector[i] << std::endl;
    }
}
于 2012-08-24T08:34:12.497 回答