我将内存地址从double转换为整数。 即使他们指向相同的地址,为什么值不同?
#include<iostream>
using namespace std;
int main()
{
double d = 2.5;
auto p = (int*)&d;
auto q = &d;
cout<<p<<endl; // prints memory address 0x7fff5fbff660
cout<<q<<endl; // print memory address 0x7fff5fbff660
cout<<*p<<endl; //prints 0
cout<<*q<<endl; // prints 2.5
return 0;
}
但为什么价值不同
0x7fff5fbff660
0x7fff5fbff660
0
2.5
Program ended with exit code: 0
答案 0 :(得分:10)
假设你在一张纸上写了“11”。如果它是十进制数字,那就是11。如果每个值都有一个标记,那就是两个。如果它是二进制的那就是三个。如何解释存储的信息会影响您理解存储信息的值。
答案 1 :(得分:7)
这是因为你违反了strict aliasing rule,给你未定义的行为。你不能通过类型B的指针来访问类型A,只是假装它可以工作。
TL; DR:
如果你有一个
int*
指向包含int
的内存,那么 你将float*
指向该记忆并将其用作float
你打破的记忆 规则。如果你的代码不尊重这个,那么就是编译器 优化器很可能会破坏您的代码。
答案 2 :(得分:7)
double d = 2.5;
auto p = (int*)&d;
auto q = &d;
创建指向同一内存位置的p和q。内存中包含一个double(通常是8个字节)
创建时
auto p = (int*)&d;
你告诉编译器(reintepret_cast< int*> ( &d)
)d中的值是一个整数。
所以指针的值是相同的,但类型不是。
打印时
cout<<*q<<endl; // prints 2.5
您正在显示正确的值 - 因为它是进出的。
打印时
cout<<*p<<endl; //prints 0
您正在查看8字节内存的4个(通常)字节,并将它们解释为整数。
这些碰巧是0x00,0x00,0x00,0x00
答案 3 :(得分:3)
内存地址相同,它们都指向内存中的双精度浮点数。但是,您已经要求编译器将其中一个视为整数,将另一个视为double。 (指针可能只是一个内存地址,但在编译时编译器也有关于该类型的信息。)恰好这个特定的双精度数字的内存表示在被视为0时看起来像0整数。
答案 4 :(得分:0)
因为您自己将它们转换为不同类型。
答案 5 :(得分:-2)
执行auto p = (int*)&d;
时,您要求编译器在为整数分配的内存区域中存储double值。在计算机的内存中以整数和双精度表示不同的格式。在内存中使用浮点representation存储double,而int不存在。这是未定义行为的典型示例。