[英]Doesn't a 2D array decay to pointer to pointer
到目前為止,我幾乎可以肯定
int arr[4][5];
然后, arr
將衰減為指向指針的指針。
我不確定如何將arr
指針,但對我來說似乎很明顯。 因為arr[i]
將是一個指針,因此arr
應該是一個指向指針的指針。
我錯過了什么嗎?
是的,您錯過了很多:)
為了避免出現其他問題,我將鏈接到我今天早些時候寫的一個答案 , 該答案解釋了多維數組。
考慮到這一點, arr
是具有4個元素的一維數組,每個元素都是5個int
s的數組。 當在&arr
或sizeof arr
以外的表達式中使用時,它衰減為&arr[0]
。 但是&arr[0]
什么? 它是一個指針,重要的是一個右值。
由於&arr[0]
是指針,因此它不能進一步衰減。 (數組衰減,指針不衰減)。 此外,這是一個右值。 即使它可以衰減為指針,該指針將指向何處? 您不能指向右值。 (什么是&(x+y)
?)
另一種看待它的方法是記住int arr[4][5];
是一個20 int
的連續塊,在編譯器的腦海中分為4批,每批5批,但是在運行時內存中沒有特殊標記。
如果存在“雙重衰減”,則int **
指向什么? 根據定義,它必須指向一個int *
。 但是int *
在內存中的什么位置? 為了防止這種情況的發生,內存中肯定不會掛滿一堆指針。
一個簡單的規則是:
出現在表達式中的對T型數組對象的引用衰減(除三個例外)為指向其第一個元素的指針 ; 結果指針的類型是T指針。
處理一維數組時,數組名稱在傳遞給函數時會轉換為指向第一個元素的指針。
2D數組可以看作是數組的數組 。 在這種情況下, int arr[4][5];
,您可以將arr[]
視為數組名,並在傳遞給函數時將其轉換為指向數組arr
的第一個元素的指針。 由於arr
第一個元素是一個數組,所以arr[i]
是指向該數組第i
行的指針,並且是指向5個int
s數組的指針 。
通常,將2維數組實現為指針數組(在某種意義上,它是指向指針的指針...指向數組中第一個元素(即指針)的指針)。第一個索引(即arr[x]
),它索引到指針數組,並將指針提供給第x
行。 第二個索引(即arr[x][y]
)給出該行中的第y
int
。
對於靜態聲明的數組(如您的示例),實際存儲空間被分配為單個塊...在您的示例中,分配為20個整數(在大多數平台上為80個字節)的單個連續塊。 在這種情況下,沒有指針數組,編譯器只是執行適當的算法以解決數組的正確元素。 具體來說, arr[x][y]
等於*(arr + x * 5 + y)
。 這種自動調整的算法僅在數組的原始范圍內發生...如果將數組傳遞給函數,則維信息將丟失(就像1維數組的維丟失一樣),並且顯式地進行數組索引計算。
為了避免這種情況,請不要將數組聲明為靜態數組,而是聲明為指針數組,每個指針都指向1維數組,例如本例:
int arr0[5];
int arr1[5];
int arr2[5];
int arr3[5];
int* arr[4] = { arr0, arr1, arr2, arr3 };
然后,將arr
傳遞給函數時,也可以將其作為函數中的2維數組進行尋址。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.