2017-07-30 125 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

相關問題