我是 C 語言的初學者,我想知道如果我這樣寫會發生什么:
int *p;
int b = 4;
int a = 3;
p = &a;
printf("%d", p[1])
我期待結果是“4”,然而,我得到了一個意想不到的結果(這是一個亂數)
我也在下面做實驗: EXP1 EXP2
這讓我更加困惑。我想要一些解釋,謝謝。
uj5u.com熱心網友回復:
p[1]points 超出指向的物件的末端p。取消參考此指標是未定義的行為。
uj5u.com熱心網友回復:
編譯器不一定按照您定義它們的順序存盤物件。
如果你遞給助理一本書、一個盒子和一個瓶子,然后告訴他們把這些東西放在架子上,你認為他們肯定會按這個順序把它們放在架子上嗎?不,他們可能會先拿最容易操作的那個放在架子上,然后是另一個,然后是另一個。如果他們認為這沒有任何意義,他們就不在乎您將物品交給他們的順序。
當您向編譯器定義物件時,它會根據大小和對齊要求等屬性來管理它們。而且它不一定按照您定義它們的順序保存它們。它可以按字母順序將它們存盤在某些資料結構中。或者它可以按哈希碼順序存盤它們。當它為專案分配記憶體位置時,它可能首先處理具有最嚴格對齊要求的物件,然后在每個組中按字母順序或通過遍歷其內部資料結構來檢索它們。
所以,b不一定是a在記憶之后。
但是,即使是這樣,C 標準也沒有定義p[1]在p指向時訪問的行為a。這意味著編譯器在分析 C 標準定義的代碼的含義時,可以確定它printf("%d", p[1])沒有意義并可以忽略它。因此,編譯器優化可以以令人驚訝的方式轉換程式。
uj5u.com熱心網友回復:
An Interesting thing is you can get 4 when you use clang to compile it( https://tio.run/##S9ZNzknMS///XzkzLzmnNCVVwaa4JCUzXy/Djiszr0QhNzEzT0OTq5pLQQHE1SqwBrIg7CQFWwUTBDcRyDWGcAuATLVEKLsIKJmmoaSaoqSjUBBtGKtpzVX7/z8A ), but it's still an undefined behavior and should not use as expect.
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/537268.html
標籤:C指针
下一篇:如何回傳帶有函式引數的動態陣列
