簡體   English   中英

C-當不轉換為其類型的指針時,數組名稱是什么?

[英]C - what is array name when not converted to pointer of its type?

所以有一陣子我對數組名稱和指針感到困惑。

我們聲明int a[10]; 在路上的某個地方也有a &a

因此,我了解了語法的工作原理。 a是數組名稱。 當它不用作sizeof &等的操作數時,它將被轉換或“衰減”,因此它返回一個指向整數的指針,該指針保存着數組第一個元素的地址。

如果將數組名用作sizeof&的操作數,則其類型為int (*)[10] 所以我猜類型是不同的,因為不會發生“衰減”。

但是我仍然不明白&a是如何工作的。 我的理解是,它為我提供whatever it was before the "decay" happened的地址。.因此,在指針發生“衰減”之前,它是什么?編譯器如何與“原始”一起使用以評估&a

相比之下,如果我們聲明int *p; 然后在代碼中的某處有&pp ...

在這種情況下,將為整數p的指針提供一個單獨的指針單元格,該指針單元格具有其地址,該地址上的值將是我們為其分配的任何地址(或該地址預分配處的垃圾值)。

a沒有得到分配在存儲器中的單獨的指針細胞時,它被聲明int a[10] 我聽說它被標識為%ebp的偏移量。 那么,編譯器在對&a求值時會發生什么? 指向整數的指針的“衰減”未發生,首先沒有單獨的“指針”。 那么,什么是編譯器識別a因為當它看到一元的它有什么作用&操作是使用數組名作為操作數?

鑒於:

int a[10];

對象a的類型為int[10] 在大多數(但不是全部)上下文中, 表達式 a “衰減”到指針表達式。 該表達式產生一個int*類型的值,等效於&a[0]

但是我仍然不明白&a是如何工作的。 我的理解是,它為我提供了“衰減”發生之前的地址。.因此,在指針發生“衰減”之前,它是什么?編譯器如何與“原始”一起使用以評估&a

那不是很正確。 &a ,衰減根本不會發生。 a是“ 10 int數組”( int[10] )類型,因此&a是“ 10 int數組的指針”( int(*)[10] )類型。

這沒有什么特別的。 對於some_type類型的任何名稱foo ,表達式&foo的類型都是“ pointer to some_type ”。 (令人困惑的是,這是罕見的情況,其中數組名稱的行為並不奇怪。)

最好將單詞“數組”和“指針”視為形容詞而不是名詞。 這樣我們就可以擁有一個數組對象,一個數組表達式,一個數組類型等等,但是“數組”是模棱兩可的。

這個:

int a[10];

定義一個名為a的數組對象(並分配4 * sizeof (int)個字節來保存它)。 沒有創建指針對象。 您可以通過獲取對象或其任何元素的地址來創建指針 這與任何其他類型的對象沒有什么不同。 定義some_type類型的對象不會創建some_type*類型的對象,但是您可以通過計算對象的地址來創建some_type*類型的值。

那么,當編譯器看到一元&運算符正在使用數組名作為操作數時,它會識別as的作用是什么?

編譯器將a標識為10個元素的整數數組,當看到&運算符時,它將返回該數組的地址。

就像它會看到int i = 3; 為整數, &i為該整數的地址。

關於獲取數組的地址:數組本身就是一個對象,因此它既有大小又有地址(盡管獲取地址很少有用)。

數組到其第一個元素的指針的轉換是強制類型的一種形式。 僅當替代方法是編譯錯誤時才會發生。

例如,您不能將數組與指針進行比較,因此將數組(隱式)強制(強制)為int* (至其第一個元素),然后將指針類型進行比較。 在C語言中,您可以比較任何指針類型。 C只是不在乎(盡管它可能會發出警告)。

正如您所說,這實際上是將int*int(*)[10]進行比較。 由於數組直接保存其數據,因此這些地址必須具有相同的地址(無論鍵入如何)。 因此,數組的地址將始終是其第一個元素的地址。

但是,獲取數組的大小並不是錯誤,因此sizeof(a)可以獲取整個數組的大小,因為無需強制即可使其合法。 因此,這與sizeof(int[10])

正如您所說,您的另一種情況sizeof(&a)實際上是sizeof(int(*)[10])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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