【发布时间】:2021-12-09 20:15:55
【问题描述】:
我目前正在自学 C++,并尽我所能学习有关内存的知识。我发现您可以使用 char 指针来复制 int 的位模式,并通过强制转换将其存储在内存中:
#include <iostream>
using namespace std;
int main()
{
int x = 20;
char* cp = new char[sizeof(int)];
cp[0] = *((char*)&x);
cp[1] = *((char*)&x+1);
cp[2] = *((char*)&x+2);
cp[3] = *((char*)&x+3);
std::cout << (int)*cp; // returns 20;
return 0;
}
上面的代码有效,当我将 cp 转换为 int 以便编译器一次读取 4 个字节时,我得到了正确的数字,即 20。
但是将其更改为浮点数:
#include <iostream>
using namespace std;
int main()
{
float x = 20;
char* cp = new char[sizeof(float)];
cp[0] = *((char*)&x);
cp[1] = *((char*)&x+1);
cp[2] = *((char*)&x+2);
cp[3] = *((char*)&x+3);
std::cout << (float)*cp; // returns 0.
return 0;
}
返回0。现在我在这里有点困惑。如果我复制每个字节,为什么它仍然给我一个 0?如果有人能帮助我理解这一点,那就太棒了。
【问题讨论】:
-
将
(float)*cp更改为*(float*)cp。我告诫不要使用这些做法,因为它们绕过了 C++ 的强类型系统,并且只应在极少数情况下使用并应谨慎使用。 -
@Elijay 这似乎已经解决了,我以为我在逻辑上做错了什么。你能解释一下为什么我必须做 (float)cp 而不是 (float)*cp。我想我明白了为什么,但它还没有完全点击。是的,非常感谢你,我绝对不会在其他项目中这样做。我目前只是想了解记忆,我发现我对它有如此多的控制权。
-
*cp首先发生,然后(float)将 ASCII 字符的值从整数转换为浮点数。其他字节不被访问。 -
@Eljay 它可能会起作用,但它是未定义的行为。千万不要这样做,说真的,如果你遇到了违反严格别名规则导致的错误,甚至猜测发生了什么都会非常痛苦。这不值得,额外的
std::memcpy不会杀死任何人,编译器可以看穿它并尽可能避免实际复制。