![](/img/trans.png)
[英]Cast int to pointer - why cast to long first? (as in p = (void*) 42; )
[英]Cast int (*a)[4] to int *p
將指向 int 數組的指針轉換為 int 指針是否合法?
int arr[4];
int (*a)[4] = &arr;
int *p = (int*)a;
C 2018 6.3.2.3 7 說我們可以將int (*)[4]
轉換為int *
:
指向對象類型的指針可以轉換為指向不同對象類型的指針。 如果結果指針沒有與引用類型正確對齊,則行為未定義......
該對准是一定正確,因為陣列int
必須有一個所需的對齊int
。
但是,C 標准關於此轉換產生的值的唯一說明是:
...當再次轉換回來時,結果將與原始指針相等。
這意味着int *
可以臨時保存int (*)[4]
。 如果我們執行:
int arr[4];
int (*x)[4] = &arr;
int *y = (int *) x;
int (*z)[4] = (int (*)[4]) y;
然后我們知道x == z
是真的,因為標准告訴我們。 但我們不知道y
是什么。 由於標准允許不同類型的指針具有不同的表示形式(使用以不同方式表示其值的位),因此y
作為int *
可能沒有任何有用的含義。 C 標准沒有說轉換后的指針可用於訪問對象。
大多數 C 實現要么有意地支持這一點,要么作為它們設計方式的產物。 但是,就 C 標准規定的內容而言,沒有給出任何保證。
如果原始指針初始化為NULL
或指向int[4]
的有效指針,則是。 指針轉換不能違反對齊要求,以免得到UB 。 作為高光澤如我所描述的不會違反這些要求,而且這將是可用於非關聯化,因為如果̶ ̶i̶n̶t̶(̶*̶a̶)̶[̶4̶]̶
̶是有效的,非空則存在確實是一個̶ ̶i̶n̶t̶
̶ ̶a̶t̶ ̶ ̶(̶i̶n̶t̶*̶)̶a̶
̶。
如果您對指針轉換感到不安(正如您應該的那樣),您可以在這種情況下通過簡單地執行*a
(將得到int[4]
將衰減為int*
)或a[0]
或&a[0][0]
或&(*a)[0]
。 這樣,您還可以在遵守標准字母的同時取消引用結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.