[英]Confusion about dereference operator (“*”) in C
據我所知,解引用運算符*
返回存儲在指針地址中的值。 我感到困惑的是,運算符與數組的指針一起使用時的行為。 例如,
int a[4][2];
然后a
在內部轉換為2個整數的4個元素的數組的第一個元素的指針。 那么*a
返回哪個值? 我真的很困惑!
的類型的a
是int[4][2]
所以類型*a
(或等價a[0]
是int[2]
它是不一樣的a[0][0]
。 如果您這樣做:
int a[4][2];
printf("%d\n",*a);
編譯器將告訴您以下內容:
警告:格式'%d'期望類型為'int',但是參數2的類型為'int *'
由於數組(在這種情況下是int [2]
類型的數組)被傳遞給函數,因此在此上下文中它會衰減為指向第一個元素的指針。
另一方面,如果您具有**a
,那么它等效於a[0][0]
並具有int
類型。
這個:
int a[4][2];
定義a
一個由4個元素組成的數組,每個元素都是2個int
元素組成的數組。 (二維數組只不過是數組的數組而已。)
在大多數情況下,數組表達式都會隱式轉換為指向數組對象的初始(第零個)元素的指針。 (請注意,存在一個數組對象的假設;這引起了一定的焦慮,但這與此處無關。)
數組表達式不轉換為指針的情況是:
sizeof
的操作數時; &
;的操作數時 和 (像gcc的typeof
這樣的編譯器特定擴展可能會創建更多異常。)
因此,在表達式*a
,子表達式a
(類型為int[4][2]
)隱式轉換為類型為int(*)[2]
指針(指向2個int
s的數組的指針)。 應用一元*
取消引用該指針,使我們得到int[2]
類型的表達式。
但我們尚未大功告成。 *a
也是數組類型的表達式,這意味着根據其使用方式,這次可能會再次轉換為指針,類型為int*
。
如果我們寫sizeof *a
,則子表達式a
從int[4][2]
為int(*)[2]
,但是子表達式*a
沒有從int[2]
轉換為int*
,因此表達式產生int[2]
類型的大小。
如果我們寫**a
, 確實發生了轉換。 *a
是int[2]
類型,將轉換為int*
; 解引用會產生int
類型的表達式。
請注意,盡管事實上我們可以使用兩個指針取消引用操作合法地引用**a
,但沒有指針對象 。 a
是一個數組對象,完全由8個int
對象組成。 隱式轉換產生指針值 。
隱式的數組到指針轉換規則在N1570第6.3.2.1節第3節中。(該段錯誤地將_Alignof
作為第四例外,但是_Alignof
無法應用於表達式。已發布的C11標准更正了該錯誤。)
推薦閱讀: comp.lang.c FAQ的第6節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.