簡體   English   中英

2D數組的C編程地址

[英]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.

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