標籤:

將一個double類型的指針自增一次,前後的地址差是否一定為sizeof(double)?

double* p=0;

p++;

//此刻p的值是否為sizeof(double)?


只能說,+1就是+1,如果你問的是+1之後兩邊static_cast&之後的差是多少,這個沒有講。雖然現在並沒有結果不是sizeof(double)的實現出現(逃


先說一個題外話,標準好像也沒規定:

double * p = 0;

的時候 reinterpret_cast&(p) 就一定 == 0 。

指針類型的字面量 0 就像 Java 的 null 和 Python 的 None ,是個特殊的值,而不一定是數字 0 ,有特殊的類型轉換規則。

實現完全可以在內存裏某個位置放個全局變量,說這個東西就是 nullptr ,然後所有 = 0 的指針實際都指向它,實現只要保證整形的 0 在轉換到指針的時候變成這個 nullptr 的地址就可以了。

基於以上前提,我覺得空指針自增也不能保證其值。


C++標準只規定了對指向數組元素的指針進行數學運算的行為。

除此之外的操作都是UB

參考 Arithmetic operators

針對你的這種情況,改成這樣就合法了

double d;
double* pd = d;

單個對象會被看作一個元素的數組

然後值的差就是8


是的。

double dbs[10];
double * pdbs = dbs;

如果你相信 pdbs[i] 就是*(pdbs + i),那麼就不要懷疑了,前後地址差一定是sizeof(double)。

如果你不相信,那麼下面的是什麼意思呢:

for(int i = 0; i &< sizeof(dbs); ++i)

{

pdbs[i] = 0.1;

}

其實上面的已經證明了 (pdbs + i) 的值是 數組 dbs 中下標為 i 的元素的地址,所以得到的結論是:

當 pdbs是double * 類型的變數時,(pdbs + i ) - pdbs = sizeof(double) * i。

這個結論不是普通的數學加法運算,所以 結論一旦反了過來 就是錯誤的:

(pdbs + i ) = sizeof(double) * i + pdbs;//error

說的再多,不如上機寫代碼,我相信自己,所以我就不上機演示了,題主自己上機寫代碼吧。


此時指針變數為空指針,空指針自增是未定義行為



PC+Win10+VS2015:

double* p = 0;

00B8166E mov dword ptr [p],0

p++;

00B81675 mov eax,dword ptr [p]

00B81678 add eax,8

00B8167B mov dword ptr [p],eax

PC+Ubuntu12+gcc 4.6.3

0x080483b7 &<+3&>: sub $0x10,%esp

0x080483ba &<+6&>: movl $0x0,0xc(%esp)

0x080483c2 &<+14&>: addl $0x8,0xc(%esp)

0x080483c7 &<+19&>: mov 0xc(%esp),%eax

怎麼看都是加8。我覺得所有C/C++編譯器都是這麼工作的,p=sizeof(double)應該是沒問題。


推薦閱讀:

C++ 中的 std::map 不同線程操作不同 key 是否需要加鎖?
g++中數組和vector元素個數最多只能是2^31 -1個嗎?

TAG:C | CC |