簡體   English   中英

關於C中的解引用運算符(“ *”)的困惑

[英]Confusion about dereference operator (“*”) in C

據我所知,解引用運算符*返回存儲在指針地址中的值。 我感到困惑的是,運算符與數組的指針一起使用時的行為。 例如,

int a[4][2];

然后a在內部轉換為2個整數的4個元素的數組的第一個元素的指針。 那么*a返回哪個值? 我真的很困惑!

的類型的aint[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 ,則子表達式aint[4][2]int(*)[2] ,但是子表達式*a 沒有int[2]轉換為int* ,因此表達式產生int[2]類型的大小。

如果我們寫**a確實發生了轉換。 *aint[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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM