我聽到很多人說,在 C 中*,&實際上在它們有效的情況下相互抵消了影響。
假設只是為了說明我定義和初始化一個指標如下:
int *ptr=2000;
顯然,我分配給的值ptr是任意的,試圖尊重它可能會導致分段錯誤。我不太記得整個代碼,但我曾經讀過一本資料結構書,其中作者展示了一些關于結構填充的計算。我想有一些陳述大致是這樣的:
int *newptr=&*ptr;
像那些很多人一樣,我覺得&和*取消了彼此,我們在上面的例子中newptr分配了ptr即的值2000。
&和*相互抵消的說法并不總是正確的。以整數變數為例。如果我們將某些內容應用為:
int x=10;
int y=&*x;
編譯器很自然地提出一個錯誤說invalid type argument of unary ‘*’ (have ‘int’)。從 C 嘗試決議運算式的方式可以很清楚地看出這一點&*x。這就像 (&(*x))
現在回到實際問題,C 應該將運算式決議&*ptr為(&(*ptr)). 所以我覺得*ptr應該先計算然后取地址。但這帶來了segmentation fault嘗試先做的可能性*ptr,因為它ptr包含一些垃圾。
我嘗試了很多次同樣的事情,通過隨機ptr數生成器隨機分配一個值,然后應用&*ptr. 但幸運的是,沒有一次出現任何分段錯誤。
可能是我太幸運了。但考慮到這種情況,我覺得我不太可能每次都走運,而且 C 編譯器可能正在做一些與我想象的相反的聰明事情。可能只是看到 &* 應用于指標,它只是使用指標的原始值,而不是首先進入令人頭疼的 (*ptr) 然后獲取結果的 &。
但問題是,我無法弄清楚實際情況如何。請問有人可以幫我嗎?
uj5u.com熱心網友回復:
指標實際上并未解除參考,因此沒有 UB。
C11 — 6.5.3.2 地址和間接運算子
3 — ... 如果運算元是一元運算
*符的結果,則該運算符和該&運算符都不會被求值,結果就像兩者都被省略了一樣,除了對運算子的約束仍然適用并且結果不是左值.
現在,您可能想知道有效的指標是否是“約束”的一部分。顯然不是,因為正上方有以下部分:
約束
1 — 一元運算
&符的運算元應為函式指示符、[]一元運算*符或一元運算符的結果,或指定不是位欄位且未使用暫存器存盤類說明符宣告的物件的左值。2 — 一元運算
*符的運算元應具有指標型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/392688.html
下一篇:指標算術等價
