2016-02-24 67 views
-4

當運行這樣的代碼它顯示d的值 - > 4 如果取消對COUT < < &一個它顯示的一個適當的值 - > 1指向下一個地址

#include<iostream> 
#include<math.h> 
using namespace std; 
int main() 
{ 
    int a=1,b=2,c=3,d=4; 
    /*cout<<&a<<endl; 
    cout<<&b<<endl; 
    cout<<&c<<endl; 
    cout<<&d<<endl;*/ 
    cout<<*(&b - 0x1); 
} 

有人能幫我理解爲什麼cout會改變返回值嗎?

+13

這是未定義的行爲,所以任何事情都可能發生。 – interjay

+2

由於這是一個猜測,我把它放在這裏:我不得不說,因爲你沒有使用它們,所以你調用未定義的行爲,因爲'a'不再存在,所以變量得到優化。 – NathanOliver

+0

我同意NathanOliver。你確定'4'來自'd'嗎?你很可能只是從堆棧中獲取一些價值。嘗試將'd'的值改爲其他值,看看打印的值是否仍然爲4.最終,過度依賴編譯器以特定順序將內容放入堆棧中是有風險的,除非您非常瞭解編譯器。特別是像這樣的東西,這是不確定的,interjay指出。 –

回答

3

沒有這個說法

cout<<&a<<endl; 

變量a沒有在程序中使用。因此,編譯器可以生成目標代碼,以便程序中不包含a的定義。

當您取消註釋此語句變量a存在於目標代碼中時。

考慮到一般情況下程序行爲是未定義的。

如果指針不是數組的一部分,則不能在變量之前引用指針。

cout<<*(&b - 0x1); 

而且其中所述編譯器將變量在存儲器中的順序是不確定的。

0

您正在調用未定義的行爲。

執行修改指針是不合法的,除非它是任何數組的一部分,並且您的算術將值保存在數組中(或超過數組末尾的值)。

所以你正在訪問一些任意區域的內存,並沒有定義你可能會回來的東西。

當你註釋掉那些線優化程序可能注意到你不使用acd等忽略他們的代碼。當你把它們放在你的頭上時,你會得到你期望的結果,因爲你已經正確地推斷出你的編譯器(儘管絕不是所有的編譯器)在的相對於b的位置(如果有的話)。

優化器不是必需的,通常不會推斷您訪問&b-0x01恰好落在a上。這是未定義的行爲,因此與您得到的結果無關。

0

根據定義,除非使用內存,否則C++會從最後一個開始分配彼此相鄰的所有地址。根據我的經驗,他們彼此相鄰。我可以看到的唯一原因是因爲如果未使用優化a,則不會分配它。 它總是顯示d的值,這是最奇怪的部分。