[英]C programming address for 2d array
如果我初始化一個二維數組,可以說
Int a[2][3] = {
1, 2, 3,
4, 5, 6};
是a[0]
== &a[0]
嗎?
我知道a[0]
指向數組第一個元素的地址。 那么&a[0]
仍然是地址嗎?
首先, arrayNum[0]
的類型為Int[3]
, &arrayNum[0]
的類型為Int(*)[3]
(我沒有將OP的Int
更改為可能的int
)。
其次,數組可以衰減為指向其第一個元素的指針,因此arrayNum[0]
可以衰減為Int*
類型的&arrayNum[0][0]
。
這兩個指針&arrayNum[0]
和&arrayNum[0][0]
都指向相同的位置,但是它們的類型非常不同。
我不確定您要在問題中使用==
表示比較什么意思,但請允許我告訴您,它們並不相同 。
數據類型:檢查數據類型。
a[0]
是int [3]
類型的數組的第一個元素。 &a[0]
是指向int [3]
類型的數組的第一個元素的指針,因此,它實質上是int (*) [3]
。 用法:現在,根據使用情況,在某些情況下, 請注意 , “數組類型”會衰減到指向其第一個元素的指針。 考慮到這種情況, a[0]
和&a[0]
都等效於寫入&(a[0][0])
,因此指針值將相同。
為了更好地理解差異,請將a[0]
和&a[0]
用作yo sizeof
運算符的參數(不發生衰減 ),然后使用%zu
轉換說明符打印該值。
通常,它們將打印
12
,即(sizeof (int) * 3)
和 8
,它是sizeof (int (*) [3])
在一個int
大小為4
且指針大小為8
。
[注意]:
引用C11
,第§6.3.2.1章
除非它是sizeof運算符,
_Alignof
運算符或一元&
運算符的操作數,或者是用於初始化數組的字符串文字,否則將類型為“ array of type”的表達式轉換為帶有鍵入“指向類型的指針” ,它指向數組對象的初始元素,而不是左值。 [....]
在兩種意義上,您可能會問a[0]
是否等於&a[0]
:
a[0]
和&a[0]
指向同一位置?
和:
a[0] == &a[0]
評估為true嗎?
從您的問題中不清楚您的意思是什么。 您的文字詢問“是a[0]
== &a[0]
嗎?”由於“ ==”不是代碼格式,因此不清楚您是否打算排除它。
第一個問題的答案是肯定的(假設a[0]
自動轉換為地址),第二個問題的答案不一定是。
正如其他答案和評論所指出的那樣, a[0]
和&a[0]
是不同的東西。 a
是三個int
的兩個數組的數組。 因此a[0]
是一個由三個int
的數組,並且在大多數表達式中,它會自動轉換為指向其第一個元素的指針。 因此,結果是一個指向int
的指針,有效地&a[0][0]
。 相反, &a[0]
是三個int
數組的地址。
因此,這些表達式指向兩個不同的對象,但是兩個對象在同一位置開始,因此指針指向相同的“位置”。
(char *) a[0] == (char *) &a[0] // Evaluates to true.
當我們將指針轉換為char
的指針時,結果指向對象的第一個(最低尋址)字節。 由於兩個指針指向同一位置,因此該表達式的計算結果為true。
但是,當您評估a[0] == &a[0]
,就會出現問題。 為了符合C標准,指針的比較必須將指針與兼容類型進行比較。 但是int
和三個int
數組不是兼容類型。 因此,盡管某些編譯器可能允許使用警告消息,但這種比較並不嚴格符合C。 我們可以改為評估:
a[0] == (int *) &a[0] // Value is not specified.
通過將右側的指針轉換為int
的指針,我們可以使左側和右側具有相同的類型,並且可以對其進行比較。 但是,比較結果未定義。 這是因為,盡管C標准允許我們將一種類型的指針轉換為另一種類型的指針,但是它通常不能保證轉換后的值是多少,除非將其轉換回原始類型,則它將等於原始指針。 (轉換為字符類型的指針很特殊;對於那些字符類型,編譯器確實保證結果指向對象的第一個字節。)
因此,由於我們不知道(int *) &a[0]
是什么,因此我們不知道將其與a[0]
進行比較將返回true還是false。
這可能看起來很奇怪。 如果一個地址與另一個地址指向相同的地方,為什么它們不相等? 在某些計算機上,引用內存中相同位置的方法不止一種。 地址實際上可以由部分的組合形成,例如基地址加偏移量。 例如,代表1230的地址(1000,230)指向與也代表1230的(1200,30)相同的位置。但是顯然(1000,230)與(1200,30)不同。
比較兩個相同類型的指針時,編譯器會以執行比較所需的任何方式自動調整地址的表示形式。 但是,當您將一種類型的指針轉換為另一種(非字符)類型的指針時,類型的更改可能會阻止編譯器獲得正確進行此調整所需的信息。 因此,C標准無法告訴我們在這種情況下會發生什么。
不,他們不一樣。
a[0]
是類型的元素 int[3]
而&a[0]
是一個指針 (int *類型[3]),以a[0]
但是它們都指向相同的地址( a[0]
的第一個元素),但並不相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.