2017-07-30 74 views
7

我将内存地址从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 

回答

6
double d = 2.5; 
auto p = (int*)&d; 
auto q = &d; 

p和q被创建指向相同的内存位置。当创建

auto p = (int*)&d; 

你告诉编译器(reintepret_cast< int*> (&d)),在d的值是一个整数的存储器保存双(通常为8个字节)

所以指针的值是相同的,但类型不是。

当你打印出

cout<<*q<<endl; // prints 2.5 

您显示正确的值 - 因为它进来了通过。

当你打印出来

cout<<*p<<endl; //prints 0 

您正在寻找在8字节内存的4(典型值)字节,将它们解释为整数。

这些恰好为0x00,0x00时,0×00,0×00

+0

非常感谢,我现在有点清楚 –

0

因为你让他们铸造到不同类型的自己。

+0

是的,我做到了:)存储地址相同 –

+0

请参阅@mksteve上面的详细解答。 –

9

假设你在一张纸上写有“11”。如果是十进制数字,那是十一。如果每个值都有一个标记,那就是两个。如果它是二进制的,那是三个。如何解释存储的信息会影响您理解存储的价值。

7

这是因为你违反了strict aliasing rule,给你未定义的行为。你不能通过类型B的指针访问类型A,只是假装它工作。


TL; DR:

如果你有一个int*指向包含int一些内存,然后 你指向一个float*到内存并把它作为一个float你打破 规则。如果您的代码不尊重这一点,那么编译器的优化器很可能会破坏您的代码。

3

内存地址是相同的,它们都指向内存中的双精度浮点数。但是,您已经要求编译器将一个视为一个整数,而另一个视为双精度。 (一个指针可能只是一个内存地址,但是在编译时编译器也会提供关于该类型的信息。)这种情况发生时,这个特殊的双精度数的内存表示看起来像0一个整数。

-2

当你做auto p = (int*)&d;你问的编译器来存储分配的整数存储区中的双重价值。一个整数和一个double在计算机内存中以不同的格式表示。在存储器中使用浮点representation存储double,而int不是。这是未定义行为的典型例子。

+0

如果你能解释downvotes背后的基本原理,那将是一件好事。 – SCCC

+2

“要求编译器在分配给整数的内存区域中存储double值” - 错误。这不会存储一个双。此声明不存储任何内容。双重已经在那里。演员阵容是一个请求,将这个double解释为一个int,而这可能会导致其他答案中所述的问题。 – 1201ProgramAlarm

相关问题